From d5b1812e2fbb017e7b0894becce2ebb18ea06f4d Mon Sep 17 00:00:00 2001 From: mvandervoord Date: Tue, 7 Jun 2011 01:32:51 +0000 Subject: [PATCH] - updated to support calling conventions without resorting to trickery with attributes git-svn-id: http://cmock.svn.sourceforge.net/svnroot/cmock/trunk@214 bf332499-1b4d-0410-844d-d2d48d5cc64c --- lib/cmock_config.rb | 1 + lib/cmock_generator.rb | 8 +++----- lib/cmock_header_parser.rb | 3 +++ targets/iar_arm_v4.yml | 1 + targets/iar_arm_v5.yml | 1 + test/system/test_compilation/callingconv.h | 7 +++++++ test/unit/cmock_generator_main_test.rb | 3 ++- test/unit/cmock_header_parser_test.rb | 24 ++++++++++++++++++++++ 8 files changed, 42 insertions(+), 6 deletions(-) create mode 100644 test/system/test_compilation/callingconv.h diff --git a/lib/cmock_config.rb b/lib/cmock_config.rb index c541e2c..21d7f50 100644 --- a/lib/cmock_config.rb +++ b/lib/cmock_config.rb @@ -14,6 +14,7 @@ class CMockConfig :plugins => [], :strippables => ['(?:__attribute__\s*\(+.*?\)+)'], :attributes => ['__ramfunc', '__irq', '__fiq', 'register', 'extern'], + :c_calling_conventions => ['__stdcall', '__cdecl', '__fastcall'], :enforce_strict_ordering => false, :unity_helper_path => false, :treat_as => {}, diff --git a/lib/cmock_generator.rb b/lib/cmock_generator.rb index ed6bce4..c8fd78f 100644 --- a/lib/cmock_generator.rb +++ b/lib/cmock_generator.rb @@ -160,11 +160,9 @@ class CMockGenerator def create_mock_implementation(file, function) # prepare return value and arguments - if (function[:modifier].empty?) - function_mod_and_rettype = function[:return][:type] - else - function_mod_and_rettype = function[:modifier] + ' ' + function[:return][:type] - end + function_mod_and_rettype = (function[:modifier].empty? ? '' : "#{function[:modifier]} ") + + (function[:return][:type]) + + (function[:c_calling_convention] ? " #{function[:c_calling_convention]}" : '') args_string = function[:args_string] args_string += (", " + function[:var_arg]) unless (function[:var_arg].nil?) diff --git a/lib/cmock_header_parser.rb b/lib/cmock_header_parser.rb index 4ea9966..fcae4b0 100644 --- a/lib/cmock_header_parser.rb +++ b/lib/cmock_header_parser.rb @@ -12,6 +12,7 @@ class CMockHeaderParser @funcs = [] @c_strippables = cfg.strippables @c_attributes = (['const'] + cfg.attributes).uniq + @c_calling_conventions = cfg.c_calling_conventions.uniq @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 @@ -200,6 +201,8 @@ class CMockHeaderParser descriptors[0..-2].each do |word| if @c_attributes.include?(word) decl[:modifier] << word + elsif @c_calling_conventions.include?(word) + decl[:c_calling_convention] = word else rettype << word end diff --git a/targets/iar_arm_v4.yml b/targets/iar_arm_v4.yml index 7acbc9d..fdda582 100644 --- a/targets/iar_arm_v4.yml +++ b/targets/iar_arm_v4.yml @@ -102,6 +102,7 @@ simulator: unsupported: - nonstandard_parsed_stuff_1 - const + - callingconv - unity_64bit_support colour: true diff --git a/targets/iar_arm_v5.yml b/targets/iar_arm_v5.yml index c68206c..e44f631 100644 --- a/targets/iar_arm_v5.yml +++ b/targets/iar_arm_v5.yml @@ -87,6 +87,7 @@ simulator: unsupported: - nonstandard_parsed_stuff_1 - const + - callingconv - unity_64bit_support colour: true diff --git a/test/system/test_compilation/callingconv.h b/test/system/test_compilation/callingconv.h new file mode 100644 index 0000000..a8209af --- /dev/null +++ b/test/system/test_compilation/callingconv.h @@ -0,0 +1,7 @@ +/* ========================================== + CMock Project - Automatic Mock Generation for C + Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams + [Released under MIT License. Please refer to license.txt for details] +========================================== */ + +int __stdcall this_uses_calling_conventions(int b); diff --git a/test/unit/cmock_generator_main_test.rb b/test/unit/cmock_generator_main_test.rb index d2a94c3..ecbf72a 100644 --- a/test/unit/cmock_generator_main_test.rb +++ b/test/unit/cmock_generator_main_test.rb @@ -381,6 +381,7 @@ class CMockGeneratorTest < Test::Unit::TestCase should "create mock implementation functions in source file with different options" do function = { :modifier => "", + :c_calling_convention => "__stdcall", :return => test_return[:int], :args_string => "uint32 sandwiches", :args => ["uint32 sandwiches"], @@ -389,7 +390,7 @@ class CMockGeneratorTest < Test::Unit::TestCase :attributes => nil } output = [] - expected = [ "int SupaFunction(uint32 sandwiches, corn ...)\n", + expected = [ "int __stdcall SupaFunction(uint32 sandwiches, corn ...)\n", "{\n", " UNITY_LINE_TYPE cmock_line = TEST_LINE_NUM;\n", " CMOCK_SupaFunction_CALL_INSTANCE* cmock_call_instance = (CMOCK_SupaFunction_CALL_INSTANCE*)CMock_Guts_GetAddressFor(Mock.SupaFunction_CallInstance);\n", diff --git a/test/unit/cmock_header_parser_test.rb b/test/unit/cmock_header_parser_test.rb index b6bf90f..b7923c3 100644 --- a/test/unit/cmock_header_parser_test.rb +++ b/test/unit/cmock_header_parser_test.rb @@ -16,6 +16,7 @@ class CMockHeaderParserTest < Test::Unit::TestCase @test_name = 'test_file.h' @config.expect.strippables.returns(['(?:__attribute__\s*\(+.*?\)+)']) @config.expect.attributes.returns(['__ramfunc', 'funky_attrib']) + @config.expect.c_calling_conventions.returns(['__stdcall']) @config.expect.treat_as_void.returns(['MY_FUNKY_VOID']) @config.expect.treat_as.returns({ "BANJOS" => "INT", "TUBAS" => "HEX16"} ) @config.expect.when_no_prototypes.returns(:error) @@ -544,6 +545,29 @@ class CMockHeaderParserTest < Test::Unit::TestCase assert_equal(expected, @parser.parse_declaration(source)) end + should "extract c calling conventions properly" do + + source = "const int __stdcall TheMatrix(int Trinity, unsigned int * Neo)" + expected = { :var_arg=>nil, + :return=>{ :type => "int", + :name => 'cmock_to_return', + :ptr? => false, + :const? => false, + :str => "int cmock_to_return", + :void? => false + }, + :name=>"TheMatrix", + :modifier=>"const", + :c_calling_convention=>"__stdcall", + :contains_ptr? => true, + :args=>[ {:type=>"int", :name=>"Trinity", :ptr? => false, :const? => false}, + {:type=>"unsigned int*", :name=>"Neo", :ptr? => true, :const? => false} + ], + :args_string=>"int Trinity, unsigned int* Neo", + :args_call=>"Trinity, Neo" } + assert_equal(expected, @parser.parse_declaration(source)) + end + should "fully parse multiple prototypes" do source = "const int TheMatrix(int Trinity, unsigned int * Neo);\n" +