- WIP (dynamic function structure implementation; parameter parcing missing)

This commit is contained in:
2017-03-01 14:36:53 +00:00
parent da56a3b6cf
commit ea0939d74d
6 changed files with 153 additions and 174 deletions

View File

@@ -12,13 +12,15 @@
*/
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include "xregex.h"
#include "xtypes.h"
#include "xstring.h"
#include "xmalloc.h"
#include "cfunction_if.h"
#include "cfile_parser_loc.h"
#define CFILE_PARSTER_MAX_REGEX_MATCHING_GROUPS 10
#define CFILE_PARSER_MAX_REGEX_MATCHING_GROUPS 10
STATIC bool cfile_parser_initialized = false;
STATIC uint8_t cfile_parser_functionLine = 0;
@@ -30,6 +32,7 @@ STATIC regex_t regXmlPar;
STATIC regex_t regXmlEnd;
STATIC regex_t regXmlProto;
STATIC regex_t regXproto;
STATIC regex_t regXprefix;
int8_t cfile_parser_init()
{
@@ -68,12 +71,102 @@ int8_t cfile_parser_init()
perror("Error regex\n");
return -1;
}
if (0 > regcomp(&regXprefix, CPARS_REGEX_PREFIX, (REG_EXTENDED)))
{
perror("Error regex\n");
return -1;
}
cfile_parser_initialized = true;
return 0;
}
// TODO adapt in cfile_parser_evaluateLine()
STATIC void printMatchGroup(char *aString, regmatch_t *aMatchGroup)
{
char match[1024] =
{ 0 };
uint8_t i = 0;
for (i = 0; i < CFILE_PARSER_MAX_REGEX_MATCHING_GROUPS && 0 <= aMatchGroup[i].rm_so; ++i)
{
if (aMatchGroup[i].rm_so < aMatchGroup[i].rm_eo)
{
printf("[%02d](%.3ld - %.3ld)[%03d]: ", i, aMatchGroup[i].rm_so, aMatchGroup[i].rm_eo, (int) (aMatchGroup[i].rm_eo - aMatchGroup[i].rm_so));
strlcpy(match, &aString[aMatchGroup[i].rm_so], (size_t) (aMatchGroup[i].rm_eo - aMatchGroup[i].rm_so + 1));
printf("%s", match);
printf("\n");
}
}
}
STATIC void checkFunctionType(cfunction_t *aFunction)
{
if (NULL == aFunction->prefix)
{
return;
}
if ((NULL != strstr(aFunction->prefix, "static") || NULL != strstr(aFunction->prefix, "STATIC")) //
&& CFUNCTION_TYPE_PROTO != aFunction->type)
{
aFunction->type = CFUNCTION_TYPE_STATIC;
}
}
/*!
* @brief Extract function prefix and data type and removing trailing blanks
* @param [out] *aFunction Pointer to function structure
* @param [in] *aString Pointer to a substring containing data type and/or prefix
* @param [in] aSize Length of string
* @retval 0 processing successful
* @retval -1 processing failed
*/
STATIC int8_t matchFunctionStart(cfunction_t *aFunction, char *aString, size_t aSize)
{
regmatch_t matchGroup[CFILE_PARSER_MAX_REGEX_MATCHING_GROUPS];
char *temp = NULL;
char *end = NULL;
if (NULL == aFunction || NULL == aString || 0 == aSize)
{
return -1;
}
temp = (char*) xmalloc(aSize + 1);
if (NULL == temp)
{
return -1;
}
strlcpy(temp, aString, aSize + 1);
// remove trailing spaces
end = temp + strlen(temp) - 1;
while (end > temp && isspace((uint8_t ) *end))
{
end--;
}
*(end + 1) = '\0';
if (0 == regexec(&regXprefix, temp, CFILE_PARSER_MAX_REGEX_MATCHING_GROUPS, matchGroup, 0))
{
if (XREGEX_IS_MATCHGROUP(matchGroup, 1))
{
cfunction_newDetail(&aFunction->prefix, &temp[matchGroup[1].rm_so], XREGEX_SIZEOF_MATCHGROUP(matchGroup, 1));
checkFunctionType(aFunction);
}
if (XREGEX_IS_MATCHGROUP(matchGroup, 2))
{
cfunction_newDetail(&aFunction->dataType, &temp[matchGroup[2].rm_so], XREGEX_SIZEOF_MATCHGROUP(matchGroup, 2));
}
}
else
{
cfunction_newDetail(&aFunction->dataType, temp, strlen(temp));
}
free(temp);
return 0;
}
/*!
* @brief Process a string (e.g. from getline()) if it is a single or multiple line function definition
* @todo closing parenthesis within parameter list will break the detection
@@ -81,156 +174,21 @@ int8_t cfile_parser_init()
* @retval -2 Given String not a function
* @retval 0 function evaluated
*/
//STATIC int matchFunction(char *aLine)
//{
// const size_t maxGroup = 10;
// regmatch_t matchGroup[maxGroup];
// const char *pattern = STUBI_FUNCTION_REGEX;
// const char *patternend = STUBI_FUNCTION_REGEX
// "\\)";
// regex_t regX;
// regex_t regXEnd;
// regex_t regXMulti;
// regex_t regXMultiEnd;
// uint8_t i = 0;
// char funPrefix[256] =
// { 0 };
// static char funTest[2056] =
// { 0 };
// static uint8_t multiParamFlag = 0;
// uint8_t multiParamEndFlag = 0;
//
// if (0 > regcomp(&regX, pattern, REG_EXTENDED)) // | REG_NEWLINE))
// {
// perror("Error regex\n");
// return -1;
// }
//
// if (0 > regcomp(&regXEnd, patternend, REG_EXTENDED)) // | REG_NEWLINE))
// {
// perror("Error regexend\n");
// return -1;
// }
//
// if (0 > regcomp(&regXMulti, STUBI_FUNCTION_MULTI, REG_EXTENDED)) // | REG_NEWLINE))
// {
// perror("Error regXMulti\n");
// return -1;
// }
//
// if (0 > regcomp(&regXMultiEnd, STUBI_FUNCTION_MULTI_END, REG_EXTENDED)) // | REG_NEWLINE))
// {
// perror("Error regXMultiEnd\n");
// return -1;
// }
//
// if (multiParamFlag)
// {
// if (0 == regexec(&regXMultiEnd, aLine, maxGroup, matchGroup, 0))
// {
// // end of multi line function
// ++multiParamFlag;
// multiParamEndFlag = 1;
// }
// else
// {
// // continuation of multi line function
// (void) regexec(&regXMulti, aLine, maxGroup, matchGroup, 0);
// ++multiParamFlag;
// }
// }
// else if (0 == regexec(&regXEnd, aLine, maxGroup, matchGroup, 0))
// {
// // single line function
// multiParamFlag = 0;
// }
// else if (0 == regexec(&regX, aLine, maxGroup, matchGroup, 0))
// {
// // start of multi line function
// ++multiParamFlag;
// printf("[ mls][%d]:", multiParamFlag);
// }
// else
// {
// // no fit
// return -2;
// }
//
// switch (multiParamFlag)
// {
// case 0: // single line function definition
// case 1: // first line of multi line function definition
// {
// (void) strlcpy(funPrefix, &aLine[matchGroup[1].rm_so], (size_t) (matchGroup[1].rm_eo - matchGroup[1].rm_so) + 1);
// (void) strlcat(funTest, &aLine[matchGroup[1].rm_so], (size_t) (matchGroup[1].rm_eo - matchGroup[1].rm_so) + 1);
//
// if ( //
// NULL == strstr(funPrefix, "extern") //
// && NULL == strstr(funPrefix, "EXTERN") //
// && NULL == strstr(funPrefix, "static") //
// && NULL == strstr(funPrefix, "STATIC") //
// && matchGroup[2].rm_so < matchGroup[2].rm_eo)
// {
// printf("[ sl ]:%s", funPrefix);
// for (i = 2; i < maxGroup && 0 <= matchGroup[i].rm_so; ++i)
// {
// printf(" (%.3ld - %.3ld): ", matchGroup[i].rm_so, matchGroup[i].rm_eo);
// printf("%.*s", (int) (matchGroup[i].rm_eo - matchGroup[i].rm_so), &aLine[matchGroup[i].rm_so]);
// (void) strncat(funTest, &aLine[matchGroup[i].rm_so], (int) (matchGroup[i].rm_eo - matchGroup[i].rm_so) + 1);
// }
// printf("\n");
// }
// // TODO special handling for static functions (as extern in stub header)
// else if (NULL != strstr(funPrefix, "static") || NULL != strstr(funPrefix, "STATIC"))
// {
// printf("[todo] %s %.*s\n", funPrefix, (int) (matchGroup[2].rm_eo - matchGroup[2].rm_so), &aLine[matchGroup[2].rm_so]);
// }
// // ignore functions declared as extern
// else if (NULL != strstr(funPrefix, "extern") || NULL != strstr(funPrefix, "EXTERN"))
// {
// printf("[ nu ] %s %.*s\n", funPrefix, (int) (matchGroup[2].rm_eo - matchGroup[2].rm_so), &aLine[matchGroup[2].rm_so]);
// }
// break;
// }
// default: // further lines
// {
// if (multiParamEndFlag)
// {
// printf("[ mle][%d]:", multiParamFlag);
// }
// else
// {
// printf("[ ml ][%d]:", multiParamFlag);
// }
//
// if (matchGroup[1].rm_so < matchGroup[1].rm_eo)
// {
// for (i = 1; i < maxGroup && 0 <= matchGroup[i].rm_so; ++i)
// {
// printf("(%.3ld-%.3ld):", matchGroup[i].rm_so, matchGroup[i].rm_eo);
// printf("%.*s", (int) (matchGroup[i].rm_eo - matchGroup[i].rm_so), &aLine[matchGroup[i].rm_so]);
// }
// printf("\n");
// }
//
// if (multiParamEndFlag)
// {
// multiParamFlag = 0;
// multiParamEndFlag = 0;
// }
//
// break;
// }
// }
//
// return 0;
//}
STATIC cfunction_t* cfile_parser_evaluateLine(char *aLine)
{
const size_t maxGroup = CFILE_PARSTER_MAX_REGEX_MATCHING_GROUPS;
const size_t maxGroup = CFILE_PARSER_MAX_REGEX_MATCHING_GROUPS;
regmatch_t matchGroup[maxGroup];
bool functionEnd = false;
cfunction_type_t tempFunctionType = CFUNCTION_TYPE_UNDEF;
cfunction_parameter_t *tempParameter = NULL;
char *tempChar = NULL;
// remove basic inline comments
tempChar = strstr(aLine, "//");
if (NULL != tempChar)
{
strlcpy(tempChar, "\r\n", 3);
}
if (cfile_parser_functionLine)
{
@@ -238,29 +196,25 @@ STATIC cfunction_t* cfile_parser_evaluateLine(char *aLine)
{
tempFunctionType = CFUNCTION_TYPE_REGULAR;
printf("[ mle]");
++cfile_parser_functionLine;
functionEnd = true;
}
else if (0 == regexec(&regXmlProto, aLine, maxGroup, matchGroup, REG_NOTEOL))
{
tempFunctionType = CFUNCTION_TYPE_PROTO;
printf("[ mlp]");
++cfile_parser_functionLine;
functionEnd = true;
}
else if (0 == regexec(&regXmlPar, aLine, maxGroup, matchGroup, REG_NOTEOL))
{
printf("[ ml+]");
++cfile_parser_functionLine;
}
else
{
tempFunctionType = CFUNCTION_TYPE_UNDEF;
++cfile_parser_functionLine;
functionEnd = true;
// TODO fallback (free currently used memory)
return NULL;
}
++cfile_parser_functionLine;
}
else if (0 == regexec(&regXsl, aLine, maxGroup, matchGroup, REG_NOTEOL) && CFILE_PARSER_IS_MATCHGROUP_FUNCTION(matchGroup))
{
@@ -287,11 +241,9 @@ STATIC cfunction_t* cfile_parser_evaluateLine(char *aLine)
{
return NULL;
}
#if (0)
{
uint8_t i = 0;
char *tempChar = NULL;
char match[1024] =
{ 0};
@@ -302,20 +254,17 @@ STATIC cfunction_t* cfile_parser_evaluateLine(char *aLine)
if (0 < i)
printf(" ");
printf("[%02d](%.3ld - %.3ld)[%03d]: ", i, matchGroup[i].rm_so, matchGroup[i].rm_eo, (int) (matchGroup[i].rm_eo - matchGroup[i].rm_so));
//printf("%.*s", (int) (matchGroup[i].rm_eo - matchGroup[i].rm_so), &aLine[matchGroup[i].rm_so]);
strlcpy(match, &aLine[matchGroup[i].rm_so], (size_t) (matchGroup[i].rm_eo - matchGroup[i].rm_so + 1));
tempChar = strstr(match, "//");
if (NULL != tempChar)
{
*tempChar = '\0';
}
printf("%s", match);
printf("\n");
}
}
if (functionEnd)
{
cfile_parser_functionLine = 0;
}
}
#endif
#else
switch (cfile_parser_functionLine)
{
case 0: // single line function definition
@@ -323,11 +272,23 @@ STATIC cfunction_t* cfile_parser_evaluateLine(char *aLine)
{
cfile_parser_function = cfunction_newFunction();
cfile_parser_function->type = tempFunctionType;
matchFunctionStart(cfile_parser_function, &aLine[matchGroup[1].rm_so], XREGEX_SIZEOF_MATCHGROUP(matchGroup, 1));
cfunction_newDetail(&cfile_parser_function->name, &aLine[matchGroup[2].rm_so], XREGEX_SIZEOF_MATCHGROUP(matchGroup, 2));
if (XREGEX_IS_MATCHGROUP(matchGroup, 3))
{
tempParameter = cfunction_newParameter(&cfile_parser_function->parameter);
cfunction_newDetail(&tempParameter->type, &aLine[matchGroup[3].rm_so], XREGEX_SIZEOF_MATCHGROUP(matchGroup, 3));
}
break;
}
default: // further lines
{
// TODO process parameter
if (XREGEX_IS_MATCHGROUP(matchGroup, 1))
{
tempParameter = cfunction_newParameter(&cfile_parser_function->parameter);
cfunction_newDetail(&tempParameter->type, &aLine[matchGroup[1].rm_so], XREGEX_SIZEOF_MATCHGROUP(matchGroup, 1));
}
if (functionEnd)
{
// TODO clean function
@@ -338,6 +299,7 @@ STATIC cfunction_t* cfile_parser_evaluateLine(char *aLine)
else
{
cfile_parser_function->type = tempFunctionType;
checkFunctionType(cfile_parser_function);
}
cfile_parser_functionLine = 0;
}
@@ -352,6 +314,7 @@ STATIC cfunction_t* cfile_parser_evaluateLine(char *aLine)
cfile_parser_function = NULL;
return funTemp;
}
#endif
return NULL;
}