# ========================================================================= # CMock - Automatic Mock Generation for C # ThrowTheSwitch.org # Copyright (c) 2007-25 Mike Karlesky, Mark VanderVoord, & Greg Williams # SPDX-License-Identifier: MIT # ========================================================================= class CMockGeneratorPluginCallback attr_accessor :include_count attr_reader :priority, :config, :utils def initialize(config, utils) @config = config @utils = utils @priority = 6 @include_count = @config.callback_include_count end def instance_structure(function) func_name = function[:name] " char #{func_name}_CallbackBool;\n" \ " CMOCK_#{func_name}_CALLBACK #{func_name}_CallbackFunctionPointer;\n" \ " int #{func_name}_CallbackCalls;\n" end def mock_function_declarations(function) func_name = function[:name] return_type = function[:return][:type] action = @config.callback_after_arg_check ? 'AddCallback' : 'Stub' style = (@include_count ? 1 : 0) | (function[:args].empty? ? 0 : 2) styles = ['void', 'int cmock_num_calls', function[:args_string], "#{function[:args_string]}, int cmock_num_calls"] "typedef #{return_type} (* CMOCK_#{func_name}_CALLBACK)(#{styles[style]});\n" \ "void #{func_name}_AddCallback(CMOCK_#{func_name}_CALLBACK Callback);\n" \ "void #{func_name}_Stub(CMOCK_#{func_name}_CALLBACK Callback);\n" \ "#define #{func_name}_StubWithCallback #{func_name}_#{action}\n" end def generate_call(function) args = function[:args].map { |m| m[:name] } args << "Mock.#{function[:name]}_CallbackCalls++" if @include_count "Mock.#{function[:name]}_CallbackFunctionPointer(#{args.join(', ')})" end def mock_implementation(function) " if (Mock.#{function[:name]}_CallbackFunctionPointer != NULL)\n {\n" + if function[:return][:void?] " #{generate_call(function)};\n }\n" else " cmock_call_instance->ReturnVal = #{generate_call(function)};\n }\n" end end def mock_implementation_precheck(function) " if (!Mock.#{function[:name]}_CallbackBool &&\n" \ " Mock.#{function[:name]}_CallbackFunctionPointer != NULL)\n {\n" + if function[:return][:void?] " #{generate_call(function)};\n" \ " UNITY_CLR_DETAILS();\n" \ " return;\n }\n" else " #{function[:return][:type]} cmock_cb_ret = #{generate_call(function)};\n" \ " UNITY_CLR_DETAILS();\n" \ " return cmock_cb_ret;\n }\n" end end def mock_interfaces(function) func_name = function[:name] has_ignore = @config.plugins.include? :ignore lines = '' lines << "void #{func_name}_AddCallback(CMOCK_#{func_name}_CALLBACK Callback)\n{\n" lines << " Mock.#{func_name}_IgnoreBool = (char)0;\n" if has_ignore lines << " Mock.#{func_name}_CallbackBool = (char)1;\n" lines << " Mock.#{func_name}_CallbackFunctionPointer = Callback;\n}\n\n" lines << "void #{func_name}_Stub(CMOCK_#{func_name}_CALLBACK Callback)\n{\n" lines << " Mock.#{func_name}_IgnoreBool = (char)0;\n" if has_ignore lines << " Mock.#{func_name}_CallbackBool = (char)0;\n" lines << " Mock.#{func_name}_CallbackFunctionPointer = Callback;\n}\n\n" end def mock_verify(function) func_name = function[:name] " if (Mock.#{func_name}_CallbackFunctionPointer != NULL)\n {\n" \ " call_instance = CMOCK_GUTS_NONE;\n" \ " (void)call_instance;\n }\n" end end