提交 ad51130d 编写于 作者: L liuwei

add annotation mechanism for ini parse

上级 f71c846a
......@@ -22,11 +22,44 @@
#define _LINE_BUFFER_SIZE 512
#define _INIT_ALLOC_ITEM_COUNT 32
static AnnotationMap *g_annotataionMap;
static int remallocSection(IniSection *pSection, IniItem **pItem);
static int iniDoLoadFromFile(const char *szFilename, \
IniContext *pContext);
static int iniDoLoadItemsFromBuffer(char *content, \
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)
{
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)
{
AnnotationMap *pAnnoMap;
IniSection *pSection;
IniItem *pItem;
char *pLine;
char *pLastEnd;
char *pEqualChar;
char *pFunc_name;
char *pItemName;
char *pAnnoItemLine;
char *pIncludeFilename;
char *pItemValue[100];
char full_filename[MAX_PATH_SIZE];
int i;
int nLineLen;
int nNameLen;
int nItemCnt;
int nValueLen;
int result;
int isAnnotation;
result = 0;
nItemCnt = -1;
pAnnoItemLine = NULL;
isAnnotation = 0;
pLastEnd = content - 1;
pSection = pContext->current_section;
pItem = pSection->items + pSection->count;
......@@ -328,6 +372,136 @@ static int iniDoLoadItemsFromBuffer(char *content, IniContext *pContext)
free(pIncludeFilename);
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);
if (*pLine == '#' || *pLine == '\0')
......@@ -368,7 +542,7 @@ static int iniDoLoadItemsFromBuffer(char *content, IniContext *pContext)
__LINE__, \
(int)sizeof(IniSection), \
result, STRERROR(result));
break;
}
......@@ -395,66 +569,38 @@ static int iniDoLoadItemsFromBuffer(char *content, IniContext *pContext)
pItem = pSection->items + pSection->count;
continue;
}
pEqualChar = strchr(pLine, '=');
if (pEqualChar == NULL)
{
continue;
}
nNameLen = pEqualChar - pLine;
nValueLen = strlen(pLine) - (nNameLen + 1);
if (nNameLen > FAST_INI_ITEM_NAME_LEN)
{
nNameLen = FAST_INI_ITEM_NAME_LEN;
}
if (nValueLen > FAST_INI_ITEM_VALUE_LEN)
{
nValueLen = FAST_INI_ITEM_VALUE_LEN;
}
if (pSection->count >= pSection->alloc_count)
{
int bytes;
IniItem *pNew;
if (pSection->alloc_count == 0)
{
pSection->alloc_count = _INIT_ALLOC_ITEM_COUNT;
}
else
{
pSection->alloc_count *= 2;
}
bytes = sizeof(IniItem) * pSection->alloc_count;
pNew = (IniItem *)malloc(bytes);
if (pNew == NULL)
{
logError("file: "__FILE__", line: %d, " \
"malloc %d bytes fail", __LINE__, bytes);
result = errno != 0 ? errno : ENOMEM;
break;
}
if (pSection->count > 0)
{
memcpy(pNew, pSection->items,
sizeof(IniItem) * pSection->count);
free(pSection->items);
if (pSection->count >= pSection->alloc_count) {
result = remallocSection(pSection, &pItem);
if (result) {
break;
}
pSection->items = pNew;
pItem = pSection->items + pSection->count;
memset(pItem, 0, sizeof(IniItem) * \
(pSection->alloc_count - pSection->count));
}
memcpy(pItem->name, pLine, nNameLen);
memcpy(pItem->value, pEqualChar + 1, nValueLen);
trim(pItem->name);
trim(pItem->value);
pSection->count++;
pItem++;
}
......@@ -462,6 +608,44 @@ static int iniDoLoadItemsFromBuffer(char *content, IniContext *pContext)
return result;
}
static int remallocSection(IniSection *pSection, IniItem **pItem)
{
int bytes, result;
IniItem *pNew;
if (pSection->alloc_count == 0)
{
pSection->alloc_count = _INIT_ALLOC_ITEM_COUNT;
}
else
{
pSection->alloc_count *= 2;
}
bytes = sizeof(IniItem) * pSection->alloc_count;
pNew = (IniItem *)malloc(bytes);
if (pNew == NULL)
{
logError("file: "__FILE__", line: %d, " \
"malloc %d bytes fail", __LINE__, bytes);
result = errno != 0 ? errno : ENOMEM;
return result;
}
if (pSection->count > 0)
{
memcpy(pNew, pSection->items,
sizeof(IniItem) * pSection->count);
free(pSection->items);
}
pSection->items = pNew;
*pItem = pSection->items + pSection->count;
memset(*pItem, 0, sizeof(IniItem) * \
(pSection->alloc_count - pSection->count));
return 0;
}
static int iniFreeHashData(const int index, const HashData *data, void *args)
{
IniSection *pSection;
......@@ -485,6 +669,8 @@ static int iniFreeHashData(const int index, const HashData *data, void *args)
void iniFreeContext(IniContext *pContext)
{
AnnotationMap *pAnnoMap;
if (pContext == NULL)
{
return;
......@@ -498,6 +684,13 @@ void iniFreeContext(IniContext *pContext)
hash_walk(&pContext->sections, iniFreeHashData, NULL);
hash_destroy(&pContext->sections);
pAnnoMap = g_annotataionMap;
while (pAnnoMap->func_name)
{
pAnnoMap->func_destroy();
pAnnoMap++;
}
}
......@@ -551,7 +744,7 @@ int64_t iniGetInt64Value(const char *szSectionName, const char *szItemName, \
IniContext *pContext, const int64_t nDefaultValue)
{
char *pValue;
pValue = iniGetStrValue(szSectionName, szItemName, pContext);
if (pValue == NULL)
{
......@@ -567,7 +760,7 @@ int iniGetIntValue(const char *szSectionName, const char *szItemName, \
IniContext *pContext, const int nDefaultValue)
{
char *pValue;
pValue = iniGetStrValue(szSectionName, szItemName, pContext);
if (pValue == NULL)
{
......@@ -583,7 +776,7 @@ double iniGetDoubleValue(const char *szSectionName, const char *szItemName, \
IniContext *pContext, const double dbDefaultValue)
{
char *pValue;
pValue = iniGetStrValue(szSectionName, szItemName, pContext);
if (pValue == NULL)
{
......@@ -599,7 +792,7 @@ bool iniGetBoolValue(const char *szSectionName, const char *szItemName, \
IniContext *pContext, const bool bDefaultValue)
{
char *pValue;
pValue = iniGetStrValue(szSectionName, szItemName, pContext);
if (pValue == NULL)
{
......@@ -628,7 +821,7 @@ int iniGetValues(const char *szSectionName, const char *szItemName, \
{
return 0;
}
INI_FIND_ITEM(szSectionName, szItemName, pContext, pSection, \
targetItem, pFound, 0)
if (pFound == NULL)
......@@ -677,7 +870,7 @@ IniItem *iniGetValuesEx(const char *szSectionName, const char *szItemName, \
IniItem *pItem;
IniItem *pItemEnd;
IniItem *pItemStart;
*nTargetCount = 0;
INI_FIND_ITEM(szSectionName, szItemName, pContext, pSection, \
targetItem, pFound, NULL)
......
......@@ -19,6 +19,13 @@
#define FAST_INI_ITEM_NAME_LEN 64
#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
{
char name[FAST_INI_ITEM_NAME_LEN + 1];
......@@ -44,6 +51,8 @@ typedef struct
extern "C" {
#endif
void iniSetAnnotationCallBack(AnnotationMap *map, int count);
/** load ini items from file
* parameters:
* szFilename: the filename, can be an URL
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册