- work on warnings counting and console output

This commit is contained in:
2017-03-13 10:11:55 +00:00
parent 0e0addd8d2
commit c6231c4007
7 changed files with 107 additions and 108 deletions

View File

@@ -43,7 +43,6 @@ STATIC regex_t regXExpressionEnd;
// line evaluation related variables // line evaluation related variables
STATIC uint32_t cfile_parser_removeCommentHelper = 0; STATIC uint32_t cfile_parser_removeCommentHelper = 0;
STATIC uint32_t cfile_parser_removeBraceHelper = 0; STATIC uint32_t cfile_parser_removeBraceHelper = 0;
STATIC char *cfile_parser_parameterStorage = NULL;
int8_t cfile_parser_init() int8_t cfile_parser_init()
{ {
@@ -367,7 +366,7 @@ STATIC int8_t cBlockRemoval(char *aLine, const char *aBlockStart, const char *aB
} }
else else
{ {
printf("[WARN] Nested block start (see file below): %s", aLine); printf(CPARS_WARNING_START"Nested block start \"%s\": %s", aBlockStart, aLine);
} }
blockWorker = (aRemove ? blockMatch + strlen(aBlockStart) : blockMatch); blockWorker = (aRemove ? blockMatch + strlen(aBlockStart) : blockMatch);
break; break;
@@ -556,17 +555,49 @@ STATIC int8_t cfile_parser_evaluateExpression(char *aExpression, cfile_t *aCfile
return 0; return 0;
} }
STATIC int8_t cfile_parser_evaluateLine(uint32_t aNumber, char *aLine, cfile_t *aCfile) STATIC uint32_t cfile_parser_evaluateLine(uint32_t aNumber, char *aLine, cfile_t *aCfile)
{ {
char *position = aLine; char *position = aLine;
int8_t result = 0; uint32_t warnings = 0;
static char *match = NULL; static char *match = NULL;
static uint8_t depth = 0; static uint8_t depth = 0;
char *tempMatch = NULL; char *tempMatch = NULL;
char *tempChar = NULL;
int8_t ret = 0;
regex_t *matchStart = &regXExpressionStart; regex_t *matchStart = &regXExpressionStart;
regex_t *matchEnd = &regXExpressionEnd; regex_t *matchEnd = &regXExpressionEnd;
ret = removeCcomments(aLine);
if (-1 == ret)
{
++warnings;
}
else if (0 != ret)
{
return 0;
}
ret = cBlockRemoval(aLine, "{", "}", &cfile_parser_removeBraceHelper, false, false);
if (-1 == ret)
{
++warnings;
}
else if (0 != ret)
{
return 0;
}
DEBUG_LOG_APPEND(2, "[ Li %04u] %s", aNumber, aLine);
tempChar = strrchr(aLine, '\n');
if (tempChar)
{
*tempChar = '\0';
}
tempChar = strrchr(aLine, '\r');
if (tempChar)
{
*tempChar = '\0';
}
while (position) while (position)
{ {
if (NULL != (tempMatch = strstr(position, "#include"))) if (NULL != (tempMatch = strstr(position, "#include")))
@@ -576,35 +607,26 @@ STATIC int8_t cfile_parser_evaluateLine(uint32_t aNumber, char *aLine, cfile_t *
position = NULL; position = NULL;
continue; continue;
} }
result = regExWorker(&match, &position, matchStart, matchEnd, &depth, false); warnings += regExWorker(&match, &position, matchStart, matchEnd, &depth, false);
if (match && 0 == result && 0 == depth) if (match && 0 == depth)
{ {
DEBUG_LOG_APPEND(1, "[ Re %04u][%zu] %s\n", aNumber, strlen(match), match); DEBUG_LOG_APPEND(1, "[ Re %04u][%zu] %s\n", aNumber, strlen(match), match);
// Evaluate C expression // Evaluate C expression
(void) cfile_parser_evaluateExpression(match, aCfile); (void) cfile_parser_evaluateExpression(match, aCfile);
xfree((void**) &match); xfree((void**) &match);
} }
if (0 > result)
{
if (-2 == result)
DEBUG_LOG_APPEND(2, "[ PEr]");
position = NULL;
xfree((void**) &match);
}
} }
return 0; return warnings;
} }
int8_t cfile_parser(char *aPath, cfile_t *aCfile) uint32_t cfile_parser(char *aPath, cfile_t *aCfile)
{ {
FILE *fdesc; FILE *fdesc;
ssize_t charRead = 0; ssize_t charRead = 0;
size_t lineSize = 0; size_t lineSize = 0;
uint32_t lineNumber = 0; uint32_t lineNumber = 0;
char *cTemp = NULL;
char *fileLine = NULL; // will be allocated by getline(); must be freed char *fileLine = NULL; // will be allocated by getline(); must be freed
int8_t ret = 0; uint32_t warningCounter = 0;
uint8_t warningCounter = 0;
if (false == cfile_parser_initialized) if (false == cfile_parser_initialized)
{ {
@@ -624,36 +646,7 @@ int8_t cfile_parser(char *aPath, cfile_t *aCfile)
if (0 <= charRead) if (0 <= charRead)
{ {
lineNumber++; lineNumber++;
ret = removeCcomments(fileLine); warningCounter += cfile_parser_evaluateLine(lineNumber, fileLine, aCfile);
if (-1 == ret)
{
++warningCounter;
}
else if (0 != ret)
{
continue;
}
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)
{
*cTemp = '\0';
}
cTemp = strrchr(fileLine, '\r');
if (cTemp)
{
*cTemp = '\0';
}
(void) cfile_parser_evaluateLine(lineNumber, fileLine, aCfile);
} }
} while (0 <= charRead); } while (0 <= charRead);
@@ -663,26 +656,16 @@ int8_t cfile_parser(char *aPath, cfile_t *aCfile)
// error detection for block removal // error detection for block removal
if (0 != cfile_parser_removeCommentHelper || 0 != cfile_parser_removeBraceHelper) if (0 != cfile_parser_removeCommentHelper || 0 != cfile_parser_removeBraceHelper)
{ {
DEBUG_LOG_APPEND(1, "Helper (%d/%d) %s %s\n", cfile_parser_removeCommentHelper, cfile_parser_removeBraceHelper, gnu_basename(aPath), DEBUG_LOG_APPEND(1, "Helper (%d/%d) %s\n", cfile_parser_removeCommentHelper, cfile_parser_removeBraceHelper, gnu_basename(aPath));
cfile_parser_parameterStorage);
cfile_parser_removeCommentHelper = 0; cfile_parser_removeCommentHelper = 0;
cfile_parser_removeBraceHelper = 0; cfile_parser_removeBraceHelper = 0;
ret = -2; ++warningCounter;
} }
// error detection for function parameter detection // if (warningCounter)
if (NULL != cfile_parser_parameterStorage) // {
{ // ret = -4;
DEBUG_LOG_APPEND(1, "Function parameter not free: %s\n", cfile_parser_parameterStorage); // }
free(cfile_parser_parameterStorage);
cfile_parser_parameterStorage = NULL;
ret = -3;
}
if (warningCounter && 0 <= ret) return warningCounter;
{
ret = -4;
}
return ret;
} }

View File

@@ -14,6 +14,6 @@
#ifndef STUBSER_CFILE_PARSER_IF_H_ #ifndef STUBSER_CFILE_PARSER_IF_H_
#define STUBSER_CFILE_PARSER_IF_H_ #define STUBSER_CFILE_PARSER_IF_H_
int8_t cfile_parser(char *aPath, cfile_t *aList); uint32_t cfile_parser(char *aPath, cfile_t *aList);
#endif /* STUBSER_CFILE_PARSER_IF_H_ */ #endif /* STUBSER_CFILE_PARSER_IF_H_ */

View File

@@ -36,6 +36,8 @@
#define CPARS_EXPRESSION_START "^[[:blank:]]*([A-Za-z\\_][\\_\\*[:alnum:]]*)" #define CPARS_EXPRESSION_START "^[[:blank:]]*([A-Za-z\\_][\\_\\*[:alnum:]]*)"
#define CPARS_EXPRESSION_END "[[:blank:]]*([\\};]+)" #define CPARS_EXPRESSION_END "[[:blank:]]*([\\};]+)"
#define CPARS_WARNING_START " W-> "
#define CFILE_PARSER_IS_MATCHGROUP_FUNCTION(matchGroup) (XREGEX_IS_MATCHGROUP(matchGroup, 1) && XREGEX_IS_MATCHGROUP(matchGroup, 2)) #define CFILE_PARSER_IS_MATCHGROUP_FUNCTION(matchGroup) (XREGEX_IS_MATCHGROUP(matchGroup, 1) && XREGEX_IS_MATCHGROUP(matchGroup, 2))
/*! @brief Type of function definition */ /*! @brief Type of function definition */

View File

@@ -20,32 +20,34 @@
/*! /*!
* @brief String block detection using regular expressions * @brief String block detection using regular expressions
* @attention Recursive function (calls itself to find block end on same line)
* @param [out] **aOutput Matched group content across multiple calls (will be allocated as needed) * @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) * @param [in,out] **aInput Char pointer to search string (will be moved to position after match)
* @param [in] *aStart Regular expression defining block start
* @param [in] *aEnd Regular expression defining block end
* @param [out] *aBlockDepth Current depth of parsing
* @param [in] aMultiLevel false - starts within block are ignored
* @return Matched string and various information about the parsing * @return Matched string and various information about the parsing
* @retval 0 parsing done (aBlockDepth = 0) or in progress (aBlockDepth > 0) * @retval uint32_t amount of warnings during parser run
* @retval -1 parsing ended without result *
* @retval -2 parsing error (end without start) * @details
* - Parsing done when (match && 0 == aBlockDepth)
* - Orphan end markers are ignored and skipped.
*/ */
int8_t regExWorker(char **aOutput, char **aInput, const regex_t *aStart, const regex_t *aEnd, uint8_t *aBlockDepth, bool aMultiLevel) uint32_t regExWorker(char **aOutput, char **aInput, const regex_t *aStart, const regex_t *aEnd, uint8_t *aBlockDepth, bool aMultiLevel)
{ {
uint32_t warningCounter = 0;
regmatch_t matchStart[2]; regmatch_t matchStart[2];
regmatch_t matchEnd[2]; regmatch_t matchEnd[2];
regmatch_t *match = NULL; regmatch_t *match = NULL;
char *begin = NULL; char *begin = NULL;
size_t size = 0; size_t size = 0;
int8_t ret = -1;
if (!**aInput || NULL == *aInput) if (!**aInput || NULL == *aInput)
{ {
if (*aBlockDepth) if (*aBlockDepth)
{ {
xmallocStrlcat(aOutput, " ", 2); xmallocStrlcat(aOutput, " ", 2);
ret = 0;
}
else
{
ret = -1;
} }
*aInput = NULL; *aInput = NULL;
goto regExWorker_end; goto regExWorker_end;
@@ -76,8 +78,8 @@ int8_t regExWorker(char **aOutput, char **aInput, const regex_t *aStart, const r
size = strlen(*aInput); size = strlen(*aInput);
if (!match) if (!match)
{ {
// complete line within block
*aInput += strlen(*aInput); *aInput += strlen(*aInput);
ret = 0;
goto regExWorker_end; goto regExWorker_end;
} }
} }
@@ -87,12 +89,12 @@ int8_t regExWorker(char **aOutput, char **aInput, const regex_t *aStart, const r
// no findings // no findings
if (!match) if (!match)
{ {
ret = -1; // skip remaining character within line without match
*aInput += strlen(*aInput);
goto regExWorker_end; goto regExWorker_end;
} }
} }
// start && aDepth > 0 -> ignore
if (match == matchStart) if (match == matchStart)
{ {
if ((*aBlockDepth && aMultiLevel) || 0 == *aBlockDepth) if ((*aBlockDepth && aMultiLevel) || 0 == *aBlockDepth)
@@ -100,8 +102,8 @@ int8_t regExWorker(char **aOutput, char **aInput, const regex_t *aStart, const r
DEBUG_LOG_APPEND(2, "[ CEs]"); DEBUG_LOG_APPEND(2, "[ CEs]");
++*aBlockDepth; ++*aBlockDepth;
size = XREGEX_SIZEOF_MATCHGROUP(match, 1); size = XREGEX_SIZEOF_MATCHGROUP(match, 1);
//begin = *aInput + match[1].rm_eo; // don't include end marker in result //begin = *aInput + match[1].rm_eo; // don't include start marker in result
begin = *aInput + match[1].rm_so; // include end marker in result begin = *aInput + match[1].rm_so; // include start marker in result
*aInput += match[1].rm_eo; *aInput += match[1].rm_eo;
} }
else else
@@ -110,19 +112,28 @@ int8_t regExWorker(char **aOutput, char **aInput, const regex_t *aStart, const r
size = match->rm_eo; size = match->rm_eo;
*aInput += match->rm_eo; *aInput += match->rm_eo;
} }
ret = 0;
goto regExWorker_end; goto regExWorker_end;
} }
if (match == matchEnd) if (match == matchEnd)
{ {
DEBUG_LOG_APPEND(2, "[ CEe]"); 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_so; // don't include end marker in result
size = match[1].rm_eo; // include end marker in result size = match[1].rm_eo; // include end marker in result
*aInput += match[1].rm_eo; *aInput += match[1].rm_eo;
ret = 0; if (0 < *aBlockDepth)
{
--*aBlockDepth;
}
// TODO orphan end markers
// must be evaluated depending on expression
// e.g. array[]={}; -> must have } and ;
// function{} -> must not have ;
// else
// {
// // orphan end marker
// ++warningCounter;
// }
goto regExWorker_end; goto regExWorker_end;
} }
@@ -133,9 +144,9 @@ int8_t regExWorker(char **aOutput, char **aInput, const regex_t *aStart, const r
xmallocStrlcat(aOutput, begin, size); xmallocStrlcat(aOutput, begin, size);
if (*aBlockDepth) if (*aBlockDepth)
{ {
(void) regExWorker(aOutput, aInput, aStart, aEnd, aBlockDepth, aMultiLevel); warningCounter += regExWorker(aOutput, aInput, aStart, aEnd, aBlockDepth, aMultiLevel);
} }
} }
return ret; return warningCounter;
} }

View File

@@ -14,6 +14,6 @@
#ifndef STUBSER_CFILE_PARSER_WORKER_LOC_H_ #ifndef STUBSER_CFILE_PARSER_WORKER_LOC_H_
#define STUBSER_CFILE_PARSER_WORKER_LOC_H_ #define STUBSER_CFILE_PARSER_WORKER_LOC_H_
int8_t regExWorker(char **aOutput, char **aInput, const regex_t *aStart, const regex_t *aEnd, uint8_t *aBlockDepth, bool aMultiLevel); uint32_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_ */ #endif /* STUBSER_CFILE_PARSER_WORKER_LOC_H_ */

View File

@@ -446,34 +446,33 @@ int stubser_createStub(char *path, char* aNoSuffix, char *aOutput)
int8_t ret = -1; int8_t ret = -1;
cfile_t cFile = cfile_t cFile =
CFILE_T_DEFAULT; CFILE_T_DEFAULT;
uint32_t warnings = 0;
char fileName[PATH_MAX] = char fileName[PATH_MAX] =
{ '\0' }; { '\0' };
ret = cfile_parser(path, &cFile); #if isDebugLevel(1)
printf(STUB_CONSOLE_PARSE_RUN_S1, path);
#else
printf(STUB_CONSOLE_PARSE_RUN_S1, gnu_basename(path));
#endif
warnings = cfile_parser(path, &cFile);
DEBUG_LOG_APPEND(1, "\n"); DEBUG_LOG_APPEND(1, "\n");
if (0 != ret) if (0 != warnings)
{ {
#if isDebugLevel(1) #if isDebugLevel(1)
printf(STUB_CONSOLE_PARSE_ERROR_S2, path, ret); printf(STUB_CONSOLE_PARSE_ERROR_S2, path, warnings);
#else #else
printf(STUB_CONSOLE_PARSE_ERROR_S2, gnu_basename(path), ret); printf(STUB_CONSOLE_PARSE_ERROR_S2, gnu_basename(path), warnings);
#endif #endif
if (-2 == ret)
{
printf(" Block removal error (likely nested comments).\n");
}
else if (-3 == ret)
{
printf(" Function parameter detection error\n");
}
ret = -1;
goto end_stubser_createStub;
} }
else
{
#if isDebugLevel(1) #if isDebugLevel(1)
printf(STUB_CONSOLE_PARSE_OK_S1, path); printf(STUB_CONSOLE_PARSE_OK_S1, path);
#else #else
printf(STUB_CONSOLE_PARSE_OK_S1, gnu_basename(path)); printf(STUB_CONSOLE_PARSE_OK_S1, gnu_basename(path));
#endif #endif
}
sprintf(fileName, "%s/stub_%s", aOutput, aNoSuffix); sprintf(fileName, "%s/stub_%s", aOutput, aNoSuffix);
ret = createStub(fileName, aNoSuffix, &cFile); ret = createStub(fileName, aNoSuffix, &cFile);
if (0 != ret) if (0 != ret)

View File

@@ -44,10 +44,14 @@
#define STUBFUNCTION_CHECK_S1 "stub_%s_checkGlobals" // stub_testfunction_checkGlobals #define STUBFUNCTION_CHECK_S1 "stub_%s_checkGlobals" // stub_testfunction_checkGlobals
#define STUBVARIABLE_EXTENDED_S1 "%s_expected" // variable_expected #define STUBVARIABLE_EXTENDED_S1 "%s_expected" // variable_expected
#define STUB_CONSOLE_GOBACK "\033[2K\r"
#define STUB_CONSOLE_RUN "[ ]"
#define STUB_CONSOLE_OK "[ OK ]" #define STUB_CONSOLE_OK "[ OK ]"
#define STUB_CONSOLE_WARN "[WARN]"
#define STUB_CONSOLE_FAIL "[FAIL]" #define STUB_CONSOLE_FAIL "[FAIL]"
#define STUB_CONSOLE_PARSE_ERROR_S2 STUB_CONSOLE_FAIL " %s parsing failed (%d)\n" #define STUB_CONSOLE_PARSE_ERROR_S2 "\n" STUB_CONSOLE_WARN " %s parsing with %d warnings (check output manually)"
#define STUB_CONSOLE_PARSE_OK_S1 STUB_CONSOLE_OK " %s parsing..." #define STUB_CONSOLE_PARSE_RUN_S1 STUB_CONSOLE_RUN " %s parsing..."
#define STUB_CONSOLE_CREATE_ERROR_S2 "fail\n"STUB_CONSOLE_FAIL " %s creation failed (%d)\n" #define STUB_CONSOLE_PARSE_OK_S1 STUB_CONSOLE_GOBACK STUB_CONSOLE_OK " %s parsing..."
#define STUB_CONSOLE_CREATE_OK_S1 "ok > %s\n" #define STUB_CONSOLE_CREATE_ERROR_S2 "...stub creation failed\n"STUB_CONSOLE_FAIL " %s creation failed (%d)\n"
#define STUB_CONSOLE_CREATE_OK_S1 "...stub created > %s\n"
#endif /* STUBSER_STUBSER_LOC_H_ */ #endif /* STUBSER_STUBSER_LOC_H_ */