mirror of
https://github.com/ThrowTheSwitch/CMock.git
synced 2026-10-08 09:57:25 +00:00
- 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
This commit is contained in:
@@ -14,6 +14,7 @@ class CMockConfig
|
|||||||
:plugins => [],
|
:plugins => [],
|
||||||
:strippables => ['(?:__attribute__\s*\(+.*?\)+)'],
|
:strippables => ['(?:__attribute__\s*\(+.*?\)+)'],
|
||||||
:attributes => ['__ramfunc', '__irq', '__fiq', 'register', 'extern'],
|
:attributes => ['__ramfunc', '__irq', '__fiq', 'register', 'extern'],
|
||||||
|
:c_calling_conventions => ['__stdcall', '__cdecl', '__fastcall'],
|
||||||
:enforce_strict_ordering => false,
|
:enforce_strict_ordering => false,
|
||||||
:unity_helper_path => false,
|
:unity_helper_path => false,
|
||||||
:treat_as => {},
|
:treat_as => {},
|
||||||
|
|||||||
@@ -160,11 +160,9 @@ class CMockGenerator
|
|||||||
|
|
||||||
def create_mock_implementation(file, function)
|
def create_mock_implementation(file, function)
|
||||||
# prepare return value and arguments
|
# prepare return value and arguments
|
||||||
if (function[:modifier].empty?)
|
function_mod_and_rettype = (function[:modifier].empty? ? '' : "#{function[:modifier]} ") +
|
||||||
function_mod_and_rettype = function[:return][:type]
|
(function[:return][:type]) +
|
||||||
else
|
(function[:c_calling_convention] ? " #{function[:c_calling_convention]}" : '')
|
||||||
function_mod_and_rettype = function[:modifier] + ' ' + function[:return][:type]
|
|
||||||
end
|
|
||||||
args_string = function[:args_string]
|
args_string = function[:args_string]
|
||||||
args_string += (", " + function[:var_arg]) unless (function[:var_arg].nil?)
|
args_string += (", " + function[:var_arg]) unless (function[:var_arg].nil?)
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ class CMockHeaderParser
|
|||||||
@funcs = []
|
@funcs = []
|
||||||
@c_strippables = cfg.strippables
|
@c_strippables = cfg.strippables
|
||||||
@c_attributes = (['const'] + cfg.attributes).uniq
|
@c_attributes = (['const'] + cfg.attributes).uniq
|
||||||
|
@c_calling_conventions = cfg.c_calling_conventions.uniq
|
||||||
@treat_as_void = (['void'] + cfg.treat_as_void).uniq
|
@treat_as_void = (['void'] + cfg.treat_as_void).uniq
|
||||||
@declaration_parse_matcher = /([\d\w\s\*\(\),\[\]]+??)\(([\d\w\s\*\(\),\.\[\]+-]*)\)$/m
|
@declaration_parse_matcher = /([\d\w\s\*\(\),\[\]]+??)\(([\d\w\s\*\(\),\.\[\]+-]*)\)$/m
|
||||||
@standards = (['int','short','char','long','unsigned','signed'] + cfg.treat_as.keys).uniq
|
@standards = (['int','short','char','long','unsigned','signed'] + cfg.treat_as.keys).uniq
|
||||||
@@ -200,6 +201,8 @@ class CMockHeaderParser
|
|||||||
descriptors[0..-2].each do |word|
|
descriptors[0..-2].each do |word|
|
||||||
if @c_attributes.include?(word)
|
if @c_attributes.include?(word)
|
||||||
decl[:modifier] << word
|
decl[:modifier] << word
|
||||||
|
elsif @c_calling_conventions.include?(word)
|
||||||
|
decl[:c_calling_convention] = word
|
||||||
else
|
else
|
||||||
rettype << word
|
rettype << word
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -102,6 +102,7 @@ simulator:
|
|||||||
unsupported:
|
unsupported:
|
||||||
- nonstandard_parsed_stuff_1
|
- nonstandard_parsed_stuff_1
|
||||||
- const
|
- const
|
||||||
|
- callingconv
|
||||||
- unity_64bit_support
|
- unity_64bit_support
|
||||||
|
|
||||||
colour: true
|
colour: true
|
||||||
|
|||||||
@@ -87,6 +87,7 @@ simulator:
|
|||||||
unsupported:
|
unsupported:
|
||||||
- nonstandard_parsed_stuff_1
|
- nonstandard_parsed_stuff_1
|
||||||
- const
|
- const
|
||||||
|
- callingconv
|
||||||
- unity_64bit_support
|
- unity_64bit_support
|
||||||
|
|
||||||
colour: true
|
colour: true
|
||||||
|
|||||||
@@ -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);
|
||||||
@@ -381,6 +381,7 @@ class CMockGeneratorTest < Test::Unit::TestCase
|
|||||||
|
|
||||||
should "create mock implementation functions in source file with different options" do
|
should "create mock implementation functions in source file with different options" do
|
||||||
function = { :modifier => "",
|
function = { :modifier => "",
|
||||||
|
:c_calling_convention => "__stdcall",
|
||||||
:return => test_return[:int],
|
:return => test_return[:int],
|
||||||
:args_string => "uint32 sandwiches",
|
:args_string => "uint32 sandwiches",
|
||||||
:args => ["uint32 sandwiches"],
|
:args => ["uint32 sandwiches"],
|
||||||
@@ -389,7 +390,7 @@ class CMockGeneratorTest < Test::Unit::TestCase
|
|||||||
:attributes => nil
|
:attributes => nil
|
||||||
}
|
}
|
||||||
output = []
|
output = []
|
||||||
expected = [ "int SupaFunction(uint32 sandwiches, corn ...)\n",
|
expected = [ "int __stdcall SupaFunction(uint32 sandwiches, corn ...)\n",
|
||||||
"{\n",
|
"{\n",
|
||||||
" UNITY_LINE_TYPE cmock_line = TEST_LINE_NUM;\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",
|
" CMOCK_SupaFunction_CALL_INSTANCE* cmock_call_instance = (CMOCK_SupaFunction_CALL_INSTANCE*)CMock_Guts_GetAddressFor(Mock.SupaFunction_CallInstance);\n",
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ class CMockHeaderParserTest < Test::Unit::TestCase
|
|||||||
@test_name = 'test_file.h'
|
@test_name = 'test_file.h'
|
||||||
@config.expect.strippables.returns(['(?:__attribute__\s*\(+.*?\)+)'])
|
@config.expect.strippables.returns(['(?:__attribute__\s*\(+.*?\)+)'])
|
||||||
@config.expect.attributes.returns(['__ramfunc', 'funky_attrib'])
|
@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_void.returns(['MY_FUNKY_VOID'])
|
||||||
@config.expect.treat_as.returns({ "BANJOS" => "INT", "TUBAS" => "HEX16"} )
|
@config.expect.treat_as.returns({ "BANJOS" => "INT", "TUBAS" => "HEX16"} )
|
||||||
@config.expect.when_no_prototypes.returns(:error)
|
@config.expect.when_no_prototypes.returns(:error)
|
||||||
@@ -544,6 +545,29 @@ class CMockHeaderParserTest < Test::Unit::TestCase
|
|||||||
assert_equal(expected, @parser.parse_declaration(source))
|
assert_equal(expected, @parser.parse_declaration(source))
|
||||||
end
|
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
|
should "fully parse multiple prototypes" do
|
||||||
|
|
||||||
source = "const int TheMatrix(int Trinity, unsigned int * Neo);\n" +
|
source = "const int TheMatrix(int Trinity, unsigned int * Neo);\n" +
|
||||||
|
|||||||
Reference in New Issue
Block a user