vendor/cmock/lib/cmock_generator.rb in ceedling-0.29.1 vs vendor/cmock/lib/cmock_generator.rb in ceedling-0.30.0

- old
+ new

@@ -1,275 +1,333 @@ -# ========================================== -# 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] -# ========================================== - -class CMockGenerator - - attr_accessor :config, :file_writer, :module_name, :clean_mock_name, :mock_name, :utils, :plugins, :weak, :ordered - - def initialize(config, file_writer, utils, plugins) - @file_writer = file_writer - @utils = utils - @plugins = plugins - @config = config - @prefix = @config.mock_prefix - @suffix = @config.mock_suffix - @weak = @config.weak - @include_inline = @config.treat_inlines - @ordered = @config.enforce_strict_ordering - @framework = @config.framework.to_s - @fail_on_unexpected_calls = @config.fail_on_unexpected_calls - - @subdir = @config.subdir - - @includes_h_pre_orig_header = (@config.includes || @config.includes_h_pre_orig_header || []).map{|h| h =~ /</ ? h : "\"#{h}\""} - @includes_h_post_orig_header = (@config.includes_h_post_orig_header || []).map{|h| h =~ /</ ? h : "\"#{h}\""} - @includes_c_pre_header = (@config.includes_c_pre_header || []).map{|h| h =~ /</ ? h : "\"#{h}\""} - @includes_c_post_header = (@config.includes_c_post_header || []).map{|h| h =~ /</ ? h : "\"#{h}\""} - - here = File.dirname __FILE__ - unity_path_in_ceedling = "#{here}/../../unity" # path to Unity from within Ceedling - unity_path_in_cmock = "#{here}/../vendor/unity" # path to Unity from within CMock - # path to Unity as specified by env var - unity_path_in_env = ENV.has_key?("UNITY_DIR") ? File.expand_path(ENV.fetch("UNITY_DIR")) : nil - - if unity_path_in_env and File.exist? unity_path_in_env - require "#{unity_path_in_env}/auto/type_sanitizer" - elsif File.exist? unity_path_in_ceedling - require "#{unity_path_in_ceedling}/auto/type_sanitizer" - elsif File.exist? unity_path_in_cmock - require "#{unity_path_in_cmock}/auto/type_sanitizer" - else - raise "Failed to find an instance of Unity to pull in type_sanitizer module!" - end - - end - - def create_mock(module_name, parsed_stuff) - @module_name = module_name - @mock_name = @prefix + @module_name + @suffix - @clean_mock_name = TypeSanitizer.sanitize_c_identifier(@mock_name) - create_mock_subdir() - create_mock_header_file(parsed_stuff) - create_mock_source_file(parsed_stuff) - end - - private if $ThisIsOnlyATest.nil? ############################## - - def create_mock_subdir() - @file_writer.create_subdir(@subdir) - end - - def create_mock_header_file(parsed_stuff) - if @include_inline == :include - @file_writer.create_file(@module_name + ".h", @subdir) do |file, filename| - file << parsed_stuff[:normalized_source] - end - end - - @file_writer.create_file(@mock_name + ".h", @subdir) do |file, filename| - create_mock_header_header(file, filename) - create_mock_header_service_call_declarations(file) - create_typedefs(file, parsed_stuff[:typedefs]) - parsed_stuff[:functions].each do |function| - file << @plugins.run(:mock_function_declarations, function) - end - create_mock_header_footer(file) - end - end - - def create_mock_source_file(parsed_stuff) - @file_writer.create_file(@mock_name + ".c", @subdir) do |file, filename| - create_source_header_section(file, filename, parsed_stuff[:functions]) - create_instance_structure(file, parsed_stuff[:functions]) - create_extern_declarations(file) - create_mock_verify_function(file, parsed_stuff[:functions]) - create_mock_init_function(file) - create_mock_destroy_function(file, parsed_stuff[:functions]) - parsed_stuff[:functions].each do |function| - create_mock_implementation(file, function) - create_mock_interfaces(file, function) - end - end - end - - def create_mock_header_header(file, filename) - define_name = @clean_mock_name.upcase - orig_filename = (@subdir ? @subdir + "/" : "") + @module_name + ".h" - file << "/* AUTOGENERATED FILE. DO NOT EDIT. */\n" - file << "#ifndef _#{define_name}_H\n" - file << "#define _#{define_name}_H\n\n" - file << "#include \"#{@framework}.h\"\n" - @includes_h_pre_orig_header.each {|inc| file << "#include #{inc}\n"} - file << @config.orig_header_include_fmt.gsub(/%s/, "#{orig_filename}") + "\n" - @includes_h_post_orig_header.each {|inc| file << "#include #{inc}\n"} - plugin_includes = @plugins.run(:include_files) - file << plugin_includes if (!plugin_includes.empty?) - file << "\n" - file << "/* Ignore the following warnings, since we are copying code */\n" - file << "#if defined(__GNUC__) && !defined(__ICC) && !defined(__TMS470__)\n" - file << "#if __GNUC__ > 4 || (__GNUC__ == 4 && (__GNUC_MINOR__ > 6 || (__GNUC_MINOR__ == 6 && __GNUC_PATCHLEVEL__ > 0)))\n" - file << "#pragma GCC diagnostic push\n" - file << "#endif\n" - file << "#if !defined(__clang__)\n" - file << "#pragma GCC diagnostic ignored \"-Wpragmas\"\n" - file << "#endif\n" - file << "#pragma GCC diagnostic ignored \"-Wunknown-pragmas\"\n" - file << "#pragma GCC diagnostic ignored \"-Wduplicate-decl-specifier\"\n" - file << "#endif\n" - file << "\n" - end - - def create_typedefs(file, typedefs) - file << "\n" - typedefs.each {|typedef| file << "#{typedef}\n" } - file << "\n\n" - end - - def create_mock_header_service_call_declarations(file) - file << "void #{@clean_mock_name}_Init(void);\n" - file << "void #{@clean_mock_name}_Destroy(void);\n" - file << "void #{@clean_mock_name}_Verify(void);\n\n" - end - - def create_mock_header_footer(header) - header << "\n" - header << "#if defined(__GNUC__) && !defined(__ICC) && !defined(__TMS470__)\n" - header << "#if __GNUC__ > 4 || (__GNUC__ == 4 && (__GNUC_MINOR__ > 6 || (__GNUC_MINOR__ == 6 && __GNUC_PATCHLEVEL__ > 0)))\n" - header << "#pragma GCC diagnostic pop\n" - header << "#endif\n" - header << "#endif\n" - header << "\n" - header << "#endif\n" - end - - def create_source_header_section(file, filename, functions) - header_file = (@subdir ? @subdir + '/' : '') + filename.gsub(".c",".h") - file << "/* AUTOGENERATED FILE. DO NOT EDIT. */\n" - file << "#include <string.h>\n" - file << "#include <stdlib.h>\n" - file << "#include <setjmp.h>\n" - file << "#include \"cmock.h\"\n" - @includes_c_pre_header.each {|inc| file << "#include #{inc}\n"} - file << "#include \"#{header_file}\"\n" - @includes_c_post_header.each {|inc| file << "#include #{inc}\n"} - file << "\n" - strs = [] - functions.each do |func| - strs << func[:name] - func[:args].each {|arg| strs << arg[:name] } - end - strs.uniq.sort.each do |str| - file << "static const char* CMockString_#{str} = \"#{str}\";\n" - end - file << "\n" - end - - def create_instance_structure(file, functions) - functions.each do |function| - file << "typedef struct _CMOCK_#{function[:name]}_CALL_INSTANCE\n{\n" - file << " UNITY_LINE_TYPE LineNumber;\n" - file << @plugins.run(:instance_typedefs, function) - file << "\n} CMOCK_#{function[:name]}_CALL_INSTANCE;\n\n" - end - file << "static struct #{@clean_mock_name}Instance\n{\n" - if (functions.size == 0) - file << " unsigned char placeHolder;\n" - end - functions.each do |function| - file << @plugins.run(:instance_structure, function) - file << " CMOCK_MEM_INDEX_TYPE #{function[:name]}_CallInstance;\n" - end - file << "} Mock;\n\n" - end - - def create_extern_declarations(file) - file << "extern jmp_buf AbortFrame;\n" - if (@ordered) - file << "extern int GlobalExpectCount;\n" - file << "extern int GlobalVerifyOrder;\n" - end - file << "\n" - end - - def create_mock_verify_function(file, functions) - file << "void #{@clean_mock_name}_Verify(void)\n{\n" - verifications = functions.collect do |function| - v = @plugins.run(:mock_verify, function) - v.empty? ? v : [" call_instance = Mock.#{function[:name]}_CallInstance;\n", v] - end.join - unless verifications.empty? - file << " UNITY_LINE_TYPE cmock_line = TEST_LINE_NUM;\n" - file << " CMOCK_MEM_INDEX_TYPE call_instance;\n" - file << verifications - end - file << "}\n\n" - end - - def create_mock_init_function(file) - file << "void #{@clean_mock_name}_Init(void)\n{\n" - file << " #{@clean_mock_name}_Destroy();\n" - file << "}\n\n" - end - - def create_mock_destroy_function(file, functions) - file << "void #{@clean_mock_name}_Destroy(void)\n{\n" - file << " CMock_Guts_MemFreeAll();\n" - file << " memset(&Mock, 0, sizeof(Mock));\n" - file << functions.collect {|function| @plugins.run(:mock_destroy, function)}.join - - unless (@fail_on_unexpected_calls) - file << functions.collect {|function| @plugins.run(:mock_ignore, function)}.join - end - - if (@ordered) - file << " GlobalExpectCount = 0;\n" - file << " GlobalVerifyOrder = 0;\n" - end - file << "}\n\n" - end - - def create_mock_implementation(file, function) - # prepare return value and arguments - 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?) - - # Create mock function - if (not @weak.empty?) - file << "#if defined (__IAR_SYSTEMS_ICC__)\n" - file << "#pragma weak #{function[:name]}\n" - file << "#else\n" - file << "#{function_mod_and_rettype} #{function[:name]}(#{args_string}) #{weak};\n" - file << "#endif\n\n" - end - file << "#{function_mod_and_rettype} #{function[:name]}(#{args_string})\n" - file << "{\n" - file << " UNITY_LINE_TYPE cmock_line = TEST_LINE_NUM;\n" - file << " CMOCK_#{function[:name]}_CALL_INSTANCE* cmock_call_instance;\n" - file << " UNITY_SET_DETAIL(CMockString_#{function[:name]});\n" - file << " cmock_call_instance = (CMOCK_#{function[:name]}_CALL_INSTANCE*)CMock_Guts_GetAddressFor(Mock.#{function[:name]}_CallInstance);\n" - file << " Mock.#{function[:name]}_CallInstance = CMock_Guts_MemNext(Mock.#{function[:name]}_CallInstance);\n" - file << @plugins.run(:mock_implementation_precheck, function) - file << " UNITY_TEST_ASSERT_NOT_NULL(cmock_call_instance, cmock_line, CMockStringCalledMore);\n" - file << " cmock_line = cmock_call_instance->LineNumber;\n" - if (@ordered) - file << " if (cmock_call_instance->CallOrder > ++GlobalVerifyOrder)\n" - file << " UNITY_TEST_FAIL(cmock_line, CMockStringCalledEarly);\n" - file << " if (cmock_call_instance->CallOrder < GlobalVerifyOrder)\n" - file << " UNITY_TEST_FAIL(cmock_line, CMockStringCalledLate);\n" - end - file << @plugins.run(:mock_implementation, function) - file << " UNITY_CLR_DETAILS();\n" - file << " return cmock_call_instance->ReturnVal;\n" unless (function[:return][:void?]) - file << "}\n\n" - end - - def create_mock_interfaces(file, function) - file << @utils.code_add_argument_loader(function) - file << @plugins.run(:mock_interfaces, function) - end -end +# ========================================== +# 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] +# ========================================== + +class CMockGenerator + attr_accessor :config, :file_writer, :module_name, :module_ext, :clean_mock_name, :mock_name, :utils, :plugins, :weak, :ordered + + def initialize(config, file_writer, utils, plugins) + @file_writer = file_writer + @utils = utils + @plugins = plugins + @config = config + @prefix = @config.mock_prefix + @suffix = @config.mock_suffix + @weak = @config.weak + @include_inline = @config.treat_inlines + @ordered = @config.enforce_strict_ordering + @framework = @config.framework.to_s + @fail_on_unexpected_calls = @config.fail_on_unexpected_calls + + @subdir = @config.subdir + + @includes_h_pre_orig_header = (@config.includes || @config.includes_h_pre_orig_header || []).map { |h| h =~ /</ ? h : "\"#{h}\"" } + @includes_h_post_orig_header = (@config.includes_h_post_orig_header || []).map { |h| h =~ /</ ? h : "\"#{h}\"" } + @includes_c_pre_header = (@config.includes_c_pre_header || []).map { |h| h =~ /</ ? h : "\"#{h}\"" } + @includes_c_post_header = (@config.includes_c_post_header || []).map { |h| h =~ /</ ? h : "\"#{h}\"" } + + here = File.dirname __FILE__ + unity_path_in_ceedling = "#{here}/../../unity" # path to Unity from within Ceedling + unity_path_in_cmock = "#{here}/../vendor/unity" # path to Unity from within CMock + # path to Unity as specified by env var + unity_path_in_env = ENV.key?('UNITY_DIR') ? File.expand_path(ENV.fetch('UNITY_DIR')) : nil + + if unity_path_in_env && File.exist?(unity_path_in_env) + require "#{unity_path_in_env}/auto/type_sanitizer" + elsif File.exist? unity_path_in_ceedling + require "#{unity_path_in_ceedling}/auto/type_sanitizer" + elsif File.exist? unity_path_in_cmock + require "#{unity_path_in_cmock}/auto/type_sanitizer" + else + raise 'Failed to find an instance of Unity to pull in type_sanitizer module!' + end + end + + def create_mock(module_name, parsed_stuff, module_ext = nil) + @module_name = module_name + @module_ext = module_ext || '.h' + @mock_name = @prefix + @module_name + @suffix + @clean_mock_name = TypeSanitizer.sanitize_c_identifier(@mock_name) + create_mock_subdir + create_mock_header_file(parsed_stuff) + create_mock_source_file(parsed_stuff) + end + + def create_skeleton(module_name, parsed_stuff) + @module_name = module_name + create_skeleton_source_file(parsed_stuff) + end + + private if $ThisIsOnlyATest.nil? ############################## + + def create_mock_subdir + @file_writer.create_subdir(@subdir) + end + + def create_using_statement(file, function) + file << "using namespace #{function[:namespace].join('::')};\n" unless function[:namespace].empty? + end + + def create_mock_header_file(parsed_stuff) + if @include_inline == :include + @file_writer.create_file(@module_name + (@module_ext || '.h'), @subdir) do |file, _filename| + file << parsed_stuff[:normalized_source] + end + end + + @file_writer.create_file(@mock_name + (@module_ext || '.h'), @subdir) do |file, filename| + create_mock_header_header(file, filename) + create_mock_header_service_call_declarations(file) + create_typedefs(file, parsed_stuff[:typedefs]) + parsed_stuff[:functions].each do |function| + create_using_statement(file, function) + file << @plugins.run(:mock_function_declarations, function) + end + create_mock_header_footer(file) + end + end + + def create_mock_source_file(parsed_stuff) + @file_writer.create_file(@mock_name + '.c', @subdir) do |file, filename| + create_source_header_section(file, filename, parsed_stuff[:functions]) + create_instance_structure(file, parsed_stuff[:functions]) + create_extern_declarations(file) + create_mock_verify_function(file, parsed_stuff[:functions]) + create_mock_init_function(file) + create_mock_destroy_function(file, parsed_stuff[:functions]) + parsed_stuff[:functions].each do |function| + create_mock_implementation(file, function) + create_mock_interfaces(file, function) + end + end + end + + def create_skeleton_source_file(parsed_stuff) + filename = "#{@config.mock_path}/#{@subdir + '/' if @subdir}#{module_name}.c" + existing = File.exist?(filename) ? File.read(filename) : '' + @file_writer.append_file(@module_name + '.c', @subdir) do |file, fullname| + create_source_header_section(file, fullname, []) if existing.empty? + parsed_stuff[:functions].each do |function| + create_function_skeleton(file, function, existing) + end + end + end + + def create_mock_header_header(file, _filename) + define_name = @clean_mock_name.upcase + orig_filename = (@subdir ? @subdir + '/' : '') + @module_name + (@module_ext || '.h') + file << "/* AUTOGENERATED FILE. DO NOT EDIT. */\n" + file << "#ifndef _#{define_name}_H\n" + file << "#define _#{define_name}_H\n\n" + file << "#include \"#{@framework}.h\"\n" + @includes_h_pre_orig_header.each { |inc| file << "#include #{inc}\n" } + file << @config.orig_header_include_fmt.gsub(/%s/, orig_filename.to_s) + "\n" + @includes_h_post_orig_header.each { |inc| file << "#include #{inc}\n" } + plugin_includes = @plugins.run(:include_files) + file << plugin_includes unless plugin_includes.empty? + file << "\n" + file << "/* Ignore the following warnings, since we are copying code */\n" + file << "#if defined(__GNUC__) && !defined(__ICC) && !defined(__TMS470__)\n" + file << "#if __GNUC__ > 4 || (__GNUC__ == 4 && (__GNUC_MINOR__ > 6 || (__GNUC_MINOR__ == 6 && __GNUC_PATCHLEVEL__ > 0)))\n" + file << "#pragma GCC diagnostic push\n" + file << "#endif\n" + file << "#if !defined(__clang__)\n" + file << "#pragma GCC diagnostic ignored \"-Wpragmas\"\n" + file << "#endif\n" + file << "#pragma GCC diagnostic ignored \"-Wunknown-pragmas\"\n" + file << "#pragma GCC diagnostic ignored \"-Wduplicate-decl-specifier\"\n" + file << "#endif\n" + file << "\n" + end + + def create_typedefs(file, typedefs) + file << "\n" + typedefs.each { |typedef| file << "#{typedef}\n" } + file << "\n\n" + end + + def create_mock_header_service_call_declarations(file) + file << "void #{@clean_mock_name}_Init(void);\n" + file << "void #{@clean_mock_name}_Destroy(void);\n" + file << "void #{@clean_mock_name}_Verify(void);\n\n" + end + + def create_mock_header_footer(header) + header << "\n" + header << "#if defined(__GNUC__) && !defined(__ICC) && !defined(__TMS470__)\n" + header << "#if __GNUC__ > 4 || (__GNUC__ == 4 && (__GNUC_MINOR__ > 6 || (__GNUC_MINOR__ == 6 && __GNUC_PATCHLEVEL__ > 0)))\n" + header << "#pragma GCC diagnostic pop\n" + header << "#endif\n" + header << "#endif\n" + header << "\n" + header << "#endif\n" + end + + def create_source_header_section(file, filename, functions) + header_file = (@subdir ? @subdir + '/' : '') + filename.gsub('.c', (@module_ext || '.h')) + file << "/* AUTOGENERATED FILE. DO NOT EDIT. */\n" unless functions.empty? + file << "#include <string.h>\n" + file << "#include <stdlib.h>\n" + file << "#include <setjmp.h>\n" + file << "#include \"cmock.h\"\n" + @includes_c_pre_header.each { |inc| file << "#include #{inc}\n" } + file << "#include \"#{header_file}\"\n" + @includes_c_post_header.each { |inc| file << "#include #{inc}\n" } + file << "\n" + strs = [] + functions.each do |func| + strs << func[:name] + func[:args].each { |arg| strs << arg[:name] } + end + strs.uniq.sort.each do |str| + file << "static const char* CMockString_#{str} = \"#{str}\";\n" + end + file << "\n" + end + + def create_instance_structure(file, functions) + functions.each do |function| + file << "typedef struct _CMOCK_#{function[:name]}_CALL_INSTANCE\n{\n" + file << " UNITY_LINE_TYPE LineNumber;\n" + file << @plugins.run(:instance_typedefs, function) + file << "\n} CMOCK_#{function[:name]}_CALL_INSTANCE;\n\n" + end + file << "static struct #{@clean_mock_name}Instance\n{\n" + if functions.empty? + file << " unsigned char placeHolder;\n" + end + functions.each do |function| + file << @plugins.run(:instance_structure, function) + file << " CMOCK_MEM_INDEX_TYPE #{function[:name]}_CallInstance;\n" + end + file << "} Mock;\n\n" + end + + def create_extern_declarations(file) + file << "extern jmp_buf AbortFrame;\n" + if @ordered + file << "extern int GlobalExpectCount;\n" + file << "extern int GlobalVerifyOrder;\n" + end + file << "\n" + end + + def create_mock_verify_function(file, functions) + file << "void #{@clean_mock_name}_Verify(void)\n{\n" + verifications = functions.collect do |function| + v = @plugins.run(:mock_verify, function) + v.empty? ? v : [" call_instance = Mock.#{function[:name]}_CallInstance;\n", v] + end.join + unless verifications.empty? + file << " UNITY_LINE_TYPE cmock_line = TEST_LINE_NUM;\n" + file << " CMOCK_MEM_INDEX_TYPE call_instance;\n" + file << verifications + end + file << "}\n\n" + end + + def create_mock_init_function(file) + file << "void #{@clean_mock_name}_Init(void)\n{\n" + file << " #{@clean_mock_name}_Destroy();\n" + file << "}\n\n" + end + + def create_mock_destroy_function(file, functions) + file << "void #{@clean_mock_name}_Destroy(void)\n{\n" + file << " CMock_Guts_MemFreeAll();\n" + file << " memset(&Mock, 0, sizeof(Mock));\n" + file << functions.collect { |function| @plugins.run(:mock_destroy, function) }.join + + unless @fail_on_unexpected_calls + file << functions.collect { |function| @plugins.run(:mock_ignore, function) }.join + end + + if @ordered + file << " GlobalExpectCount = 0;\n" + file << " GlobalVerifyOrder = 0;\n" + end + file << "}\n\n" + end + + def create_mock_implementation(file, function) + # prepare return value and arguments + 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? + + # Encapsulate in namespace(s) if applicable + function[:namespace].each do |ns| + file << "namespace #{ns} {\n" + end + + # Determine class prefix (if any) + cls_pre = '' + unless function[:class].nil? + cls_pre = "#{function[:class]}::" + end + + # Create mock function + unless @weak.empty? + file << "#if defined (__IAR_SYSTEMS_ICC__)\n" + file << "#pragma weak #{function[:unscoped_name]}\n" + file << "#else\n" + file << "#{function_mod_and_rettype} #{function[:unscoped_name]}(#{args_string}) #{weak};\n" + file << "#endif\n\n" + end + file << "#{function_mod_and_rettype} #{cls_pre}#{function[:unscoped_name]}(#{args_string})\n" + file << "{\n" + file << " UNITY_LINE_TYPE cmock_line = TEST_LINE_NUM;\n" + file << " CMOCK_#{function[:name]}_CALL_INSTANCE* cmock_call_instance;\n" + file << " UNITY_SET_DETAIL(CMockString_#{function[:name]});\n" + file << " cmock_call_instance = (CMOCK_#{function[:name]}_CALL_INSTANCE*)CMock_Guts_GetAddressFor(Mock.#{function[:name]}_CallInstance);\n" + file << " Mock.#{function[:name]}_CallInstance = CMock_Guts_MemNext(Mock.#{function[:name]}_CallInstance);\n" + file << @plugins.run(:mock_implementation_precheck, function) + file << " UNITY_TEST_ASSERT_NOT_NULL(cmock_call_instance, cmock_line, CMockStringCalledMore);\n" + file << " cmock_line = cmock_call_instance->LineNumber;\n" + if @ordered + file << " if (cmock_call_instance->CallOrder > ++GlobalVerifyOrder)\n" + file << " UNITY_TEST_FAIL(cmock_line, CMockStringCalledEarly);\n" + file << " if (cmock_call_instance->CallOrder < GlobalVerifyOrder)\n" + file << " UNITY_TEST_FAIL(cmock_line, CMockStringCalledLate);\n" + end + file << @plugins.run(:mock_implementation, function) + file << " UNITY_CLR_DETAILS();\n" + file << " return cmock_call_instance->ReturnVal;\n" unless function[:return][:void?] + file << "}\n" + + # Close any namespace(s) opened above + function[:namespace].each do + file << "}\n" + end + + file << "\n" + end + + def create_mock_interfaces(file, function) + file << @utils.code_add_argument_loader(function) + file << @plugins.run(:mock_interfaces, function) + end + + def create_function_skeleton(file, function, existing) + # prepare return value and arguments + 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? + + decl = "#{function_mod_and_rettype} #{function[:name]}(#{args_string})" + + return if existing.include?(decl) + + file << "#{decl}\n" + file << "{\n" + file << " /*TODO: Implement Me!*/\n" + function[:args].each { |arg| file << " (void)#{arg[:name]};\n" } + file << " return (#{(function[:return][:type])})0;\n" unless function[:return][:void?] + file << "}\n\n" + end +end