From 789c5852b597ac0f6c72806a1aefb76a21ae3a87 Mon Sep 17 00:00:00 2001 From: John Lindgren Date: Wed, 29 Aug 2018 16:15:27 -0400 Subject: [PATCH] Add treat_as_array configuration option. --- docs/CMock_Summary.md | 12 ++++++++++++ lib/cmock_config.rb | 1 + lib/cmock_header_parser.rb | 10 ++++++++++ test/unit/cmock_header_parser_test.rb | 27 +++++++++++++++++++++++++++ 4 files changed, 50 insertions(+) diff --git a/docs/CMock_Summary.md b/docs/CMock_Summary.md index 87f9c00..4e4ec55 100644 --- a/docs/CMock_Summary.md +++ b/docs/CMock_Summary.md @@ -479,6 +479,18 @@ from the defaults. We've tried to specify what the defaults are below. * 'float': 'FLOAT' * 'double': 'FLOAT' +* `:treat_as_array`: + A specialized sort of `:treat_as` to be used when you've created a + typedef of an array type, such as `typedef int TenIntegers[10];`. This + is a hash of typedef name to element type. For example: + + { "TenIntegers" => "int", + "ArrayOfFloat" => "float" } + + Telling CMock about these typedefs allows it to be more intelligent + about parameters of such types, so that you can use features like + ExpectWithArray and ReturnArrayThruPtr with them. + * `:treat_as_void`: We've seen "fun" legacy systems typedef 'void' with a custom type, like MY_VOID. Add any instances of those to this list to help CMock diff --git a/lib/cmock_config.rb b/lib/cmock_config.rb index 398c582..de12a56 100644 --- a/lib/cmock_config.rb +++ b/lib/cmock_config.rb @@ -22,6 +22,7 @@ class CMockConfig :fail_on_unexpected_calls => true, :unity_helper_path => false, :treat_as => {}, + :treat_as_array => {}, :treat_as_void => [], :memcmp_if_unknown => true, :when_no_prototypes => :warn, #the options being :ignore, :warn, or :error diff --git a/lib/cmock_header_parser.rb b/lib/cmock_header_parser.rb index ee0fe6a..eded60a 100644 --- a/lib/cmock_header_parser.rb +++ b/lib/cmock_header_parser.rb @@ -14,6 +14,7 @@ class CMockHeaderParser @c_attr_noconst = cfg.attributes.uniq - ['const'] @c_attributes = ['const'] + c_attr_noconst @c_calling_conventions = cfg.c_calling_conventions.uniq + @treat_as_array = cfg.treat_as_array @treat_as_void = (['void'] + cfg.treat_as_void).uniq @declaration_parse_matcher = /([\d\w\s\*\(\),\[\]]+??)\(([\d\w\s\*\(\),\.\[\]+-]*)\)$/m @standards = (['int','short','char','long','unsigned','signed'] + cfg.treat_as.keys).uniq @@ -184,6 +185,15 @@ class CMockHeaderParser arg_info = parse_type_and_name(arg) arg_info.delete(:modifier) # don't care about this arg_info.delete(:c_calling_convention) # don't care about this + + # in C, array arguments implicitly degrade to pointers + # make the translation explicit here to simplify later logic + if @treat_as_array[arg_info[:type]] and not arg_info[:ptr?] then + arg_info[:type] = "#{@treat_as_array[arg_info[:type]]}*" + arg_info[:type] = "const #{arg_info[:type]}" if arg_info[:const?] + arg_info[:ptr?] = true + end + args << arg_info end return args diff --git a/test/unit/cmock_header_parser_test.rb b/test/unit/cmock_header_parser_test.rb index add920f..805780d 100644 --- a/test/unit/cmock_header_parser_test.rb +++ b/test/unit/cmock_header_parser_test.rb @@ -19,6 +19,7 @@ describe CMockHeaderParser, "Verify CMockHeaderParser Module" do @config.expect :c_calling_conventions, ['__stdcall'] @config.expect :treat_as_void, ['MY_FUNKY_VOID'] @config.expect :treat_as, { "BANJOS" => "INT", "TUBAS" => "HEX16"} + @config.expect :treat_as_array, {"IntArray" => "int", "Book" => "Page"} @config.expect :when_no_prototypes, :error @config.expect :verbosity, 1 @config.expect :treat_externs, :exclude @@ -949,6 +950,32 @@ describe CMockHeaderParser, "Verify CMockHeaderParser Module" do assert_equal(expected, @parser.parse("module", source)[:functions]) end + it "converts typedef'd array arguments to pointers" do + + source = "Book AddToBook(Book book, const IntArray values);\n" + + expected = [{ :name => "AddToBook", + :modifier=>"", + :return => { :type => "Book", + :name => "cmock_to_return", + :str => "Book cmock_to_return", + :void? => false, + :ptr? => false, + :const? => false, + :const_ptr? => false + }, + :var_arg => nil, + :args => [{ :type => "Page*", :name => "book", :ptr? => true, :const? => false, :const_ptr? => false }, + { :type => "const int*", :name => "values", :ptr? => true, :const? => true, :const_ptr? => false }], + :args_string => "Book book, const IntArray values", + :args_call => "book, values", + :contains_ptr? => true + }] + + assert_equal(expected, @parser.parse("module", source)[:functions]) + + end + it "properly detect typedef'd variants of void and use those" do source = "typedef (void) FUNKY_VOID_T;\n" +