From 615b3874b8cfd2e94aca038aa3387826399f2176 Mon Sep 17 00:00:00 2001 From: John Lindgren Date: Fri, 15 Nov 2019 16:53:23 -0500 Subject: [PATCH] Allow arbitrary parentheses within length of array arguments. Previously, CMock would fail to parse a function like this one: void broken(uint8_t arg[((uint8_t)8)]); --- lib/cmock_header_parser.rb | 13 ++++++++----- test/unit/cmock_header_parser_test.rb | 23 +++++++++++++++-------- 2 files changed, 23 insertions(+), 13 deletions(-) diff --git a/lib/cmock_header_parser.rb b/lib/cmock_header_parser.rb index 0cf1947..0ce5234 100644 --- a/lib/cmock_header_parser.rb +++ b/lib/cmock_header_parser.rb @@ -246,12 +246,15 @@ class CMockHeaderParser if ((@local_as_void.include?(arg_list.strip)) or (arg_list.empty?)) return 'void' else - c=0 - arg_list.gsub!(/(\w+)(?:\s*\[\s*\(*[\s\w+-]*\)*\s*\])+/,'*\1') # magically turn brackets into asterisks, also match for parentheses that come from macros - arg_list.gsub!(/\s+\*/,'*') # remove space to place asterisks with type (where they belong) - arg_list.gsub!(/\*(\w)/,'* \1') # pull asterisks away from arg to place asterisks with type (where they belong) + c = 0 + # magically turn brackets into asterisks, also match for parentheses that come from macros + arg_list.gsub!(/(\w+)(?:\s*\[[\s\w\(\)+-]*\])+/, '*\1') + # remove space to place asterisks with type (where they belong) + arg_list.gsub!(/\s+\*/, '*') + # pull asterisks away from arg to place asterisks with type (where they belong) + arg_list.gsub!(/\*(\w)/, '* \1') - #scan argument list for function pointers and replace them with custom types + # scan argument list for function pointers and replace them with custom types arg_list.gsub!(/([\w\s\*]+)\(+\s*\*[\*\s]*([\w\s]*)\s*\)+\s*\(((?:[\w\s\*]*,?)*)\s*\)*/) do |m| functype = "cmock_#{@module_name}_func_ptr#{@typedefs.size + 1}" diff --git a/test/unit/cmock_header_parser_test.rb b/test/unit/cmock_header_parser_test.rb index fa156f4..3ced1d7 100644 --- a/test/unit/cmock_header_parser_test.rb +++ b/test/unit/cmock_header_parser_test.rb @@ -1203,7 +1203,17 @@ describe CMockHeaderParser, "Verify CMockHeaderParser Module" do end it "handle arrays and treat them as pointers or strings" do - source = "void KeyOperated(CUSTOM_TYPE thing1[], int thing2 [ ], char thing3 [][2 ][ 3], int* thing4[4])" + source = 'void KeyOperated(CUSTOM_TYPE thing1[], int thing2 [ ], ' \ + 'char thing3 [][2 ][ 3], int* thing4[4], u8 thing5[((u8)5)])' + expected_args = [ + { type: 'CUSTOM_TYPE*', name: 'thing1', ptr?: true, const?: false, const_ptr?: false }, + { type: 'int*', name: 'thing2', ptr?: true, const?: false, const_ptr?: false }, + # this one will likely change in the future when we improve multidimensional array support + { type: 'char*', name: 'thing3', ptr?: false, const?: false, const_ptr?: false }, + # this one will likely change in the future when we improve multidimensional array support + { type: 'int**', name: 'thing4', ptr?: true, const?: false, const_ptr?: false }, + { type: 'u8*', name: 'thing5', ptr?: true, const?: false, const_ptr?: false } + ] expected = [{:var_arg=>nil, :return=>{ :type => "void", :name => 'cmock_to_return', @@ -1216,13 +1226,10 @@ describe CMockHeaderParser, "Verify CMockHeaderParser Module" do :name=>"KeyOperated", :modifier=>"", :contains_ptr? => true, - :args=>[ {:type=>"CUSTOM_TYPE*", :name=>"thing1", :ptr? => true, :const? => false, :const_ptr? => false}, - {:type=>"int*", :name=>"thing2", :ptr? => true, :const? => false, :const_ptr? => false}, - {:type=>"char*", :name=>"thing3", :ptr? => false, :const? => false, :const_ptr? => false}, #THIS one will likely change in the future when we improve multidimensional array support - {:type=>"int**", :name=>"thing4", :ptr? => true, :const? => false, :const_ptr? => false} #THIS one will likely change in the future when we improve multidimensional array support - ], - :args_string=>"CUSTOM_TYPE* thing1, int* thing2, char* thing3, int** thing4", - :args_call=>"thing1, thing2, thing3, thing4" }] + :args => expected_args, + :args_string => 'CUSTOM_TYPE* thing1, int* thing2, ' \ + 'char* thing3, int** thing4, u8* thing5', + :args_call => 'thing1, thing2, thing3, thing4, thing5' }] result = @parser.parse("module", source) assert_equal(expected, result[:functions]) end