summaryrefslogtreecommitdiffstats
path: root/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/lib
diff options
context:
space:
mode:
authorJoey Castillo <jose.castillo@gmail.com>2021-08-28 12:50:18 -0400
committerJoey Castillo <jose.castillo@gmail.com>2021-08-28 12:50:18 -0400
commit39a5c822a2a2e798e2e39ff8a98b7af84253026c (patch)
treefa157c98d3aea0d4f996e4415aa2a7ad1093ac05 /tinyusb/test/vendor/ceedling/plugins/fake_function_framework/lib
parentc9e00b83bbdcb05058806d915ec4fff3cf4e596f (diff)
downloadSensor-Watch-39a5c822a2a2e798e2e39ff8a98b7af84253026c.tar.gz
Sensor-Watch-39a5c822a2a2e798e2e39ff8a98b7af84253026c.tar.bz2
Sensor-Watch-39a5c822a2a2e798e2e39ff8a98b7af84253026c.zip
add tinyusb
Diffstat (limited to 'tinyusb/test/vendor/ceedling/plugins/fake_function_framework/lib')
-rwxr-xr-xtinyusb/test/vendor/ceedling/plugins/fake_function_framework/lib/fake_function_framework.rb87
-rwxr-xr-xtinyusb/test/vendor/ceedling/plugins/fake_function_framework/lib/fff_mock_generator.rb163
2 files changed, 250 insertions, 0 deletions
diff --git a/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/lib/fake_function_framework.rb b/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/lib/fake_function_framework.rb
new file mode 100755
index 00000000..51a90b3a
--- /dev/null
+++ b/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/lib/fake_function_framework.rb
@@ -0,0 +1,87 @@
+require 'ceedling/plugin'
+require 'fff_mock_generator'
+
+class FakeFunctionFramework < Plugin
+
+ # Set up Ceedling to use this plugin.
+ def setup
+ # Get the location of this plugin.
+ @plugin_root = File.expand_path(File.join(File.dirname(__FILE__), '..'))
+ puts "Using fake function framework (fff)..."
+
+ # Switch out the cmock_builder with our own.
+ @ceedling[:cmock_builder].cmock = FffMockGeneratorForCMock.new(@ceedling[:setupinator].config_hash[:cmock])
+
+ # Add the path to fff.h to the include paths.
+ COLLECTION_PATHS_TEST_SUPPORT_SOURCE_INCLUDE_VENDOR << "#{@plugin_root}/vendor/fff"
+ COLLECTION_PATHS_TEST_SUPPORT_SOURCE_INCLUDE_VENDOR << "#{@plugin_root}/src"
+ end
+
+ def post_runner_generate(arg_hash)
+ # After the test runner file has been created, append the FFF globals
+ # definition to the end of the test runner. These globals will be shared by
+ # all mocks linked into the test.
+ File.open(arg_hash[:runner_file], 'a') do |f|
+ f.puts
+ f.puts "//=======Defintions of FFF variables====="
+ f.puts %{#include "fff.h"}
+ f.puts "DEFINE_FFF_GLOBALS;"
+ end
+ end
+
+end # class FakeFunctionFramework
+
+class FffMockGeneratorForCMock
+
+ def initialize(options=nil)
+ @cm_config = CMockConfig.new(options)
+ @cm_parser = CMockHeaderParser.new(@cm_config)
+ @silent = (@cm_config.verbosity < 2)
+
+ # These are the additional files to include in the mock files.
+ @includes_h_pre_orig_header = (@cm_config.includes || @cm_config.includes_h_pre_orig_header || []).map{|h| h =~ /</ ? h : "\"#{h}\""}
+ @includes_h_post_orig_header = (@cm_config.includes_h_post_orig_header || []).map{|h| h =~ /</ ? h : "\"#{h}\""}
+ @includes_c_pre_header = (@cm_config.includes_c_pre_header || []).map{|h| h =~ /</ ? h : "\"#{h}\""}
+ @includes_c_post_header = (@cm_config.includes_c_post_header || []).map{|h| h =~ /</ ? h : "\"#{h}\""}
+ end
+
+ def setup_mocks(files)
+ [files].flatten.each do |src|
+ generate_mock (src)
+ end
+ end
+
+ def generate_mock (header_file_to_mock)
+ module_name = File.basename(header_file_to_mock, '.h')
+ puts "Creating mock for #{module_name}..." unless @silent
+ mock_name = @cm_config.mock_prefix + module_name + @cm_config.mock_suffix
+ mock_path = @cm_config.mock_path
+ if @cm_config.subdir
+ # If a subdirectory has been configured, append it to the mock path.
+ mock_path = "#{mock_path}/#{@cm_config.subdir}"
+ end
+ full_path_for_mock = "#{mock_path}/#{mock_name}"
+
+ # Parse the header file so we know what to mock.
+ parsed_header = @cm_parser.parse(module_name, File.read(header_file_to_mock))
+
+ # Create the directory if it doesn't exist.
+ mkdir_p full_path_for_mock.pathmap("%d")
+
+ # Generate the mock header file.
+ puts "Creating mock: #{full_path_for_mock}.h"
+
+ # Create the mock header.
+ File.open("#{full_path_for_mock}.h", 'w') do |f|
+ f.write(FffMockGenerator.create_mock_header(module_name, mock_name, parsed_header,
+ @includes_h_pre_orig_header, @includes_h_post_orig_header))
+ end
+
+ # Create the mock source file.
+ File.open("#{full_path_for_mock}.c", 'w') do |f|
+ f.write(FffMockGenerator.create_mock_source(mock_name, parsed_header,
+ @includes_c_pre_orig_header, @includes_c_post_orig_header))
+ end
+ end
+
+end
diff --git a/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/lib/fff_mock_generator.rb b/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/lib/fff_mock_generator.rb
new file mode 100755
index 00000000..9dc03a65
--- /dev/null
+++ b/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/lib/fff_mock_generator.rb
@@ -0,0 +1,163 @@
+# Creates mock files from parsed header files that can be linked into applications.
+# The mocks created are compatible with CMock for use with Ceedling.
+
+class FffMockGenerator
+
+ def self.create_mock_header(module_name, mock_name, parsed_header, pre_includes=nil,
+ post_includes=nil)
+ output = StringIO.new
+ write_opening_include_guard(mock_name, output)
+ output.puts
+ write_extra_includes(pre_includes, output)
+ write_header_includes(module_name, output)
+ write_extra_includes(post_includes, output)
+ output.puts
+ write_typedefs(parsed_header, output)
+ output.puts
+ write_function_declarations(parsed_header, output)
+ output.puts
+ write_control_function_prototypes(mock_name, output)
+ output.puts
+ write_closing_include_guard(mock_name, output)
+ output.string
+ end
+
+ def self.create_mock_source (mock_name, parsed_header, pre_includes=nil,
+ post_includes=nil)
+ output = StringIO.new
+ write_extra_includes(pre_includes, output)
+ write_source_includes(mock_name, output)
+ write_extra_includes(post_includes, output)
+ output.puts
+ write_function_definitions(parsed_header, output)
+ output.puts
+ write_control_function_definitions(mock_name, parsed_header, output)
+ output.string
+ end
+
+ private
+
+# Header file generation functions.
+
+ def self.write_opening_include_guard(mock_name, output)
+ output.puts "#ifndef #{mock_name}_H"
+ output.puts "#define #{mock_name}_H"
+ end
+
+ def self.write_header_includes(module_name, output)
+ output.puts %{#include "fff.h"}
+ output.puts %{#include "fff_unity_helper.h"}
+ output.puts %{#include "#{module_name}.h"}
+ end
+
+ def self.write_typedefs(parsed_header, output)
+ return unless parsed_header.key?(:typedefs)
+ parsed_header[:typedefs].each do |typedef|
+ output.puts typedef
+ end
+ end
+
+ def self.write_function_declarations(parsed_header, output)
+ write_function_macros("DECLARE", parsed_header, output)
+ end
+
+
+ def self.write_control_function_prototypes(mock_name, output)
+ output.puts "void #{mock_name}_Init(void);"
+ output.puts "void #{mock_name}_Verify(void);"
+ output.puts "void #{mock_name}_Destroy(void);"
+ end
+
+ def self.write_closing_include_guard(mock_name, output)
+ output.puts "#endif // #{mock_name}_H"
+ end
+
+# Source file generation functions.
+
+ def self.write_source_includes (mock_name, output)
+ output.puts "#include <string.h>"
+ output.puts %{#include "fff.h"}
+ output.puts %{#include "#{mock_name}.h"}
+ end
+
+ def self.write_function_definitions(parsed_header, output)
+ write_function_macros("DEFINE", parsed_header, output)
+ end
+
+ def self.write_control_function_definitions(mock_name, parsed_header, output)
+ output.puts "void #{mock_name}_Init(void)"
+ output.puts "{"
+ # In the init function, reset the FFF globals. These are used for things
+ # like the call history.
+ output.puts " FFF_RESET_HISTORY();"
+
+ # Also, reset all of the fakes.
+ if parsed_header[:functions]
+ parsed_header[:functions].each do |function|
+ output.puts " RESET_FAKE(#{function[:name]})"
+ end
+ end
+ output.puts "}"
+ output.puts "void #{mock_name}_Verify(void)"
+ output.puts "{"
+ output.puts "}"
+ output.puts "void #{mock_name}_Destroy(void)"
+ output.puts "{"
+ output.puts "}"
+ end
+
+# Shared functions.
+
+ def self.write_extra_includes(includes, output)
+ if includes
+ includes.each {|inc| output.puts "#include #{inc}\n"}
+ end
+ end
+
+ def self.write_function_macros(macro_type, parsed_header, output)
+ return unless parsed_header.key?(:functions)
+ parsed_header[:functions].each do |function|
+ name = function[:name]
+ return_type = function[:return][:type]
+ if function.has_key? :modifier
+ # Prepend any modifier. If there isn't one, trim any leading whitespace.
+ return_type = "#{function[:modifier]} #{return_type}".lstrip
+ end
+ arg_count = function[:args].size
+
+ # Check for variable arguments.
+ var_arg_suffix = ""
+ if function[:var_arg]
+ # If there are are variable arguments, then we need to add this argument
+ # to the count, update the suffix that will get added to the macro.
+ arg_count += 1
+ var_arg_suffix = "_VARARG"
+ end
+
+ # Generate the correct macro.
+ if return_type == 'void'
+ output.print "#{macro_type}_FAKE_VOID_FUNC#{arg_count}#{var_arg_suffix}(#{name}"
+ else
+ output.print "#{macro_type}_FAKE_VALUE_FUNC#{arg_count}#{var_arg_suffix}(#{return_type}, #{name}"
+ end
+
+ # Append each argument type.
+ function[:args].each do |arg|
+ output.print ", "
+ if arg[:const?]
+ output.print "const "
+ end
+ output.print "#{arg[:type]}"
+ end
+
+ # If this argument list ends with a variable argument, add it here at the end.
+ if function[:var_arg]
+ output.print ", ..."
+ end
+
+ # Close the declaration.
+ output.puts ");"
+ end
+ end
+
+end