ini_file_reader use extra context for compatible

pull/37/head
yuqing 2017-02-06 15:06:30 +08:00
parent ba1d541051
commit 2b0706775a
3 changed files with 124 additions and 39 deletions

View File

@ -1,9 +1,10 @@
Version 1.34 2017-01-31 Version 1.34 2017-02-06
* ini_file_reader: LOCAL_IP support CIDR addresses * ini_file_reader: LOCAL_IP support CIDR addresses
* ini_file_reader: return the last when get single value, * ini_file_reader: return the last when get single value,
such as iniGetStrValue and iniGetIntValue such as iniGetStrValue and iniGetIntValue
* ini_file_reader support #@set directive * ini_file_reader support #@set directive
* ini_file_reader use extra context for compatible
Version 1.33 2017-01-04 Version 1.33 2017-01-04
* add function hash_get_prime_capacity * add function hash_get_prime_capacity

View File

@ -62,15 +62,21 @@ typedef struct {
char **contents; char **contents;
} DynamicContents; } DynamicContents;
typedef struct {
int offset; //deal offset
HashArray *vars; //variables with #@set
} SetDirectiveVars;
typedef struct { typedef struct {
bool used; bool used;
IniContext *context; IniContext *context;
DynamicContents dynamicContents; DynamicContents dynamicContents;
SetDirectiveVars set;
} CDCPair; } CDCPair;
static int g_dynamic_content_count = 0; static int g_dynamic_content_count = 0;
static int g_dynamic_content_index = 0; static int g_dynamic_content_index = 0;
static CDCPair g_dynamic_contents[_MAX_DYNAMIC_CONTENTS] = {{false, NULL, {0, 0, NULL}}}; static CDCPair g_dynamic_contents[_MAX_DYNAMIC_CONTENTS] = {{false, NULL, {0, 0, NULL}, {0, NULL}}};
//dynamic alloced contents which will be freed when destroy //dynamic alloced contents which will be freed when destroy
@ -688,12 +694,12 @@ static int iniDoLoadItemsFromBuffer(char *content, IniContext *pContext)
return result; return result;
} }
static DynamicContents *iniAllocDynamicContent(IniContext *pContext) static CDCPair *iniGetCDCPair(IniContext *pContext)
{ {
int i; int i;
if (g_dynamic_contents[g_dynamic_content_index].context == pContext) if (g_dynamic_contents[g_dynamic_content_index].context == pContext)
{ {
return &g_dynamic_contents[g_dynamic_content_index].dynamicContents; return g_dynamic_contents + g_dynamic_content_index;
} }
if (g_dynamic_content_count > 0) if (g_dynamic_content_count > 0)
@ -703,11 +709,23 @@ static DynamicContents *iniAllocDynamicContent(IniContext *pContext)
if (g_dynamic_contents[i].context == pContext) if (g_dynamic_contents[i].context == pContext)
{ {
g_dynamic_content_index = i; g_dynamic_content_index = i;
return &g_dynamic_contents[g_dynamic_content_index].dynamicContents; return g_dynamic_contents + g_dynamic_content_index;
} }
} }
} }
return NULL;
}
static CDCPair *iniAllocCDCPair(IniContext *pContext)
{
int i;
CDCPair *pair;
if ((pair=iniGetCDCPair(pContext)) != NULL)
{
return pair;
}
if (g_dynamic_content_count == _MAX_DYNAMIC_CONTENTS) if (g_dynamic_content_count == _MAX_DYNAMIC_CONTENTS)
{ {
return NULL; return NULL;
@ -721,13 +739,74 @@ static DynamicContents *iniAllocDynamicContent(IniContext *pContext)
g_dynamic_contents[i].context = pContext; g_dynamic_contents[i].context = pContext;
g_dynamic_content_index = i; g_dynamic_content_index = i;
g_dynamic_content_count++; g_dynamic_content_count++;
return &g_dynamic_contents[g_dynamic_content_index].dynamicContents; return g_dynamic_contents + g_dynamic_content_index;
} }
} }
return NULL; return NULL;
} }
static DynamicContents *iniAllocDynamicContent(IniContext *pContext)
{
static CDCPair *pair;
pair = iniAllocCDCPair(pContext);
if (pair == NULL)
{
return NULL;
}
return &pair->dynamicContents;
}
static SetDirectiveVars *iniGetVars(IniContext *pContext)
{
static CDCPair *pair;
pair = iniGetCDCPair(pContext);
if (pair == NULL)
{
return NULL;
}
return &pair->set;
}
static SetDirectiveVars *iniAllocVars(IniContext *pContext, const bool initVars)
{
static CDCPair *pair;
SetDirectiveVars *set;
set = iniGetVars(pContext);
if (set == NULL)
{
pair = iniAllocCDCPair(pContext);
if (pair == NULL)
{
return NULL;
}
set = &pair->set;
}
if (initVars && set->vars == NULL)
{
set->vars = (HashArray *)malloc(sizeof(HashArray));
if (set->vars == NULL)
{
logWarning("file: "__FILE__", line: %d, "
"malloc %d bytes fail",
__LINE__, (int)sizeof(HashArray));
return NULL;
}
if (hash_init_ex(set->vars, simple_hash, 17, 0.75, 0, true) != 0)
{
free(set->vars);
set->vars = NULL;
return NULL;
}
}
return set;
}
static void iniFreeDynamicContent(IniContext *pContext) static void iniFreeDynamicContent(IniContext *pContext)
{ {
CDCPair *pCDCPair; CDCPair *pCDCPair;
@ -1095,16 +1174,29 @@ static bool iniCalcCondition(char *condition, const int condition_len,
else else
{ {
char *value; char *value;
value = (char *)hash_find(pContext->set.vars, varStr, varLen); SetDirectiveVars *set;
if (value == NULL)
set = iniGetVars(pContext);
if (set != NULL && set->vars != NULL)
{
value = (char *)hash_find(set->vars, varStr, varLen);
if (value == NULL)
{
logWarning("file: "__FILE__", line: %d, "
"variable \"%.*s\" not exist", __LINE__,
varLen, varStr);
}
else
{
return iniMatchValue(value, values, count);
}
}
else
{ {
logWarning("file: "__FILE__", line: %d, " logWarning("file: "__FILE__", line: %d, "
"variable \"%.*s\" not exist", __LINE__, "variable \"%.*s\" not exist", __LINE__,
varLen, varStr); varLen, varStr);
} return false;
else
{
return iniMatchValue(value, values, count);
} }
} }
@ -1159,6 +1251,7 @@ static int iniDoProccessSet(char *pSet, char **ppSetEnd,
char *key; char *key;
char *value; char *value;
int value_len; int value_len;
SetDirectiveVars *set;
pStart = pSet + _PREPROCESS_TAG_LEN_SET; pStart = pSet + _PREPROCESS_TAG_LEN_SET;
*ppSetEnd = strchr(pStart, '\n'); *ppSetEnd = strchr(pStart, '\n');
@ -1184,21 +1277,9 @@ static int iniDoProccessSet(char *pSet, char **ppSetEnd,
return EFAULT; return EFAULT;
} }
if (pContext->set.vars == NULL) if ((set=iniAllocVars(pContext, true)) == NULL)
{ {
pContext->set.vars = (HashArray *)malloc(sizeof(HashArray)); return ENOMEM;
if (pContext->set.vars == NULL)
{
logWarning("file: "__FILE__", line: %d, "
"malloc %d bytes fail",
__LINE__, (int)sizeof(HashArray));
return ENOMEM;
}
if ((result=hash_init_ex(pContext->set.vars,
simple_hash, 17, 0.75, 0, true)) != 0)
{
return result;
}
} }
key = trim(parts[0]); key = trim(parts[0]);
@ -1226,7 +1307,7 @@ static int iniDoProccessSet(char *pSet, char **ppSetEnd,
value_len = strlen(value); value_len = strlen(value);
} }
return hash_insert_ex(pContext->set.vars, key, strlen(key), return hash_insert_ex(set->vars, key, strlen(key),
value, value_len + 1, false); value, value_len + 1, false);
} }
@ -1234,11 +1315,17 @@ static int iniProccessSet(char *content, char *pEnd,
IniContext *pContext) IniContext *pContext)
{ {
int result; int result;
SetDirectiveVars *set;
char *pStart; char *pStart;
char *pSet; char *pSet;
char *pSetEnd; char *pSetEnd;
pStart = content + pContext->set.offset; if ((set=iniAllocVars(pContext, false)) == NULL)
{
return ENOMEM;
}
pStart = content + set->offset;
while (pStart < pEnd) while (pStart < pEnd)
{ {
pSet = iniFindTag(content, pStart, _PREPROCESS_TAG_STR_SET, pSet = iniFindTag(content, pStart, _PREPROCESS_TAG_STR_SET,
@ -1270,7 +1357,7 @@ static int iniProccessSet(char *content, char *pEnd,
} }
} }
pContext->set.offset = pEnd - content; set->offset = pEnd - content;
return 0; return 0;
} }
@ -1827,6 +1914,7 @@ static int iniFreeHashData(const int index, const HashData *data, void *args)
void iniFreeContext(IniContext *pContext) void iniFreeContext(IniContext *pContext)
{ {
SetDirectiveVars *set;
if (pContext == NULL) if (pContext == NULL)
{ {
return; return;
@ -1840,17 +1928,17 @@ void iniFreeContext(IniContext *pContext)
hash_walk(&pContext->sections, iniFreeHashData, NULL); hash_walk(&pContext->sections, iniFreeHashData, NULL);
hash_destroy(&pContext->sections); hash_destroy(&pContext->sections);
iniFreeDynamicContent(pContext);
if (pContext->set.vars != NULL) set = iniGetVars(pContext);
if (set != NULL && set->vars != NULL)
{ {
hash_destroy(pContext->set.vars); hash_destroy(set->vars);
free(pContext->set.vars); free(set->vars);
pContext->set.vars = NULL; set->vars = NULL;
} }
iniFreeDynamicContent(pContext);
} }
#define INI_FIND_ITEM(szSectionName, szItemName, pContext, pSection, \ #define INI_FIND_ITEM(szSectionName, szItemName, pContext, pSection, \
targetItem, pItem, return_val) \ targetItem, pItem, return_val) \
do { \ do { \

View File

@ -52,10 +52,6 @@ typedef struct
IniSection *current_section; //for load from ini file IniSection *current_section; //for load from ini file
char config_path[MAX_PATH_SIZE]; //save the config filepath char config_path[MAX_PATH_SIZE]; //save the config filepath
bool ignore_annotation; bool ignore_annotation;
struct {
int offset; //deal offset
HashArray *vars; //variables with #@set
} set;
} IniContext; } IniContext;
#ifdef __cplusplus #ifdef __cplusplus