ThrowTheSwitch / CMock

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

CMock gets confused by the "__attribute__" directives #402

Closed GlebPlekhotko closed 1 year ago

GlebPlekhotko commented 2 years ago

Hello!

In my project there is a "task.h" file. Obviously, it comes from the FreeRTOS. I'm trying to mock it up using CMock. CMock is invoked by the Ceedling.

Attempt failed with the following message:

In file included from build/test/runners/Test_DevicesTask_create_runner.c:7:
build/test/mocks/Mock_task.h:979:74: error: expected declaration specifiers or '...' before ')' token
  979 | void vTaskSwitchContext_CMockIgnoreAndReturn(UNITY_LINE_TYPE cmock_line, )void cmock_to_return);
      |                                                                          ^
build/test/mocks/Mock_task.h:983:74: error: expected declaration specifiers or '...' before ')' token
  983 | void vTaskSwitchContext_CMockExpectAndReturn(UNITY_LINE_TYPE cmock_line, )void cmock_to_return);
      |                                                                          ^
build/test/mocks/Mock_task.h:984:9: error: expected identifier or '(' before ')' token
  984 | typedef )void (* CMOCK_vTaskSwitchContext_CALLBACK)(int cmock_num_calls);
      |         ^
build/test/mocks/Mock_task.h:985:37: error: unknown type name 'CMOCK_vTaskSwitchContext_CALLBACK'; did you mean 'CMOCK_vTaskEndScheduler_CALLBACK'?
  985 | void vTaskSwitchContext_AddCallback(CMOCK_vTaskSwitchContext_CALLBACK Callback);
      |                                     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      |                                     CMOCK_vTaskEndScheduler_CALLBACK
build/test/mocks/Mock_task.h:986:30: error: unknown type name 'CMOCK_vTaskSwitchContext_CALLBACK'; did you mean 'CMOCK_vTaskEndScheduler_CALLBACK'?
  986 | void vTaskSwitchContext_Stub(CMOCK_vTaskSwitchContext_CALLBACK Callback);
      |                              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      |                              CMOCK_vTaskEndScheduler_CALLBACK

So there is a syntax mistake in the generated mock. I peeked that file and saw this:

#define vTaskSwitchContext_IgnoreAndReturn(cmock_retval) vTaskSwitchContext_CMockIgnoreAndReturn(__LINE__, cmock_retval)
void vTaskSwitchContext_CMockIgnoreAndReturn(UNITY_LINE_TYPE cmock_line, )void cmock_to_return);

And this:

void vTaskSwitchContext_CMockExpectAndReturn(UNITY_LINE_TYPE cmock_line, )void cmock_to_return);
typedef )void (* CMOCK_vTaskSwitchContext_CALLBACK)(int cmock_num_calls);

To narrow down the search, I took the preprocessed task.h module and fed it to the standalone CMock to exclude influence of the Ceedling. Here is how vTaskSwitchContext function looked there: __attribute__( ( used ) ) void vTaskSwitchContext( void ) ;

And generated mock was corrupted too:

#define vTaskSwitchContext_ExpectAndReturn(cmock_retval) vTaskSwitchContext_CMockExpectAndReturn(__LINE__, cmock_retval)
void vTaskSwitchContext_CMockExpectAndReturn(UNITY_LINE_TYPE cmock_line, )void cmock_to_return);

Hence, it seems, that CMock does not recognize attribute at the beginning of the function and considers it as a some sort of return type. I thought that it might be caused by spaced between brackets (who knows, right?) and removed them: __attribute__(( used )) void vTaskSwitchContext( void ) ;

And it worked! After this little modification CMock generated absolutely correct mocking module:

#define vTaskSwitchContext_Expect() vTaskSwitchContext_CMockExpect(__LINE__)
void vTaskSwitchContext_CMockExpect(UNITY_LINE_TYPE cmock_line);

A little, but annoying issue, especially if met in library or third-party code which is not expected to be altered.

mvandervoord commented 1 year ago

Fixed in PR #420