diff --git a/src/stubser/stubser.c b/src/stubser/stubser.c index b776355..9343e07 100644 --- a/src/stubser/stubser.c +++ b/src/stubser/stubser.c @@ -14,6 +14,7 @@ */ #include #include +#include #include #include #include @@ -160,21 +161,55 @@ STATIC void createVariableSpecificCheck(FILE *aFile, cfile_variable_t *aVariable STATIC void createParameterSpecificCheck(FILE *aFile, cfunction_t *aFunction, cfunction_parameter_t *aParameter, char aParameterIndex) { - if (NULL != strstr(aParameter->dataType, "*") && NULL != strstr(aParameter->dataType, "char")) + if (CPARAMETER_TYPE_FUNCPTR == aParameter->type) { - fprintf(aFile, "\tCU_ASSERT_MEMORY_CHECK(\"%s(%s)\", ", aFunction->name, aParameter->name); - fprintf(aFile, STUBINIT_PARAM_PARAMETER_S1", "STUBPARAMETER_STRUCT_S1"["STUBINSTANCE_S1"]."STUBPARAMETER_PARAM_S1, aParameterIndex, aFunction->name, - aFunction->name, aParameterIndex); - fprintf(aFile, ", strlen("STUBINIT_PARAM_PARAMETER_S1"));"NEWLINES, aParameterIndex); - } - else if (NULL != strstr(aParameter->dataType, "*") || NULL != aParameter->array) - { - // matches also function pointer (array containing function pointer parameter list) + // function pointer fprintf(aFile, "\tCU_ASSERT_PTR_EQUAL("); fprintf(aFile, STUBINIT_PARAM_PARAMETER_S1", "STUBPARAMETER_STRUCT_S1"["STUBINSTANCE_S1"]."STUBPARAMETER_PARAM_S1, aParameterIndex, aFunction->name, aFunction->name, aParameterIndex); fprintf(aFile, ");"NEWLINES); } + else if (NULL != strstr(aParameter->dataType, "*") && NULL != strstr(aParameter->dataType, "char")) + { + fprintf(aFile, + "\tif ("STUBPARAMETER_POINTERHANDLING_ADDRESS_S " == " STUBPARAMETER_STRUCT_S1"["STUBINSTANCE_S1"]."STUBPARAMETER_POINTERHANDLING_S")" NEWLINES "\t{" NEWLINES, + aFunction->name, aFunction->name); + fprintf(aFile, "\t\tCU_ASSERT_MEMORY_CHECK(\"%s(%s)\", ", aFunction->name, aParameter->name); + fprintf(aFile, STUBINIT_PARAM_PARAMETER_S1", "STUBPARAMETER_STRUCT_S1"["STUBINSTANCE_S1"]."STUBPARAMETER_PARAM_S1, aParameterIndex, aFunction->name, + aFunction->name, aParameterIndex); + fprintf(aFile, ", strlen("STUBINIT_PARAM_PARAMETER_S1"));"NEWLINES, aParameterIndex); + fprintf(aFile, "\t}" NEWLINES); + if (NULL == strstr(aParameter->dataType, "const")) + { + fprintf(aFile, "\telse" NEWLINES "\t{" NEWLINES); + fprintf(aFile, "\t\tmemcpy(" STUBINIT_PARAM_PARAMETER_S1 ", "STUBPARAMETER_STRUCT_S1"["STUBINSTANCE_S1"]."STUBPARAMETER_PARAM_S1", " // + STUBPARAMETER_STRUCT_S1"["STUBINSTANCE_S1"]."STUBPARAMETER_PARAM_S1"_size",// + aParameterIndex, aFunction->name, aFunction->name, aParameterIndex, aFunction->name, aFunction->name, aParameterIndex); + fprintf(aFile, ");" NEWLINES); + fprintf(aFile, "\t}" NEWLINES); + } + } + else if (NULL != strstr(aParameter->dataType, "*") || NULL != aParameter->array) + { + // pointer + fprintf(aFile, + "\tif ("STUBPARAMETER_POINTERHANDLING_ADDRESS_S " == " STUBPARAMETER_STRUCT_S1"["STUBINSTANCE_S1"]."STUBPARAMETER_POINTERHANDLING_S")" NEWLINES "\t{" NEWLINES, + aFunction->name, aFunction->name); + fprintf(aFile, "\t\tCU_ASSERT_PTR_EQUAL("); + fprintf(aFile, STUBINIT_PARAM_PARAMETER_S1", "STUBPARAMETER_STRUCT_S1"["STUBINSTANCE_S1"]."STUBPARAMETER_PARAM_S1, aParameterIndex, aFunction->name, + aFunction->name, aParameterIndex); + fprintf(aFile, ");" NEWLINES); + fprintf(aFile, "\t}" NEWLINES); + if (NULL == strstr(aParameter->dataType, "const")) + { + fprintf(aFile, "\telse" NEWLINES "\t{" NEWLINES); + fprintf(aFile, "\t\tmemcpy(" STUBINIT_PARAM_PARAMETER_S1 ", "STUBPARAMETER_STRUCT_S1"["STUBINSTANCE_S1"]."STUBPARAMETER_PARAM_S1", " // + STUBPARAMETER_STRUCT_S1"["STUBINSTANCE_S1"]."STUBPARAMETER_PARAM_S1"_size",// + aParameterIndex, aFunction->name, aFunction->name, aParameterIndex, aFunction->name, aFunction->name, aParameterIndex); + fprintf(aFile, ");" NEWLINES); + fprintf(aFile, "\t}" NEWLINES); + } + } else if (isDatatypeStandard(aParameter->dataType)) { fprintf(aFile, "\tCU_ASSERT_EQUAL("); @@ -327,6 +362,18 @@ STATIC int8_t createStubFunctionBlock(FILE *aFile, FILE *aHeader, cfunction_t *a { cfunction_parameter_t *parameter = NULL; char parameterIndex = 'a'; + bool pointerAvailable = false; + + parameter = aFunction->parameter.head; + while (parameter) + { + if (NULL != strstr(parameter->dataType, "*") || parameter->array) + { + pointerAvailable = true; + break; + } + parameter = parameter->next; + } if (NULL == aFile || NULL == aHeader || NULL == aFunction) { @@ -349,10 +396,14 @@ STATIC int8_t createStubFunctionBlock(FILE *aFile, FILE *aHeader, cfunction_t *a 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 "STUBPARAMETER_CALLTEST_S"; /**< @brief If stub call is a STUB_CALL_PASS or STUB_CALL_FAIL */" NEWLINES); + fprintf(aFile, "\tuint8_t "STUBPARAMETER_CALLTEST_S"; /*!< @brief If stub call is a STUB_CALL_PASS or STUB_CALL_FAIL */" NEWLINES); + if (pointerAvailable) + { + fprintf(aFile, "\t%s "STUBPARAMETER_POINTERHANDLING_S"; /*!< @brief pointer handling */" NEWLINES, STUBPARAMETER_POINTERHANDLING_ENUM_S); + } if (!isDatatypeVoid(aFunction->dataType)) { - fprintf(aFile, "\t%s "STUBPARAMETER_RETURN_S"; /**< @brief return value */" NEWLINES, aFunction->dataType); + fprintf(aFile, "\t%s "STUBPARAMETER_RETURN_S"; /*!< @brief return value */" NEWLINES, aFunction->dataType); } parameter = aFunction->parameter.head; parameterIndex = 'a'; @@ -365,7 +416,15 @@ STATIC int8_t createStubFunctionBlock(FILE *aFile, FILE *aHeader, cfunction_t *a } else if (parameter->array) { - fprintf(aFile, "\t%s *"STUBPARAMETER_PARAM_S1"; /*!< @brief %s */" NEWLINES, NCHECK(parameter->dataType), parameterIndex++, NCHECK(parameter->name)); + fprintf(aFile, "\t%s *"STUBPARAMETER_PARAM_S1"; /*!< @brief %s */" NEWLINES, NCHECK(parameter->dataType), parameterIndex, NCHECK(parameter->name)); + fprintf(aFile, "\tuint32_t "STUBPARAMETER_PARAM_S1"_size; /*!< @brief %s size to copy in case of parameter injection */" NEWLINES, parameterIndex++, + NCHECK(parameter->name)); + } + else if (NULL != strstr(parameter->dataType, "*")) + { + fprintf(aFile, "\t%s "STUBPARAMETER_PARAM_S1"; /*!< @brief %s */" NEWLINES, NCHECK(parameter->dataType), parameterIndex, NCHECK(parameter->name)); + fprintf(aFile, "\tuint32_t "STUBPARAMETER_PARAM_S1"_size; /*!< @brief %s size to copy in case of parameter injection */" NEWLINES, parameterIndex++, + NCHECK(parameter->name)); } else if (CPARAMETER_TYPE_REGULAR == parameter->type) { @@ -379,7 +438,7 @@ STATIC int8_t createStubFunctionBlock(FILE *aFile, FILE *aHeader, cfunction_t *a // Instance counter fprintf(aFile, "// Instance counter for stub functions" NEWLINES); - fprintf(aFile, "uint8_t "STUBINSTANCE_S1" = 0;" NEWLINES, aFunction->name); + fprintf(aFile, STUBINSTANCE_DATATYPE_S" "STUBINSTANCE_S1" = 0;" NEWLINES, aFunction->name); NEWLINE(aFile); // expected parameter @@ -388,8 +447,40 @@ STATIC int8_t createStubFunctionBlock(FILE *aFile, FILE *aHeader, cfunction_t *a aFunction->name); NEWLINE(aFile); +// stub function init header; function comment + fprintf(aHeader, "/*! @brief Stub initialization of init_%s" NEWLINES, aFunction->name); + fprintf(aHeader, " * @param " STUBINIT_PARAM_INSTANCE_S " Which stub call to initialize" NEWLINES); + fprintf(aHeader, " * @param " STUBINIT_PARAM_CALLTEST_S " Is stub call allowed (STUB_CALL_FAIL, STUB_CALL_PASS)" NEWLINES); + if (pointerAvailable) + { + fprintf(aHeader, + " * @param " STUBINIT_PARAM_POINTERHANDLING_S " How to handle pointer to data (STUB_PARAMETER_POINTER_HANDLING_ADDRESS, STUB_PARAMETER_POINTER_HANDLING_INJECT" NEWLINES); + } + if (!isDatatypeVoid(aFunction->dataType)) + { + fprintf(aHeader, " * @param " STUBINIT_PARAM_RETURN_S " Return value to inject" NEWLINES); + } + parameter = aFunction->parameter.head; + parameterIndex = 'a'; + while (parameter) + { + if (NULL != strstr(parameter->dataType, "*") || parameter->array) + { + fprintf(aHeader, + " * @param " STUBINIT_PARAM_PARAMETER_S1 "_size Use injection size 0 to ignore pointer (e.g. test subject references to internal variables)" NEWLINES, + parameterIndex); + } + parameterIndex++; + parameter = parameter->next; + } + fprintf(aHeader, " */" NEWLINES); + // stub function init header - fprintf(aHeader, "void init_%s(uint8_t "STUBINIT_PARAM_INSTANCE_S", uint8_t "STUBINIT_PARAM_CALLTEST_S, aFunction->name); + fprintf(aHeader, "void init_%s("STUBINSTANCE_DATATYPE_S " " STUBINIT_PARAM_INSTANCE_S", uint8_t "STUBINIT_PARAM_CALLTEST_S, aFunction->name); + if (pointerAvailable) + { + fprintf(aHeader, ", %s "STUBINIT_PARAM_POINTERHANDLING_S, STUBPARAMETER_POINTERHANDLING_ENUM_S); + } if (!isDatatypeVoid(aFunction->dataType)) { fprintf(aHeader, ", %s "STUBINIT_PARAM_RETURN_S, aFunction->dataType); @@ -402,6 +493,11 @@ STATIC int8_t createStubFunctionBlock(FILE *aFile, FILE *aHeader, cfunction_t *a { fprintf(aHeader, ", %s (*"STUBINIT_PARAM_PARAMETER_S1")%s", NCHECK(parameter->dataType), parameterIndex++, NCHECK(parameter->array)); } + else if (NULL != strstr(parameter->dataType, "*") || parameter->array) + { + fprintf(aHeader, ", %s "STUBINIT_PARAM_PARAMETER_S1"%s", NCHECK(parameter->dataType), parameterIndex, NCHECK(parameter->array)); + fprintf(aHeader, ", uint32_t "STUBINIT_PARAM_PARAMETER_S1"_size", parameterIndex++); + } else { fprintf(aHeader, ", %s "STUBINIT_PARAM_PARAMETER_S1"%s", NCHECK(parameter->dataType), parameterIndex++, NCHECK(parameter->array)); @@ -411,7 +507,11 @@ STATIC int8_t createStubFunctionBlock(FILE *aFile, FILE *aHeader, cfunction_t *a fprintf(aHeader, ");" NEWLINES); // stub function init - fprintf(aFile, "void init_%s(uint8_t "STUBINIT_PARAM_INSTANCE_S", uint8_t "STUBINIT_PARAM_CALLTEST_S, aFunction->name); + fprintf(aFile, "void init_%s("STUBINSTANCE_DATATYPE_S " " STUBINIT_PARAM_INSTANCE_S", uint8_t "STUBINIT_PARAM_CALLTEST_S, aFunction->name); + if (pointerAvailable) + { + fprintf(aFile, ", %s "STUBINIT_PARAM_POINTERHANDLING_S, STUBPARAMETER_POINTERHANDLING_ENUM_S); + } if (!isDatatypeVoid(aFunction->dataType)) { fprintf(aFile, ", %s "STUBINIT_PARAM_RETURN_S, aFunction->dataType); @@ -424,6 +524,11 @@ STATIC int8_t createStubFunctionBlock(FILE *aFile, FILE *aHeader, cfunction_t *a { fprintf(aFile, ", %s (*"STUBINIT_PARAM_PARAMETER_S1")%s", NCHECK(parameter->dataType), parameterIndex++, NCHECK(parameter->array)); } + else if (NULL != strstr(parameter->dataType, "*") || parameter->array) + { + fprintf(aFile, ", %s "STUBINIT_PARAM_PARAMETER_S1"%s", NCHECK(parameter->dataType), parameterIndex, NCHECK(parameter->array)); + fprintf(aFile, ", uint32_t "STUBINIT_PARAM_PARAMETER_S1"_size", parameterIndex++); + } else { fprintf(aFile, ", %s "STUBINIT_PARAM_PARAMETER_S1"%s", NCHECK(parameter->dataType), parameterIndex++, NCHECK(parameter->array)); @@ -439,6 +544,12 @@ STATIC int8_t createStubFunctionBlock(FILE *aFile, FILE *aHeader, cfunction_t *a fprintf(aFile, "\t"STUBINSTANCE_S1" = 0;" NEWLINES, aFunction->name); fprintf(aFile, "\t"STUBPARAMETER_STRUCT_S1"["STUBINIT_PARAM_INSTANCE_S"]."STUBPARAMETER_CALLTEST_S" = "STUBINIT_PARAM_CALLTEST_S";" NEWLINES, aFunction->name); + if (pointerAvailable) + { + fprintf(aFile, + "\t"STUBPARAMETER_STRUCT_S1"["STUBINIT_PARAM_INSTANCE_S"]."STUBPARAMETER_POINTERHANDLING_S" = "STUBINIT_PARAM_POINTERHANDLING_S";" 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, @@ -450,6 +561,11 @@ STATIC int8_t createStubFunctionBlock(FILE *aFile, FILE *aHeader, cfunction_t *a { fprintf(aFile, "\t"STUBPARAMETER_STRUCT_S1"["STUBINIT_PARAM_INSTANCE_S"]."STUBPARAMETER_PARAM_S1" = "STUBINIT_PARAM_PARAMETER_S1";" NEWLINES, aFunction->name, parameterIndex, parameterIndex); + if ((NULL != strstr(parameter->dataType, "*") || parameter->array) && CPARAMETER_TYPE_FUNCPTR != parameter->type) + { + fprintf(aFile, "\t"STUBPARAMETER_STRUCT_S1"["STUBINIT_PARAM_INSTANCE_S"]."STUBPARAMETER_PARAM_S1"_size = "STUBINIT_PARAM_PARAMETER_S1"_size;" NEWLINES, + aFunction->name, parameterIndex, parameterIndex); + } ++parameterIndex; parameter = parameter->next; } diff --git a/src/stubser/stubser_loc.h b/src/stubser/stubser_loc.h index 7389934..306e780 100644 --- a/src/stubser/stubser_loc.h +++ b/src/stubser/stubser_loc.h @@ -31,12 +31,18 @@ #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_POINTERHANDLING_S "stubPointerHandling" +#define STUBPARAMETER_POINTERHANDLING_ENUM_S "stub_parameter_pointer_handling_t" +#define STUBPARAMETER_POINTERHANDLING_ADDRESS_S "STUB_PARAMETER_POINTER_HANDLING_ADDRESS" +#define STUBPARAMETER_POINTERHANDLING_INJECT_S "STUB_PARAMETER_POINTER_HANDLING_INJECT" #define STUBPARAMETER_RETURN_S "returnValue" // "stubparameter_modulfunction_1".returnValue #define STUBINSTANCE_S1 "stubInstance_%s" // stubInstance_modulfunction_1 +#define STUBINSTANCE_DATATYPE_S "uint8_t" #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 STUBINIT_PARAM_POINTERHANDLING_S "aPointerHandling" #define STUBFUNCTION_USER_INITEXPECTED_S1 "stub_%s_user_initExpected" // stub_testfunction_initExpected #define STUBFUNCTION_USER_INITGLOBALS_S1 "stub_%s_user_initGlobals" // stub_testfunction_initGlobals