ThrowTheSwitch / CMock

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

Parentheses around expression in variable assignment causes exception in CMock #414

Closed bw35 closed 1 year ago

bw35 commented 1 year ago

The following statement in a header file causes CMock to raise an exception when generating mocks:

// bug.h
static const unsigned int foo = (1);
// test_bug.c
#include "mock_bug.h"

Without the parentheses, CMock runs fine. Of course the parentheses can be omitted in this simple case, but in other situations with more complex expressions they are required.

Test 'test_bug.c'
-----------------
Generating include list for bug.h...
Creating mock for bug...
rake aborted!
TypeError: no implicit conversion of nil into String
C:/Users/peter/Temp/ceedling-test/bug/vendor/ceedling/vendor/cmock/lib/cmock_header_parser.rb:555:in `parse_declaration'
C:/Users/peter/Temp/ceedling-test/bug/vendor/ceedling/vendor/cmock/lib/cmock_header_parser.rb:45:in `block in parse'
C:/Users/peter/Temp/ceedling-test/bug/vendor/ceedling/vendor/cmock/lib/cmock_header_parser.rb:44:in `map'
C:/Users/peter/Temp/ceedling-test/bug/vendor/ceedling/vendor/cmock/lib/cmock_header_parser.rb:44:in `parse'
C:/Users/peter/Temp/ceedling-test/bug/vendor/ceedling/vendor/cmock/lib/cmock.rb:48:in `generate_mock'
C:/Users/peter/Temp/ceedling-test/bug/vendor/ceedling/vendor/cmock/lib/cmock.rb:32:in `block in setup_mocks'
C:/Users/peter/Temp/ceedling-test/bug/vendor/ceedling/vendor/cmock/lib/cmock.rb:31:in `each'
C:/Users/peter/Temp/ceedling-test/bug/vendor/ceedling/vendor/cmock/lib/cmock.rb:31:in `setup_mocks'
C:/Users/peter/Temp/ceedling-test/bug/vendor/ceedling/lib/ceedling/generator.rb:50:in `generate_mock'
C:/Users/peter/Temp/ceedling-test/bug/vendor/ceedling/lib/ceedling/rules_cmock.rake:8:in `block in <top (required)>'
C:/Users/peter/Temp/ceedling-test/bug/vendor/ceedling/lib/ceedling/task_invoker.rb:60:in `block in invoke_test_mocks'
C:/Users/peter/Temp/ceedling-test/bug/vendor/ceedling/lib/ceedling/task_invoker.rb:58:in `invoke_test_mocks'
C:/Users/peter/Temp/ceedling-test/bug/vendor/ceedling/lib/ceedling/preprocessinator.rb:28:in `preprocess_test_and_invoke_test_mocks'
C:/Users/peter/Temp/ceedling-test/bug/vendor/ceedling/lib/ceedling/test_invoker.rb:84:in `block in setup_and_invoke'
C:/Users/peter/Temp/ceedling-test/bug/vendor/ceedling/lib/ceedling/test_invoker.rb:51:in `setup_and_invoke'
C:/Users/peter/Temp/ceedling-test/bug/vendor/ceedling/lib/ceedling/tasks_tests.rake:13:in `block (2 levels) in <top (required)>'
vendor/ceedling/bin/ceedling:345:in `block in <main>'
vendor/ceedling/bin/ceedling:332:in `<main>'
Tasks: TOP => build/test/mocks/mock_bug.c
(See full trace by running task with --trace)

--------------------
OVERALL TEST SUMMARY
--------------------

No tests executed.
C:\Users\peter\Temp\ceedling-test\bug>ruby vendor\ceedling\bin\ceedling version
   Ceedling:: 0.31.1
      Unity:: 2.5.4
      CMock:: 2.5.4
 CException:: 1.3.3
C:\Users\peter\Temp\ceedling-test\bug>ruby --version
ruby 3.0.4p208 (2022-04-12 revision 3fa771dded) [x64-mingw32]
Letme commented 1 year ago

We can put this on pile of: CMock only has a regexp and not a whole preprocessor. As a workaround: run your header files through the preprocessor to avoid such syntaxes.

PS: static variable in header file? I hope whoever wrote that burns in hell, since next guy including this file will have to go through it.

bw35 commented 1 year ago

Thanks for the suggested workaround

PS: Maybe you didn't note the const static. The compiler computes the value at compile time and uses it directly when optimization is on. Much like a #define, but typed. No memory is allocated, unless the address of the constant is taken.

mvandervoord commented 1 year ago

Fixed in PR #420