ThrowTheSwitch / CMock

CMock - Mock/stub generator for C
http://throwtheswitch.org
MIT License
672 stars 273 forks source link

CMock incorrectly mocks function parameter #349

Open songg10 opened 3 years ago

songg10 commented 3 years ago

Hi, I am having a piece of code that needs to be mocked and cannot be modified. Its function prototype goes roughly like this void func(char *str, int (* numb)); When I run cmock.rb on this with default configuration, it would misinterpret the second parameter and gives an error like this when I try to compile it

mocks/Mockfunc.c:9:36: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘)’ token
    9 | static const char* CMockString_numb) = "numb)";
      |                                    ^
In file included from CMock/vendor/unity/src/unity.h:21,
                 from CMock/src/cmock_internals.h:10,
                 from CMock/src/cmock.h:10,
                 from mocks/Mockfunc.c:5:
mocks/Mockfunc.c: In function ‘func’:
mocks/Mockfunc.c:64:40: error: ‘CMockString_numb’ undeclared (first use in this function); did you mean ‘CMockString_func’?
   64 |     UNITY_SET_DETAILS(CMockString_func,CMockString_numb));
      |                                        ^~~~~~~~~~~~~~~~
CMock/vendor/unity/src/unity_internals.h:507:90: note: in definition of macro ‘UNITY_SET_DETAILS’
  507 | S(d1,d2) { Unity.CurrentDetail1 = (d1);  Unity.CurrentDetail2 = (d2); }
      |                                                                  ^~

mocks/Mockfunc.c:64:40: note: each undeclared identifier is reported only once for each function it appears in
   64 |     UNITY_SET_DETAILS(CMockString_func,CMockString_numb));
      |                                        ^~~~~~~~~~~~~~~~
CMock/vendor/unity/src/unity_internals.h:507:90: note: in definition of macro ‘UNITY_SET_DETAILS’
  507 | S(d1,d2) { Unity.CurrentDetail1 = (d1);  Unity.CurrentDetail2 = (d2); }
      |                                                                  ^~

mocks/Mockfunc.c:64:57: error: expected statement before ‘)’ token
   64 |     UNITY_SET_DETAILS(CMockString_func,CMockString_numb));
      |                                                         ^
mocks/Mockfunc.c:65:79: error: macro "UNITY_TEST_ASSERT_EQUAL_MEMORY" requires 5 arguments, but only 1 given
   65 | ERT_EQUAL_MEMORY((void*)(cmock_call_instance->Expected_numb)), (void*)(numb)), sizeof(int(), cmock_line, CMockStringMismatch);
      |                                                             ^

In file included from CMock/vendor/unity/src/unity.h:21,
                 from CMock/src/cmock_internals.h:10,
                 from CMock/src/cmock.h:10,
                 from mocks/Mockfunc.c:5:
CMock/vendor/unity/src/unity_internals.h:890: note: macro "UNITY_TEST_ASSERT_EQUAL_MEMORY" defined here
  890 | #define UNITY_TEST_ASSERT_EQUAL_MEMORY(expected, actual, len, line, message)                     UnityAssertEqualMemory((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(len), 1, (message), (UNITY_LINE_TYPE)(line), UNITY_ARRAY_TO_ARRAY)
      | 
mocks/Mockfunc.c:65:5: error: ‘UNITY_TEST_ASSERT_EQUAL_MEMORY’ undeclared (first use in this function)
   65 |     UNITY_TEST_ASSERT_EQUAL_MEMORY((void*)(cmock_call_instance->Expected_numb)), (void*)(numb)), sizeof(int(), cmock_line, CMockStringMismatch);
      |     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
mocks/Mockfunc.c:65:95: error: expected ‘;’ before ‘)’ token
   65 | ((void*)(cmock_call_instance->Expected_numb)), (void*)(numb)), sizeof(int(), cmock_line, CMockStringMismatch);
      |                                                             ^
      |                                                             ;
mocks/Mockfunc.c:65:95: error: expected statement before ‘)’ token
mocks/Mockfunc.c:65:96: error: expected expression before ‘,’ token
   65 | (void*)(cmock_call_instance->Expected_numb)), (void*)(numb)), sizeof(int(), cmock_line, CMockStringMismatch);
      |                                                             ^

mocks/Mockfunc.c: In function ‘CMockExpectParameters_func’:
mocks/Mockfunc.c:74:37: error: expected ‘;’ before ‘)’ token
   74 |   cmock_call_instance->Expected_numb) = numb);
      |                                     ^
      |                                     ;
mocks/Mockfunc.c:74:37: error: expected statement before ‘)’ token
mocks/Mockfunc.c:74:39: error: expected expression before ‘=’ token
   74 |   cmock_call_instance->Expected_numb) = numb);
      |                                       ^
mocks/Mockfunc.c:74:45: error: expected statement before ‘)’ token
   74 |   cmock_call_instance->Expected_numb) = numb);
      |                                             ^
mocks/Mockfunc.c: In function ‘func_CMockExpect’:
mocks/Mockfunc.c:85:61: error: expected ‘;’ before ‘)’ token
   85 |   CMockExpectParameters_func(cmock_call_instance, str, numb));
      |                                                             ^
      |                                                             ;
mocks/Mockfunc.c:85:61: error: expected statement before ‘)’ token
In file included from sample.c:3:
sample.c: In function ‘test_case_0’:
mocks/Mockfunc.h:27:31: error: expected statement before ‘)’ token
   27 | #define func_Expect(str, numb)) func_CMockExpect(__LINE__, str, numb))
      |                               ^
sample.c:17:5: note: in expansion of macro ‘func_Expect’
   17 |     func_Expect("test", &a);
      |     ^~~~~~~~~~~
mocks/Mockfunc.h:27:70: error: expected ‘;’ before ‘)’ token
   27 | #define func_Expect(str, numb)) func_CMockExpect(__LINE__, str, numb))
      |                                                                      ^
sample.c:17:5: note: in expansion of macro ‘func_Expect’
   17 |     func_Expect("test", &a);
      |     ^~~~~~~~~~~
mocks/Mockfunc.h:27:70: error: expected statement before ‘)’ token
   27 | #define func_Expect(str, numb)) func_CMockExpect(__LINE__, str, numb))
      |                                                                      ^
sample.c:17:5: note: in expansion of macro ‘func_Expect’
   17 |     func_Expect("test", &a);
      |     ^~~~~~~~~~~

Is there anyway to get around this except from changing the way the parameter is written?

Christer-Ekholm commented 3 years ago
My C-skill is at limit now but is void func(char *str, int (* numb)); same as void func(char *str, int (* numb)(void)); ? 
If yes then is it possible you to modify  that function prototype?

I  have had many proplem with callback function parameters and I have fixed those to use proper typedefs and then 
normal paramaters in functions. something like this

typedef void (*CB)(void);
void dummy(CB callback);