WIP multiline parser running (detecting variables, function, prototypes as whole string)
- TODO parsing result of first pass (detecting C elements) - TODO #include, #if, ... not included
This commit is contained in:
@@ -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)
|
||||
{
|
||||
if (false == workerActive)
|
||||
result = regExWorker(&match, &position, matchStart, matchEnd, &depth, false);
|
||||
if (match && 0 == result && 0 == depth)
|
||||
{
|
||||
DEBUG_LOG_APPEND(1, "[ Re %04u] Works %zu %s\n", aNumber, strlen(match), match);
|
||||
xfree((void**) &match);
|
||||
++worker;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
xmallocStrlcat(&match, result, cSize);
|
||||
|
||||
if (false == workerActive)
|
||||
if (0 > result)
|
||||
{
|
||||
DEBUG_LOG_APPEND(1, "Works %zu %s\n", cSize, match);
|
||||
// TODO evaluate expression according to worker
|
||||
if (-2 == result)
|
||||
DEBUG_LOG_APPEND(2, "[ PEr]");
|
||||
position = NULL;
|
||||
xfree((void**) &match);
|
||||
worker = (stringWorker*) cWorker;
|
||||
}
|
||||
else
|
||||
{
|
||||
// force space between findings
|
||||
xmallocStrlcat(&match, " ", 2);
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
@@ -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))
|
||||
|
@@ -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)
|
||||
if (*aBlockDepth)
|
||||
{
|
||||
*aSize = 0;
|
||||
begin = NULL;
|
||||
xmallocStrlcat(aOutput, " ", 2);
|
||||
ret = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = -1;
|
||||
}
|
||||
*aInput = NULL;
|
||||
goto regExWorker_end;
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
if (*aActive)
|
||||
{
|
||||
if (aEnd != NULL && 0 == regexec(aEnd, *aInput, CFILE_PARSER_MAX_REGEX_MATCHING_GROUPS, matchGroup, REG_NOTEOL) && XREGEX_IS_MATCHGROUP(matchGroup, 1))
|
||||
{
|
||||
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;
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG_LOG_APPEND(1, "[ CE+]");
|
||||
*aSize += strlen(*aInput);
|
||||
*aInput += strlen(*aInput);
|
||||
return begin;
|
||||
}
|
||||
}
|
||||
else if (0 == regexec(aStart, *aInput, CFILE_PARSER_MAX_REGEX_MATCHING_GROUPS, matchGroup, REG_NOTEOL) && XREGEX_IS_MATCHGROUP(matchGroup, 1))
|
||||
begin = NULL;
|
||||
// no findings
|
||||
if (!match)
|
||||
{
|
||||
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);
|
||||
ret = -1;
|
||||
goto regExWorker_end;
|
||||
}
|
||||
}
|
||||
|
||||
return begin;
|
||||
// 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;
|
||||
}
|
||||
|
@@ -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_ */
|
||||
|
Reference in New Issue
Block a user