mirror of
https://github.com/ThrowTheSwitch/CMock.git
synced 2026-07-31 00:07:49 +00:00
Automatically strip out compile-time assertions so they're not confused with function prototypes (Fixes #128)
This commit is contained in:
+5
-1
@@ -52,7 +52,11 @@ class CMockConfig
|
||||
# - The keywords can appear before or after the return type (this is a compiler warning but people do weird stuff),
|
||||
# so we check for word boundaries when searching for them
|
||||
# - We first remove "static inline" combinations and boil down to single inline or static statements
|
||||
:inline_function_patterns => ['(static\s+inline|inline\s+static)\s*', '(\binline\b)\s*', '(?:static\s*)?(?:__inline__)?__attribute__\s*\([ (]*always_inline[ )]*\)', 'static __inline__'] # Last part (\s*) is just to remove whitespaces (only to prettify the output)
|
||||
:inline_function_patterns => ['(static\s+inline|inline\s+static)\s*', '(\binline\b)\s*', '(?:static\s*)?(?:__inline__)?__attribute__\s*\([ (]*always_inline[ )]*\)', 'static __inline__'], # Last part (\s*) is just to remove whitespaces (only to prettify the output)
|
||||
|
||||
# Compile-time assertion macro names to strip entirely to avoid being confused with function prototypes
|
||||
# Common C11, BSD, and embedded RTOS variants are included by default. Add custom names as needed.
|
||||
:ct_assert_patterns => ['ct_assert', '_?[Ss]tatic_[Aa]ssert', 'STATIC_ASSERT', 'BUILD_ASSERT', 'CTASSERT']
|
||||
}.freeze
|
||||
|
||||
def initialize(options = nil)
|
||||
|
||||
@@ -26,6 +26,7 @@ class CMockHeaderParser
|
||||
@treat_externs = cfg.treat_externs
|
||||
@treat_inlines = cfg.treat_inlines
|
||||
@inline_function_patterns = cfg.inline_function_patterns
|
||||
@ct_assert_patterns = cfg.ct_assert_patterns
|
||||
@c_strippables += ['extern'] if @treat_externs == :include # we'll need to remove the attribute if we're allowing externs
|
||||
@c_strippables += ['inline'] if @treat_inlines == :include # we'll need to remove the attribute if we're allowing inlines
|
||||
end
|
||||
@@ -306,6 +307,12 @@ class CMockHeaderParser
|
||||
source.gsub!(/(\W)(?:register|auto|restrict)(\W)/, '\1\2')
|
||||
source.gsub!(/(\W)(?:static)(\W)/, '\1\2') unless cpp
|
||||
|
||||
# strip calls to known compile-time assertion macros by name -- never function prototypes regardless of argument form
|
||||
source.gsub!(/\b(?:#{@ct_assert_patterns.join('|')})\s*\([^;]*\)/, '') unless @ct_assert_patterns.empty?
|
||||
# strip any remaining WORD(...==...) etc. -- calls containing comparison operators cannot be C function prototypes
|
||||
# must run before default-value removal, which would corrupt "!= 0" into "!" by removing "= 0"
|
||||
source.gsub!(/\b\w+\s*\((?:[^()!=<>]*(?:\([^()]*\))*)*(?:==|!=|<=|>=)[^;]*\)/, '')
|
||||
|
||||
source.gsub!(/\s*=\s*['"a-zA-Z0-9_.]+\s*/, '') # remove default value statements from argument lists
|
||||
|
||||
# strip macro decorator patterns that cannot be C function prototypes.
|
||||
|
||||
@@ -27,6 +27,7 @@ describe CMockHeaderParser, "Verify CMockHeaderParser Module" do
|
||||
@config.expect :inline_function_patterns, ['(static\s+inline|inline\s+static)\s*', '(\bstatic\b|\binline\b)\s*']
|
||||
@config.expect :array_size_type, ['int', 'size_t']
|
||||
@config.expect :array_size_name, 'size|len'
|
||||
@config.expect :ct_assert_patterns, ['ct_assert', '_?[Ss]tatic_[Aa]ssert', '_Static_assert', 'STATIC_ASSERT', 'BUILD_ASSERT', 'CTASSERT']
|
||||
|
||||
@parser = CMockHeaderParser.new(@config)
|
||||
|
||||
@@ -371,6 +372,21 @@ describe CMockHeaderParser, "Verify CMockHeaderParser Module" do
|
||||
end
|
||||
|
||||
|
||||
it "ignore compile-time assertions and not treat them as function prototypes" do
|
||||
source =
|
||||
"static_assert(BLAH_BOOLEAN_TRAIT);\n" +
|
||||
"void real_func(int a);\n" +
|
||||
"ct_assert(COMMIT_ID_H, ID_SIZE == (sizeof(ID)) - 1);\n" +
|
||||
"CTASSERT(OTHER_HEADER_H, BUF_SIZE != 0);\n" +
|
||||
"BUILD_ASSERT(MAX_LEN <= 256);\n" +
|
||||
"STATIC_ASSERT(sizeof(MyStruct) >= 4);\n"
|
||||
|
||||
expected = ["void real_func(int a)"]
|
||||
|
||||
assert_equal(expected, @parser.import_source(source, @test_project).map! { |s| s.strip })
|
||||
end
|
||||
|
||||
|
||||
it "remove struct statements" do
|
||||
source =
|
||||
"struct _NamedStruct1 {\n" +
|
||||
|
||||
Reference in New Issue
Block a user