From 91d5e578d866f1f0c667ac570916b21b635c2ec6 Mon Sep 17 00:00:00 2001 From: mvandervoord Date: Mon, 18 Nov 2019 09:09:42 -0500 Subject: [PATCH] Add support for function pointers using the shorthand notation --- lib/cmock_header_parser.rb | 17 +++++++++++++ test/rakefile | 5 +++- .../function_pointer_handling.yml | 1 + test/unit/cmock_header_parser_test.rb | 24 +++++++++++++++++++ 4 files changed, 46 insertions(+), 1 deletion(-) diff --git a/lib/cmock_header_parser.rb b/lib/cmock_header_parser.rb index 3e2d31b..e31821b 100644 --- a/lib/cmock_header_parser.rb +++ b/lib/cmock_header_parser.rb @@ -382,6 +382,23 @@ class CMockHeaderParser "#{functype} #{funconst}#{funcname}" end + #scan argument list for function pointers with shorthand notation and replace them with custom types + arg_list.gsub!(/([\w\s\*]+)+\s+(\w+)\s*\(((?:[\w\s\*]*,?)*)\s*\)*/) do |m| + + functype = "cmock_#{@module_name}_func_ptr#{@typedefs.size + 1}" + funcret = $1.strip + funcname = $2.strip + funcargs = $3.strip + funconst = '' + if (funcname.include? 'const') + funcname.gsub!('const','').strip! + funconst = 'const ' + end + @typedefs << "typedef #{funcret}(*#{functype})(#{funcargs});" + funcname = "cmock_arg#{c+=1}" if (funcname.empty?) + "#{functype} #{funconst}#{funcname}" + end + #automatically name unnamed arguments (those that only had a type) arg_list.split(/\s*,\s*/).map { |arg| parts = (arg.split - ['struct', 'union', 'enum', 'const', 'const*']) diff --git a/test/rakefile b/test/rakefile index da895f3..1feaf98 100644 --- a/test/rakefile +++ b/test/rakefile @@ -42,10 +42,13 @@ task :config, :config_file do |t, args| configure_toolchain(args[:config_file]) end -desc "Run all unit, c, and system tests" +# Still support testing everything with just 'test' but switch default to ceedling-like test:all task :test => [:clobber, :prep_system_tests, 'test:units', 'test:c', 'test:system'] namespace :test do + desc "Run all unit, c, and system tests" + task :all => [:clobber, :prep_system_tests, 'test:units', 'test:c', 'test:system'] + desc "Run Unit Tests" Rake::TestTask.new('units') do |t| t.pattern = 'unit/*_test.rb' diff --git a/test/system/test_interactions/function_pointer_handling.yml b/test/system/test_interactions/function_pointer_handling.yml index 4119770..d286bdb 100644 --- a/test/system/test_interactions/function_pointer_handling.yml +++ b/test/system/test_interactions/function_pointer_handling.yml @@ -12,6 +12,7 @@ :mockable: | void takes_function_type( FUNCTION_T myfunc ); void takes_function_ptr( unsigned int (*func_ptr)(int, char) ); + void takes_function_ptr_shorthand( unsigned int func_ptr(int, char*) ); void takes_const_function_ptr( unsigned int (* const)(int, char) ); unsigned short (*returns_function_ptr( const char op_code ))( int, long int ); diff --git a/test/unit/cmock_header_parser_test.rb b/test/unit/cmock_header_parser_test.rb index f0bb21b..2513b54 100644 --- a/test/unit/cmock_header_parser_test.rb +++ b/test/unit/cmock_header_parser_test.rb @@ -1369,6 +1369,30 @@ describe CMockHeaderParser, "Verify CMockHeaderParser Module" do assert_equal(typedefs, result[:typedefs]) end + it "extract functions using a function pointer with shorthand notation" do + source = "void FunkyTurkey(unsigned int func_ptr(int, char))" + expected = [{ :var_arg=>nil, + :return=>{ :type => "void", + :name => 'cmock_to_return', + :ptr? => false, + :const? => false, + :const_ptr? => false, + :str => "void cmock_to_return", + :void? => true + }, + :name=>"FunkyTurkey", + :modifier=>"", + :contains_ptr? => false, + :args=>[ {:type=>"cmock_module_func_ptr1", :name=>"func_ptr", :ptr? => false, :const? => false, :const_ptr? => false} + ], + :args_string=>"cmock_module_func_ptr1 func_ptr", + :args_call=>"func_ptr" }] + typedefs = ["typedef unsigned int(*cmock_module_func_ptr1)(int, char);"] + result = @parser.parse("module", source) + assert_equal(expected, result[:functions]) + assert_equal(typedefs, result[:typedefs]) + end + it "extract functions containing a function pointer with a void" do source = "void FunkyTurkey(void (*func_ptr)(void))" expected = [{ :var_arg=>nil,