From d34dfee8dcbd1421b96c0908b1008e8c9f8d4fe0 Mon Sep 17 00:00:00 2001 From: yuqing Date: Tue, 14 Jun 2016 21:56:49 +0800 Subject: [PATCH] ini_file_reader support for statement --- src/ini_file_reader.c | 326 +++++++++++++++++++++++++++++++++++++++++- src/tests/Makefile | 2 +- 2 files changed, 324 insertions(+), 4 deletions(-) diff --git a/src/ini_file_reader.c b/src/ini_file_reader.c index 9c8edc2..b6f5e4c 100644 --- a/src/ini_file_reader.c +++ b/src/ini_file_reader.c @@ -43,6 +43,13 @@ #define _PREPROCESS_VARIABLE_LEN_LOCAL_HOST \ (sizeof(_PREPROCESS_VARIABLE_STR_LOCAL_HOST) - 1) +#define _PREPROCESS_TAG_STR_FOR_FROM "from" +#define _PREPROCESS_TAG_LEN_FOR_FROM (sizeof(_PREPROCESS_TAG_STR_FOR_FROM) - 1) +#define _PREPROCESS_TAG_STR_FOR_TO "to" +#define _PREPROCESS_TAG_LEN_FOR_TO (sizeof(_PREPROCESS_TAG_STR_FOR_TO) - 1) +#define _PREPROCESS_TAG_STR_FOR_STEP "step" +#define _PREPROCESS_TAG_LEN_FOR_STEP (sizeof(_PREPROCESS_TAG_STR_FOR_STEP) - 1) + static AnnotationMap *g_annotataionMap = NULL; static int remallocSection(IniSection *pSection, IniItem **pItem); @@ -705,6 +712,20 @@ static char *iniAllocContent(IniContext *pContext, const int content_len) return buff; } +static bool iniMatchValue(const char *target, char **values, const int count) +{ + int i; + for (i=0; i= '0' && *p <= '9')) + { + p++; + } + + *nlen = p - pNumber; + return pNumber; +} + +static int iniParseForRange(char *range, const int range_len, + char **id, int *idLen, int *start, int *end, int *step) +{ + /** + * + * #@for i from 0 to 15 step 1 + */ + + + char *p; + char *pEnd; + char *pNumber; + int nlen; + + pEnd = range + range_len; + p = range; + while (p < pEnd && (*p == ' ' || *p == '\t')) + { + p++; + } + + if (pEnd - p < 10) + { + logWarning("file: "__FILE__", line: %d, " + "unkown for range: %.*s", __LINE__, + range_len, range); + return EINVAL; + } + + *id = p; + while (p < pEnd && !(*p == ' ' || *p == '\t')) + { + p++; + } + *idLen = p - *id; + if (*idLen == 0 || *idLen > 64) + { + logWarning("file: "__FILE__", line: %d, " + "invalid for range: %.*s", __LINE__, + range_len, range); + return EINVAL; + } + + if (pEnd - p < 8) + { + logWarning("file: "__FILE__", line: %d, " + "invalid for range: %.*s", __LINE__, + range_len, range); + return EINVAL; + } + + p++; + if (!(memcmp(p, _PREPROCESS_TAG_STR_FOR_FROM, + _PREPROCESS_TAG_LEN_FOR_FROM) == 0 && + (*p == ' ' || *p == '\t'))) + { + logWarning("file: "__FILE__", line: %d, " + "invalid for range: %.*s", __LINE__, + range_len, range); + return EINVAL; + } + p += _PREPROCESS_TAG_LEN_FOR_FROM + 1; + pNumber = iniGetInteger(p, pEnd, &nlen); + if (nlen == 0) + { + logWarning("file: "__FILE__", line: %d, " + "invalid for range: %.*s", __LINE__, + range_len, range); + return EINVAL; + } + *start = atoi(pNumber); + p = pNumber + nlen; + + if (pEnd - p < 4 || !(*p == ' ' || *p == '\t')) + { + logWarning("file: "__FILE__", line: %d, " + "invalid for range: %.*s", __LINE__, + range_len, range); + return EINVAL; + } + p++; + while (p < pEnd && !(*p == ' ' || *p == '\t')) + { + p++; + } + if (!(memcmp(p, _PREPROCESS_TAG_STR_FOR_TO, + _PREPROCESS_TAG_LEN_FOR_TO) == 0 && + (*p == ' ' || *p == '\t'))) + { + logWarning("file: "__FILE__", line: %d, " + "unkown for range: %.*s", __LINE__, + range_len, range); + return EINVAL; + } + p += _PREPROCESS_TAG_LEN_FOR_TO + 1; + pNumber = iniGetInteger(p, pEnd, &nlen); + if (nlen == 0) + { + logWarning("file: "__FILE__", line: %d, " + "invalid for range: %.*s", __LINE__, + range_len, range); + return EINVAL; + } + *end = atoi(pNumber); + p = pNumber + nlen; + + if (p == pEnd) + { + *step = 1; + return 0; + } + + if (!(*p == ' ' || *p == '\t')) + { + logWarning("file: "__FILE__", line: %d, " + "invalid for range: %.*s", __LINE__, + range_len, range); + return EINVAL; + } + while (p < pEnd && (*p == ' ' || *p == '\t')) + { + p++; + } + if (!(memcmp(p, _PREPROCESS_TAG_STR_FOR_STEP, + _PREPROCESS_TAG_LEN_FOR_STEP) == 0 && + (*p == ' ' || *p == '\t'))) + { + logWarning("file: "__FILE__", line: %d, " + "unkown for range: %.*s", __LINE__, + range_len, range); + return EINVAL; + } + p += _PREPROCESS_TAG_LEN_FOR_STEP + 1; + pNumber = iniGetInteger(p, pEnd, &nlen); + if (nlen == 0) + { + logWarning("file: "__FILE__", line: %d, " + "invalid for range: %.*s", __LINE__, + range_len, range); + return EINVAL; + } + *step = atoi(pNumber); + p = pNumber + nlen; + while (p < pEnd && (*p == ' ' || *p == '\t')) + { + p++; + } + if (p != pEnd) + { + logWarning("file: "__FILE__", line: %d, " + "invalid for range: %.*s", __LINE__, + range_len, range); + return EINVAL; + } + + return 0; +} + +static char *iniProccessFor(char *content, const int content_len, + IniContext *pContext, int *new_content_len) +{ + char *pStart; + char *pEnd; + char *pForRange; + char *pForBlock; + char *id; + char tag[80]; + char value[16]; + int idLen; + int rangeLen; + int forBlockLen; + int start; + int end; + int step; + int count; + int i; + int copyLen; + int tagLen; + int valueLen; + char *newContent; + char *pDest; + + *new_content_len = content_len; + pStart = strstr(content, _PREPROCESS_TAG_STR_FOR); + if (pStart == NULL) + { + return content; + } + pForRange = pStart + _PREPROCESS_TAG_LEN_FOR; + pForBlock = strchr(pForRange, '\n'); + if (pForBlock == NULL) + { + return content; + } + rangeLen = pForBlock - pForRange; + + pEnd = strstr(pForBlock, _PREPROCESS_TAG_STR_ENDFOR); + if (pEnd == NULL) + { + return content; + } + forBlockLen = pEnd - pForBlock; + + if (iniParseForRange(pForRange, rangeLen, &id, &idLen, + &start, &end, &step) != 0) + { + return NULL; + } + if (step == 0) + { + logWarning("file: "__FILE__", line: %d, " + "invalid step: %d for range: %.*s", __LINE__, + step, rangeLen, pForRange); + return NULL; + } + count = (end - start) / step; + if (count < 0) + { + logWarning("file: "__FILE__", line: %d, " + "invalid step: %d for range: %.*s", __LINE__, + step, rangeLen, pForRange); + return NULL; + } + + newContent = iniAllocContent(pContext, content_len + (forBlockLen + 16) * count); + if (newContent == NULL) + { + return NULL; + } + + pDest = newContent; + copyLen = pStart - content; + if (copyLen > 0) + { + memcpy(pDest, content, copyLen); + pDest += copyLen; + } + + tagLen = sprintf(tag, "{$%.*s}", idLen, id); + for (i=start; i<=end; i+=step) + { + valueLen = sprintf(value, "%d", i); + } + + copyLen = (content + content_len) - (pEnd + _PREPROCESS_TAG_LEN_ENDFOR); + if (copyLen > 0) + { + memcpy(pDest, pEnd + _PREPROCESS_TAG_LEN_ENDFOR, copyLen); + pDest += copyLen; + } + + *pDest = '\0'; + *new_content_len = pDest - newContent; + return newContent; +} + static int iniLoadItemsFromBuffer(char *content, IniContext *pContext) { char *pContent; @@ -943,6 +1250,19 @@ static int iniLoadItemsFromBuffer(char *content, IniContext *pContext) } } while (new_content != pContent); + do + { + pContent = new_content; + content_len = new_content_len; + if ((new_content=iniProccessFor(pContent, content_len, + pContext, &new_content_len)) == NULL) + { + return ENOMEM; + } + } while (new_content != pContent); + + logInfo("new_content(%d): %s", new_content_len, new_content); + return iniDoLoadItemsFromBuffer(new_content, pContext); } diff --git a/src/tests/Makefile b/src/tests/Makefile index aeb9171..3aaa4fb 100644 --- a/src/tests/Makefile +++ b/src/tests/Makefile @@ -5,7 +5,7 @@ INC_PATH = -I/usr/include/fastcommon LIB_PATH = -lfastcommon -lpthread ALL_PRGS = test_allocator test_skiplist test_multi_skiplist test_mblock test_blocked_queue \ - test_id_generator + test_id_generator test_ini_parser all: $(ALL_PRGS) .c: