mirror of
https://github.com/ThrowTheSwitch/CMock.git
synced 2026-08-23 19:49:56 +00:00
- support typedefs of pointer types in treat_as
- fixed multi-line typedef declaration rejection git-svn-id: http://cmock.svn.sourceforge.net/svnroot/cmock/trunk@179 bf332499-1b4d-0410-844d-d2d48d5cc64c
This commit is contained in:
@@ -69,11 +69,11 @@ class CMockHeaderParser
|
||||
|
||||
# enums, unions, structs, and typedefs can all contain things (e.g. function pointers) that parse like function prototypes, so yank them
|
||||
# forward declared structs are removed before struct definitions so they don't mess up real thing later. we leave structs keywords in function prototypes
|
||||
source.gsub!(/^[\w\s]*struct[^;\{\}\(\)]+;/m, '') # remove forward declared structs
|
||||
source.gsub!(/^[\w\s]*(enum|union|struct)[\w\s]*\{[^\}]+\}[\w\s]*;/m, '') # remove struct definitions
|
||||
source.gsub!(/(\W)(register|auto|static|restrict)(\W)/, '\1\3') # remove problem keywords
|
||||
source.gsub!(/\s*=\s*['"a-zA-Z0-9_\.]+\s*/, '') # remove default value statements from argument lists
|
||||
source.gsub!(/^(?:.*\W)?typedef\W.*/, '') # remove typedef statements
|
||||
source.gsub!(/^[\w\s]*struct[^;\{\}\(\)]+;/m, '') # remove forward declared structs
|
||||
source.gsub!(/^[\w\s]*(enum|union|struct|typepdef)[\w\s]*\{[^\}]+\}[\w\s\*\,]*;/m, '') # remove struct, union, and enum definitions and typedefs with braces
|
||||
source.gsub!(/(\W)(register|auto|static|restrict)(\W)/, '\1\3') # remove problem keywords
|
||||
source.gsub!(/\s*=\s*['"a-zA-Z0-9_\.]+\s*/, '') # remove default value statements from argument lists
|
||||
source.gsub!(/^(?:[\w\s]*\W)?typedef\W.*/, '') # remove typedef statements
|
||||
|
||||
#scan for functions which return function pointers, because they are a pain
|
||||
source.gsub!(/([\w\s\*]+)\(*\(\s*\*([\w\s\*]+)\s*\(([\w\s\*,]*)\)\)\s*\(([\w\s\*,]*)\)\)*/) do |m|
|
||||
|
||||
@@ -33,8 +33,12 @@ class CMockUnityHelperParser
|
||||
def map_C_types
|
||||
c_types = {}
|
||||
@config.treat_as.each_pair do |ctype, expecttype|
|
||||
c_types[ctype.gsub(/\s+/,'_')] = "UNITY_TEST_ASSERT_EQUAL_#{expecttype}"
|
||||
c_types[ctype.gsub(/\s+/,'_')+'*'] = "UNITY_TEST_ASSERT_EQUAL_#{expecttype}_ARRAY"
|
||||
if (expecttype =~ /\*/)
|
||||
c_types[ctype.gsub(/\s+/,'_')] = "UNITY_TEST_ASSERT_EQUAL_#{expecttype.gsub(/\*/,'')}_ARRAY"
|
||||
else
|
||||
c_types[ctype.gsub(/\s+/,'_')] = "UNITY_TEST_ASSERT_EQUAL_#{expecttype}"
|
||||
c_types[ctype.gsub(/\s+/,'_')+'*'] = "UNITY_TEST_ASSERT_EQUAL_#{expecttype}_ARRAY"
|
||||
end
|
||||
end
|
||||
c_types
|
||||
end
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
:cmock:
|
||||
:plugins:
|
||||
- # none
|
||||
:treat_as:
|
||||
INT_PTR: INT*
|
||||
|
||||
:systest:
|
||||
:types: |
|
||||
@@ -9,6 +11,7 @@
|
||||
int x;
|
||||
int y;
|
||||
} POINT_T;
|
||||
typedef int* INT_PTR;
|
||||
|
||||
:mockable: |
|
||||
void foo(POINT_T* a);
|
||||
@@ -16,12 +19,14 @@
|
||||
void fooa(POINT_T a[]);
|
||||
void foos(const char *a);
|
||||
const char* bars(void);
|
||||
INT_PTR zoink(INT_PTR a);
|
||||
|
||||
:source:
|
||||
:header: |
|
||||
void function_a(void);
|
||||
void function_b(void);
|
||||
void function_c(void);
|
||||
int function_d(void);
|
||||
|
||||
:code: |
|
||||
void function_a(void)
|
||||
@@ -37,6 +42,12 @@
|
||||
foos(bars());
|
||||
}
|
||||
|
||||
int function_d(void) {
|
||||
int i = 456;
|
||||
INT_PTR ptr = (INT_PTR)(&i);
|
||||
return (int)(*(zoink(ptr)));
|
||||
}
|
||||
|
||||
:tests:
|
||||
:common: |
|
||||
void setUp(void) {}
|
||||
@@ -162,6 +173,36 @@
|
||||
|
||||
function_c();
|
||||
}
|
||||
|
||||
- :pass: TRUE
|
||||
:should: 'handle handle typedefs that ARE pointers by using treat_as'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
int e = 456;
|
||||
int r = 789;
|
||||
INT_PTR ptr_e = (INT_PTR)(&e);
|
||||
INT_PTR ptr_r = (INT_PTR)(&r);
|
||||
|
||||
zoink_ExpectAndReturn(ptr_e, ptr_r);
|
||||
|
||||
TEST_ASSERT_EQUAL(r, function_d());
|
||||
}
|
||||
|
||||
- :pass: FALSE
|
||||
:should: 'handle handle typedefs that ARE pointers by using treat_as and catch failures'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
int e = 457;
|
||||
int r = 789;
|
||||
INT_PTR ptr_e = (INT_PTR)(&e);
|
||||
INT_PTR ptr_r = (INT_PTR)(&r);
|
||||
|
||||
zoink_ExpectAndReturn(ptr_e, ptr_r);
|
||||
|
||||
TEST_ASSERT_EQUAL(r, function_d());
|
||||
}
|
||||
|
||||
|
||||
...
|
||||
|
||||
@@ -140,12 +140,25 @@ class CMockHeaderParserTest < Test::Unit::TestCase
|
||||
should "remove typedef statements" do
|
||||
source =
|
||||
"typedef uint32 (unsigned int);\n" +
|
||||
"whack me! typedef int INT;\n" +
|
||||
"const typedef int INT;\n" +
|
||||
"int notatypedef;\n" +
|
||||
"int typedef_isnt_me;\n" +
|
||||
" typedef who cares what really comes here \\\n" + # exercise multiline typedef
|
||||
" continuation;\n" +
|
||||
"this should remain!\n"
|
||||
"this should remain!;\n" +
|
||||
"typedef blah bleh;\n" +
|
||||
"typedef struct shell_command_struct {\n" +
|
||||
" char_ptr COMMAND;\n" +
|
||||
" int_32 (*SHELL_FUNC)(int_32 argc);\n" +
|
||||
"} SHELL_COMMAND_STRUCT, * SHELL_COMMAND_PTR;\n" +
|
||||
"typedef struct shell_command_struct {\n" +
|
||||
" char_ptr COMMAND;\n" +
|
||||
" int_32 (*SHELL_FUNC)(int_32 argc, char_ptr argv[]);\n" +
|
||||
"} SHELL_COMMAND_STRUCT, * SHELL_COMMAND_PTR;\n" +
|
||||
"typedef struct shell_command_struct {\n" +
|
||||
" char_ptr COMMAND;\n" +
|
||||
" int_32 (*SHELL_FUNC)(int_32 argc);\n" +
|
||||
"};\n"
|
||||
|
||||
expected =
|
||||
[
|
||||
@@ -787,7 +800,7 @@ class CMockHeaderParserTest < Test::Unit::TestCase
|
||||
end
|
||||
|
||||
should "handle arrays and treat them as pointers" do
|
||||
source = "void KeyOperated(CUSTOM_TYPE thing1[], int thing2 [ ], char thing3 [][2 ][ 3])"
|
||||
source = "void KeyOperated(CUSTOM_TYPE thing1[], int thing2 [ ], char thing3 [][2 ][ 3], int* thing4[4])"
|
||||
expected = [{:var_arg=>nil,
|
||||
:return=>{ :type => "void",
|
||||
:name => 'cmock_to_return',
|
||||
@@ -801,10 +814,11 @@ class CMockHeaderParserTest < Test::Unit::TestCase
|
||||
:contains_ptr? => true,
|
||||
:args=>[ {:type=>"CUSTOM_TYPE*", :name=>"thing1", :ptr? => true, :const? => false},
|
||||
{:type=>"int*", :name=>"thing2", :ptr? => true, :const? => false},
|
||||
{:type=>"char*", :name=>"thing3", :ptr? => false, :const? => false} #THIS one will likely change in the future when we improve multidimensional array support
|
||||
{:type=>"char*", :name=>"thing3", :ptr? => false, :const? => false}, #THIS one will likely change in the future when we improve multidimensional array support
|
||||
{:type=>"int**", :name=>"thing4", :ptr? => true, :const? => false} #THIS one will likely change in the future when we improve multidimensional array support
|
||||
],
|
||||
:args_string=>"CUSTOM_TYPE* thing1, int* thing2, char* thing3",
|
||||
:args_call=>"thing1, thing2, thing3" }]
|
||||
:args_string=>"CUSTOM_TYPE* thing1, int* thing2, char* thing3, int** thing4",
|
||||
:args_call=>"thing1, thing2, thing3, thing4" }]
|
||||
result = @parser.parse("module", source)
|
||||
assert_equal(expected, result[:functions])
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user