summaryrefslogtreecommitdiffstats
path: root/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/lib/fff_mock_generator.rb
diff options
context:
space:
mode:
Diffstat (limited to 'tinyusb/test/vendor/ceedling/plugins/fake_function_framework/lib/fff_mock_generator.rb')
-rwxr-xr-xtinyusb/test/vendor/ceedling/plugins/fake_function_framework/lib/fff_mock_generator.rb163
1 files changed, 163 insertions, 0 deletions
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