diff --git a/src/ext/xmalloc.c b/src/ext/xmalloc.c index 3859f32..ea215dc 100644 --- a/src/ext/xmalloc.c +++ b/src/ext/xmalloc.c @@ -25,3 +25,49 @@ void* xmalloc(size_t size) memset(value, 0, size); return value; } + +char* xmallocStrlcpy(char **aDest, char *aSource, size_t aSize) +{ + if (NULL == aSource || 0 == aSize) + { + return NULL; + } + if (NULL != *aDest) + { + *aDest = (char*) realloc(*aDest, aSize + 1); + } + else + { + *aDest = (char*) xmalloc(aSize + 1); + } + if (NULL != *aDest) + { + (void) strlcpy(*aDest, aSource, aSize + 1); + } + return *aDest; +} + +char* xmallocStrlcat(char **aDest, char *aSource, size_t aSize) +{ + size_t newSize = 0; + if (NULL == aSource || 0 == aSize) + { + return NULL; + } + if (NULL != *aDest) + { + newSize = strlen(*aDest) + aSize + 1; + *aDest = (char*) realloc(*aDest, newSize); + } + else + { + newSize = aSize + 1; + *aDest = (char*) xmalloc(newSize); + } + if (NULL != *aDest) + { + (void) strlcat(*aDest, aSource, newSize); + } + return *aDest; +} + diff --git a/src/ext/xmalloc.h b/src/ext/xmalloc.h index f077fb9..fe5e5c9 100644 --- a/src/ext/xmalloc.h +++ b/src/ext/xmalloc.h @@ -17,5 +17,7 @@ #include void *xmalloc(size_t size); +char* xmallocStrlcpy(char **aDest, char *aSource, size_t aSize); +char* xmallocStrlcat(char **aDest, char *aSource, size_t aSize); #endif /* EXT_XMALLOC_H_ */ diff --git a/src/ext/xstring.c b/src/ext/xstring.c index a78a7be..d365efe 100644 --- a/src/ext/xstring.c +++ b/src/ext/xstring.c @@ -1,13 +1,13 @@ /*! * @file xstring.c - * @brief + * @brief * @details * Project: \n * Subsystem: \n * Module: \n * Code: GNU-C\n - * - * @date 27.02.2017 + * + * @date 27.02.2017 * @author SESA354004 */ #include "xstring.h" @@ -60,7 +60,7 @@ char* strntrimStatic(char *aStr, size_t aMaxLength) end = aStr + strlen(aStr) - 1; } - while (end > aStr && isspace((unsigned char)*end)) + while (end > aStr && isspace((unsigned char )*end)) { end--; } @@ -73,3 +73,53 @@ char* strntrimStatic(char *aStr, size_t aMaxLength) return aStr; } + +void xStringTrim(char *aStr, size_t aMaxLength) +{ + char *start; + char *end; + + if (NULL == aStr) + { + return; + } + start = aStr; + // Trim leading space + while (isspace((unsigned char)*aStr) && 0 < aMaxLength) + { + if (--aMaxLength > 0) + { + ++aStr; + } + } + + // All spaces at termination or end of max length + if (*aStr == '\0' || 0 == aMaxLength) + { + start = '\0'; + return; + } + + (void) strlcpy(start, aStr, strlen(aStr) + 1); + + // Trim trailing space + if (strlen(start) >= aMaxLength) + { + end = start + aMaxLength - 1; + } + else + { + end = start + strlen(start) - 1; + } + + while (end > start && isspace((unsigned char )*end)) + { + end--; + } + + // Write new null terminator (if length is enough) + if (end < (start + aMaxLength - 1)) + { + *(end + 1) = '\0'; + } +} diff --git a/src/ext/xstring.h b/src/ext/xstring.h index 6d777cc..324bb76 100644 --- a/src/ext/xstring.h +++ b/src/ext/xstring.h @@ -1,13 +1,13 @@ /*! * @file xstring.h - * @brief + * @brief * @details * Project: \n * Subsystem: \n * Module: \n * Code: GNU-C\n - * - * @date 27.02.2017 + * + * @date 27.02.2017 * @author SESA354004 */ #ifndef XSTRING_H_ @@ -17,5 +17,6 @@ char* gnu_basename(char *path); char* strntrimStatic(char *aStr, size_t aMaxLength); +void xStringTrim(char *aStr, size_t aMaxLength); #endif /* XSTRING_H_ */ diff --git a/src/stubser/cfile_parser.c b/src/stubser/cfile_parser.c index 7b58863..a9842b1 100644 --- a/src/stubser/cfile_parser.c +++ b/src/stubser/cfile_parser.c @@ -42,6 +42,7 @@ STATIC regex_t regXmlEnd; STATIC regex_t regXmlProto; STATIC regex_t regXproto; STATIC regex_t regXprefix; +STATIC regex_t regXparameter; int8_t cfile_parser_init() { @@ -85,6 +86,11 @@ int8_t cfile_parser_init() perror("Error regex\n"); return -1; } + if (0 > regcomp(®Xparameter, CPARS_REGEX_PARAMETER, (REG_EXTENDED))) + { + perror("Error regex\n"); + return -1; + } cfile_parser_initialized = true; return 0; @@ -101,7 +107,7 @@ STATIC void printMatchGroup(char *aString, regmatch_t *aMatchGroup) { 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)); + 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"); @@ -161,17 +167,17 @@ STATIC int8_t matchFunctionStart(cfunction_t *aFunction, char *aString, size_t a { if (XREGEX_IS_MATCHGROUP(matchGroup, 1)) { - cfunction_newDetail(&aFunction->prefix, &temp[matchGroup[1].rm_so], XREGEX_SIZEOF_MATCHGROUP(matchGroup, 1)); + xmallocStrlcpy(&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)); + xmallocStrlcpy(&aFunction->dataType, &temp[matchGroup[2].rm_so], XREGEX_SIZEOF_MATCHGROUP(matchGroup, 2)); } } else { - cfunction_newDetail(&aFunction->dataType, temp, strlen(temp)); + xmallocStrlcpy(&aFunction->dataType, temp, strlen(temp)); } free(temp); @@ -411,6 +417,48 @@ STATIC int8_t removeCcomments(char *aLine) return cBlockRemoval(aLine, CPARS_COMMENT_BLOCK_START, CPARS_COMMENT_BLOCK_END, &helper, true); } +STATIC int8_t evaluateParameter(char **aParameter, cfunction_t *aFunction) +{ + char *token = NULL; + regmatch_t matchGroup[CFILE_PARSER_MAX_REGEX_MATCHING_GROUPS]; + cfunction_parameter_t *tempParameter = NULL; + + if (NULL == aParameter || NULL == *aParameter || NULL == aFunction) + { + return -1; + } + + token = strtok(*aParameter, ","); + while (token) + { + if (0 == regexec(®Xparameter, token, CFILE_PARSER_MAX_REGEX_MATCHING_GROUPS, matchGroup, 0)) + { + tempParameter = cfunction_newParameter(&aFunction->parameter); + if (XREGEX_IS_MATCHGROUP(matchGroup, 1)) + { + xmallocStrlcpy(&tempParameter->type, &token[matchGroup[1].rm_so], XREGEX_SIZEOF_MATCHGROUP(matchGroup, 1)); + if (NULL != tempParameter->type) + { + xStringTrim(tempParameter->type, XREGEX_SIZEOF_MATCHGROUP(matchGroup, 1)); + } + } + if (XREGEX_IS_MATCHGROUP(matchGroup, 2)) + { + xmallocStrlcpy(&tempParameter->name, &token[matchGroup[2].rm_so], XREGEX_SIZEOF_MATCHGROUP(matchGroup, 2)); + if (NULL != tempParameter->name) + { + xStringTrim(tempParameter->name, XREGEX_SIZEOF_MATCHGROUP(matchGroup, 2)); + } + } + } + token = strtok(NULL, ","); + } + + free(*aParameter); + *aParameter = NULL; + 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 @@ -420,12 +468,12 @@ STATIC int8_t removeCcomments(char *aLine) */ STATIC cfunction_t* cfile_parser_evaluateLine(char *aLine) { + static char *parameterStorage = NULL; static uint32_t braceHelper = 0; 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; if (0 != removeCcomments(aLine)) { @@ -516,24 +564,22 @@ STATIC cfunction_t* cfile_parser_evaluateLine(char *aLine) case 0: // single line function definition case 1: // first line of multi line function definition { + // TODO multiple functions in one line 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)); + xmallocStrlcpy(&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)); + xmallocStrlcat(¶meterStorage, &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)); + xmallocStrlcat(¶meterStorage, &aLine[matchGroup[1].rm_so], XREGEX_SIZEOF_MATCHGROUP(matchGroup, 1)); } if (functionEnd) { @@ -555,6 +601,7 @@ STATIC cfunction_t* cfile_parser_evaluateLine(char *aLine) // return evaluated function if (0 == cfile_parser_functionLine) { + evaluateParameter(¶meterStorage, cfile_parser_function); cfunction_t *funTemp = cfile_parser_function; cfile_parser_function = NULL; return funTemp; diff --git a/src/stubser/cfile_parser_loc.h b/src/stubser/cfile_parser_loc.h index f49bed1..8620025 100644 --- a/src/stubser/cfile_parser_loc.h +++ b/src/stubser/cfile_parser_loc.h @@ -27,6 +27,8 @@ #define FUNCTION_ML_PROTO FUNCTION_ML_PAR "\\).*[[:blank:]]*;" #define FUNCTION_PROTO FUNCTION_BASE "\\).*[[:blank:]]*;" +#define CPARS_REGEX_PARAMETER "[[:blank:]]*([ _\\*[:alnum:]]* +\\**)([_\\*[:alnum:]]*)[[:blank:]]*" + #define CPARS_REGEX_PREFIX "(extern|EXTERN|static|STATIC|volatile|near|far)[[:blank:]]+([^\\*]*\\**)" #define CFILE_PARSER_IS_MATCHGROUP_FUNCTION(matchGroup) (XREGEX_IS_MATCHGROUP(matchGroup, 1) && XREGEX_IS_MATCHGROUP(matchGroup, 2)) diff --git a/src/stubser/cfunction.c b/src/stubser/cfunction.c index 808b5c1..2f21d22 100644 --- a/src/stubser/cfunction.c +++ b/src/stubser/cfunction.c @@ -75,23 +75,6 @@ cfunction_parameter_t* cfunction_newParameter(struct _CFUNCTION_PARAMETER_LIST_T return new; } -char* cfunction_newDetail(char **aDest, char *aSource, size_t aSize) -{ - if (NULL != *aDest) - { - *aDest = (char*) realloc(*aDest, aSize + 1); - } - else - { - *aDest = (char*) xmalloc(aSize + 1); - } - if (NULL != *aDest) - { - (void) strlcpy(*aDest, aSource, aSize + 1); - } - return *aDest; -} - STATIC int8_t cfunction_freeParameter(struct _CFUNCTION_PARAMETER_LIST_T *aParameter) { cfunction_parameter_t *work = NULL; @@ -182,7 +165,7 @@ void cfunction_printList(cfunction_list_t *aList) printf("[ cfu]%d:%s %s %s [%d] ", work->type, work->prefix, work->dataType, work->name, work->parameter.amount); while (param) { - printf("%s ", param->type); + printf("%s|%s,", param->type, param->name); param = param->next; } printf("\n"); diff --git a/src/stubser/cfunction_if.h b/src/stubser/cfunction_if.h index 67715f3..2a23859 100644 --- a/src/stubser/cfunction_if.h +++ b/src/stubser/cfunction_if.h @@ -62,7 +62,6 @@ typedef struct _CFUNCTION_LIST_T cfunction_t* cfunction_newFunction(); int8_t cfunction_addFunction(cfunction_list_t *aList, cfunction_t *aNew); cfunction_parameter_t* cfunction_newParameter(struct _CFUNCTION_PARAMETER_LIST_T *aList); -char* cfunction_newDetail(char **aDest, char *aSource, size_t aSize); int8_t cfunction_freeFunction(cfunction_t **aFunction); int8_t cfunction_freeList(cfunction_list_t *aList); void cfunction_printList(cfunction_list_t *aList);