diff --git a/src/stubser/stubser.c b/src/stubser/stubser.c index 0d58968..5d09c63 100644 --- a/src/stubser/stubser.c +++ b/src/stubser/stubser.c @@ -22,9 +22,22 @@ #include "stubser_if.h" #include "stubser_loc.h" +STATIC bool isDatatypeVoid(char *aType) +{ + + if (NULL == aType || // + (NULL != strstr(aType, "void") && NULL != strstr(aType, "*")) // + || NULL == strstr(aType, "void")) + { + return false; + } + return true; +} + STATIC int8_t createStubFunctionBlock(FILE *aFile, cfunction_t *aFunction) { cfunction_parameter_t *parameter = NULL; + char parameterIndex = 'a'; if (NULL == aFile || NULL == aFunction) { @@ -35,29 +48,128 @@ STATIC int8_t createStubFunctionBlock(FILE *aFile, cfunction_t *aFunction) { return 1; } - // start comments +// start comments fprintf(aFile, STUB_START_S1 NEWLINES, aFunction->name); - // prep +// prep fprintf(aFile, "// Maximum amount of instances within test subject functions" NEWLINES); - fprintf(aFile, "#define STUB_INSTANCES_AMOUNT_%s %d" NEWLINES, aFunction->name, STUB_INSTANCES_AMOUNT); + fprintf(aFile, "#define "STUBINSTANCE_AMOUNT_S1" %d" NEWLINES, aFunction->name, STUB_INSTANCES_AMOUNT); NEWLINE(aFile); + +// parameter structure fprintf(aFile, "// Expected parameter and return value structures" NEWLINES); fprintf(aFile, "typedef struct _STUBPARAMETER_%s" NEWLINES, aFunction->name); fprintf(aFile, "{" NEWLINES); - fprintf(aFile, "\tuint8_t u8StubCallTest; /**< @brief If stub call is a STUB_CALL_PASS or STUB_CALL_FAIL */" NEWLINES); - fprintf(aFile, "}" NEWLINES); - - fprintf(aFile, "%s %s %s(", NCHECK(aFunction->prefix), NCHECK(aFunction->dataType), NCHECK(aFunction->name)); // todo remove leading " " when prefix is missing + fprintf(aFile, "\tuint8_t "STUBPARAMETER_CALLTEST_S"; /**< @brief If stub call is a STUB_CALL_PASS or STUB_CALL_FAIL */" NEWLINES); parameter = aFunction->parameter.head; + parameterIndex = 'a'; while (parameter) { - fprintf(aFile, "%s %s%s", NCHECK(parameter->type), NCHECK(parameter->name), (NULL != parameter->next ? ", " : "")); + fprintf(aFile, "\t%s "STUBPARAMETER_PARAM_S1"; /*!< @brief %s */" NEWLINES, NCHECK(parameter->type), parameterIndex++, NCHECK(parameter->name)); parameter = parameter->next; } - fprintf(aFile, "){}" NEWLINES); + if (!isDatatypeVoid(aFunction->dataType)) + { + fprintf(aFile, "\t%s "STUBPARAMETER_RETURN_S"; /**< @brief return value */" NEWLINES, aFunction->dataType); + } + fprintf(aFile, "} "STUBPARAMETER_TYPEDEF_S1";" NEWLINES, aFunction->name); + NEWLINE(aFile); - // end comments +// Instance counter + fprintf(aFile, "// Instance counter for stub functions" NEWLINES); + fprintf(aFile, "uint8_t "STUBINSTANCE_S1" = 0;" NEWLINES, aFunction->name); + NEWLINE(aFile); + +// expected parameter + fprintf(aFile, "// Expected parameter and return value arrays for in-stub tests" NEWLINES); + fprintf(aFile, STUBPARAMETER_TYPEDEF_S1 " " STUBPARAMETER_STRUCT_S1"["STUBINSTANCE_AMOUNT_S1"];" NEWLINES, aFunction->name, aFunction->name, + aFunction->name); + NEWLINE(aFile); + +// stub function init + fprintf(aFile, "void init_%s(uint8_t "STUBINIT_PARAM_INSTANCE_S", uint8_t "STUBINIT_PARAM_CALLTEST_S, aFunction->name); + if (!isDatatypeVoid(aFunction->dataType)) + { + fprintf(aFile, ", %s "STUBINIT_PARAM_RETURN_S, aFunction->dataType); + } + parameter = aFunction->parameter.head; + parameterIndex = 'a'; + while (parameter) + { + fprintf(aFile, ", %s "STUBINIT_PARAM_PARAMETER_S1, NCHECK(parameter->type), parameterIndex++); + parameter = parameter->next; + } + fprintf(aFile, ")" NEWLINES); + fprintf(aFile, "{" NEWLINES); + fprintf(aFile, "\tif ("STUBINSTANCE_AMOUNT_S1" <= "STUBINIT_PARAM_INSTANCE_S")" NEWLINES, aFunction->name); + fprintf(aFile, "\t{" NEWLINES); + fprintf(aFile, "\t\tCU_FAIL_FATAL(\"init_%s() - "STUBINIT_PARAM_INSTANCE_S" out of bounce\");" NEWLINES, aFunction->name); + fprintf(aFile, "\t}" NEWLINES); + fprintf(aFile, "\t"STUBINSTANCE_S1" = 0;" NEWLINES, aFunction->name); + if (!isDatatypeVoid(aFunction->dataType)) + { + fprintf(aFile, "\t"STUBPARAMETER_STRUCT_S1"["STUBINIT_PARAM_INSTANCE_S"]."STUBPARAMETER_RETURN_S" = "STUBINIT_PARAM_RETURN_S";" NEWLINES, aFunction->name); + } + parameter = aFunction->parameter.head; + parameterIndex = 'a'; + while (parameter) + { + fprintf(aFile, "\t"STUBPARAMETER_STRUCT_S1"["STUBINIT_PARAM_INSTANCE_S"]."STUBPARAMETER_PARAM_S1" = "STUBINIT_PARAM_PARAMETER_S1";" NEWLINES, + aFunction->name, parameterIndex, parameterIndex); + ++parameterIndex; + parameter = parameter->next; + } + fprintf(aFile, "}" NEWLINES); + NEWLINE(aFile); + +// stub function + fprintf(aFile, "%s %s %s(", NCHECK(aFunction->prefix), NCHECK(aFunction->dataType), NCHECK(aFunction->name)); // todo remove leading " " when prefix is missing + parameter = aFunction->parameter.head; + parameterIndex = 'a'; + while (parameter) + { + fprintf(aFile, "%s "STUBINIT_PARAM_PARAMETER_S1"%s", NCHECK(parameter->type), parameterIndex++, (NULL != parameter->next ? ", " : "")); + parameter = parameter->next; + } + fprintf(aFile, ")" NEWLINES); + fprintf(aFile, "{" NEWLINES); + fprintf(aFile, "\tswitch ("STUBPARAMETER_STRUCT_S1"["STUBINSTANCE_S1"]."STUBPARAMETER_CALLTEST_S")" NEWLINES, aFunction->name, aFunction->name); + fprintf(aFile, "\t{" NEWLINES"\tcase STUB_CALL_FAIL:"NEWLINES); + fprintf(aFile, "\t\tCU_FAIL(\"Inadvertent %s() call.\");"NEWLINES"\t\tbreak;"NEWLINES, aFunction->name); + fprintf(aFile, "\tcase STUB_CALL_PASS:" NEWLINES); + fprintf(aFile, "\t\tCU_PASS(\"%s() called.\");"NEWLINES"\t\tbreak;"NEWLINES, aFunction->name); + fprintf(aFile, "\tdefault:"NEWLINES"\t\tbreak;"NEWLINES); + fprintf(aFile, "\t}" NEWLINES); + + parameter = aFunction->parameter.head; + parameterIndex = 'a'; + while (parameter) + { + if (NULL != strstr(parameter->type, "*")) + { + fprintf(aFile, "\tCU_ASSERT_PTR_EQUAL("); + } + else + { + fprintf(aFile, "\tCU_ASSERT_EQUAL("); + } + fprintf(aFile, STUBINIT_PARAM_PARAMETER_S1", "STUBPARAMETER_STRUCT_S1"["STUBINSTANCE_S1"]."STUBPARAMETER_PARAM_S1");" NEWLINES, parameterIndex, + aFunction->name, aFunction->name, parameterIndex); + ++parameterIndex; + parameter = parameter->next; + } + + if (!isDatatypeVoid(aFunction->dataType)) + { + fprintf(aFile, "\treturn "STUBPARAMETER_STRUCT_S1"["STUBINSTANCE_S1"++]."STUBPARAMETER_RETURN_S";" NEWLINES, aFunction->name, aFunction->name); + } + else + { + fprintf(aFile, "\t++"STUBINSTANCE_S1";"NEWLINES, aFunction->name); + } + fprintf(aFile, "}" NEWLINES); + +// end comments fprintf(aFile, STUB_END_S1 NEWLINES, aFunction->name, (NULL != aFunction->next ? NEWLINES : "")); return 0; @@ -80,7 +192,9 @@ STATIC int8_t createStub(char *aOutput, cfunction_list_t *aFunctionList) return -1; } - fprintf(fdesc, "/* This is a stub for %s */" NEWLINES NEWLINES, gnu_basename(aOutput)); + fprintf(fdesc, "/* @file %s"NEWLINES, gnu_basename(aOutput)); + fprintf(fdesc, " * @details"NEWLINES" * This is a stub for CUnit.\\n"NEWLINES); + fprintf(fdesc, " * - generated by stubser -"NEWLINES" */" NEWLINES NEWLINES); function = aFunctionList->head; while (function) @@ -117,7 +231,7 @@ int stubser_createStub(char *path, char *aOutput) } printf(STUB_CONSOLE_PARSE_OK_S1, gnu_basename(path)); - sprintf(fileName, "%s/%s_stub.d", aOutput, strtok(gnu_basename(path), ".")); // todo only cut suffix (last ".") + sprintf(fileName, "%s/%s_stub.c", aOutput, strtok(gnu_basename(path), ".")); // todo only cut suffix (last ".") ret = createStub(fileName, &functionList); if (0 != ret) { diff --git a/src/stubser/stubser_loc.h b/src/stubser/stubser_loc.h index d0e345c..6863c17 100644 --- a/src/stubser/stubser_loc.h +++ b/src/stubser/stubser_loc.h @@ -26,9 +26,20 @@ #define STUB_END_S1 "/* End of stub %s() */" NEWLINES \ "// ----------------------------------------------<%s" +#define STUBINSTANCE_AMOUNT_S1 "STUB_INSTANCES_AMOUNT_%s" //STUB_INSTANCES_AMOUNT_modulfunction_1 +#define STUBPARAMETER_TYPEDEF_S1 "stubparameter_t_%s" // stubparameter_t_modulfunction_1 +#define STUBPARAMETER_STRUCT_S1 "stubparameter_%s" // stubparameter_modulfunction_1 +#define STUBPARAMETER_PARAM_S1 "parameter_%c" // "stubparameter_modulfunction_1".parameter_a +#define STUBPARAMETER_CALLTEST_S "stubCallTest" +#define STUBPARAMETER_RETURN_S "returnValue" // "stubparameter_modulfunction_1".returnValue +#define STUBINSTANCE_S1 "stubInstance_%s" // stubInstance_modulfunction_1 +#define STUBINIT_PARAM_INSTANCE_S "aInstance" +#define STUBINIT_PARAM_CALLTEST_S "aStubCallTest" +#define STUBINIT_PARAM_PARAMETER_S1 "aParameter_%c" // aParameter_a +#define STUBINIT_PARAM_RETURN_S "aReturnValue" + #define STUB_CONSOLE_OK "[ OK ]" #define STUB_CONSOLE_FAIL "[FAIL]" - #define STUB_CONSOLE_PARSE_ERROR_S2 STUB_CONSOLE_FAIL " %s parsing failed (%d)\n" #define STUB_CONSOLE_PARSE_OK_S1 STUB_CONSOLE_OK " %s parsing..." #define STUB_CONSOLE_CREATE_ERROR_S2 STUB_CONSOLE_FAIL " %s creation failed (%d)\n"