add annotation mechanism for ini parse
parent
f71c846a24
commit
ad51130d2d
|
|
@ -22,11 +22,44 @@
|
||||||
#define _LINE_BUFFER_SIZE 512
|
#define _LINE_BUFFER_SIZE 512
|
||||||
#define _INIT_ALLOC_ITEM_COUNT 32
|
#define _INIT_ALLOC_ITEM_COUNT 32
|
||||||
|
|
||||||
|
static AnnotationMap *g_annotataionMap;
|
||||||
|
|
||||||
|
static int remallocSection(IniSection *pSection, IniItem **pItem);
|
||||||
static int iniDoLoadFromFile(const char *szFilename, \
|
static int iniDoLoadFromFile(const char *szFilename, \
|
||||||
IniContext *pContext);
|
IniContext *pContext);
|
||||||
static int iniDoLoadItemsFromBuffer(char *content, \
|
static int iniDoLoadItemsFromBuffer(char *content, \
|
||||||
IniContext *pContext);
|
IniContext *pContext);
|
||||||
|
|
||||||
|
void iniSetAnnotationCallBack(AnnotationMap *map, int count)
|
||||||
|
{
|
||||||
|
int bytes;
|
||||||
|
AnnotationMap *p;
|
||||||
|
|
||||||
|
if (count <= 0) {
|
||||||
|
logWarning("file: "__FILE__", line: %d, " \
|
||||||
|
"iniSetAnnotationCallBack fail count(%d) is incorrectly.", \
|
||||||
|
__LINE__, count);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bytes = sizeof(AnnotationMap) * (count + 1);
|
||||||
|
g_annotataionMap = (AnnotationMap *) malloc(bytes);
|
||||||
|
if (g_annotataionMap == NULL) {
|
||||||
|
logError("file: "__FILE__", line: %d, " \
|
||||||
|
"malloc fail, errno: %d, error info: %s", \
|
||||||
|
__LINE__, errno, STRERROR(errno));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(g_annotataionMap, map, bytes);
|
||||||
|
|
||||||
|
p = g_annotataionMap + count;
|
||||||
|
p->func_name = NULL;
|
||||||
|
p->func_init = NULL;
|
||||||
|
p->func_destroy = NULL;
|
||||||
|
p->func_get = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static int iniCompareByItemName(const void *p1, const void *p2)
|
static int iniCompareByItemName(const void *p1, const void *p2)
|
||||||
{
|
{
|
||||||
return strcmp(((IniItem *)p1)->name, ((IniItem *)p2)->name);
|
return strcmp(((IniItem *)p1)->name, ((IniItem *)p2)->name);
|
||||||
|
|
@ -241,19 +274,30 @@ int iniLoadFromBuffer(char *content, IniContext *pContext)
|
||||||
|
|
||||||
static int iniDoLoadItemsFromBuffer(char *content, IniContext *pContext)
|
static int iniDoLoadItemsFromBuffer(char *content, IniContext *pContext)
|
||||||
{
|
{
|
||||||
|
AnnotationMap *pAnnoMap;
|
||||||
IniSection *pSection;
|
IniSection *pSection;
|
||||||
IniItem *pItem;
|
IniItem *pItem;
|
||||||
char *pLine;
|
char *pLine;
|
||||||
char *pLastEnd;
|
char *pLastEnd;
|
||||||
char *pEqualChar;
|
char *pEqualChar;
|
||||||
|
char *pFunc_name;
|
||||||
|
char *pItemName;
|
||||||
|
char *pAnnoItemLine;
|
||||||
char *pIncludeFilename;
|
char *pIncludeFilename;
|
||||||
|
char *pItemValue[100];
|
||||||
char full_filename[MAX_PATH_SIZE];
|
char full_filename[MAX_PATH_SIZE];
|
||||||
|
int i;
|
||||||
int nLineLen;
|
int nLineLen;
|
||||||
int nNameLen;
|
int nNameLen;
|
||||||
|
int nItemCnt;
|
||||||
int nValueLen;
|
int nValueLen;
|
||||||
int result;
|
int result;
|
||||||
|
int isAnnotation;
|
||||||
|
|
||||||
result = 0;
|
result = 0;
|
||||||
|
nItemCnt = -1;
|
||||||
|
pAnnoItemLine = NULL;
|
||||||
|
isAnnotation = 0;
|
||||||
pLastEnd = content - 1;
|
pLastEnd = content - 1;
|
||||||
pSection = pContext->current_section;
|
pSection = pContext->current_section;
|
||||||
pItem = pSection->items + pSection->count;
|
pItem = pSection->items + pSection->count;
|
||||||
|
|
@ -328,6 +372,136 @@ static int iniDoLoadItemsFromBuffer(char *content, IniContext *pContext)
|
||||||
free(pIncludeFilename);
|
free(pIncludeFilename);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
else if (isAnnotation || (*pLine == '#' && \
|
||||||
|
strncasecmp(pLine+1, "@function", 9) == 0 && \
|
||||||
|
(*(pLine+10) == ' ' || *(pLine+10) == '\t')))
|
||||||
|
{
|
||||||
|
if (isAnnotation == 0) {
|
||||||
|
pFunc_name = strdup(pLine + 11);
|
||||||
|
if (pFunc_name == NULL) {
|
||||||
|
logError("file: "__FILE__", line: %d, " \
|
||||||
|
"strdup %d bytes fail", __LINE__, \
|
||||||
|
(int)strlen(pLine + 11) + 1);
|
||||||
|
result = errno != 0 ? errno : ENOMEM;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
trim(pFunc_name);
|
||||||
|
isAnnotation = 1;
|
||||||
|
pAnnoItemLine = pLastEnd + 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
isAnnotation = 0;
|
||||||
|
|
||||||
|
if (pLine != pAnnoItemLine) {
|
||||||
|
logError("file: "__FILE__", line: %d, " \
|
||||||
|
"the @function and annotation item " \
|
||||||
|
"must be next to each other", __LINE__);
|
||||||
|
result = EINVAL;
|
||||||
|
free(pFunc_name);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
trim(pLine);
|
||||||
|
if (*pLine == '#' || *pLine == '\0') {
|
||||||
|
logError("file: "__FILE__", line: %d, " \
|
||||||
|
"the @function and annotation item " \
|
||||||
|
"must be next to each other", __LINE__);
|
||||||
|
result = EINVAL;
|
||||||
|
free(pFunc_name);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
pEqualChar = strchr(pLine, '=');
|
||||||
|
if (pEqualChar == NULL) {
|
||||||
|
logError("file: "__FILE__", line: %d, " \
|
||||||
|
"the @function and annotation item " \
|
||||||
|
"must be next to each other", __LINE__);
|
||||||
|
result = EINVAL;
|
||||||
|
free(pFunc_name);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
nNameLen = pEqualChar - pLine;
|
||||||
|
nValueLen = strlen(pLine) - (nNameLen + 1);
|
||||||
|
if (nNameLen > FAST_INI_ITEM_NAME_LEN) {
|
||||||
|
nNameLen = FAST_INI_ITEM_NAME_LEN;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pSection->count >= pSection->alloc_count) {
|
||||||
|
result = remallocSection(pSection, &pItem);
|
||||||
|
if (result) {
|
||||||
|
free(pFunc_name);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(pItem->name, pLine, nNameLen);
|
||||||
|
memcpy(pItem->value, pEqualChar + 1, nValueLen);
|
||||||
|
|
||||||
|
trim(pItem->name);
|
||||||
|
trim(pItem->value);
|
||||||
|
|
||||||
|
if (g_annotataionMap == NULL) {
|
||||||
|
logWarning("file: "__FILE__", line: %d, " \
|
||||||
|
"not set annotataionMap and (%s) will use " \
|
||||||
|
"the item value (%s)", __LINE__, pItem->name,
|
||||||
|
pItem->value);
|
||||||
|
pSection->count++;
|
||||||
|
pItem++;
|
||||||
|
free(pFunc_name);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
pAnnoMap = g_annotataionMap;
|
||||||
|
while (pAnnoMap->func_name) {
|
||||||
|
if (strlen(pAnnoMap->func_name) == strlen(pFunc_name)
|
||||||
|
&& strcasecmp(pFunc_name, pAnnoMap->func_name) == 0)
|
||||||
|
{
|
||||||
|
pAnnoMap->func_init();
|
||||||
|
nItemCnt = pAnnoMap->func_get(pItem->value, pItemValue, 100);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
pAnnoMap++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nItemCnt == -1) {
|
||||||
|
logWarning("file: "__FILE__", line: %d, " \
|
||||||
|
"not found corresponding annotation func (%s)" \
|
||||||
|
" and (%s) will use the item value (%s).", __LINE__,
|
||||||
|
pItem->name, pFunc_name, pItem->value);
|
||||||
|
pSection->count++;
|
||||||
|
pItem++;
|
||||||
|
free(pFunc_name);
|
||||||
|
continue;
|
||||||
|
} else if (nItemCnt == 0) {
|
||||||
|
logWarning("file: "__FILE__", line: %d, " \
|
||||||
|
"annotation func(%s) execute failed and"
|
||||||
|
"(%s) will use the item value (%s)", __LINE__,
|
||||||
|
pItem->name, pFunc_name, pItem->value);
|
||||||
|
pSection->count++;
|
||||||
|
pItem++;
|
||||||
|
free(pFunc_name);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
pItemName = pItem->name;
|
||||||
|
for (i = 0; i < nItemCnt; i++) {
|
||||||
|
memcpy(pItem->name, pItemName, strlen(pItemName) + 1);
|
||||||
|
memcpy(pItem->value, pItemValue[i], strlen(pItemValue[i]) + 1);
|
||||||
|
pSection->count++;
|
||||||
|
pItem++;
|
||||||
|
if (pSection->count >= pSection->alloc_count) {
|
||||||
|
result = remallocSection(pSection, &pItem);
|
||||||
|
if (result) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(pFunc_name);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
trim(pLine);
|
trim(pLine);
|
||||||
if (*pLine == '#' || *pLine == '\0')
|
if (*pLine == '#' || *pLine == '\0')
|
||||||
|
|
@ -414,10 +588,31 @@ static int iniDoLoadItemsFromBuffer(char *content, IniContext *pContext)
|
||||||
nValueLen = FAST_INI_ITEM_VALUE_LEN;
|
nValueLen = FAST_INI_ITEM_VALUE_LEN;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pSection->count >= pSection->alloc_count)
|
if (pSection->count >= pSection->alloc_count) {
|
||||||
{
|
result = remallocSection(pSection, &pItem);
|
||||||
int bytes;
|
if (result) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(pItem->name, pLine, nNameLen);
|
||||||
|
memcpy(pItem->value, pEqualChar + 1, nValueLen);
|
||||||
|
|
||||||
|
trim(pItem->name);
|
||||||
|
trim(pItem->value);
|
||||||
|
|
||||||
|
pSection->count++;
|
||||||
|
pItem++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int remallocSection(IniSection *pSection, IniItem **pItem)
|
||||||
|
{
|
||||||
|
int bytes, result;
|
||||||
IniItem *pNew;
|
IniItem *pNew;
|
||||||
|
|
||||||
if (pSection->alloc_count == 0)
|
if (pSection->alloc_count == 0)
|
||||||
{
|
{
|
||||||
pSection->alloc_count = _INIT_ALLOC_ITEM_COUNT;
|
pSection->alloc_count = _INIT_ALLOC_ITEM_COUNT;
|
||||||
|
|
@ -433,7 +628,7 @@ static int iniDoLoadItemsFromBuffer(char *content, IniContext *pContext)
|
||||||
logError("file: "__FILE__", line: %d, " \
|
logError("file: "__FILE__", line: %d, " \
|
||||||
"malloc %d bytes fail", __LINE__, bytes);
|
"malloc %d bytes fail", __LINE__, bytes);
|
||||||
result = errno != 0 ? errno : ENOMEM;
|
result = errno != 0 ? errno : ENOMEM;
|
||||||
break;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pSection->count > 0)
|
if (pSection->count > 0)
|
||||||
|
|
@ -444,22 +639,11 @@ static int iniDoLoadItemsFromBuffer(char *content, IniContext *pContext)
|
||||||
}
|
}
|
||||||
|
|
||||||
pSection->items = pNew;
|
pSection->items = pNew;
|
||||||
pItem = pSection->items + pSection->count;
|
*pItem = pSection->items + pSection->count;
|
||||||
memset(pItem, 0, sizeof(IniItem) * \
|
memset(*pItem, 0, sizeof(IniItem) * \
|
||||||
(pSection->alloc_count - pSection->count));
|
(pSection->alloc_count - pSection->count));
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(pItem->name, pLine, nNameLen);
|
return 0;
|
||||||
memcpy(pItem->value, pEqualChar + 1, nValueLen);
|
|
||||||
|
|
||||||
trim(pItem->name);
|
|
||||||
trim(pItem->value);
|
|
||||||
|
|
||||||
pSection->count++;
|
|
||||||
pItem++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int iniFreeHashData(const int index, const HashData *data, void *args)
|
static int iniFreeHashData(const int index, const HashData *data, void *args)
|
||||||
|
|
@ -485,6 +669,8 @@ static int iniFreeHashData(const int index, const HashData *data, void *args)
|
||||||
|
|
||||||
void iniFreeContext(IniContext *pContext)
|
void iniFreeContext(IniContext *pContext)
|
||||||
{
|
{
|
||||||
|
AnnotationMap *pAnnoMap;
|
||||||
|
|
||||||
if (pContext == NULL)
|
if (pContext == NULL)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
|
|
@ -498,6 +684,13 @@ void iniFreeContext(IniContext *pContext)
|
||||||
|
|
||||||
hash_walk(&pContext->sections, iniFreeHashData, NULL);
|
hash_walk(&pContext->sections, iniFreeHashData, NULL);
|
||||||
hash_destroy(&pContext->sections);
|
hash_destroy(&pContext->sections);
|
||||||
|
|
||||||
|
pAnnoMap = g_annotataionMap;
|
||||||
|
while (pAnnoMap->func_name)
|
||||||
|
{
|
||||||
|
pAnnoMap->func_destroy();
|
||||||
|
pAnnoMap++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,13 @@
|
||||||
#define FAST_INI_ITEM_NAME_LEN 64
|
#define FAST_INI_ITEM_NAME_LEN 64
|
||||||
#define FAST_INI_ITEM_VALUE_LEN 256
|
#define FAST_INI_ITEM_VALUE_LEN 256
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char *func_name;
|
||||||
|
int (*func_init) ();
|
||||||
|
void (*func_destroy) ();
|
||||||
|
int (*func_get) (char *key, char **pOutValue, int max_values);
|
||||||
|
} AnnotationMap;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
char name[FAST_INI_ITEM_NAME_LEN + 1];
|
char name[FAST_INI_ITEM_NAME_LEN + 1];
|
||||||
|
|
@ -44,6 +51,8 @@ typedef struct
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
void iniSetAnnotationCallBack(AnnotationMap *map, int count);
|
||||||
|
|
||||||
/** load ini items from file
|
/** load ini items from file
|
||||||
* parameters:
|
* parameters:
|
||||||
* szFilename: the filename, can be an URL
|
* szFilename: the filename, can be an URL
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue