diff --git a/src/stubser/cfile_parser.c b/src/stubser/cfile_parser.c index 7923294..826c501 100644 --- a/src/stubser/cfile_parser.c +++ b/src/stubser/cfile_parser.c @@ -46,7 +46,6 @@ STATIC regex_t regXparameter; STATIC regex_t regXvariable; STATIC regex_t regXExpressionStart; -STATIC regex_t regXExpressionAssign; STATIC regex_t regXExpressionEnd; // line evaluation related variables @@ -61,11 +60,6 @@ int8_t cfile_parser_init() perror("Error regex\n"); return -1; } - if (0 > regcomp(®XExpressionAssign, CPARS_EXPRESSION_EXPEND, (REG_EXTENDED | REG_NEWLINE))) - { - perror("Error regex\n"); - return -1; - } if (0 > regcomp(®XExpressionEnd, CPARS_EXPRESSION_END, (REG_EXTENDED | REG_NEWLINE))) { perror("Error regex\n"); @@ -650,49 +644,30 @@ STATIC cfunction_t* cfile_parser_evaluateLine1(char *aLine) } #endif -STATIC bool workerActive = false; -const stringWorker cWorker[2] = -{ cfile_expWorker, // Parse for variables - NULL }; -STATIC char *match = NULL; STATIC int8_t cfile_parser_evaluateLine(uint32_t aNumber, char *aLine, cfile_t *aCfile) { - stringWorker *worker = (stringWorker*) cWorker; char *position = aLine; - char *result = NULL; - size_t cSize = 0; + int8_t result = 0; + static char *match = NULL; + static uint8_t depth = 0; regex_t *matchStart = ®XExpressionStart; regex_t *matchEnd = ®XExpressionEnd; - DEBUG_LOG_APPEND(1, "[ Li %04u] %s\n", aNumber, aLine); - // start with variable worker - - while (position && NULL != *worker) + while (position) { - result = (*worker)(&position, matchStart, matchEnd, &workerActive, &cSize); - if (NULL == result) + result = regExWorker(&match, &position, matchStart, matchEnd, &depth, false); + if (match && 0 == result && 0 == depth) { - if (false == workerActive) - { - xfree((void**) &match); - ++worker; - } - continue; - } - xmallocStrlcat(&match, result, cSize); - - if (false == workerActive) - { - DEBUG_LOG_APPEND(1, "Works %zu %s\n", cSize, match); - // TODO evaluate expression according to worker + DEBUG_LOG_APPEND(1, "[ Re %04u] Works %zu %s\n", aNumber, strlen(match), match); xfree((void**) &match); - worker = (stringWorker*) cWorker; } - else + if (0 > result) { - // force space between findings - xmallocStrlcat(&match, " ", 2); + if (-2 == result) + DEBUG_LOG_APPEND(2, "[ PEr]"); + position = NULL; + xfree((void**) &match); } } return 0; @@ -703,9 +678,11 @@ int8_t cfile_parser(char *aPath, cfile_t *aCfile) FILE *fdesc; ssize_t charRead = 0; size_t lineSize = 0; - uint32_t lineNumber = 1; + uint32_t lineNumber = 0; char *cTemp = NULL; char *fileLine = NULL; // will be allocated by getline(); must be freed + int8_t ret = 0; + uint8_t warningCounter = 0; if (false == cfile_parser_initialized) { @@ -724,14 +701,26 @@ int8_t cfile_parser(char *aPath, cfile_t *aCfile) charRead = getline(&fileLine, &lineSize, fdesc); if (0 <= charRead) { - if (0 != removeCcomments(fileLine)) + lineNumber++; + ret = removeCcomments(fileLine); + if (-1 == ret) + { + ++warningCounter; + } + else if (0 != ret) { continue; } - if (0 != cBlockRemoval(fileLine, "{", "}", &cfile_parser_removeBraceHelper, false, false)) + ret = cBlockRemoval(fileLine, "{", "}", &cfile_parser_removeBraceHelper, false, false); + if (-1 == ret) + { + ++warningCounter; + } + else if (0 != ret) { continue; } + DEBUG_LOG_APPEND(2, "[ Li %04u] %s", lineNumber, fileLine); cTemp = strrchr(fileLine, '\n'); if (cTemp) { @@ -742,7 +731,7 @@ int8_t cfile_parser(char *aPath, cfile_t *aCfile) { *cTemp = '\0'; } - (void) cfile_parser_evaluateLine(lineNumber++, fileLine, aCfile); + (void) cfile_parser_evaluateLine(lineNumber, fileLine, aCfile); } } while (0 <= charRead); @@ -756,7 +745,7 @@ int8_t cfile_parser(char *aPath, cfile_t *aCfile) cfile_parser_parameterStorage); cfile_parser_removeCommentHelper = 0; cfile_parser_removeBraceHelper = 0; - return -2; + ret = -2; } // error detection for function parameter detection @@ -765,8 +754,13 @@ int8_t cfile_parser(char *aPath, cfile_t *aCfile) DEBUG_LOG_APPEND(1, "Function parameter not free: %s\n", cfile_parser_parameterStorage); free(cfile_parser_parameterStorage); cfile_parser_parameterStorage = NULL; - return -3; + ret = -3; } - return 0; + if (warningCounter && 0 <= ret) + { + ret = -4; + } + + return ret; } diff --git a/src/stubser/cfile_parser_loc.h b/src/stubser/cfile_parser_loc.h index 393142b..c18226b 100644 --- a/src/stubser/cfile_parser_loc.h +++ b/src/stubser/cfile_parser_loc.h @@ -33,8 +33,7 @@ #define CPARS_REGEX_PARAMETER "[[:blank:]]*([ _\\*[:alnum:]]* +\\**)([_\\*[:alnum:]]*)[[:blank:]]*" #define CPARS_REGEX_PREFIX "(extern|EXTERN|static|STATIC|volatile|near|far)[[:blank:]]+([^\\*]*\\**)" -#define CPARS_EXPRESSION_START "^[[:blank:]]*([A-Za-z][\\_\\*[:alnum:]]*)" -#define CPARS_EXPRESSION_EXPEND "[[:blank:]]*([=\{])[[:blank:]]*" +#define CPARS_EXPRESSION_START "^[[:blank:]]*([A-Za-z\\_][\\_\\*[:alnum:]]*)" #define CPARS_EXPRESSION_END "[[:blank:]]*([\\};]+)" #define CFILE_PARSER_IS_MATCHGROUP_FUNCTION(matchGroup) (XREGEX_IS_MATCHGROUP(matchGroup, 1) && XREGEX_IS_MATCHGROUP(matchGroup, 2)) diff --git a/src/stubser/cfile_parser_worker.c b/src/stubser/cfile_parser_worker.c index 0e7d4a4..1f40c9f 100644 --- a/src/stubser/cfile_parser_worker.c +++ b/src/stubser/cfile_parser_worker.c @@ -13,57 +13,129 @@ #include "xtypes.h" #include "xregex.h" +#include "xmalloc.h" #include "debug.h" #include "cfile_parser_loc.h" #include "cfile_parser_worker_loc.h" -char* cfile_expWorker(char **aInput, const regex_t *aStart, const regex_t *aEnd, bool *aActive, size_t *aSize) +/*! + * @brief String block detection using regular expressions + * @param [out] **aOutput Matched group content across multiple calls (will be allocated as needed) + * @param [in,out] **aInput Char pointer to search string (will be moved to position after match) + * @return Matched string and various information about the parsing + * @retval 0 parsing done (aBlockDepth = 0) or in progress (aBlockDepth > 0) + * @retval -1 parsing ended without result + * @retval -2 parsing error (end without start) + */ +int8_t regExWorker(char **aOutput, char **aInput, const regex_t *aStart, const regex_t *aEnd, uint8_t *aBlockDepth, bool aMultiLevel) { - regmatch_t matchGroup[CFILE_PARSER_MAX_REGEX_MATCHING_GROUPS]; - char *begin; + regmatch_t matchStart[2]; + regmatch_t matchEnd[2]; + regmatch_t *match = NULL; + char *begin = NULL; + size_t size = 0; + int8_t ret = -1; - if (!**aInput) + if (!**aInput || NULL == *aInput) { - *aInput = NULL; - return NULL; - } - if (!*aActive) - { - *aSize = 0; - begin = NULL; - } - else - { - begin = *aInput; - } - - if (*aActive) - { - if (aEnd != NULL && 0 == regexec(aEnd, *aInput, CFILE_PARSER_MAX_REGEX_MATCHING_GROUPS, matchGroup, REG_NOTEOL) && XREGEX_IS_MATCHGROUP(matchGroup, 1)) + if (*aBlockDepth) { - DEBUG_LOG_APPEND(1, "[ CEe]"); - *aActive = false; - *aSize += matchGroup[1].rm_so; // don't include end marker in result - *aInput += matchGroup[1].rm_eo; - return begin; + xmallocStrlcat(aOutput, " ", 2); + ret = 0; } else { - DEBUG_LOG_APPEND(1, "[ CE+]"); - *aSize += strlen(*aInput); - *aInput += strlen(*aInput); - return begin; + ret = -1; } - } - else if (0 == regexec(aStart, *aInput, CFILE_PARSER_MAX_REGEX_MATCHING_GROUPS, matchGroup, REG_NOTEOL) && XREGEX_IS_MATCHGROUP(matchGroup, 1)) - { - DEBUG_LOG_APPEND(1, "[ CEs]"); - *aActive = true; - *aSize += XREGEX_SIZEOF_MATCHGROUP(matchGroup, 1); - begin = *aInput + matchGroup[1].rm_so; - *aInput += matchGroup[1].rm_eo; - cfile_expWorker(aInput, aStart, aEnd, aActive, aSize); + *aInput = NULL; + goto regExWorker_end; } - return begin; + // start + if (0 == regexec(aStart, *aInput, 2, matchStart, REG_NOTEOL) && XREGEX_IS_MATCHGROUP(matchStart, 1)) + { + match = matchStart; + } + + // end < start + if (0 == regexec(aEnd, *aInput, 2, matchEnd, REG_NOTEOL) && XREGEX_IS_MATCHGROUP(matchEnd, 1)) + { + if (match && match->rm_so > matchEnd[1].rm_so) + { + match = matchEnd; + } + else if (!match) + { + match = matchEnd; + } + } + + if (*aBlockDepth) + { + begin = *aInput; + size = strlen(*aInput); + if (!match) + { + *aInput += strlen(*aInput); + ret = 0; + goto regExWorker_end; + } + } + else + { + begin = NULL; + // no findings + if (!match) + { + ret = -1; + goto regExWorker_end; + } + } + + // start && aDepth > 0 -> ignore + if (match == matchStart) + { + if ((*aBlockDepth && aMultiLevel) || 0 == *aBlockDepth) + { + DEBUG_LOG_APPEND(2, "[ CEs]"); + ++*aBlockDepth; + size = XREGEX_SIZEOF_MATCHGROUP(match, 1); + //begin = *aInput + match[1].rm_eo; // don't include end marker in result + begin = *aInput + match[1].rm_so; // include end marker in result + *aInput += match[1].rm_eo; + } + else + { + // ignore starts within block + size = match->rm_eo; + *aInput += match->rm_eo; + } + ret = 0; + goto regExWorker_end; + } + + if (match == matchEnd) + { + DEBUG_LOG_APPEND(2, "[ CEe]"); + if (0 < *aBlockDepth) + --*aBlockDepth; + //size = match[1].rm_so; // don't include end marker in result + size = match[1].rm_eo; // include end marker in result + *aInput += match[1].rm_eo; + ret = 0; + goto regExWorker_end; + } + + regExWorker_end: + + if (begin) + { + xmallocStrlcat(aOutput, begin, size); + if (*aBlockDepth) + { + (void) regExWorker(aOutput, aInput, aStart, aEnd, aBlockDepth, aMultiLevel); + } + } + + return ret; } diff --git a/src/stubser/cfile_parser_worker_loc.h b/src/stubser/cfile_parser_worker_loc.h index 5a7d1b4..0039580 100644 --- a/src/stubser/cfile_parser_worker_loc.h +++ b/src/stubser/cfile_parser_worker_loc.h @@ -14,8 +14,6 @@ #ifndef STUBSER_CFILE_PARSER_WORKER_LOC_H_ #define STUBSER_CFILE_PARSER_WORKER_LOC_H_ -typedef char* (*stringWorker)(char**, const regex_t *, const regex_t *, bool*, size_t*); - -char* cfile_expWorker(char **aInput, const regex_t *aStart, const regex_t *aEnd, bool *aActive, size_t *aSize); +int8_t regExWorker(char **aOutput, char **aInput, const regex_t *aStart, const regex_t *aEnd, uint8_t *aBlockDepth, bool aMultiLevel); #endif /* STUBSER_CFILE_PARSER_WORKER_LOC_H_ */