- cleaning and refactoring functionality
- parser function new WIP (old included as comment-> must be integrated)
This commit is contained in:
@@ -30,8 +30,8 @@
|
|||||||
<tool id="cdt.managedbuild.tool.gnu.c.compiler.cygwin.exe.debug.75372444" name="Cygwin C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.cygwin.exe.debug">
|
<tool id="cdt.managedbuild.tool.gnu.c.compiler.cygwin.exe.debug.75372444" name="Cygwin C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.cygwin.exe.debug">
|
||||||
<option defaultValue="gnu.c.optimization.level.none" id="gnu.c.compiler.cygwin.exe.debug.option.optimization.level.1758127696" name="Optimization Level" superClass="gnu.c.compiler.cygwin.exe.debug.option.optimization.level" useByScannerDiscovery="false" valueType="enumerated"/>
|
<option defaultValue="gnu.c.optimization.level.none" id="gnu.c.compiler.cygwin.exe.debug.option.optimization.level.1758127696" name="Optimization Level" superClass="gnu.c.compiler.cygwin.exe.debug.option.optimization.level" useByScannerDiscovery="false" valueType="enumerated"/>
|
||||||
<option id="gnu.c.compiler.cygwin.exe.debug.option.debugging.level.196472971" name="Debug Level" superClass="gnu.c.compiler.cygwin.exe.debug.option.debugging.level" useByScannerDiscovery="false" value="gnu.c.debugging.level.max" valueType="enumerated"/>
|
<option id="gnu.c.compiler.cygwin.exe.debug.option.debugging.level.196472971" name="Debug Level" superClass="gnu.c.compiler.cygwin.exe.debug.option.debugging.level" useByScannerDiscovery="false" value="gnu.c.debugging.level.max" valueType="enumerated"/>
|
||||||
<option id="gnu.c.compiler.option.include.paths.1914441723" superClass="gnu.c.compiler.option.include.paths" valueType="includePath">
|
<option id="gnu.c.compiler.option.include.paths.1914441723" name="Include paths (-I)" superClass="gnu.c.compiler.option.include.paths" useByScannerDiscovery="false" valueType="includePath">
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/stubi_svn/src/ext}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/src/ext}""/>
|
||||||
</option>
|
</option>
|
||||||
<inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.cygwin.1850965" superClass="cdt.managedbuild.tool.gnu.c.compiler.input.cygwin"/>
|
<inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.cygwin.1850965" superClass="cdt.managedbuild.tool.gnu.c.compiler.input.cygwin"/>
|
||||||
</tool>
|
</tool>
|
||||||
|
25
src/ext/xmalloc.c
Normal file
25
src/ext/xmalloc.c
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
/*!
|
||||||
|
* @file xmalloc.c
|
||||||
|
* @brief
|
||||||
|
* @details
|
||||||
|
* Project: \n
|
||||||
|
* Subsystem: \n
|
||||||
|
* Module: \n
|
||||||
|
* Code: GNU-C\n
|
||||||
|
*
|
||||||
|
* @date 28.02.2017
|
||||||
|
* @author SESA354004
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "xmalloc.h"
|
||||||
|
#include "xtypes.h"
|
||||||
|
|
||||||
|
void *xmalloc(size_t size)
|
||||||
|
{
|
||||||
|
void *value = malloc(size);
|
||||||
|
if (value == 0)
|
||||||
|
perror("virtual memory exhausted");
|
||||||
|
else
|
||||||
|
memset(value, 0, size);
|
||||||
|
return value;
|
||||||
|
}
|
21
src/ext/xmalloc.h
Normal file
21
src/ext/xmalloc.h
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
/*!
|
||||||
|
* @file xmalloc.h
|
||||||
|
* @brief
|
||||||
|
* @details
|
||||||
|
* Project: \n
|
||||||
|
* Subsystem: \n
|
||||||
|
* Module: \n
|
||||||
|
* Code: GNU-C\n
|
||||||
|
*
|
||||||
|
* @date 28.02.2017
|
||||||
|
* @author SESA354004
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef EXT_XMALLOC_H_
|
||||||
|
#define EXT_XMALLOC_H_
|
||||||
|
|
||||||
|
#include <malloc.h>
|
||||||
|
|
||||||
|
void *xmalloc(size_t size);
|
||||||
|
|
||||||
|
#endif /* EXT_XMALLOC_H_ */
|
@@ -1,13 +1,13 @@
|
|||||||
/*!
|
/*!
|
||||||
* @file main.c
|
* @file main.c
|
||||||
* @brief
|
* @brief
|
||||||
* @details
|
* @details
|
||||||
* Project: \n
|
* Project: \n
|
||||||
* Subsystem: \n
|
* Subsystem: \n
|
||||||
* Module: \n
|
* Module: \n
|
||||||
* Code: GNU-C\n
|
* Code: GNU-C\n
|
||||||
*
|
*
|
||||||
* @date 27.02.2017
|
* @date 27.02.2017
|
||||||
* @author SESA354004
|
* @author SESA354004
|
||||||
*/
|
*/
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@@ -67,7 +67,7 @@ int main(int argc, char **argv)
|
|||||||
{
|
{
|
||||||
sprintf(filePath, "%s/%s", argv[1], eps[cnt]->d_name);
|
sprintf(filePath, "%s/%s", argv[1], eps[cnt]->d_name);
|
||||||
printf("%s (%d)\n", filePath, eps[cnt]->d_type);
|
printf("%s (%d)\n", filePath, eps[cnt]->d_type);
|
||||||
scanFile(filePath);
|
stubser_createStub(filePath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
325
src/stubser/cfile_parser.c
Normal file
325
src/stubser/cfile_parser.c
Normal file
@@ -0,0 +1,325 @@
|
|||||||
|
/*!
|
||||||
|
* @file cfile_parser.c
|
||||||
|
* @brief
|
||||||
|
* @details
|
||||||
|
* Project: \n
|
||||||
|
* Subsystem: \n
|
||||||
|
* Module: \n
|
||||||
|
* Code: GNU-C\n
|
||||||
|
*
|
||||||
|
* @date 28.02.2017
|
||||||
|
* @author SESA354004
|
||||||
|
*/
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <regex.h>
|
||||||
|
#include "xtypes.h"
|
||||||
|
#include "xstring.h"
|
||||||
|
#include "cfile_parser_loc.h"
|
||||||
|
#include "cfunction_if.h"
|
||||||
|
|
||||||
|
STATIC bool cfile_parser_initialized = false;
|
||||||
|
STATIC regex_t regX;
|
||||||
|
STATIC regex_t regXsl;
|
||||||
|
STATIC regex_t regXmlStart;
|
||||||
|
STATIC regex_t regXmlPar;
|
||||||
|
STATIC regex_t regXmlEnd;
|
||||||
|
STATIC regex_t regXmlProto;
|
||||||
|
STATIC regex_t regXproto;
|
||||||
|
|
||||||
|
int8_t cfile_parser_init()
|
||||||
|
{
|
||||||
|
if (0 > regcomp(®X, FUNCTION_BASE, (REG_EXTENDED | REG_NEWLINE)))
|
||||||
|
{
|
||||||
|
perror("Error regex\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (0 > regcomp(®Xsl, FUNCTION_SL, (REG_EXTENDED | REG_NEWLINE)))
|
||||||
|
{
|
||||||
|
perror("Error regex\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (0 > regcomp(®XmlStart, FUNCTION_ML_SOF, (REG_EXTENDED | REG_NEWLINE)))
|
||||||
|
{
|
||||||
|
perror("Error regex\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (0 > regcomp(®XmlPar, FUNCTION_ML_PAR, (REG_EXTENDED | REG_NEWLINE)))
|
||||||
|
{
|
||||||
|
perror("Error regex\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (0 > regcomp(®XmlEnd, FUNCTION_ML_END, (REG_EXTENDED | REG_NEWLINE)))
|
||||||
|
{
|
||||||
|
perror("Error regex\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (0 > regcomp(®XmlProto, FUNCTION_ML_PROTO, (REG_EXTENDED | REG_NEWLINE)))
|
||||||
|
{
|
||||||
|
perror("Error regex\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (0 > regcomp(®Xproto, FUNCTION_PROTO, (REG_EXTENDED | REG_NEWLINE)))
|
||||||
|
{
|
||||||
|
perror("Error regex\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
cfile_parser_initialized = true;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO adapt in cfile_parser_evaluateLine()
|
||||||
|
/*!
|
||||||
|
* @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
|
||||||
|
* @retval -1 Invalid regula expressions
|
||||||
|
* @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(®X, pattern, REG_EXTENDED)) // | REG_NEWLINE))
|
||||||
|
// {
|
||||||
|
// perror("Error regex\n");
|
||||||
|
// return -1;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// if (0 > regcomp(®XEnd, patternend, REG_EXTENDED)) // | REG_NEWLINE))
|
||||||
|
// {
|
||||||
|
// perror("Error regexend\n");
|
||||||
|
// return -1;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// if (0 > regcomp(®XMulti, STUBI_FUNCTION_MULTI, REG_EXTENDED)) // | REG_NEWLINE))
|
||||||
|
// {
|
||||||
|
// perror("Error regXMulti\n");
|
||||||
|
// return -1;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// if (0 > regcomp(®XMultiEnd, STUBI_FUNCTION_MULTI_END, REG_EXTENDED)) // | REG_NEWLINE))
|
||||||
|
// {
|
||||||
|
// perror("Error regXMultiEnd\n");
|
||||||
|
// return -1;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// if (multiParamFlag)
|
||||||
|
// {
|
||||||
|
// if (0 == regexec(®XMultiEnd, aLine, maxGroup, matchGroup, 0))
|
||||||
|
// {
|
||||||
|
// // end of multi line function
|
||||||
|
// ++multiParamFlag;
|
||||||
|
// multiParamEndFlag = 1;
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// // continuation of multi line function
|
||||||
|
// (void) regexec(®XMulti, aLine, maxGroup, matchGroup, 0);
|
||||||
|
// ++multiParamFlag;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// else if (0 == regexec(®XEnd, aLine, maxGroup, matchGroup, 0))
|
||||||
|
// {
|
||||||
|
// // single line function
|
||||||
|
// multiParamFlag = 0;
|
||||||
|
// }
|
||||||
|
// else if (0 == regexec(®X, 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 void cfile_parser_evaluateLine(char *aLine)
|
||||||
|
{
|
||||||
|
uint8_t i;
|
||||||
|
const size_t maxGroup = 10;
|
||||||
|
regmatch_t matchGroup[maxGroup];
|
||||||
|
|
||||||
|
char match[1024] =
|
||||||
|
{ 0 };
|
||||||
|
static uint8_t mlFlag = 0;
|
||||||
|
|
||||||
|
if (mlFlag)
|
||||||
|
{
|
||||||
|
if (0 == regexec(®XmlEnd, aLine, maxGroup, matchGroup, REG_NOTEOL))
|
||||||
|
{
|
||||||
|
printf("[ mle]");
|
||||||
|
mlFlag = 0;
|
||||||
|
}
|
||||||
|
else if (0 == regexec(®XmlProto, aLine, maxGroup, matchGroup, REG_NOTEOL))
|
||||||
|
{
|
||||||
|
printf("[ mlp]");
|
||||||
|
mlFlag = 0;
|
||||||
|
}
|
||||||
|
else if (0 == regexec(®XmlPar, aLine, maxGroup, matchGroup, REG_NOTEOL))
|
||||||
|
{
|
||||||
|
printf("[ ml+]");
|
||||||
|
++mlFlag;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// fallback
|
||||||
|
mlFlag = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (0 == regexec(®Xsl, aLine, maxGroup, matchGroup, REG_NOTEOL) && matchGroup[2].rm_so < matchGroup[2].rm_eo)
|
||||||
|
{
|
||||||
|
printf("[ sl ]");
|
||||||
|
}
|
||||||
|
else if (0 == regexec(®XmlStart, aLine, maxGroup, matchGroup, REG_NOTEOL) && matchGroup[2].rm_so < matchGroup[2].rm_eo)
|
||||||
|
{
|
||||||
|
printf("[ mls]");
|
||||||
|
++mlFlag;
|
||||||
|
}
|
||||||
|
else if (0 == regexec(®Xproto, aLine, maxGroup, matchGroup, REG_NOTEOL) && matchGroup[2].rm_so < matchGroup[2].rm_eo)
|
||||||
|
{
|
||||||
|
printf("[prot]");
|
||||||
|
}
|
||||||
|
else if (0 == regexec(®X, aLine, maxGroup, matchGroup, REG_NOTEOL) && matchGroup[2].rm_so < matchGroup[2].rm_eo)
|
||||||
|
{
|
||||||
|
printf("[ fuX]");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < maxGroup && 0 <= matchGroup[i].rm_so; ++i)
|
||||||
|
{
|
||||||
|
if (matchGroup[i].rm_so < matchGroup[i].rm_eo)
|
||||||
|
{
|
||||||
|
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));
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int8_t cfile_parser(char *aPath, cfunction_list_t *aList)
|
||||||
|
{
|
||||||
|
FILE *fdesc;
|
||||||
|
ssize_t charRead = 0;
|
||||||
|
size_t lineSize = 0;
|
||||||
|
char *fileLine = NULL; // will be allocated by getline(); must be freed
|
||||||
|
|
||||||
|
if (false == cfile_parser_initialized)
|
||||||
|
{
|
||||||
|
cfile_parser_init();
|
||||||
|
}
|
||||||
|
|
||||||
|
fdesc = fopen(aPath, "r");
|
||||||
|
if (NULL == fdesc)
|
||||||
|
{
|
||||||
|
perror("Error open file");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
charRead = getline(&fileLine, &lineSize, fdesc);
|
||||||
|
if (0 <= charRead)
|
||||||
|
{
|
||||||
|
(void) cfile_parser_evaluateLine(fileLine);
|
||||||
|
}
|
||||||
|
} while (0 <= charRead);
|
||||||
|
|
||||||
|
free(fileLine);
|
||||||
|
(void) fclose(fdesc);
|
||||||
|
return 0;
|
||||||
|
}
|
19
src/stubser/cfile_parser_if.h
Normal file
19
src/stubser/cfile_parser_if.h
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
/*!
|
||||||
|
* @file cfile_parser_if.h
|
||||||
|
* @brief
|
||||||
|
* @details
|
||||||
|
* Project: \n
|
||||||
|
* Subsystem: \n
|
||||||
|
* Module: \n
|
||||||
|
* Code: GNU-C\n
|
||||||
|
*
|
||||||
|
* @date 28.02.2017
|
||||||
|
* @author SESA354004
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef STUBSER_CFILE_PARSER_IF_H_
|
||||||
|
#define STUBSER_CFILE_PARSER_IF_H_
|
||||||
|
|
||||||
|
int8_t cfile_parser(char *aPath, cfunction_list_t *aList);
|
||||||
|
|
||||||
|
#endif /* STUBSER_CFILE_PARSER_IF_H_ */
|
25
src/stubser/cfile_parser_loc.h
Normal file
25
src/stubser/cfile_parser_loc.h
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
/*!
|
||||||
|
* @file cfile_parser_loc.h
|
||||||
|
* @brief
|
||||||
|
* @details
|
||||||
|
* Project: \n
|
||||||
|
* Subsystem: \n
|
||||||
|
* Module: \n
|
||||||
|
* Code: GNU-C\n
|
||||||
|
*
|
||||||
|
* @date 28.02.2017
|
||||||
|
* @author SESA354004
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef STUBSER_CFILE_PARSER_LOC_H_
|
||||||
|
#define STUBSER_CFILE_PARSER_LOC_H_
|
||||||
|
|
||||||
|
#define FUNCTION_BASE "^[[:blank:]]*([ _\\*[:alnum:]]*) +([_\\*[:alnum:]]*)[[:blank:]]*\\(([^\\)]*)"
|
||||||
|
#define FUNCTION_SL FUNCTION_BASE "\\)[^;]*$"
|
||||||
|
#define FUNCTION_ML_SOF FUNCTION_BASE "$"
|
||||||
|
#define FUNCTION_ML_PAR "^[[:blank:]]*([^\r]*)"
|
||||||
|
#define FUNCTION_ML_END FUNCTION_ML_PAR "\\)[^;]*$"
|
||||||
|
#define FUNCTION_ML_PROTO FUNCTION_ML_PAR "\\).*[[:blank:]]*;"
|
||||||
|
#define FUNCTION_PROTO FUNCTION_BASE "\\).*[[:blank:]]*;"
|
||||||
|
|
||||||
|
#endif /* STUBSER_CFILE_PARSER_LOC_H_ */
|
138
src/stubser/cfunction.c
Normal file
138
src/stubser/cfunction.c
Normal file
@@ -0,0 +1,138 @@
|
|||||||
|
/*!
|
||||||
|
* @file cfunction.c
|
||||||
|
* @brief
|
||||||
|
* @details
|
||||||
|
* Project: \n
|
||||||
|
* Subsystem: \n
|
||||||
|
* Module: \n
|
||||||
|
* Code: GNU-C\n
|
||||||
|
*
|
||||||
|
* @date 28.02.2017
|
||||||
|
* @author SESA354004
|
||||||
|
*/
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "xtypes.h"
|
||||||
|
#include "xmalloc.h"
|
||||||
|
#include "cfunction_if.h"
|
||||||
|
|
||||||
|
cfunction_t* cfunction_newFunction(cfunction_list_t *aList)
|
||||||
|
{
|
||||||
|
cfunction_t *next = NULL;
|
||||||
|
|
||||||
|
if (NULL == aList)
|
||||||
|
{
|
||||||
|
perror("Null pointer");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
next = (cfunction_t*) xmalloc(sizeof(cfunction_t));
|
||||||
|
memset(next, 0, sizeof(cfunction_t));
|
||||||
|
|
||||||
|
if (NULL == aList->head)
|
||||||
|
{
|
||||||
|
aList->head = next;
|
||||||
|
}
|
||||||
|
|
||||||
|
aList->current = next;
|
||||||
|
|
||||||
|
return next;
|
||||||
|
}
|
||||||
|
|
||||||
|
cfunction_parameter_t* cfunction_newParameter(struct _CFUNCTION_PARAMETER_LIST_T *aList)
|
||||||
|
{
|
||||||
|
cfunction_parameter_t *next = NULL;
|
||||||
|
|
||||||
|
if (NULL == aList)
|
||||||
|
{
|
||||||
|
perror("Null pointer");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
next = (cfunction_parameter_t*) xmalloc(sizeof(cfunction_parameter_t));
|
||||||
|
memset(next, 0, sizeof(cfunction_parameter_t));
|
||||||
|
|
||||||
|
if (NULL == aList->head)
|
||||||
|
{
|
||||||
|
aList->head = next;
|
||||||
|
}
|
||||||
|
|
||||||
|
aList->current = next;
|
||||||
|
|
||||||
|
return next;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
int8_t cfunction_freeParameter(struct _CFUNCTION_PARAMETER_LIST_T *aParameter)
|
||||||
|
{
|
||||||
|
cfunction_parameter_t *work = NULL;
|
||||||
|
cfunction_parameter_t *next = NULL;
|
||||||
|
|
||||||
|
if (NULL == aParameter)
|
||||||
|
{
|
||||||
|
perror("Null pointer");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
work = aParameter->head;
|
||||||
|
|
||||||
|
while (work)
|
||||||
|
{
|
||||||
|
next = work->next;
|
||||||
|
free(work->type);
|
||||||
|
free(work->name);
|
||||||
|
free(work);
|
||||||
|
work = next;
|
||||||
|
}
|
||||||
|
|
||||||
|
aParameter->head = NULL;
|
||||||
|
aParameter->current = NULL;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int8_t cfunction_freeList(cfunction_list_t *aList)
|
||||||
|
{
|
||||||
|
cfunction_t *work = NULL;
|
||||||
|
cfunction_t *next = NULL;
|
||||||
|
|
||||||
|
if (NULL == aList)
|
||||||
|
{
|
||||||
|
perror("Null pointer");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
work = aList->head;
|
||||||
|
|
||||||
|
while (work)
|
||||||
|
{
|
||||||
|
next = work->next;
|
||||||
|
free(work->prefix);
|
||||||
|
free(work->dataType);
|
||||||
|
free(work->name);
|
||||||
|
cfunction_freeParameter(&work->parameter);
|
||||||
|
free(work);
|
||||||
|
work = next;
|
||||||
|
}
|
||||||
|
|
||||||
|
aList->head = NULL;
|
||||||
|
aList->current = NULL;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
56
src/stubser/cfunction_if.h
Normal file
56
src/stubser/cfunction_if.h
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
/*!
|
||||||
|
* @file cfunction_if.h
|
||||||
|
* @brief
|
||||||
|
* @details
|
||||||
|
* Project: \n
|
||||||
|
* Subsystem: \n
|
||||||
|
* Module: \n
|
||||||
|
* Code: GNU-C\n
|
||||||
|
*
|
||||||
|
* @date 28.02.2017
|
||||||
|
* @author SESA354004
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef STUBSER_CFUNCTION_IF_H_
|
||||||
|
#define STUBSER_CFUNCTION_IF_H_
|
||||||
|
|
||||||
|
/*! @brief Parameter list node */
|
||||||
|
typedef struct _CFUNCTION_PARAMETER_T
|
||||||
|
{
|
||||||
|
char* type; /*!< @brief data type */
|
||||||
|
char* name; /*!< @brief name */
|
||||||
|
struct _CFUNCTION_PARAMETER_T *next;
|
||||||
|
} cfunction_parameter_t;
|
||||||
|
|
||||||
|
/*! @brief brief_description */
|
||||||
|
typedef struct _CFUNCTION_T
|
||||||
|
{
|
||||||
|
char *prefix; /*!< @brief prefix like static or extern */
|
||||||
|
char *dataType; /*!< @brief return type */
|
||||||
|
char *name; /*!< @brief name */
|
||||||
|
struct _CFUNCTION_PARAMETER_LIST_T
|
||||||
|
{
|
||||||
|
cfunction_parameter_t *head;
|
||||||
|
cfunction_parameter_t *current;
|
||||||
|
} parameter;/*!< @brief parameter array */
|
||||||
|
struct _CFUNCTION_T *next;
|
||||||
|
} cfunction_t;
|
||||||
|
|
||||||
|
/*! @brief Dynamic function list */
|
||||||
|
typedef struct _CFUNCTION_LIST_T
|
||||||
|
{
|
||||||
|
cfunction_t *head;
|
||||||
|
cfunction_t *current;
|
||||||
|
} cfunction_list_t;
|
||||||
|
|
||||||
|
#define CFUNCTION_LIST_DEFAULT {\
|
||||||
|
.head = NULL, \
|
||||||
|
.current = NULL }
|
||||||
|
|
||||||
|
cfunction_t* cfunction_newFunction(cfunction_list_t *aList);
|
||||||
|
cfunction_parameter_t* cfunction_newParameter(struct _CFUNCTION_PARAMETER_LIST_T *aList);
|
||||||
|
char* cfunction_newDetail(char **aDest, char *aSource, size_t aSize);
|
||||||
|
int8_t cfunction_freeParameter(struct _CFUNCTION_PARAMETER_LIST_T *aParameter);
|
||||||
|
int8_t cfunction_freeList(cfunction_list_t *aList);
|
||||||
|
|
||||||
|
#endif /* STUBSER_CFUNCTION_IF_H_ */
|
@@ -2,7 +2,7 @@
|
|||||||
Name : stubi.c
|
Name : stubi.c
|
||||||
Author : Martin Winkler
|
Author : Martin Winkler
|
||||||
Version :
|
Version :
|
||||||
Copyright :
|
Copyright :
|
||||||
Description : Scan a folder for .c files and generate stubs from function definitions
|
Description : Scan a folder for .c files and generate stubs from function definitions
|
||||||
|
|
||||||
@todo complete function dissection
|
@todo complete function dissection
|
||||||
@@ -17,159 +17,8 @@
|
|||||||
#include <regex.h>
|
#include <regex.h>
|
||||||
#include "xtypes.h"
|
#include "xtypes.h"
|
||||||
#include "xstring.h"
|
#include "xstring.h"
|
||||||
|
#include "cfunction_if.h"
|
||||||
#define STUBI_FUNCTION_REGEX "^[ \\t]*([ _\\*[:alnum:]]*) ([_\\*[:alnum:]]*)[ \\t]*\\(([^\\)]*)"
|
#include "cfile_parser_if.h"
|
||||||
#define STUBI_FUNCTION_MULTI "[ \\t]*(.*)"
|
|
||||||
#define STUBI_FUNCTION_MULTI_END "[ \\t]*(.*)\\)[ \\t\\{;]*"
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* @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
|
|
||||||
* @retval -1 Invalid regula expressions
|
|
||||||
* @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 uint8_t multiParamFlag = 0;
|
|
||||||
uint8_t multiParamEndFlag = 0;
|
|
||||||
|
|
||||||
if (0 > regcomp(®X, pattern, REG_EXTENDED | REG_NEWLINE))
|
|
||||||
{
|
|
||||||
perror("Error regex\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (0 > regcomp(®XEnd, patternend, REG_EXTENDED | REG_NEWLINE))
|
|
||||||
{
|
|
||||||
perror("Error regexend\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (0 > regcomp(®XMulti, STUBI_FUNCTION_MULTI, REG_EXTENDED | REG_NEWLINE))
|
|
||||||
{
|
|
||||||
perror("Error regXMulti\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (0 > regcomp(®XMultiEnd, STUBI_FUNCTION_MULTI_END, REG_EXTENDED | REG_NEWLINE))
|
|
||||||
{
|
|
||||||
perror("Error regXMultiEnd\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (multiParamFlag)
|
|
||||||
{
|
|
||||||
if (0 == regexec(®XMultiEnd, aLine, maxGroup, matchGroup, 0))
|
|
||||||
{
|
|
||||||
// end of multi line function
|
|
||||||
++multiParamFlag;
|
|
||||||
multiParamEndFlag = 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// continuation of multi line function
|
|
||||||
(void) regexec(®XMulti, aLine, maxGroup, matchGroup, 0);
|
|
||||||
++multiParamFlag;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (0 == regexec(®XEnd, aLine, maxGroup, matchGroup, 0))
|
|
||||||
{
|
|
||||||
// single line function
|
|
||||||
multiParamFlag = 0;
|
|
||||||
}
|
|
||||||
else if (0 == regexec(®X, 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);
|
|
||||||
|
|
||||||
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]);
|
|
||||||
}
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @brief Opens given file for line by line function matching
|
* @brief Opens given file for line by line function matching
|
||||||
@@ -177,31 +26,12 @@ STATIC int matchFunction(char *aLine)
|
|||||||
* @retval 0 matching complete
|
* @retval 0 matching complete
|
||||||
* @retval -1 error opening file
|
* @retval -1 error opening file
|
||||||
*/
|
*/
|
||||||
int scanFile(char *path)
|
int stubser_createStub(char *path)
|
||||||
{
|
{
|
||||||
FILE *fdesc;
|
cfunction_list_t functionList =
|
||||||
ssize_t charRead = 0;
|
CFUNCTION_LIST_DEFAULT;
|
||||||
size_t lineSize = 0;
|
(void) cfile_parser(path, &functionList);
|
||||||
char *fileLine = NULL; // will be allocated by getline(); must be freed
|
cfunction_freeList(&functionList);
|
||||||
|
|
||||||
fdesc = fopen(path, "r");
|
|
||||||
if (NULL == fdesc)
|
|
||||||
{
|
|
||||||
perror("Error open file");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
charRead = getline(&fileLine, &lineSize, fdesc);
|
|
||||||
if (0 <= charRead)
|
|
||||||
{
|
|
||||||
(void) matchFunction(fileLine);
|
|
||||||
}
|
|
||||||
} while (0 <= charRead);
|
|
||||||
|
|
||||||
free(fileLine);
|
|
||||||
(void) fclose(fdesc);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,19 +1,19 @@
|
|||||||
/*!
|
/*!
|
||||||
* @file stubser_if.h
|
* @file stubser_if.h
|
||||||
* @brief
|
* @brief
|
||||||
* @details
|
* @details
|
||||||
* Project: \n
|
* Project: \n
|
||||||
* Subsystem: \n
|
* Subsystem: \n
|
||||||
* Module: \n
|
* Module: \n
|
||||||
* Code: GNU-C\n
|
* Code: GNU-C\n
|
||||||
*
|
*
|
||||||
* @date 27.02.2017
|
* @date 27.02.2017
|
||||||
* @author SESA354004
|
* @author SESA354004
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef STUBSER_STUBSER_IF_H_
|
#ifndef STUBSER_STUBSER_IF_H_
|
||||||
#define STUBSER_STUBSER_IF_H_
|
#define STUBSER_STUBSER_IF_H_
|
||||||
|
|
||||||
int scanFile(char *path);
|
int stubser_createStub(char *path);
|
||||||
|
|
||||||
#endif /* STUBSER_STUBSER_IF_H_ */
|
#endif /* STUBSER_STUBSER_IF_H_ */
|
||||||
|
Reference in New Issue
Block a user