diff --git a/.cproject b/.cproject
index f6e368e1c..93870fc27 100644
--- a/.cproject
+++ b/.cproject
@@ -269,294 +269,7 @@
-
-
- rake.bat
- test:all
- true
- false
- true
-
-
- rake.bat
-
- clean
- true
- false
- true
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- rake.bat
- test:all
- true
- false
- true
-
-
- rake.bat
-
- clean
- true
- false
- true
-
-
+
diff --git a/.project b/.project
index 38841f49c..f33b2e593 100644
--- a/.project
+++ b/.project
@@ -29,10 +29,6 @@
org.eclipse.cdt.make.core.buildCommand
make
-
- org.eclipse.cdt.make.core.buildLocation
- ${workspace_loc:/tinyusb/test}
-
org.eclipse.cdt.make.core.cleanBuildTarget
clean
diff --git a/tests/.cproject b/tests/.cproject
new file mode 100644
index 000000000..e86cdee98
--- /dev/null
+++ b/tests/.cproject
@@ -0,0 +1,199 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ rake.bat
+
+ default
+ true
+ false
+ true
+
+
+ rake.bat
+
+ test:all
+ true
+ false
+ true
+
+
+ rake.bat
+ test:delta
+ true
+ false
+ true
+
+
+ rake.bat
+
+ clean
+ true
+ false
+ true
+
+
+
+
+
+
+
+
+
diff --git a/tests/.project b/tests/.project
new file mode 100644
index 000000000..fe66302d6
--- /dev/null
+++ b/tests/.project
@@ -0,0 +1,82 @@
+
+
+ tests
+
+
+
+
+
+ org.eclipse.cdt.managedbuilder.core.genmakebuilder
+ clean,full,incremental,
+
+
+ ?name?
+
+
+
+ org.eclipse.cdt.make.core.append_environment
+ true
+
+
+ org.eclipse.cdt.make.core.autoBuildTarget
+ all
+
+
+ org.eclipse.cdt.make.core.buildArguments
+
+
+
+ org.eclipse.cdt.make.core.buildCommand
+ make
+
+
+ org.eclipse.cdt.make.core.buildLocation
+ ${workspace_loc:/tests/Default}
+
+
+ org.eclipse.cdt.make.core.cleanBuildTarget
+ clean
+
+
+ org.eclipse.cdt.make.core.contents
+ org.eclipse.cdt.make.core.activeConfigSettings
+
+
+ org.eclipse.cdt.make.core.enableAutoBuild
+ false
+
+
+ org.eclipse.cdt.make.core.enableCleanBuild
+ true
+
+
+ org.eclipse.cdt.make.core.enableFullBuild
+ true
+
+
+ org.eclipse.cdt.make.core.fullBuildTarget
+ all
+
+
+ org.eclipse.cdt.make.core.stopOnError
+ true
+
+
+ org.eclipse.cdt.make.core.useDefaultBuildCmd
+ true
+
+
+
+
+ org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder
+ full,incremental,
+
+
+
+
+
+ org.eclipse.cdt.core.cnature
+ org.eclipse.cdt.managedbuilder.core.managedBuildNature
+ org.eclipse.cdt.managedbuilder.core.ScannerConfigNature
+
+
diff --git a/tests/project.yml b/tests/project.yml
new file mode 100644
index 000000000..f09d1facd
--- /dev/null
+++ b/tests/project.yml
@@ -0,0 +1,78 @@
+---
+
+# Notes:
+# Sample project C code is not presently written to produce a release artifact.
+# As such, release build options are disabled.
+# This sample, therefore, only demonstrates running a collection of unit tests.
+
+:project:
+ :use_exceptions: FALSE
+ :use_test_preprocessor: TRUE
+ :use_auxiliary_dependencies: TRUE
+ :use_deep_dependencies: FALSE
+ :build_root: build
+# :release_build: TRUE
+ :test_file_prefix: test_
+
+:release_build:
+ :output: test_tinyusb.exe
+ :use_assembly: FALSE
+
+:environment:
+
+:extension:
+ :executable: .exe
+
+:paths:
+ :test:
+ - +:test/**
+ - -:test/support
+ :source:
+ - src/**
+ - ../../tinyusb/**
+ - ../../../CMSISv2p10_LPC43xx_DriverLib/inc
+ :support:
+ - test/support
+
+:defines:
+ # in order to add common defines:
+ # 1) remove the trailing [] from the :common: section
+ # 2) add entries to the :common: section (e.g. :test: has TEST defined)
+ :commmon: &common_defines []
+ :test:
+ - *common_defines
+ - _TEST_
+ - MCU=MCU_LPC43XX
+ - CORE_M4
+ :test_preprocess:
+ - *common_defines
+ - _TEST_
+ - MCU=MCU_LPC43XX
+ - CORE_M4
+
+:cmock:
+ :mock_prefix: mock_
+ :when_no_prototypes: :warn
+ :enforce_strict_ordering: TRUE
+ :plugins:
+ - :ignore
+ - :callback
+ :treat_as:
+ uint8: HEX8
+ uint16: HEX16
+ uint32: UINT32
+ int8: INT8
+ bool: UINT8
+
+#:tools:
+# Ceedling defaults to using gcc for compiling, linking, etc.
+# As [:tools] is blank, gcc will be used (so long as it's in your system path)
+# See documentation to configure a given toolchain for use
+
+:plugins:
+ :load_paths:
+ - vendor/ceedling/plugins
+ :enabled:
+ - stdout_pretty_tests_report
+ - module_generator
+...
diff --git a/tests/rakefile.rb b/tests/rakefile.rb
new file mode 100644
index 000000000..563d2e0d3
--- /dev/null
+++ b/tests/rakefile.rb
@@ -0,0 +1,4 @@
+PROJECT_CEEDLING_ROOT = "vendor/ceedling"
+load "#{PROJECT_CEEDLING_ROOT}/lib/rakefile.rb"
+
+task :default => %w[ test:all release ]
diff --git a/tests/test/test_hid_host.c b/tests/test/test_hid_host.c
new file mode 100644
index 000000000..4c74109b3
--- /dev/null
+++ b/tests/test/test_hid_host.c
@@ -0,0 +1,56 @@
+/*
+ * test_main.c
+ *
+ * Created on: Dec 18, 2012
+ * Author: hathach
+ */
+
+/*
+ * Software License Agreement (BSD License)
+ * Copyright (c) 2012, hathach (tinyusb.net)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the tiny usb stack.
+ */
+
+#include "unity.h"
+
+void setUp(void)
+{
+}
+
+void tearDown(void)
+{
+}
+
+void test_always_succeed()
+{
+
+}
+
+void test_always_fail()
+{
+ TEST_FAIL();
+}
diff --git a/tests/vendor/ceedling/docs/CExceptionSummary.pdf b/tests/vendor/ceedling/docs/CExceptionSummary.pdf
new file mode 100644
index 000000000..70c28a64c
Binary files /dev/null and b/tests/vendor/ceedling/docs/CExceptionSummary.pdf differ
diff --git a/tests/vendor/ceedling/docs/CMock Summary.pdf b/tests/vendor/ceedling/docs/CMock Summary.pdf
new file mode 100644
index 000000000..21f58e896
Binary files /dev/null and b/tests/vendor/ceedling/docs/CMock Summary.pdf differ
diff --git a/tests/vendor/ceedling/docs/CeedlingPacket.pdf b/tests/vendor/ceedling/docs/CeedlingPacket.pdf
new file mode 100644
index 000000000..b27381b58
Binary files /dev/null and b/tests/vendor/ceedling/docs/CeedlingPacket.pdf differ
diff --git a/tests/vendor/ceedling/docs/Unity Summary.pdf b/tests/vendor/ceedling/docs/Unity Summary.pdf
new file mode 100644
index 000000000..b1e641987
Binary files /dev/null and b/tests/vendor/ceedling/docs/Unity Summary.pdf differ
diff --git a/tests/vendor/ceedling/lib/build_invoker_utils.rb b/tests/vendor/ceedling/lib/build_invoker_utils.rb
new file mode 100644
index 000000000..043c4048f
--- /dev/null
+++ b/tests/vendor/ceedling/lib/build_invoker_utils.rb
@@ -0,0 +1,27 @@
+require 'constants'
+
+
+class BuildInvokerUtils
+
+ constructor :configurator, :streaminator
+
+ def process_exception(exception, context, test_build=true)
+ if (exception.message =~ /Don't know how to build task '(.+)'/i)
+ error_header = "ERROR: Rake could not find file referenced in source"
+ error_header += " or test" if (test_build)
+ error_header += ": '#{$1}'. Possible stale dependency."
+
+ @streaminator.stderr_puts( error_header )
+
+ if (@configurator.project_use_deep_dependencies)
+ help_message = "Try fixing #include statements or adding missing file. Then run '#{REFRESH_TASK_ROOT}#{context.to_s}' task and try again."
+ @streaminator.stderr_puts( help_message )
+ end
+
+ raise ''
+ else
+ raise exception
+ end
+ end
+
+end
diff --git a/tests/vendor/ceedling/lib/cacheinator.rb b/tests/vendor/ceedling/lib/cacheinator.rb
new file mode 100644
index 000000000..47953dd99
--- /dev/null
+++ b/tests/vendor/ceedling/lib/cacheinator.rb
@@ -0,0 +1,42 @@
+
+class Cacheinator
+
+ constructor :cacheinator_helper, :file_path_utils, :file_wrapper, :yaml_wrapper
+
+ def cache_test_config(hash)
+ @yaml_wrapper.dump( @file_path_utils.form_test_build_cache_path( INPUT_CONFIGURATION_CACHE_FILE), hash )
+ end
+
+ def cache_release_config(hash)
+ @yaml_wrapper.dump( @file_path_utils.form_release_build_cache_path( INPUT_CONFIGURATION_CACHE_FILE ), hash )
+ end
+
+
+ def diff_cached_test_file( filepath )
+ cached_filepath = @file_path_utils.form_test_build_cache_path( filepath )
+
+ if (@file_wrapper.exist?( cached_filepath ) and (!@file_wrapper.compare( filepath, cached_filepath )))
+ @file_wrapper.cp(filepath, cached_filepath, {:preserve => false})
+ return filepath
+ elsif (!@file_wrapper.exist?( cached_filepath ))
+ @file_wrapper.cp(filepath, cached_filepath, {:preserve => false})
+ return filepath
+ end
+
+ return cached_filepath
+ end
+
+
+ def diff_cached_test_config?(hash)
+ cached_filepath = @file_path_utils.form_test_build_cache_path(INPUT_CONFIGURATION_CACHE_FILE)
+
+ return @cacheinator_helper.diff_cached_config?( cached_filepath, hash )
+ end
+
+ def diff_cached_release_config?(hash)
+ cached_filepath = @file_path_utils.form_release_build_cache_path(INPUT_CONFIGURATION_CACHE_FILE)
+
+ return @cacheinator_helper.diff_cached_config?( cached_filepath, hash )
+ end
+
+end
diff --git a/tests/vendor/ceedling/lib/cacheinator_helper.rb b/tests/vendor/ceedling/lib/cacheinator_helper.rb
new file mode 100644
index 000000000..cb0ef7813
--- /dev/null
+++ b/tests/vendor/ceedling/lib/cacheinator_helper.rb
@@ -0,0 +1,12 @@
+
+class CacheinatorHelper
+
+ constructor :file_wrapper, :yaml_wrapper
+
+ def diff_cached_config?(cached_filepath, hash)
+ return true if ( not @file_wrapper.exist?(cached_filepath) )
+ return true if ( (@file_wrapper.exist?(cached_filepath)) and (!(@yaml_wrapper.load(cached_filepath) == hash)) )
+ return false
+ end
+
+end
diff --git a/tests/vendor/ceedling/lib/ceedling.rb b/tests/vendor/ceedling/lib/ceedling.rb
new file mode 100644
index 000000000..ac4126077
--- /dev/null
+++ b/tests/vendor/ceedling/lib/ceedling.rb
@@ -0,0 +1,27 @@
+require 'rake'
+
+ERR_MSG = <"
+ # @private
+ CEXCEPTION = "<%= versions["CEXCEPTION"] %>"
+ # @private
+ CMOCK = "<%= versions["CMOCK"] %>"
+ # @private
+ UNITY = "<%= versions["UNITY"] %>"
+ end
+end
diff --git a/tests/vendor/ceedling/lib/cmock_builder.rb b/tests/vendor/ceedling/lib/cmock_builder.rb
new file mode 100644
index 000000000..4a74aa842
--- /dev/null
+++ b/tests/vendor/ceedling/lib/cmock_builder.rb
@@ -0,0 +1,15 @@
+require 'cmock'
+
+class CmockBuilder
+
+ attr_accessor :cmock
+
+ def setup
+ @cmock = nil
+ end
+
+ def manufacture(cmock_config)
+ @cmock = CMock.new(cmock_config)
+ end
+
+end
diff --git a/tests/vendor/ceedling/lib/configurator.rb b/tests/vendor/ceedling/lib/configurator.rb
new file mode 100644
index 000000000..d54f97e73
--- /dev/null
+++ b/tests/vendor/ceedling/lib/configurator.rb
@@ -0,0 +1,329 @@
+require 'defaults'
+require 'constants'
+require 'file_path_utils'
+require 'deep_merge'
+
+
+
+class Configurator
+
+ attr_reader :project_config_hash, :script_plugins, :rake_plugins
+ attr_accessor :project_logging, :project_debug, :project_verbosity, :sanity_checks
+
+ constructor(:configurator_setup, :configurator_builder, :configurator_plugins, :cmock_builder, :yaml_wrapper, :system_wrapper) do
+ @project_logging = false
+ @project_debug = false
+ @project_verbosity = Verbosity::NORMAL
+ @sanity_checks = TestResultsSanityChecks::NORMAL
+ end
+
+ def setup
+ # special copy of cmock config to provide to cmock for construction
+ @cmock_config_hash = {}
+
+ # note: project_config_hash is an instance variable so constants and accessors created
+ # in eval() statements in build() have something of proper scope and persistence to reference
+ @project_config_hash = {}
+ @project_config_hash_backup = {}
+
+ @script_plugins = []
+ @rake_plugins = []
+ end
+
+
+ def replace_flattened_config(config)
+ @project_config_hash.merge!(config)
+ @configurator_setup.build_constants_and_accessors(@project_config_hash, binding())
+ end
+
+
+ def store_config
+ @project_config_hash_backup = @project_config_hash.clone
+ end
+
+
+ def restore_config
+ @project_config_hash = @project_config_hash_backup
+ @configurator_setup.build_constants_and_accessors(@project_config_hash, binding())
+ end
+
+
+ def reset_defaults(config)
+ [:test_compiler,
+ :test_linker,
+ :test_fixture,
+ :test_includes_preprocessor,
+ :test_file_preprocessor,
+ :test_dependencies_generator,
+ :release_compiler,
+ :release_assembler,
+ :release_linker,
+ :release_dependencies_generator].each do |tool|
+ config[:tools].delete(tool) if (not (config[:tools][tool].nil?))
+ end
+ end
+
+
+ def populate_defaults(config)
+ new_config = DEFAULT_CEEDLING_CONFIG.deep_clone
+ new_config.deep_merge!(config)
+ config.replace(new_config)
+
+ @configurator_builder.populate_defaults( config, DEFAULT_TOOLS_TEST )
+ @configurator_builder.populate_defaults( config, DEFAULT_TOOLS_TEST_PREPROCESSORS ) if (config[:project][:use_test_preprocessor])
+ @configurator_builder.populate_defaults( config, DEFAULT_TOOLS_TEST_DEPENDENCIES ) if (config[:project][:use_deep_dependencies])
+
+ @configurator_builder.populate_defaults( config, DEFAULT_TOOLS_RELEASE ) if (config[:project][:release_build])
+ @configurator_builder.populate_defaults( config, DEFAULT_TOOLS_RELEASE_ASSEMBLER ) if (config[:project][:release_build] and config[:release_build][:use_assembly])
+ @configurator_builder.populate_defaults( config, DEFAULT_TOOLS_RELEASE_DEPENDENCIES ) if (config[:project][:release_build] and config[:project][:use_deep_dependencies])
+ end
+
+
+ def populate_cmock_defaults(config)
+ # cmock has its own internal defaults handling, but we need to set these specific values
+ # so they're present for the build environment to access;
+ # note: these need to end up in the hash given to initialize cmock for this to be successful
+ cmock = config[:cmock] || {}
+
+ # yes, we're duplicating the default mock_prefix in cmock, but it's because we need CMOCK_MOCK_PREFIX always available in Ceedling's environment
+ cmock[:mock_prefix] = 'Mock' if (cmock[:mock_prefix].nil?)
+
+ # just because strict ordering is the way to go
+ cmock[:enforce_strict_ordering] = true if (cmock[:enforce_strict_ordering].nil?)
+
+ cmock[:mock_path] = File.join(config[:project][:build_root], TESTS_BASE_PATH, 'mocks') if (cmock[:mock_path].nil?)
+ cmock[:verbosity] = @project_verbosity if (cmock[:verbosity].nil?)
+
+ cmock[:plugins] = [] if (cmock[:plugins].nil?)
+ cmock[:plugins].map! { |plugin| plugin.to_sym }
+ cmock[:plugins] << (:cexception) if (!cmock[:plugins].include?(:cexception) and (config[:project][:use_exceptions]))
+ cmock[:plugins].uniq!
+
+ cmock[:unity_helper] = false if (cmock[:unity_helper].nil?)
+
+ if (cmock[:unity_helper])
+ cmock[:includes] << File.basename(cmock[:unity_helper])
+ cmock[:includes].uniq!
+ end
+
+ @runner_config = cmock.merge(config[:test_runner] || {})
+ @cmock_builder.manufacture(cmock)
+ end
+
+
+ def get_runner_config
+ @runner_config
+ end
+
+
+ # grab tool names from yaml and insert into tool structures so available for error messages
+ # set up default values
+ def tools_setup(config)
+ config[:tools].each_key do |name|
+ tool = config[:tools][name]
+
+ # populate name if not given
+ tool[:name] = name.to_s if (tool[:name].nil?)
+
+ # populate stderr redirect option
+ tool[:stderr_redirect] = StdErrRedirect::NONE if (tool[:stderr_redirect].nil?)
+
+ # populate background execution option
+ tool[:background_exec] = BackgroundExec::NONE if (tool[:background_exec].nil?)
+
+ # populate optional option to control verification of executable in search paths
+ tool[:optional] = false if (tool[:optional].nil?)
+ end
+ end
+
+
+ def tools_supplement_arguments(config)
+ tools_name_prefix = 'tools_'
+ config[:tools].each_key do |name|
+ tool = @project_config_hash[(tools_name_prefix + name.to_s).to_sym]
+
+ # smoosh in extra arguments if specified at top-level of config (useful for plugins & default gcc tools)
+ # arguments are squirted in at beginning of list
+ top_level_tool = (tools_name_prefix + name.to_s).to_sym
+ if (not config[top_level_tool].nil?)
+ # adding and flattening is not a good idea: might over-flatten if there's array nesting in tool args
+ # use _with_index to preserve order
+ config[top_level_tool][:arguments].each_with_index { |arg, index| tool[:arguments].insert( index, arg ) }
+ end
+ end
+ end
+
+
+ def find_and_merge_plugins(config)
+ # plugins must be loaded before generic path evaluation & magic that happen later;
+ # perform path magic here as discrete step
+ config[:plugins][:load_paths].each do |path|
+ path.replace(@system_wrapper.module_eval(path)) if (path =~ RUBY_STRING_REPLACEMENT_PATTERN)
+ FilePathUtils::standardize(path)
+ end
+
+ paths_hash = @configurator_plugins.add_load_paths(config)
+
+ @rake_plugins = @configurator_plugins.find_rake_plugins(config)
+ @script_plugins = @configurator_plugins.find_script_plugins(config)
+ config_plugins = @configurator_plugins.find_config_plugins(config)
+ plugin_defaults = @configurator_plugins.find_plugin_defaults(config)
+
+ config_plugins.each do |plugin|
+ config.deep_merge( @yaml_wrapper.load(plugin) )
+ end
+
+ plugin_defaults.each do |defaults|
+ @configurator_builder.populate_defaults( config, @yaml_wrapper.load(defaults) )
+ end
+
+ # special plugin setting for results printing
+ config[:plugins][:display_raw_test_results] = true if (config[:plugins][:display_raw_test_results].nil?)
+
+ paths_hash.each_pair { |name, path| config[:plugins][name] = path }
+ end
+
+
+ def eval_environment_variables(config)
+ config[:environment].each do |hash|
+ key = hash.keys[0]
+ value = hash[key]
+ items = []
+
+ interstitial = ((key == :path) ? File::PATH_SEPARATOR : '')
+ items = ((value.class == Array) ? hash[key] : [value])
+
+ items.each { |item| item.replace( @system_wrapper.module_eval( item ) ) if (item =~ RUBY_STRING_REPLACEMENT_PATTERN) }
+ hash[key] = items.join( interstitial )
+
+ @system_wrapper.env_set( key.to_s.upcase, hash[key] )
+ end
+ end
+
+
+ def eval_paths(config)
+ # [:plugins]:[load_paths] already handled
+
+ paths = [ # individual paths that don't follow convention processed below
+ config[:project][:build_root],
+ config[:release_build][:artifacts]]
+
+ eval_path_list( paths )
+
+ config[:paths].each_pair { |collection, paths| eval_path_list( paths ) }
+
+ config[:files].each_pair { |collection, files| eval_path_list( paths ) }
+
+ # all other paths at secondary hash key level processed by convention:
+ # ex. [:toplevel][:foo_path] & [:toplevel][:bar_paths] are evaluated
+ config.each_pair { |parent, child| eval_path_list( collect_path_list( child ) ) }
+ end
+
+
+ def standardize_paths(config)
+ # [:plugins]:[load_paths] already handled
+
+ paths = [ # individual paths that don't follow convention processed below
+ config[:project][:build_root],
+ config[:release_build][:artifacts]] # cmock path in case it was explicitly set in config
+
+ paths.flatten.each { |path| FilePathUtils::standardize( path ) }
+
+ config[:paths].each_pair do |collection, paths|
+ paths.each{|path| FilePathUtils::standardize( path )}
+ # ensure that list is an array (i.e. handle case of list being a single string)
+ config[:paths][collection] = [paths].flatten
+ end
+
+ config[:files].each_pair { |collection, files| files.each{ |path| FilePathUtils::standardize( path ) } }
+
+ config[:tools].each_pair { |tool, config| FilePathUtils::standardize( config[:executable] ) }
+
+ # all other paths at secondary hash key level processed by convention:
+ # ex. [:toplevel][:foo_path] & [:toplevel][:bar_paths] are standardized
+ config.each_pair do |parent, child|
+ collect_path_list( child ).each { |path| FilePathUtils::standardize( path ) }
+ end
+ end
+
+
+ def validate(config)
+ # collect felonies and go straight to jail
+ raise if (not @configurator_setup.validate_required_sections( config ))
+
+ # collect all misdemeanors, everybody on probation
+ blotter = []
+ blotter << @configurator_setup.validate_required_section_values( config )
+ blotter << @configurator_setup.validate_paths( config )
+ blotter << @configurator_setup.validate_tools( config )
+ blotter << @configurator_setup.validate_plugins( config )
+
+ raise if (blotter.include?( false ))
+ end
+
+
+ # create constants and accessors (attached to this object) from given hash
+ def build(config, *keys)
+ # create flattened & expanded configuration hash
+ built_config = @configurator_setup.build_project_config( config, @configurator_builder.flattenify( config ) )
+
+ @project_config_hash = built_config.clone
+ store_config()
+
+ @configurator_setup.build_constants_and_accessors(built_config, binding())
+
+ # top-level keys disappear when we flatten, so create global constants & accessors to any specified keys
+ keys.each do |key|
+ hash = { key => config[key] }
+ @configurator_setup.build_constants_and_accessors(hash, binding())
+ end
+ end
+
+
+ # add to constants and accessors as post build step
+ def build_supplement(config_base, config_more)
+ # merge in our post-build additions to base configuration hash
+ config_base.deep_merge!( config_more )
+
+ # flatten our addition hash
+ config_more_flattened = @configurator_builder.flattenify( config_more )
+
+ # merge our flattened hash with built hash from previous build
+ @project_config_hash.deep_merge!( config_more_flattened )
+ store_config()
+
+ # create more constants and accessors
+ @configurator_setup.build_constants_and_accessors(config_more_flattened, binding())
+
+ # recreate constants & update accessors with new merged, base values
+ config_more.keys.each do |key|
+ hash = { key => config_base[key] }
+ @configurator_setup.build_constants_and_accessors(hash, binding())
+ end
+ end
+
+
+ def insert_rake_plugins(plugins)
+ plugins.each do |plugin|
+ @project_config_hash[:project_rakefile_component_files] << plugin
+ end
+ end
+
+ ### private ###
+
+ private
+
+ def collect_path_list( container )
+ paths = []
+ container.each_key { |key| paths << container[key] if (key.to_s =~ /_path(s)?$/) } if (container.class == Hash)
+ return paths.flatten
+ end
+
+ def eval_path_list( paths )
+ paths.flatten.each do |path|
+ path.replace( @system_wrapper.module_eval( path ) ) if (path =~ RUBY_STRING_REPLACEMENT_PATTERN)
+ end
+ end
+
+
+end
diff --git a/tests/vendor/ceedling/lib/configurator_builder.rb b/tests/vendor/ceedling/lib/configurator_builder.rb
new file mode 100644
index 000000000..03380ed73
--- /dev/null
+++ b/tests/vendor/ceedling/lib/configurator_builder.rb
@@ -0,0 +1,437 @@
+require 'rubygems'
+require 'rake' # for ext() method
+require 'file_path_utils' # for class methods
+require 'defaults'
+require 'constants' # for Verbosity constants class & base file paths
+
+
+
+class ConfiguratorBuilder
+
+ constructor :file_system_utils, :file_wrapper, :system_wrapper
+
+
+ def build_global_constants(config)
+ config.each_pair do |key, value|
+ formatted_key = key.to_s.upcase
+ # undefine global constant if it already exists
+ Object.send(:remove_const, formatted_key.to_sym) if @system_wrapper.constants_include?(formatted_key)
+ # create global constant
+ Object.module_eval("#{formatted_key} = value")
+ end
+ end
+
+
+ def build_accessor_methods(config, context)
+ config.each_pair do |key, value|
+ # fill configurator object with accessor methods
+ eval("def #{key.to_s.downcase}() return @project_config_hash[:#{key.to_s}] end", context)
+ end
+ end
+
+
+ # create a flattened hash from the original configuration structure
+ def flattenify(config)
+ new_hash = {}
+
+ config.each_key do | parent |
+
+ # gracefully handle empty top-level entries
+ next if (config[parent].nil?)
+
+ case config[parent]
+ when Array
+ config[parent].each do |hash|
+ key = "#{parent.to_s.downcase}_#{hash.keys[0].to_s.downcase}".to_sym
+ new_hash[key] = hash[hash.keys[0]]
+ end
+ when Hash
+ config[parent].each_pair do | child, value |
+ key = "#{parent.to_s.downcase}_#{child.to_s.downcase}".to_sym
+ new_hash[key] = value
+ end
+ # handle entries with no children, only values
+ else
+ new_hash["#{parent.to_s.downcase}".to_sym] = config[parent]
+ end
+
+ end
+
+ return new_hash
+ end
+
+
+ def populate_defaults(config, defaults)
+ defaults.keys.sort.each do |section|
+ defaults[section].keys.sort.each do |entry|
+ config[section][entry] = defaults[section][entry].deep_clone if (config[section].nil? or config[section][entry].nil?)
+ end
+ end
+ end
+
+
+ def clean(in_hash)
+ # ensure that include files inserted into test runners have file extensions & proper ones at that
+ in_hash[:test_runner_includes].map!{|include| include.ext(in_hash[:extension_header])}
+ end
+
+
+ def set_build_paths(in_hash)
+ out_hash = {}
+
+ project_build_artifacts_root = File.join(in_hash[:project_build_root], 'artifacts')
+ project_build_tests_root = File.join(in_hash[:project_build_root], TESTS_BASE_PATH)
+ project_build_release_root = File.join(in_hash[:project_build_root], RELEASE_BASE_PATH)
+
+ paths = [
+ [:project_build_artifacts_root, project_build_artifacts_root, true ],
+ [:project_build_tests_root, project_build_tests_root, true ],
+ [:project_build_release_root, project_build_release_root, in_hash[:project_release_build] ],
+
+ [:project_test_artifacts_path, File.join(project_build_artifacts_root, TESTS_BASE_PATH), true ],
+ [:project_test_runners_path, File.join(project_build_tests_root, 'runners'), true ],
+ [:project_test_results_path, File.join(project_build_tests_root, 'results'), true ],
+ [:project_test_build_output_path, File.join(project_build_tests_root, 'out'), true ],
+ [:project_test_build_cache_path, File.join(project_build_tests_root, 'cache'), true ],
+ [:project_test_dependencies_path, File.join(project_build_tests_root, 'dependencies'), true ],
+
+ [:project_release_artifacts_path, File.join(project_build_artifacts_root, RELEASE_BASE_PATH), in_hash[:project_release_build] ],
+ [:project_release_build_cache_path, File.join(project_build_release_root, 'cache'), in_hash[:project_release_build] ],
+ [:project_release_build_output_path, File.join(project_build_release_root, 'out'), in_hash[:project_release_build] ],
+ [:project_release_build_output_asm_path, File.join(project_build_release_root, 'out', 'asm'), in_hash[:project_release_build] ],
+ [:project_release_build_output_c_path, File.join(project_build_release_root, 'out', 'c'), in_hash[:project_release_build] ],
+ [:project_release_dependencies_path, File.join(project_build_release_root, 'dependencies'), in_hash[:project_release_build] ],
+
+ [:project_log_path, File.join(in_hash[:project_build_root], 'logs'), true ],
+ [:project_temp_path, File.join(in_hash[:project_build_root], 'temp'), true ],
+
+ [:project_test_preprocess_includes_path, File.join(project_build_tests_root, 'preprocess/includes'), in_hash[:project_use_test_preprocessor] ],
+ [:project_test_preprocess_files_path, File.join(project_build_tests_root, 'preprocess/files'), in_hash[:project_use_test_preprocessor] ],
+ ]
+
+ out_hash[:project_build_paths] = []
+
+ # fetch already set mock path
+ out_hash[:project_build_paths] << in_hash[:cmock_mock_path] if (in_hash[:project_use_mocks])
+
+ paths.each do |path|
+ build_path_name = path[0]
+ build_path = path[1]
+ build_path_add_condition = path[2]
+
+ # insert path into build paths if associated with true condition
+ out_hash[:project_build_paths] << build_path if build_path_add_condition
+ # set path symbol name and path for each entry in paths array
+ out_hash[build_path_name] = build_path
+ end
+
+ return out_hash
+ end
+
+
+ def set_force_build_filepaths(in_hash)
+ out_hash = {}
+
+ out_hash[:project_test_force_rebuild_filepath] = File.join( in_hash[:project_test_dependencies_path], 'force_build' )
+ out_hash[:project_release_force_rebuild_filepath] = File.join( in_hash[:project_release_dependencies_path], 'force_build' ) if (in_hash[:project_release_build])
+
+ return out_hash
+ end
+
+
+ def set_rakefile_components(in_hash)
+ out_hash = {
+ :project_rakefile_component_files =>
+ [File.join(CEEDLING_LIB, 'tasks_base.rake'),
+ File.join(CEEDLING_LIB, 'tasks_filesystem.rake'),
+ File.join(CEEDLING_LIB, 'tasks_tests.rake'),
+ File.join(CEEDLING_LIB, 'tasks_vendor.rake'),
+ File.join(CEEDLING_LIB, 'rules_tests.rake')]}
+
+ out_hash[:project_rakefile_component_files] << File.join(CEEDLING_LIB, 'rules_cmock.rake') if (in_hash[:project_use_mocks])
+ out_hash[:project_rakefile_component_files] << File.join(CEEDLING_LIB, 'rules_preprocess.rake') if (in_hash[:project_use_test_preprocessor])
+ out_hash[:project_rakefile_component_files] << File.join(CEEDLING_LIB, 'rules_tests_deep_dependencies.rake') if (in_hash[:project_use_deep_dependencies])
+ out_hash[:project_rakefile_component_files] << File.join(CEEDLING_LIB, 'tasks_tests_deep_dependencies.rake') if (in_hash[:project_use_deep_dependencies])
+
+ out_hash[:project_rakefile_component_files] << File.join(CEEDLING_LIB, 'rules_release_deep_dependencies.rake') if (in_hash[:project_release_build] and in_hash[:project_use_deep_dependencies])
+ out_hash[:project_rakefile_component_files] << File.join(CEEDLING_LIB, 'rules_release.rake') if (in_hash[:project_release_build])
+ out_hash[:project_rakefile_component_files] << File.join(CEEDLING_LIB, 'tasks_release_deep_dependencies.rake') if (in_hash[:project_release_build] and in_hash[:project_use_deep_dependencies])
+ out_hash[:project_rakefile_component_files] << File.join(CEEDLING_LIB, 'tasks_release.rake') if (in_hash[:project_release_build])
+
+ return out_hash
+ end
+
+
+ def set_library_build_info_filepaths(hash)
+
+ # Notes:
+ # - Dependency on a change to our input configuration hash is handled elsewhere as it is
+ # dynamically formed during ceedling's execution
+ # - Compiled vendor dependencies like cmock.o, unity.o, cexception.o are handled below;
+ # here we're interested only in ceedling-based code generation dependencies
+
+ ceedling_build_info_filepath = File.join(CEEDLING_RELEASE, 'build.info')
+ cmock_build_info_filepath = FilePathUtils::form_ceedling_vendor_path('cmock/release', 'build.info')
+
+ out_hash = {
+ :ceedling_build_info_filepath => ceedling_build_info_filepath,
+ :cmock_build_info_filepath => cmock_build_info_filepath
+ }
+
+ return out_hash
+ end
+
+
+ def set_release_target(in_hash)
+ return {} if (not in_hash[:project_release_build])
+
+ release_target_file = ((in_hash[:release_build_output].nil?) ? (DEFAULT_RELEASE_TARGET_NAME.ext(in_hash[:extension_executable])) : in_hash[:release_build_output])
+ release_map_file = ((in_hash[:release_build_output].nil?) ? (DEFAULT_RELEASE_TARGET_NAME.ext(in_hash[:extension_map])) : in_hash[:release_build_output].ext(in_hash[:extension_map]))
+
+ return {
+ # tempted to make a helper method in file_path_utils? stop right there, pal. you'll introduce a cyclical dependency
+ :project_release_build_target => File.join(in_hash[:project_build_release_root], release_target_file),
+ :project_release_build_map => File.join(in_hash[:project_build_release_root], release_map_file)
+ }
+ end
+
+
+ def collect_project_options(in_hash)
+ options = []
+
+ in_hash[:project_options_paths].each do |path|
+ options << @file_wrapper.directory_listing( File.join(path, '*.yml') )
+ end
+
+ return {
+ :collection_project_options => options.flatten
+ }
+ end
+
+
+ def expand_all_path_globs(in_hash)
+ out_hash = {}
+ path_keys = []
+
+ in_hash.each_key do |key|
+ next if (not key.to_s[0..4] == 'paths')
+ path_keys << key
+ end
+
+ # sorted to provide assured order of traversal in test calls on mocks
+ path_keys.sort.each do |key|
+ out_hash["collection_#{key.to_s}".to_sym] = @file_system_utils.collect_paths( in_hash[key] )
+ end
+
+ return out_hash
+ end
+
+
+ def collect_source_and_include_paths(in_hash)
+ return {
+ :collection_paths_source_and_include =>
+ ( in_hash[:collection_paths_source] +
+ in_hash[:collection_paths_include] ).select {|x| File.directory?(x)}
+ }
+ end
+
+
+ def collect_source_include_vendor_paths(in_hash)
+ extra_paths = []
+ extra_paths << FilePathUtils::form_ceedling_vendor_path(CEXCEPTION_LIB_PATH) if (in_hash[:project_use_exceptions])
+
+ return {
+ :collection_paths_source_include_vendor =>
+ in_hash[:collection_paths_source_and_include] +
+ extra_paths
+ }
+ end
+
+
+ def collect_test_support_source_include_paths(in_hash)
+ return {
+ :collection_paths_test_support_source_include =>
+ (in_hash[:collection_paths_test] +
+ in_hash[:collection_paths_support] +
+ in_hash[:collection_paths_source] +
+ in_hash[:collection_paths_include] ).select {|x| File.directory?(x)}
+ }
+ end
+
+
+ def collect_vendor_paths(in_hash)
+ return {:collection_paths_vendor => get_vendor_paths(in_hash)}
+ end
+
+
+ def collect_test_support_source_include_vendor_paths(in_hash)
+ return {
+ :collection_paths_test_support_source_include_vendor =>
+ in_hash[:collection_paths_test_support_source_include] +
+ get_vendor_paths(in_hash)
+ }
+ end
+
+
+ def collect_tests(in_hash)
+ all_tests = @file_wrapper.instantiate_file_list
+
+ in_hash[:collection_paths_test].each do |path|
+ all_tests.include( File.join(path, "#{in_hash[:project_test_file_prefix]}*#{in_hash[:extension_source]}") )
+ end
+
+ @file_system_utils.revise_file_list( all_tests, in_hash[:files_test] )
+
+ return {:collection_all_tests => all_tests}
+ end
+
+
+ def collect_assembly(in_hash)
+ all_assembly = @file_wrapper.instantiate_file_list
+
+ return {:collection_all_assembly => all_assembly} if (not in_hash[:release_build_use_assembly])
+
+ in_hash[:collection_paths_source].each do |path|
+ all_assembly.include( File.join(path, "*#{in_hash[:extension_assembly]}") )
+ end
+
+ @file_system_utils.revise_file_list( all_assembly, in_hash[:files_assembly] )
+
+ return {:collection_all_assembly => all_assembly}
+ end
+
+
+ def collect_source(in_hash)
+ all_source = @file_wrapper.instantiate_file_list
+ in_hash[:collection_paths_source].each do |path|
+ if File.exists?(path) and not File.directory?(path)
+ all_source.include( path )
+ else
+ all_source.include( File.join(path, "*#{in_hash[:extension_source]}") )
+ end
+ end
+ @file_system_utils.revise_file_list( all_source, in_hash[:files_source] )
+
+ return {:collection_all_source => all_source}
+ end
+
+
+ def collect_headers(in_hash)
+ all_headers = @file_wrapper.instantiate_file_list
+
+ paths =
+ in_hash[:collection_paths_test] +
+ in_hash[:collection_paths_support] +
+ in_hash[:collection_paths_source] +
+ in_hash[:collection_paths_include]
+
+ paths.each do |path|
+ all_headers.include( File.join(path, "*#{in_hash[:extension_header]}") )
+ end
+
+ @file_system_utils.revise_file_list( all_headers, in_hash[:files_include] )
+
+ return {:collection_all_headers => all_headers}
+ end
+
+
+ def collect_all_existing_compilation_input(in_hash)
+ all_input = @file_wrapper.instantiate_file_list
+
+ paths =
+ in_hash[:collection_paths_test] +
+ in_hash[:collection_paths_support] +
+ in_hash[:collection_paths_source] +
+ in_hash[:collection_paths_include] +
+ [FilePathUtils::form_ceedling_vendor_path(UNITY_LIB_PATH)]
+
+ paths << FilePathUtils::form_ceedling_vendor_path(CEXCEPTION_LIB_PATH) if (in_hash[:project_use_exceptions])
+ paths << FilePathUtils::form_ceedling_vendor_path(CMOCK_LIB_PATH) if (in_hash[:project_use_mocks])
+
+ paths.each do |path|
+ all_input.include( File.join(path, "*#{in_hash[:extension_header]}") )
+ if File.exists?(path) and not File.directory?(path)
+ all_input.include( path )
+ else
+ all_input.include( File.join(path, "*#{in_hash[:extension_source]}") )
+ end
+ end
+
+ @file_system_utils.revise_file_list( all_input, in_hash[:files_test] )
+ @file_system_utils.revise_file_list( all_input, in_hash[:files_support] )
+ @file_system_utils.revise_file_list( all_input, in_hash[:files_source] )
+ @file_system_utils.revise_file_list( all_input, in_hash[:files_include] )
+ # finding assembly files handled explicitly through other means
+
+ return {:collection_all_existing_compilation_input => all_input}
+ end
+
+
+ def collect_test_and_vendor_defines(in_hash)
+ test_defines = in_hash[:defines_test].clone
+
+ test_defines.concat(in_hash[:unity_defines])
+ test_defines.concat(in_hash[:cmock_defines]) if (in_hash[:project_use_mocks])
+ test_defines.concat(in_hash[:cexception_defines]) if (in_hash[:project_use_exceptions])
+
+ return {:collection_defines_test_and_vendor => test_defines}
+ end
+
+
+ def collect_release_and_vendor_defines(in_hash)
+ release_defines = in_hash[:defines_release].clone
+
+ release_defines.concat(in_hash[:cexception_defines]) if (in_hash[:project_use_exceptions])
+
+ return {:collection_defines_release_and_vendor => release_defines}
+ end
+
+
+ def collect_release_artifact_extra_link_objects(in_hash)
+ objects = []
+
+ # no build paths here so plugins can remap if necessary (i.e. path mapping happens at runtime)
+ objects << CEXCEPTION_C_FILE.ext( in_hash[:extension_object] ) if (in_hash[:project_use_exceptions])
+
+ return {:collection_release_artifact_extra_link_objects => objects}
+ end
+
+
+ def collect_test_fixture_extra_link_objects(in_hash)
+ # Note: Symbols passed to compiler at command line can change Unity and CException behavior / configuration;
+ # we also handle those dependencies elsewhere in compilation dependencies
+
+ objects = [UNITY_C_FILE]
+
+ # we don't include paths here because use of plugins or mixing different compilers may require different build paths
+ objects << CEXCEPTION_C_FILE if (in_hash[:project_use_exceptions])
+ objects << CMOCK_C_FILE if (in_hash[:project_use_mocks])
+
+ # if we're using mocks & a unity helper is defined & that unity helper includes a source file component (not only a header of macros),
+ # then link in the unity_helper object file too
+ if ( in_hash[:project_use_mocks] and
+ in_hash[:cmock_unity_helper] and
+ @file_wrapper.exist?(in_hash[:cmock_unity_helper].ext(in_hash[:extension_source])) )
+ objects << File.basename(in_hash[:cmock_unity_helper])
+ end
+
+ # no build paths here so plugins can remap if necessary (i.e. path mapping happens at runtime)
+ objects.map! { |object| object.ext(in_hash[:extension_object]) }
+
+ return { :collection_test_fixture_extra_link_objects => objects }
+ end
+
+
+ private
+
+ def get_vendor_paths(in_hash)
+ vendor_paths = []
+ vendor_paths << FilePathUtils::form_ceedling_vendor_path(UNITY_LIB_PATH)
+ vendor_paths << FilePathUtils::form_ceedling_vendor_path(CEXCEPTION_LIB_PATH) if (in_hash[:project_use_exceptions])
+ vendor_paths << FilePathUtils::form_ceedling_vendor_path(CMOCK_LIB_PATH) if (in_hash[:project_use_mocks])
+ vendor_paths << in_hash[:cmock_mock_path] if (in_hash[:project_use_mocks])
+
+ return vendor_paths
+ end
+
+end
diff --git a/tests/vendor/ceedling/lib/configurator_plugins.rb b/tests/vendor/ceedling/lib/configurator_plugins.rb
new file mode 100644
index 000000000..19e40602e
--- /dev/null
+++ b/tests/vendor/ceedling/lib/configurator_plugins.rb
@@ -0,0 +1,124 @@
+require 'constants'
+
+class ConfiguratorPlugins
+
+ constructor :stream_wrapper, :file_wrapper, :system_wrapper
+ attr_reader :rake_plugins, :script_plugins
+
+ def setup
+ @rake_plugins = []
+ @script_plugins = []
+ end
+
+
+ def add_load_paths(config)
+ plugin_paths = {}
+
+ config[:plugins][:load_paths].each do |root|
+ @system_wrapper.add_load_path( root ) if ( not @file_wrapper.directory_listing( File.join( root, '*.rb' ) ).empty? )
+
+ config[:plugins][:enabled].each do |plugin|
+ path = File.join(root, plugin, "lib")
+ old_path = File.join( root, plugin )
+
+ if ( not @file_wrapper.directory_listing( File.join( path, '*.rb' ) ).empty? )
+ plugin_paths[(plugin + '_path').to_sym] = path
+ @system_wrapper.add_load_path( path )
+ elsif ( not @file_wrapper.directory_listing( File.join( old_path, '*.rb' ) ).empty? )
+ plugin_paths[(plugin + '_path').to_sym] = old_path
+ @system_wrapper.add_load_path( old_path )
+ end
+ end
+ end
+
+ return plugin_paths
+ end
+
+
+ # gather up and return .rake filepaths that exist on-disk
+ def find_rake_plugins(config)
+ plugins_with_path = []
+
+ config[:plugins][:load_paths].each do |root|
+ config[:plugins][:enabled].each do |plugin|
+ rake_plugin_path = File.join(root, plugin, "#{plugin}.rake")
+ if (@file_wrapper.exist?(rake_plugin_path))
+ plugins_with_path << rake_plugin_path
+ @rake_plugins << plugin
+ end
+ end
+ end
+
+ return plugins_with_path
+ end
+
+
+ # gather up and return just names of .rb classes that exist on-disk
+ def find_script_plugins(config)
+ config[:plugins][:load_paths].each do |root|
+ config[:plugins][:enabled].each do |plugin|
+ script_plugin_path = File.join(root, plugin, "lib", "#{plugin}.rb")
+
+ # Add the old path here to support legacy style. Eventaully remove.
+ old_script_plugin_path = File.join(root, plugin, "#{plugin}.rb")
+
+ if @file_wrapper.exist?(script_plugin_path) or @file_wrapper.exist?(old_script_plugin_path)
+ @script_plugins << plugin
+ end
+
+ # Print depreciation warning.
+ if @file_wrapper.exist?(old_script_plugin_path)
+ $stderr.puts "WARNING: Depreciated plugin style used in #{plugin}. Use new directory structure!"
+ end
+ end
+ end
+
+ return @script_plugins
+ end
+
+
+ # gather up and return configuration .yml filepaths that exist on-disk
+ def find_config_plugins(config)
+ plugins_with_path = []
+
+ config[:plugins][:load_paths].each do |root|
+ config[:plugins][:enabled].each do |plugin|
+ config_plugin_path = File.join(root, plugin, "config", "#{plugin}.yml")
+
+ # Add the old path here to support legacy style. Eventaully remove.
+ old_config_plugin_path = File.join(root, plugin, "#{plugin}.yml")
+
+ if @file_wrapper.exist?(config_plugin_path)
+ plugins_with_path << config_plugin_path
+ elsif @file_wrapper.exist?(old_config_plugin_path)
+ # there's a warning printed for this in find_script_plugins
+ plugins_with_path << old_config_plugin_path
+ end
+ end
+ end
+
+ return plugins_with_path
+ end
+
+
+ # gather up and return default .yml filepaths that exist on-disk
+ def find_plugin_defaults(config)
+ defaults_with_path = []
+
+ config[:plugins][:load_paths].each do |root|
+ config[:plugins][:enabled].each do |plugin|
+ default_path = File.join(root, plugin, 'config', 'defaults.yml')
+ old_default_path = File.join(root, plugin, 'defaults.yml')
+
+ if @file_wrapper.exist?(default_path)
+ defaults_with_path << default_path
+ elsif @file_wrapper.exist?(old_default_path)
+ defaults_with_path << old_default_path
+ end
+ end
+ end
+
+ return defaults_with_path
+ end
+
+end
diff --git a/tests/vendor/ceedling/lib/configurator_setup.rb b/tests/vendor/ceedling/lib/configurator_setup.rb
new file mode 100644
index 000000000..d6cf37737
--- /dev/null
+++ b/tests/vendor/ceedling/lib/configurator_setup.rb
@@ -0,0 +1,124 @@
+
+# add sort-ability to symbol so we can order keys array in hash for test-ability
+class Symbol
+ include Comparable
+
+ def <=>(other)
+ self.to_s <=> other.to_s
+ end
+end
+
+
+class ConfiguratorSetup
+
+ constructor :configurator_builder, :configurator_validator, :configurator_plugins, :stream_wrapper
+
+
+ def build_project_config(config, flattened_config)
+ ### flesh out config
+ @configurator_builder.clean(flattened_config)
+
+ ### add to hash values we build up from configuration & file system contents
+ flattened_config.merge!(@configurator_builder.set_build_paths(flattened_config))
+ flattened_config.merge!(@configurator_builder.set_force_build_filepaths(flattened_config))
+ flattened_config.merge!(@configurator_builder.set_rakefile_components(flattened_config))
+ flattened_config.merge!(@configurator_builder.set_library_build_info_filepaths(flattened_config))
+ flattened_config.merge!(@configurator_builder.set_release_target(flattened_config))
+ flattened_config.merge!(@configurator_builder.collect_project_options(flattened_config))
+
+ ### iterate through all entries in paths section and expand any & all globs to actual paths
+ flattened_config.merge!(@configurator_builder.expand_all_path_globs(flattened_config))
+
+ flattened_config.merge!(@configurator_builder.collect_vendor_paths(flattened_config))
+ flattened_config.merge!(@configurator_builder.collect_source_and_include_paths(flattened_config))
+ flattened_config.merge!(@configurator_builder.collect_source_include_vendor_paths(flattened_config))
+ flattened_config.merge!(@configurator_builder.collect_test_support_source_include_paths(flattened_config))
+ flattened_config.merge!(@configurator_builder.collect_test_support_source_include_vendor_paths(flattened_config))
+ flattened_config.merge!(@configurator_builder.collect_tests(flattened_config))
+ flattened_config.merge!(@configurator_builder.collect_assembly(flattened_config))
+ flattened_config.merge!(@configurator_builder.collect_source(flattened_config))
+ flattened_config.merge!(@configurator_builder.collect_headers(flattened_config))
+ flattened_config.merge!(@configurator_builder.collect_all_existing_compilation_input(flattened_config))
+ flattened_config.merge!(@configurator_builder.collect_test_and_vendor_defines(flattened_config))
+ flattened_config.merge!(@configurator_builder.collect_release_and_vendor_defines(flattened_config))
+ flattened_config.merge!(@configurator_builder.collect_release_artifact_extra_link_objects(flattened_config))
+ flattened_config.merge!(@configurator_builder.collect_test_fixture_extra_link_objects(flattened_config))
+
+ return flattened_config
+ end
+
+
+ def build_constants_and_accessors(config, context)
+ @configurator_builder.build_global_constants(config)
+ @configurator_builder.build_accessor_methods(config, context)
+ end
+
+
+ def validate_required_sections(config)
+ validation = []
+ validation << @configurator_validator.exists?(config, :project)
+ validation << @configurator_validator.exists?(config, :paths)
+
+ return false if (validation.include?(false))
+ return true
+ end
+
+ def validate_required_section_values(config)
+ validation = []
+ validation << @configurator_validator.exists?(config, :project, :build_root)
+ validation << @configurator_validator.exists?(config, :paths, :test)
+ validation << @configurator_validator.exists?(config, :paths, :source)
+
+ return false if (validation.include?(false))
+ return true
+ end
+
+ def validate_paths(config)
+ validation = []
+
+ validation << @configurator_validator.validate_filepath(config, :project, :build_root)
+ validation << @configurator_validator.validate_filepath(config, :cmock, :unity_helper) if config[:cmock][:unity_helper]
+
+ config[:project][:options_paths].each do |path|
+ validation << @configurator_validator.validate_filepath_simple( path, :project, :options_paths )
+ end
+
+ config[:plugins][:load_paths].each do |path|
+ validation << @configurator_validator.validate_filepath_simple( path, :plugins, :load_paths )
+ end
+
+ config[:paths].keys.sort.each do |key|
+ validation << @configurator_validator.validate_path_list(config, :paths, key)
+ end
+
+ return false if (validation.include?(false))
+ return true
+ end
+
+ def validate_tools(config)
+ validation = []
+
+ config[:tools].keys.sort.each do |key|
+ validation << @configurator_validator.exists?(config, :tools, key, :executable)
+ validation << @configurator_validator.validate_executable_filepath(config, :tools, key, :executable) if (not config[:tools][key][:optional])
+ validation << @configurator_validator.validate_tool_stderr_redirect(config, :tools, key)
+ end
+
+ return false if (validation.include?(false))
+ return true
+ end
+
+ def validate_plugins(config)
+ missing_plugins =
+ Set.new( config[:plugins][:enabled] ) -
+ Set.new( @configurator_plugins.rake_plugins ) -
+ Set.new( @configurator_plugins.script_plugins )
+
+ missing_plugins.each do |plugin|
+ @stream_wrapper.stderr_puts("ERROR: Ceedling plugin '#{plugin}' contains no rake or ruby class entry point. (Misspelled or missing files?)")
+ end
+
+ return ( (missing_plugins.size > 0) ? false : true )
+ end
+
+end
diff --git a/tests/vendor/ceedling/lib/configurator_validator.rb b/tests/vendor/ceedling/lib/configurator_validator.rb
new file mode 100644
index 000000000..970e6c9d0
--- /dev/null
+++ b/tests/vendor/ceedling/lib/configurator_validator.rb
@@ -0,0 +1,184 @@
+require 'rubygems'
+require 'rake' # for ext()
+require 'constants'
+require 'tool_executor' # for argument replacement pattern
+require 'file_path_utils' # for glob handling class methods
+
+
+class ConfiguratorValidator
+
+ constructor :file_wrapper, :stream_wrapper, :system_wrapper
+
+ # walk into config hash verify existence of data at key depth
+ def exists?(config, *keys)
+ hash = retrieve_value(config, keys)
+ exist = !hash[:value].nil?
+
+ if (not exist)
+ # no verbosity checking since this is lowest level anyhow & verbosity checking depends on configurator
+ @stream_wrapper.stderr_puts("ERROR: Required config file entry #{format_key_sequence(keys, hash[:depth])} does not exist.")
+ end
+
+ return exist
+ end
+
+
+ # walk into config hash. verify directory path(s) at given key depth
+ def validate_path_list(config, *keys)
+ hash = retrieve_value(config, keys)
+ list = hash[:value]
+
+ # return early if we couldn't walk into hash and find a value
+ return false if (list.nil?)
+
+ path_list = []
+ exist = true
+
+ case list
+ when String then path_list << list
+ when Array then path_list = list
+ end
+
+ path_list.each do |path|
+ base_path = FilePathUtils::extract_path(path) # lop off add/subtract notation & glob specifiers
+
+ if (not @file_wrapper.exist?(base_path))
+ # no verbosity checking since this is lowest level anyhow & verbosity checking depends on configurator
+ @stream_wrapper.stderr_puts("ERROR: Config path #{format_key_sequence(keys, hash[:depth])}['#{base_path}'] does not exist on disk.")
+ exist = false
+ end
+ end
+
+ return exist
+ end
+
+
+ # simple path verification
+ def validate_filepath_simple(path, *keys)
+ validate_path = path
+
+ if (not @file_wrapper.exist?(validate_path))
+ # no verbosity checking since this is lowest level anyhow & verbosity checking depends on configurator
+ @stream_wrapper.stderr_puts("ERROR: Config path '#{validate_path}' associated with #{format_key_sequence(keys, keys.size)} does not exist on disk.")
+ return false
+ end
+
+ return true
+ end
+
+ # walk into config hash. verify specified file exists.
+ def validate_filepath(config, *keys)
+ hash = retrieve_value(config, keys)
+ filepath = hash[:value]
+
+ # return early if we couldn't walk into hash and find a value
+ return false if (filepath.nil?)
+
+ # skip everything if we've got an argument replacement pattern
+ return true if (filepath =~ TOOL_EXECUTOR_ARGUMENT_REPLACEMENT_PATTERN)
+
+ if (not @file_wrapper.exist?(filepath))
+ # no verbosity checking since this is lowest level anyhow & verbosity checking depends on configurator
+ @stream_wrapper.stderr_puts("ERROR: Config filepath #{format_key_sequence(keys, hash[:depth])}['#{filepath}'] does not exist on disk.")
+ return false
+ end
+
+ return true
+ end
+
+ # walk into config hash. verify specified file exists.
+ def validate_executable_filepath(config, *keys)
+ exe_extension = config[:extension][:executable]
+ hash = retrieve_value(config, keys)
+ filepath = hash[:value]
+
+ # return early if we couldn't walk into hash and find a value
+ return false if (filepath.nil?)
+
+ # skip everything if we've got an argument replacement pattern
+ return true if (filepath =~ TOOL_EXECUTOR_ARGUMENT_REPLACEMENT_PATTERN)
+
+ # if there's no path included, verify file exists somewhere in system search paths
+ if (not filepath.include?('/'))
+ exists = false
+
+ @system_wrapper.search_paths.each do |path|
+ if (@file_wrapper.exist?( File.join(path, filepath)) )
+ exists = true
+ break
+ end
+
+ if (@file_wrapper.exist?( (File.join(path, filepath)).ext( exe_extension ) ))
+ exists = true
+ break
+ elsif (@system_wrapper.windows? and @file_wrapper.exist?( (File.join(path, filepath)).ext( EXTENSION_WIN_EXE ) ))
+ exists = true
+ break
+ end
+ end
+
+ if (not exists)
+ # no verbosity checking since this is lowest level anyhow & verbosity checking depends on configurator
+ @stream_wrapper.stderr_puts("ERROR: Config filepath #{format_key_sequence(keys, hash[:depth])}['#{filepath}'] does not exist in system search paths.")
+ return false
+ end
+
+ # if there is a path included, check that explicit filepath exists
+ else
+ if (not @file_wrapper.exist?(filepath))
+ # no verbosity checking since this is lowest level anyhow & verbosity checking depends on configurator
+ @stream_wrapper.stderr_puts("ERROR: Config filepath #{format_key_sequence(keys, hash[:depth])}['#{filepath}'] does not exist on disk.")
+ return false
+ end
+ end
+
+ return true
+ end
+
+ def validate_tool_stderr_redirect(config, tools, tool)
+ redirect = config[tools][tool][:stderr_redirect]
+ if (redirect.class == Symbol)
+ # map constants and force to array of strings for runtime universality across ruby versions
+ if (not StdErrRedirect.constants.map{|constant| constant.to_s}.include?(redirect.to_s.upcase))
+ error = "ERROR: [:#{tools}][:#{tool}][:stderr_redirect][:#{redirect}] is not a recognized option " +
+ "{#{StdErrRedirect.constants.map{|constant| ':' + constant.to_s.downcase}.join(', ')}}."
+ @stream_wrapper.stderr_puts(error)
+ return false
+ end
+ end
+
+ return true
+ end
+
+ private #########################################
+
+
+ def retrieve_value(config, keys)
+ value = nil
+ hash = config
+ depth = 0
+
+ # walk into hash & extract value at requested key sequence
+ keys.each do |symbol|
+ depth += 1
+ if (not hash[symbol].nil?)
+ hash = hash[symbol]
+ value = hash
+ else
+ value = nil
+ break
+ end
+ end
+
+ return {:value => value, :depth => depth}
+ end
+
+
+ def format_key_sequence(keys, depth)
+ walked_keys = keys.slice(0, depth)
+ formatted_keys = walked_keys.map{|key| "[:#{key.to_s}]"}
+
+ return formatted_keys.join
+ end
+
+end
diff --git a/tests/vendor/ceedling/lib/constants.rb b/tests/vendor/ceedling/lib/constants.rb
new file mode 100644
index 000000000..c7fd9ca04
--- /dev/null
+++ b/tests/vendor/ceedling/lib/constants.rb
@@ -0,0 +1,91 @@
+
+class Verbosity
+ SILENT = 0 # as silent as possible (though there are some messages that must be spit out)
+ ERRORS = 1 # only errors
+ COMPLAIN = 2 # spit out errors and warnings/notices
+ NORMAL = 3 # errors, warnings/notices, standard status messages
+ OBNOXIOUS = 4 # all messages including extra verbose output (used for lite debugging / verification)
+ DEBUG = 5 # special extra verbose output for hardcore debugging
+end
+
+
+class TestResultsSanityChecks
+ NONE = 0 # no sanity checking of test results
+ NORMAL = 1 # perform non-problematic checks
+ THOROUGH = 2 # perform checks that require inside knowledge of system workings
+end
+
+
+class StdErrRedirect
+ NONE = :none
+ AUTO = :auto
+ WIN = :win
+ UNIX = :unix
+ TCSH = :tcsh
+end
+
+
+class BackgroundExec
+ NONE = :none
+ AUTO = :auto
+ WIN = :win
+ UNIX = :unix
+end
+
+
+EXTENSION_WIN_EXE = '.exe'
+EXTENSION_NONWIN_EXE = '.out'
+
+
+CEXCEPTION_ROOT_PATH = 'c_exception'
+CEXCEPTION_LIB_PATH = "#{CEXCEPTION_ROOT_PATH}/lib"
+CEXCEPTION_C_FILE = 'CException.c'
+CEXCEPTION_H_FILE = 'CException.h'
+
+UNITY_ROOT_PATH = 'unity'
+UNITY_LIB_PATH = "#{UNITY_ROOT_PATH}/src"
+UNITY_C_FILE = 'unity.c'
+UNITY_H_FILE = 'unity.h'
+UNITY_INTERNALS_H_FILE = 'unity_internals.h'
+
+CMOCK_ROOT_PATH = 'cmock'
+CMOCK_LIB_PATH = "#{CMOCK_ROOT_PATH}/src"
+CMOCK_C_FILE = 'cmock.c'
+CMOCK_H_FILE = 'cmock.h'
+
+
+DEFAULT_CEEDLING_MAIN_PROJECT_FILE = 'project.yml' # main project file
+DEFAULT_CEEDLING_USER_PROJECT_FILE = 'user.yml' # supplemental user config file
+
+INPUT_CONFIGURATION_CACHE_FILE = 'input.yml' # input configuration file dump
+
+
+TEST_ROOT_NAME = 'test'
+TEST_TASK_ROOT = TEST_ROOT_NAME + ':'
+TEST_SYM = TEST_ROOT_NAME.to_sym
+
+RELEASE_ROOT_NAME = 'release'
+RELEASE_TASK_ROOT = RELEASE_ROOT_NAME + ':'
+RELEASE_SYM = RELEASE_ROOT_NAME.to_sym
+
+REFRESH_ROOT_NAME = 'refresh'
+REFRESH_TASK_ROOT = REFRESH_ROOT_NAME + ':'
+REFRESH_SYM = REFRESH_ROOT_NAME.to_sym
+
+UTILS_ROOT_NAME = 'utils'
+UTILS_TASK_ROOT = UTILS_ROOT_NAME + ':'
+UTILS_SYM = UTILS_ROOT_NAME.to_sym
+
+OPERATION_COMPILE_SYM = :compile
+OPERATION_LINK_SYM = :link
+
+
+RUBY_STRING_REPLACEMENT_PATTERN = /#\{.+\}/
+RUBY_EVAL_REPLACEMENT_PATTERN = /^\{(.+)\}$/
+TOOL_EXECUTOR_ARGUMENT_REPLACEMENT_PATTERN = /(\$\{(\d+)\})/
+TEST_STDOUT_STATISTICS_PATTERN = /-+\s+(\d+)\s+Tests\s+(\d+)\s+Failures\s+(\d+)\s+Ignored\s+(OK|FAIL)\s*/i
+
+NULL_FILE_PATH = '/dev/null'
+
+TESTS_BASE_PATH = TEST_ROOT_NAME
+RELEASE_BASE_PATH = RELEASE_ROOT_NAME
diff --git a/tests/vendor/ceedling/lib/defaults.rb b/tests/vendor/ceedling/lib/defaults.rb
new file mode 100644
index 000000000..6254a64f9
--- /dev/null
+++ b/tests/vendor/ceedling/lib/defaults.rb
@@ -0,0 +1,380 @@
+require 'constants'
+require 'system_wrapper'
+require 'file_path_utils'
+
+
+DEFAULT_TEST_COMPILER_TOOL = {
+ :executable => FilePathUtils.os_executable_ext('gcc').freeze,
+ :name => 'default_test_compiler'.freeze,
+ :stderr_redirect => StdErrRedirect::NONE.freeze,
+ :background_exec => BackgroundExec::NONE.freeze,
+ :optional => false.freeze,
+ :arguments => [
+ {"-I\"$\"" => 'COLLECTION_PATHS_TEST_SUPPORT_SOURCE_INCLUDE_VENDOR'}.freeze,
+ {"-I\"$\"" => 'COLLECTION_PATHS_TEST_TOOLCHAIN_INCLUDE'}.freeze,
+ {"-D$" => 'COLLECTION_DEFINES_TEST_AND_VENDOR'}.freeze,
+ "-DGNU_COMPILER".freeze,
+ "-c \"${1}\"".freeze,
+ "-o \"${2}\"".freeze,
+ # gcc's list file output options are complex; no use of ${3} parameter in default config
+ ].freeze
+ }
+
+DEFAULT_TEST_LINKER_TOOL = {
+ :executable => FilePathUtils.os_executable_ext('gcc').freeze,
+ :name => 'default_test_linker'.freeze,
+ :stderr_redirect => StdErrRedirect::NONE.freeze,
+ :background_exec => BackgroundExec::NONE.freeze,
+ :optional => false.freeze,
+ :arguments => [
+ "\"${1}\"".freeze,
+ "-o \"${2}\"".freeze,
+ ].freeze
+ }
+
+DEFAULT_TEST_FIXTURE_TOOL = {
+ :executable => '${1}'.freeze,
+ :name => 'default_test_fixture'.freeze,
+ :stderr_redirect => StdErrRedirect::AUTO.freeze,
+ :background_exec => BackgroundExec::NONE.freeze,
+ :optional => false.freeze,
+ :arguments => [].freeze
+ }
+
+
+
+DEFAULT_TEST_INCLUDES_PREPROCESSOR_TOOL = {
+ :executable => FilePathUtils.os_executable_ext('cpp').freeze,
+ :name => 'default_test_includes_preprocessor'.freeze,
+ :stderr_redirect => StdErrRedirect::NONE.freeze,
+ :background_exec => BackgroundExec::NONE.freeze,
+ :optional => false.freeze,
+ :arguments => [
+ '-MM'.freeze,
+ '-MG'.freeze,
+ # avoid some possibility of deep system lib header file complications by omitting vendor paths
+ # if cpp is run on *nix system, escape spaces in paths; if cpp on windows just use the paths collection as is
+ {"-I\"$\"" => "{SystemWrapper.windows? ? COLLECTION_PATHS_TEST_SUPPORT_SOURCE_INCLUDE : COLLECTION_PATHS_TEST_SUPPORT_SOURCE_INCLUDE.map{|path| path.gsub(\/ \/, \'\\\\ \') }}"}.freeze,
+ {"-D$" => 'COLLECTION_DEFINES_TEST_AND_VENDOR'}.freeze,
+ {"-D$" => 'DEFINES_TEST_PREPROCESS'}.freeze,
+ "-DGNU_PREPROCESSOR".freeze,
+ '-w'.freeze,
+ '-nostdinc'.freeze,
+ "\"${1}\"".freeze
+ ].freeze
+ }
+
+DEFAULT_TEST_FILE_PREPROCESSOR_TOOL = {
+ :executable => FilePathUtils.os_executable_ext('gcc').freeze,
+ :name => 'default_test_file_preprocessor'.freeze,
+ :stderr_redirect => StdErrRedirect::NONE.freeze,
+ :background_exec => BackgroundExec::NONE.freeze,
+ :optional => false.freeze,
+ :arguments => [
+ '-E'.freeze,
+ {"-I\"$\"" => 'COLLECTION_PATHS_TEST_SUPPORT_SOURCE_INCLUDE_VENDOR'}.freeze,
+ {"-I\"$\"" => 'COLLECTION_PATHS_TEST_TOOLCHAIN_INCLUDE'}.freeze,
+ {"-D$" => 'COLLECTION_DEFINES_TEST_AND_VENDOR'}.freeze,
+ {"-D$" => 'DEFINES_TEST_PREPROCESS'}.freeze,
+ "-DGNU_PREPROCESSOR".freeze,
+ "\"${1}\"".freeze,
+ "-o \"${2}\"".freeze
+ ].freeze
+ }
+
+DEFAULT_TEST_DEPENDENCIES_GENERATOR_TOOL = {
+ :executable => FilePathUtils.os_executable_ext('gcc').freeze,
+ :name => 'default_test_dependencies_generator'.freeze,
+ :stderr_redirect => StdErrRedirect::NONE.freeze,
+ :background_exec => BackgroundExec::NONE.freeze,
+ :optional => false.freeze,
+ :arguments => [
+ {"-I\"$\"" => 'COLLECTION_PATHS_TEST_SUPPORT_SOURCE_INCLUDE_VENDOR'}.freeze,
+ {"-I\"$\"" => 'COLLECTION_PATHS_TEST_TOOLCHAIN_INCLUDE'}.freeze,
+ {"-D$" => 'COLLECTION_DEFINES_TEST_AND_VENDOR'}.freeze,
+ {"-D$" => 'DEFINES_TEST_PREPROCESS'}.freeze,
+ "-DGNU_PREPROCESSOR".freeze,
+ "-MT \"${3}\"".freeze,
+ '-MM'.freeze,
+ '-MD'.freeze,
+ '-MG'.freeze,
+ "-MF \"${2}\"".freeze,
+ "-c \"${1}\"".freeze,
+ ].freeze
+ }
+
+DEFAULT_RELEASE_DEPENDENCIES_GENERATOR_TOOL = {
+ :executable => FilePathUtils.os_executable_ext('gcc').freeze,
+ :name => 'default_release_dependencies_generator'.freeze,
+ :stderr_redirect => StdErrRedirect::NONE.freeze,
+ :background_exec => BackgroundExec::NONE.freeze,
+ :optional => false.freeze,
+ :arguments => [
+ {"-I\"$\"" => 'COLLECTION_PATHS_SOURCE_INCLUDE_VENDOR'}.freeze,
+ {"-I\"$\"" => 'COLLECTION_PATHS_RELEASE_TOOLCHAIN_INCLUDE'}.freeze,
+ {"-D$" => 'COLLECTION_DEFINES_RELEASE_AND_VENDOR'}.freeze,
+ {"-D$" => 'DEFINES_RELEASE_PREPROCESS'}.freeze,
+ "-DGNU_PREPROCESSOR".freeze,
+ "-MT \"${3}\"".freeze,
+ '-MM'.freeze,
+ '-MD'.freeze,
+ '-MG'.freeze,
+ "-MF \"${2}\"".freeze,
+ "-c \"${1}\"".freeze,
+ ].freeze
+ }
+
+
+DEFAULT_RELEASE_COMPILER_TOOL = {
+ :executable => FilePathUtils.os_executable_ext('gcc').freeze,
+ :name => 'default_release_compiler'.freeze,
+ :stderr_redirect => StdErrRedirect::NONE.freeze,
+ :background_exec => BackgroundExec::NONE.freeze,
+ :optional => false.freeze,
+ :arguments => [
+ {"-I\"$\"" => 'COLLECTION_PATHS_SOURCE_INCLUDE_VENDOR'}.freeze,
+ {"-I\"$\"" => 'COLLECTION_PATHS_RELEASE_TOOLCHAIN_INCLUDE'}.freeze,
+ {"-D$" => 'COLLECTION_DEFINES_RELEASE_AND_VENDOR'}.freeze,
+ "-DGNU_COMPILER".freeze,
+ "-c \"${1}\"".freeze,
+ "-o \"${2}\"".freeze,
+ # gcc's list file output options are complex; no use of ${3} parameter in default config
+ ].freeze
+ }
+
+DEFAULT_RELEASE_ASSEMBLER_TOOL = {
+ :executable => FilePathUtils.os_executable_ext('as').freeze,
+ :name => 'default_release_assembler'.freeze,
+ :stderr_redirect => StdErrRedirect::NONE.freeze,
+ :background_exec => BackgroundExec::NONE.freeze,
+ :optional => false.freeze,
+ :arguments => [
+ {"-I\"$\"" => 'COLLECTION_PATHS_SOURCE_AND_INCLUDE'}.freeze,
+ "\"${1}\"".freeze,
+ "-o \"${2}\"".freeze,
+ ].freeze
+ }
+
+DEFAULT_RELEASE_LINKER_TOOL = {
+ :executable => FilePathUtils.os_executable_ext('gcc').freeze,
+ :name => 'default_release_linker'.freeze,
+ :stderr_redirect => StdErrRedirect::NONE.freeze,
+ :background_exec => BackgroundExec::NONE.freeze,
+ :optional => false.freeze,
+ :arguments => [
+ "\"${1}\"".freeze,
+ "-o \"${2}\"".freeze,
+ ].freeze
+ }
+
+
+DEFAULT_TOOLS_TEST = {
+ :tools => {
+ :test_compiler => DEFAULT_TEST_COMPILER_TOOL,
+ :test_linker => DEFAULT_TEST_LINKER_TOOL,
+ :test_fixture => DEFAULT_TEST_FIXTURE_TOOL,
+ }
+ }
+
+DEFAULT_TOOLS_TEST_PREPROCESSORS = {
+ :tools => {
+ :test_includes_preprocessor => DEFAULT_TEST_INCLUDES_PREPROCESSOR_TOOL,
+ :test_file_preprocessor => DEFAULT_TEST_FILE_PREPROCESSOR_TOOL,
+ }
+ }
+
+DEFAULT_TOOLS_TEST_DEPENDENCIES = {
+ :tools => {
+ :test_dependencies_generator => DEFAULT_TEST_DEPENDENCIES_GENERATOR_TOOL,
+ }
+ }
+
+
+DEFAULT_TOOLS_RELEASE = {
+ :tools => {
+ :release_compiler => DEFAULT_RELEASE_COMPILER_TOOL,
+ :release_linker => DEFAULT_RELEASE_LINKER_TOOL,
+ }
+ }
+
+DEFAULT_TOOLS_RELEASE_ASSEMBLER = {
+ :tools => {
+ :release_assembler => DEFAULT_RELEASE_ASSEMBLER_TOOL,
+ }
+ }
+
+DEFAULT_TOOLS_RELEASE_DEPENDENCIES = {
+ :tools => {
+ :release_dependencies_generator => DEFAULT_RELEASE_DEPENDENCIES_GENERATOR_TOOL,
+ }
+ }
+
+
+DEFAULT_RELEASE_TARGET_NAME = 'project'
+
+DEFAULT_CEEDLING_CONFIG = {
+ :project => {
+ # :build_root must be set by user
+ :use_exceptions => true,
+ :use_mocks => true,
+ :compile_threads => 1,
+ :test_threads => 1,
+ :use_test_preprocessor => false,
+ :use_deep_dependencies => false,
+ :test_file_prefix => 'test_',
+ :options_paths => [],
+ :release_build => false,
+ },
+
+ :release_build => {
+ # :output is set while building configuration -- allows smart default system-dependent file extension handling
+ :use_assembly => false,
+ :artifacts => [],
+ },
+
+ :paths => {
+ :test => [], # must be populated by user
+ :source => [], # must be populated by user
+ :support => [],
+ :include => [],
+ :test_toolchain_include => [],
+ :release_toolchain_include => [],
+ },
+
+ :files => {
+ :test => [],
+ :source => [],
+ :assembly => [],
+ :support => [],
+ :include => [],
+ },
+
+ # unlike other top-level entries, environment's value is an array to preserve order
+ :environment => [
+ # when evaluated, this provides wider text field for rake task comments
+ {:rake_columns => '120'},
+ ],
+
+ :defines => {
+ :test => [],
+ :test_preprocess => [],
+ :release => [],
+ :release_preprocess => [],
+ },
+
+ :flags => {},
+
+ :extension => {
+ :header => '.h',
+ :source => '.c',
+ :assembly => '.s',
+ :object => '.o',
+ :executable => ( SystemWrapper.windows? ? EXTENSION_WIN_EXE : EXTENSION_NONWIN_EXE ),
+ :map => '.map',
+ :list => '.lst',
+ :testpass => '.pass',
+ :testfail => '.fail',
+ :dependencies => '.d',
+ },
+
+ :unity => {
+ :defines => []
+ },
+
+ :cmock => {
+ :defines => []
+ },
+
+ :cexception => {
+ :defines => []
+ },
+
+ :test_runner => {
+ :includes => [],
+ :file_suffix => '_runner',
+ },
+
+ # all tools populated while building up config structure
+ :tools => {},
+
+ # empty argument lists for default tools
+ # (these can be overridden in project file to add arguments to tools without totally redefining tools)
+ :test_compiler => { :arguments => [] },
+ :test_linker => { :arguments => [] },
+ :test_fixture => {
+ :arguments => [],
+ :link_objects => [], # compiled object files to always be linked in (e.g. cmock.o if using mocks)
+ },
+ :test_includes_preprocessor => { :arguments => [] },
+ :test_file_preprocessor => { :arguments => [] },
+ :test_dependencies_generator => { :arguments => [] },
+ :release_compiler => { :arguments => [] },
+ :release_linker => { :arguments => [] },
+ :release_assembler => { :arguments => [] },
+ :release_dependencies_generator => { :arguments => [] },
+
+ :plugins => {
+ :load_paths => [],
+ :enabled => [],
+ }
+ }.freeze
+
+
+DEFAULT_TESTS_RESULTS_REPORT_TEMPLATE = %q{
+% ignored = hash[:results][:counts][:ignored]
+% failed = hash[:results][:counts][:failed]
+% stdout_count = hash[:results][:counts][:stdout]
+% header_prepend = ((hash[:header].length > 0) ? "#{hash[:header]}: " : '')
+% banner_width = 25 + header_prepend.length # widest message
+
+% if (ignored > 0)
+<%=@ceedling[:plugin_reportinator].generate_banner(header_prepend + 'IGNORED UNIT TEST SUMMARY')%>
+% hash[:results][:ignores].each do |ignore|
+% ignore[:collection].each do |item|
+<%=ignore[:source][:path]%><%=File::SEPARATOR%><%=ignore[:source][:file]%>:<%=item[:line]%>:<%=item[:test]%>
+% if (item[:message].length > 0)
+: "<%=item[:message]%>"
+% else
+<%="\n"%>
+% end
+% end
+% end
+
+% end
+% if (failed > 0)
+<%=@ceedling[:plugin_reportinator].generate_banner(header_prepend + 'FAILED UNIT TEST SUMMARY')%>
+% hash[:results][:failures].each do |failure|
+% failure[:collection].each do |item|
+<%=failure[:source][:path]%><%=File::SEPARATOR%><%=failure[:source][:file]%>:<%=item[:line]%>:<%=item[:test]%>
+% if (item[:message].length > 0)
+: "<%=item[:message]%>"
+% else
+<%="\n"%>
+% end
+% end
+% end
+
+% end
+% if (stdout_count > 0)
+<%=@ceedling[:plugin_reportinator].generate_banner(header_prepend + 'UNIT TEST OTHER OUTPUT')%>
+% hash[:results][:stdout].each do |string|
+% string[:collection].each do |item|
+<%=string[:source][:path]%><%=File::SEPARATOR%><%=string[:source][:file]%>: "<%=item%>"
+% end
+% end
+
+% end
+% total_string = hash[:results][:counts][:total].to_s
+% format_string = "%#{total_string.length}i"
+<%=@ceedling[:plugin_reportinator].generate_banner(header_prepend + 'OVERALL UNIT TEST SUMMARY')%>
+% if (hash[:results][:counts][:total] > 0)
+TESTED: <%=hash[:results][:counts][:total].to_s%>
+PASSED: <%=sprintf(format_string, hash[:results][:counts][:passed])%>
+FAILED: <%=sprintf(format_string, failed)%>
+IGNORED: <%=sprintf(format_string, ignored)%>
+% else
+
+No tests executed.
+% end
+
+}
diff --git a/tests/vendor/ceedling/lib/dependinator.rb b/tests/vendor/ceedling/lib/dependinator.rb
new file mode 100644
index 000000000..061caee4e
--- /dev/null
+++ b/tests/vendor/ceedling/lib/dependinator.rb
@@ -0,0 +1,92 @@
+
+class Dependinator
+
+ constructor :configurator, :project_config_manager, :test_includes_extractor, :file_path_utils, :rake_wrapper, :file_wrapper
+
+ def touch_force_rebuild_files
+ @file_wrapper.touch( @configurator.project_test_force_rebuild_filepath )
+ @file_wrapper.touch( @configurator.project_release_force_rebuild_filepath ) if (@configurator.project_release_build)
+ end
+
+
+
+ def load_release_object_deep_dependencies(dependencies_list)
+ dependencies_list.each { |dependencies_file| @rake_wrapper.load_dependencies( dependencies_file ) }
+ end
+
+
+ def enhance_release_file_dependencies(files)
+ files.each do |filepath|
+ @rake_wrapper[filepath].enhance( [@configurator.project_release_force_rebuild_filepath] ) if (@project_config_manager.release_config_changed)
+ @rake_wrapper[filepath].enhance( [@configurator.ceedling_build_info_filepath] )
+ end
+ end
+
+
+
+ def load_test_object_deep_dependencies(files_list)
+ dependencies_list = @file_path_utils.form_test_dependencies_filelist(files_list)
+ dependencies_list.each { |dependencies_file| @rake_wrapper.load_dependencies(dependencies_file) }
+ end
+
+
+ def enhance_runner_dependencies(runner_filepath)
+ @rake_wrapper[runner_filepath].enhance( [@configurator.project_test_force_rebuild_filepath] ) if (@project_config_manager.test_config_changed)
+ @rake_wrapper[runner_filepath].enhance( [@configurator.ceedling_build_info_filepath] )
+ end
+
+
+ def enhance_shallow_include_lists_dependencies(include_lists)
+ include_lists.each do |include_list_filepath|
+ @rake_wrapper[include_list_filepath].enhance( [@configurator.project_test_force_rebuild_filepath] ) if (@project_config_manager.test_config_changed)
+ @rake_wrapper[include_list_filepath].enhance( [@configurator.ceedling_build_info_filepath] )
+ end
+ end
+
+
+ def enhance_preprocesed_file_dependencies(files)
+ files.each do |filepath|
+ @rake_wrapper[filepath].enhance( [@configurator.project_test_force_rebuild_filepath] ) if (@project_config_manager.test_config_changed)
+ @rake_wrapper[filepath].enhance( [@configurator.ceedling_build_info_filepath] )
+ end
+ end
+
+
+ def enhance_mock_dependencies(mocks_list)
+ # if input configuration or ceedling changes, make sure these guys get rebuilt
+ mocks_list.each do |mock_filepath|
+ @rake_wrapper[mock_filepath].enhance( [@configurator.project_test_force_rebuild_filepath] ) if (@project_config_manager.test_config_changed)
+ @rake_wrapper[mock_filepath].enhance( [@configurator.cmock_unity_helper] ) if (@configurator.cmock_unity_helper)
+ @rake_wrapper[mock_filepath].enhance( [@configurator.ceedling_build_info_filepath] )
+ @rake_wrapper[mock_filepath].enhance( [@configurator.cmock_build_info_filepath] )
+ end
+ end
+
+
+ def enhance_dependencies_dependencies(dependencies)
+ dependencies.each do |dependencies_filepath|
+ @rake_wrapper[dependencies_filepath].enhance( [@configurator.project_test_force_rebuild_filepath] ) if (@project_config_manager.test_config_changed)
+ @rake_wrapper[dependencies_filepath].enhance( [@configurator.ceedling_build_info_filepath] )
+ end
+ end
+
+
+ def enhance_test_build_object_dependencies(objects)
+ objects.each do |object_filepath|
+ @rake_wrapper[object_filepath].enhance( [@configurator.project_test_force_rebuild_filepath] ) if (@project_config_manager.test_config_changed)
+ @rake_wrapper[object_filepath].enhance( [@configurator.ceedling_build_info_filepath] )
+ end
+ end
+
+
+ def enhance_results_dependencies(result_filepath)
+ @rake_wrapper[result_filepath].enhance( [@configurator.project_test_force_rebuild_filepath] ) if (@project_config_manager.test_config_changed)
+ @rake_wrapper[result_filepath].enhance( [@configurator.ceedling_build_info_filepath] )
+ end
+
+
+ def setup_test_executable_dependencies(test, objects)
+ @rake_wrapper.create_file_task( @file_path_utils.form_test_executable_filepath(test), objects)
+ end
+
+end
diff --git a/tests/vendor/ceedling/lib/erb_wrapper.rb b/tests/vendor/ceedling/lib/erb_wrapper.rb
new file mode 100644
index 000000000..8d70b6d28
--- /dev/null
+++ b/tests/vendor/ceedling/lib/erb_wrapper.rb
@@ -0,0 +1,9 @@
+require 'erb'
+
+class ErbWrapper
+ def generate_file(template, data, output_file)
+ File.open(output_file, "w") do |f|
+ f << ERB.new(template, 0, "<>").result(binding)
+ end
+ end
+end
\ No newline at end of file
diff --git a/tests/vendor/ceedling/lib/file_finder.rb b/tests/vendor/ceedling/lib/file_finder.rb
new file mode 100644
index 000000000..f9a7cfe29
--- /dev/null
+++ b/tests/vendor/ceedling/lib/file_finder.rb
@@ -0,0 +1,132 @@
+require 'rubygems'
+require 'rake' # for adding ext() method to string
+
+class FileFinder
+
+ constructor :configurator, :file_finder_helper, :cacheinator, :file_path_utils, :file_wrapper, :yaml_wrapper
+
+ def prepare_search_sources
+ @all_test_source_and_header_file_collection =
+ @configurator.collection_all_tests +
+ @configurator.collection_all_source +
+ @configurator.collection_all_headers
+ end
+
+
+ def find_header_file(mock_file)
+ header = File.basename(mock_file).sub(/#{@configurator.cmock_mock_prefix}/, '').ext(@configurator.extension_header)
+
+ found_path = @file_finder_helper.find_file_in_collection(header, @configurator.collection_all_headers, :error)
+
+ return found_path
+ end
+
+
+ def find_header_input_for_mock_file(mock_file)
+ found_path = find_header_file(mock_file)
+ mock_input = found_path
+
+ if (@configurator.project_use_test_preprocessor)
+ mock_input = @cacheinator.diff_cached_test_file( @file_path_utils.form_preprocessed_file_filepath( found_path ) )
+ end
+
+ return mock_input
+ end
+
+
+ def find_source_from_test(test, complain)
+ test_prefix = @configurator.project_test_file_prefix
+ source_paths = @configurator.collection_all_source
+
+ source = File.basename(test).sub(/#{test_prefix}/, '')
+
+ # we don't blow up if a test file has no corresponding source file
+ return @file_finder_helper.find_file_in_collection(source, source_paths, complain)
+ end
+
+
+ def find_test_from_runner_path(runner_path)
+ extension_source = @configurator.extension_source
+
+ test_file = File.basename(runner_path).sub(/#{@configurator.test_runner_file_suffix}#{'\\'+extension_source}/, extension_source)
+
+ found_path = @file_finder_helper.find_file_in_collection(test_file, @configurator.collection_all_tests, :error)
+
+ return found_path
+ end
+
+
+ def find_test_input_for_runner_file(runner_path)
+ found_path = find_test_from_runner_path(runner_path)
+ runner_input = found_path
+
+ if (@configurator.project_use_test_preprocessor)
+ runner_input = @cacheinator.diff_cached_test_file( @file_path_utils.form_preprocessed_file_filepath( found_path ) )
+ end
+
+ return runner_input
+ end
+
+
+ def find_test_from_file_path(file_path)
+ test_file = File.basename(file_path).ext(@configurator.extension_source)
+
+ found_path = @file_finder_helper.find_file_in_collection(test_file, @configurator.collection_all_tests, :error)
+
+ return found_path
+ end
+
+
+ def find_test_or_source_or_header_file(file_path)
+ file = File.basename(file_path)
+ return @file_finder_helper.find_file_in_collection(file, @all_test_source_and_header_file_collection, :error)
+ end
+
+
+ def find_compilation_input_file(file_path, complain=:error)
+ found_file = nil
+
+ source_file = File.basename(file_path).ext(@configurator.extension_source)
+
+ # We only collect files that already exist when we start up.
+ # FileLists can produce undesired results for dynamically generated files depending on when they're accessed.
+ # So collect mocks and runners separately and right now.
+ if (source_file =~ /#{@configurator.test_runner_file_suffix}/)
+ found_file =
+ @file_finder_helper.find_file_in_collection(
+ source_file,
+ @file_wrapper.directory_listing( File.join(@configurator.project_test_runners_path, '*') ),
+ complain)
+
+ elsif (@configurator.project_use_mocks and (source_file =~ /#{@configurator.cmock_mock_prefix}/))
+ found_file =
+ @file_finder_helper.find_file_in_collection(
+ source_file,
+ @file_wrapper.directory_listing( File.join(@configurator.cmock_mock_path, '*') ),
+ complain)
+
+ else
+ found_file =
+ @file_finder_helper.find_file_in_collection(
+ source_file,
+ @configurator.collection_all_existing_compilation_input,
+ complain)
+ end
+
+ return found_file
+ end
+
+
+ def find_source_file(file_path, complain)
+ source_file = File.basename(file_path).ext(@configurator.extension_source)
+ return @file_finder_helper.find_file_in_collection(source_file, @configurator.collection_all_source, complain)
+ end
+
+
+ def find_assembly_file(file_path)
+ assembly_file = File.basename(file_path).ext(@configurator.extension_assembly)
+ return @file_finder_helper.find_file_in_collection(assembly_file, @configurator.collection_all_assembly, :error)
+ end
+
+end
+
diff --git a/tests/vendor/ceedling/lib/file_finder_helper.rb b/tests/vendor/ceedling/lib/file_finder_helper.rb
new file mode 100644
index 000000000..487f0fe28
--- /dev/null
+++ b/tests/vendor/ceedling/lib/file_finder_helper.rb
@@ -0,0 +1,54 @@
+require 'fileutils'
+require 'constants' # for Verbosity enumeration
+
+class FileFinderHelper
+
+ constructor :streaminator
+
+
+ def find_file_in_collection(file_name, file_list, complain, extra_message="")
+ file_to_find = nil
+
+ file_list.each do |item|
+ base_file = File.basename(item)
+
+ # case insensitive comparison
+ if (base_file.casecmp(file_name) == 0)
+ # case sensitive check
+ if (base_file == file_name)
+ file_to_find = item
+ break
+ else
+ blow_up(file_name, "However, a filename having different capitalization was found: '#{item}'.")
+ end
+ end
+
+ end
+
+ case (complain)
+ when :error then blow_up(file_name, extra_message) if (file_to_find.nil?)
+ when :warn then gripe(file_name, extra_message) if (file_to_find.nil?)
+ #when :ignore then
+ end
+
+ return file_to_find
+ end
+
+ private
+
+ def blow_up(file_name, extra_message="")
+ error = "ERROR: Found no file '#{file_name}' in search paths."
+ error += ' ' if (extra_message.length > 0)
+ @streaminator.stderr_puts(error + extra_message, Verbosity::ERRORS)
+ raise
+ end
+
+ def gripe(file_name, extra_message="")
+ warning = "WARNING: Found no file '#{file_name}' in search paths."
+ warning += ' ' if (extra_message.length > 0)
+ @streaminator.stderr_puts(warning + extra_message, Verbosity::COMPLAIN)
+ end
+
+end
+
+
diff --git a/tests/vendor/ceedling/lib/file_path_utils.rb b/tests/vendor/ceedling/lib/file_path_utils.rb
new file mode 100644
index 000000000..747c7b539
--- /dev/null
+++ b/tests/vendor/ceedling/lib/file_path_utils.rb
@@ -0,0 +1,189 @@
+require 'rubygems'
+require 'rake' # for ext()
+require 'fileutils'
+require 'system_wrapper'
+
+# global utility methods (for plugins, project files, etc.)
+def ceedling_form_filepath(destination_path, original_filepath, new_extension=nil)
+ filename = File.basename(original_filepath)
+ filename.replace(filename.ext(new_extension)) if (!new_extension.nil?)
+ return File.join( destination_path.gsub(/\\/, '/'), filename )
+end
+
+class FilePathUtils
+
+ GLOB_MATCHER = /[\*\?\{\}\[\]]/
+
+ constructor :configurator, :file_wrapper
+
+
+ ######### class methods ##########
+
+ # standardize path to use '/' path separator & begin with './' & have no trailing path separator
+ def self.standardize(path)
+ path.strip!
+ path.gsub!(/\\/, '/')
+ path.gsub!(/^((\+|-):)?\.\//, '')
+ path.chomp!('/')
+ return path
+ end
+
+ def self.os_executable_ext(executable)
+ return executable.ext('.exe') if SystemWrapper.windows?
+ return executable
+ end
+
+ # extract directory path from between optional add/subtract aggregation modifiers and up to glob specifiers
+ # note: slightly different than File.dirname in that /files/foo remains /files/foo and does not become /files
+ def self.extract_path(path)
+ path = path.sub(/^(\+|-):/, '')
+
+ # find first occurrence of path separator followed by directory glob specifier: *, ?, {, }, [, ]
+ find_index = (path =~ GLOB_MATCHER)
+
+ # no changes needed (lop off final path separator)
+ return path.chomp('/') if (find_index.nil?)
+
+ # extract up to first glob specifier
+ path = path[0..(find_index-1)]
+
+ # lop off everything up to and including final path separator
+ find_index = path.rindex('/')
+ return path[0..(find_index-1)] if (not find_index.nil?)
+
+ # return string up to first glob specifier if no path separator found
+ return path
+ end
+
+ # return whether the given path is to be aggregated (no aggregation modifier defaults to same as +:)
+ def self.add_path?(path)
+ return (path =~ /^-:/).nil?
+ end
+
+ # get path (and glob) lopping off optional +: / -: prefixed aggregation modifiers
+ def self.extract_path_no_aggregation_operators(path)
+ return path.sub(/^(\+|-):/, '')
+ end
+
+ # all the globs that may be in a path string work fine with one exception;
+ # to recurse through all subdirectories, the glob is dir/**/** but our paths use
+ # convention of only dir/**
+ def self.reform_glob(path)
+ return path if (path =~ /\/\*\*$/).nil?
+ return path + '/**'
+ end
+
+ def self.form_ceedling_vendor_path(*filepaths)
+ return File.join( CEEDLING_VENDOR, filepaths )
+ end
+
+ ######### instance methods ##########
+
+ def form_temp_path(filepath, prefix='')
+ return File.join( @configurator.project_temp_path, prefix + File.basename(filepath) )
+ end
+
+ ### release ###
+ def form_release_build_cache_path(filepath)
+ return File.join( @configurator.project_release_build_cache_path, File.basename(filepath) )
+ end
+
+ def form_release_dependencies_filepath(filepath)
+ return File.join( @configurator.project_release_dependencies_path, File.basename(filepath).ext(@configurator.extension_dependencies) )
+ end
+
+ def form_release_build_c_object_filepath(filepath)
+ return File.join( @configurator.project_release_build_output_c_path, File.basename(filepath).ext(@configurator.extension_object) )
+ end
+
+ def form_release_build_asm_object_filepath(filepath)
+ return File.join( @configurator.project_release_build_output_asm_path, File.basename(filepath).ext(@configurator.extension_object) )
+ end
+
+ def form_release_build_c_objects_filelist(files)
+ return (@file_wrapper.instantiate_file_list(files)).pathmap("#{@configurator.project_release_build_output_c_path}/%n#{@configurator.extension_object}")
+ end
+
+ def form_release_build_asm_objects_filelist(files)
+ return (@file_wrapper.instantiate_file_list(files)).pathmap("#{@configurator.project_release_build_output_asm_path}/%n#{@configurator.extension_object}")
+ end
+
+ def form_release_build_c_list_filepath(filepath)
+ return File.join( @configurator.project_release_build_output_c_path, File.basename(filepath).ext(@configurator.extension_list) )
+ end
+
+ def form_release_dependencies_filelist(files)
+ return (@file_wrapper.instantiate_file_list(files)).pathmap("#{@configurator.project_release_dependencies_path}/%n#{@configurator.extension_dependencies}")
+ end
+
+ ### tests ###
+ def form_test_build_cache_path(filepath)
+ return File.join( @configurator.project_test_build_cache_path, File.basename(filepath) )
+ end
+
+ def form_pass_results_filepath(filepath)
+ return File.join( @configurator.project_test_results_path, File.basename(filepath).ext(@configurator.extension_testpass) )
+ end
+
+ def form_fail_results_filepath(filepath)
+ return File.join( @configurator.project_test_results_path, File.basename(filepath).ext(@configurator.extension_testfail) )
+ end
+
+ def form_runner_filepath_from_test(filepath)
+ return File.join( @configurator.project_test_runners_path, File.basename(filepath, @configurator.extension_source)) + @configurator.test_runner_file_suffix + @configurator.extension_source
+ end
+
+ def form_test_filepath_from_runner(filepath)
+ return filepath.sub(/#{TEST_RUNNER_FILE_SUFFIX}/, '')
+ end
+
+ def form_runner_object_filepath_from_test(filepath)
+ return (form_test_build_object_filepath(filepath)).sub(/(#{@configurator.extension_object})$/, "#{@configurator.test_runner_file_suffix}\\1")
+ end
+
+ def form_test_build_object_filepath(filepath)
+ return File.join( @configurator.project_test_build_output_path, File.basename(filepath).ext(@configurator.extension_object) )
+ end
+
+ def form_test_executable_filepath(filepath)
+ return File.join( @configurator.project_test_build_output_path, File.basename(filepath).ext(@configurator.extension_executable) )
+ end
+
+ def form_test_build_map_filepath(filepath)
+ return File.join( @configurator.project_test_build_output_path, File.basename(filepath).ext(@configurator.extension_map) )
+ end
+
+ def form_test_build_list_filepath(filepath)
+ return File.join( @configurator.project_test_build_output_path, File.basename(filepath).ext(@configurator.extension_list) )
+ end
+
+ def form_preprocessed_file_filepath(filepath)
+ return File.join( @configurator.project_test_preprocess_files_path, File.basename(filepath) )
+ end
+
+ def form_preprocessed_includes_list_filepath(filepath)
+ return File.join( @configurator.project_test_preprocess_includes_path, File.basename(filepath) )
+ end
+
+ def form_test_build_objects_filelist(sources)
+ return (@file_wrapper.instantiate_file_list(sources)).pathmap("#{@configurator.project_test_build_output_path}/%n#{@configurator.extension_object}")
+ end
+
+ def form_preprocessed_mockable_headers_filelist(mocks)
+ # pathmapping note: "%{#{@configurator.cmock_mock_prefix},}n" replaces mock_prefix with nothing (signified by absence of anything after comma inside replacement brackets)
+ return (@file_wrapper.instantiate_file_list(mocks)).pathmap("#{@configurator.project_test_preprocess_files_path}/%{#{@configurator.cmock_mock_prefix},}n#{@configurator.extension_header}")
+ end
+
+ def form_mocks_source_filelist(mocks)
+ return (@file_wrapper.instantiate_file_list(mocks)).pathmap("#{@configurator.cmock_mock_path}/%n#{@configurator.extension_source}")
+ end
+
+ def form_test_dependencies_filelist(files)
+ return (@file_wrapper.instantiate_file_list(files)).pathmap("#{@configurator.project_test_dependencies_path}/%n#{@configurator.extension_dependencies}")
+ end
+
+ def form_pass_results_filelist(path, files)
+ return (@file_wrapper.instantiate_file_list(files)).pathmap("#{path}/%n#{@configurator.extension_testpass}")
+ end
+
+end
diff --git a/tests/vendor/ceedling/lib/file_system_utils.rb b/tests/vendor/ceedling/lib/file_system_utils.rb
new file mode 100644
index 000000000..6ba454bbf
--- /dev/null
+++ b/tests/vendor/ceedling/lib/file_system_utils.rb
@@ -0,0 +1,69 @@
+require 'rubygems'
+require 'rake'
+require 'set'
+require 'fileutils'
+require 'file_path_utils.rb'
+
+
+class FileSystemUtils
+
+ constructor :file_wrapper
+
+ # build up path list from input of one or more strings or arrays of (+/-) paths & globs
+ def collect_paths(*paths)
+ raw = [] # all paths and globs
+ plus = Set.new # all paths to expand and add
+ minus = Set.new # all paths to remove from plus set
+
+ # assemble all globs and simple paths, reforming our glob notation to ruby globs
+ paths.each do |paths_container|
+ case (paths_container)
+ when String then raw << (FilePathUtils::reform_glob(paths_container))
+ when Array then paths_container.each {|path| raw << (FilePathUtils::reform_glob(path))}
+ else raise "Don't know how to handle #{paths_container.class}"
+ end
+ end
+
+ # iterate through each path and glob
+ raw.each do |path|
+
+ dirs = [] # container for only (expanded) paths
+
+ # if a glob, expand it and slurp up all non-file paths
+ if path.include?('*')
+ # grab base directory only if globs are snug up to final path separator
+ if (path =~ /\/\*+$/)
+ dirs << FilePathUtils.extract_path(path)
+ end
+
+ # grab expanded sub-directory globs
+ expanded = @file_wrapper.directory_listing( FilePathUtils.extract_path_no_aggregation_operators(path) )
+ expanded.each do |entry|
+ dirs << entry if @file_wrapper.directory?(entry)
+ end
+
+ # else just grab simple path
+ # note: we could just run this through glob expansion but such an
+ # approach doesn't handle a path not yet on disk)
+ else
+ dirs << FilePathUtils.extract_path_no_aggregation_operators(path)
+ end
+
+ # add dirs to the appropriate set based on path aggregation modifier if present
+ FilePathUtils.add_path?(path) ? plus.merge(dirs) : minus.merge(dirs)
+ end
+
+ return (plus - minus).to_a.uniq
+ end
+
+
+ # given a file list, add to it or remove from it
+ def revise_file_list(list, revisions)
+ revisions.each do |revision|
+ # include or exclude file or glob to file list
+ file = FilePathUtils.extract_path_no_aggregation_operators( revision )
+ FilePathUtils.add_path?(revision) ? list.include(file) : list.exclude(file)
+ end
+ end
+
+end
diff --git a/tests/vendor/ceedling/lib/file_system_wrapper.rb b/tests/vendor/ceedling/lib/file_system_wrapper.rb
new file mode 100644
index 000000000..807cbd23f
--- /dev/null
+++ b/tests/vendor/ceedling/lib/file_system_wrapper.rb
@@ -0,0 +1,10 @@
+
+class FileSystemWrapper
+
+ def cd(path)
+ FileUtils.cd path do
+ yield
+ end
+ end
+
+end
\ No newline at end of file
diff --git a/tests/vendor/ceedling/lib/file_wrapper.rb b/tests/vendor/ceedling/lib/file_wrapper.rb
new file mode 100644
index 000000000..55411d1ba
--- /dev/null
+++ b/tests/vendor/ceedling/lib/file_wrapper.rb
@@ -0,0 +1,79 @@
+require 'rubygems'
+require 'rake' # for FileList
+require 'constants'
+require 'fileutils'
+
+
+class FileWrapper
+
+ def get_expanded_path(path)
+ return File.expand_path(path)
+ end
+
+ def basename(path, extension=nil)
+ return File.basename(path, extension) if extension
+ return File.basename(path)
+ end
+
+ def exist?(filepath)
+ return true if (filepath == NULL_FILE_PATH)
+ return File.exist?(filepath)
+ end
+
+ def directory?(path)
+ return File.directory?(path)
+ end
+
+ def dirname(path)
+ return File.dirname(path)
+ end
+
+ def directory_listing(glob)
+ return Dir.glob(glob)
+ end
+
+ def rm_f(filepath, options={})
+ FileUtils.rm_f(filepath, options)
+ end
+
+ def rm_r(filepath, options={})
+ FileUtils.rm_r(filepath, options={})
+ end
+
+ def cp(source, destination, options={})
+ FileUtils.cp(source, destination, options)
+ end
+
+ def compare(from, to)
+ return FileUtils.compare_file(from, to)
+ end
+
+ def open(filepath, flags)
+ File.open(filepath, flags) do |file|
+ yield(file)
+ end
+ end
+
+ def read(filepath)
+ return File.read(filepath)
+ end
+
+ def touch(filepath, options={})
+ FileUtils.touch(filepath, options)
+ end
+
+ def write(filepath, contents, flags='w')
+ File.open(filepath, flags) do |file|
+ file.write(contents)
+ end
+ end
+
+ def readlines(filepath)
+ return File.readlines(filepath)
+ end
+
+ def instantiate_file_list(files=[])
+ return FileList.new(files)
+ end
+
+end
diff --git a/tests/vendor/ceedling/lib/flaginator.rb b/tests/vendor/ceedling/lib/flaginator.rb
new file mode 100644
index 000000000..0693447f9
--- /dev/null
+++ b/tests/vendor/ceedling/lib/flaginator.rb
@@ -0,0 +1,54 @@
+require 'rubygems'
+require 'rake' # for ext()
+require 'fileutils'
+require 'constants'
+
+
+# :flags:
+# :release:
+# :compile:
+# :*: # add '-foo' to compilation of all files not main.c
+# - -foo
+# :main: # add '-Wall' to compilation of main.c
+# - -Wall
+# :test:
+# :link:
+# :test_main: # add '--bar --baz' to linking of test_main.exe
+# - --bar
+# - --baz
+
+
+class Flaginator
+
+ constructor :configurator
+
+ def flag_down( operation, context, file )
+ # create configurator accessor method
+ accessor = ('flags_' + context.to_s).to_sym
+
+ # create simple filename key from whatever filename provided
+ file_key = File.basename( file ).ext('').to_sym
+
+ # if no entry in configuration for flags for this context, bail out
+ return [] if not @configurator.respond_to?( accessor )
+
+ # get flags sub hash associated with this context
+ flags = @configurator.send( accessor )
+
+ # if operation not represented in flags hash, bail out
+ return [] if not flags.include?( operation )
+
+ # redefine flags to sub hash associated with the operation
+ flags = flags[operation]
+
+ # if our file is in the flags hash, extract the array of flags
+ if (flags.include?( file_key )) then return flags[file_key]
+ # if our file isn't in the flags hash, but there is default for all other files, extract array of flags
+ elsif (flags.include?( :* )) then return flags[:*]
+ end
+
+ # fall through: flags were specified but none applying to present file
+ return []
+ end
+
+end
diff --git a/tests/vendor/ceedling/lib/generator.rb b/tests/vendor/ceedling/lib/generator.rb
new file mode 100644
index 000000000..7eaf0d384
--- /dev/null
+++ b/tests/vendor/ceedling/lib/generator.rb
@@ -0,0 +1,164 @@
+require 'constants'
+
+
+class Generator
+
+ constructor :configurator,
+ :generator_helper,
+ :preprocessinator,
+ :cmock_builder,
+ :generator_test_runner,
+ :generator_test_results,
+ :flaginator,
+ :test_includes_extractor,
+ :tool_executor,
+ :file_finder,
+ :file_path_utils,
+ :streaminator,
+ :plugin_manager,
+ :file_wrapper
+
+
+ def generate_shallow_includes_list(context, file)
+ @preprocessinator.preprocess_shallow_includes(file)
+ end
+
+ def generate_preprocessed_file(context, file)
+ @streaminator.stdout_puts("Preprocessing #{File.basename(file)}...", Verbosity::NORMAL)
+ @preprocessinator.preprocess_file(file)
+ end
+
+ def generate_dependencies_file(tool, context, source, object, dependencies)
+ @streaminator.stdout_puts("Generating dependencies for #{File.basename(source)}...", Verbosity::NORMAL)
+
+ command =
+ @tool_executor.build_command_line(
+ tool,
+ source,
+ dependencies,
+ object)
+
+ @tool_executor.exec( command[:line], command[:options] )
+ end
+
+ def generate_mock(context, header_filepath)
+ arg_hash = {:header_file => header_filepath, :context => context}
+ @plugin_manager.pre_mock_generate( arg_hash )
+
+ begin
+ @cmock_builder.cmock.setup_mocks( arg_hash[:header_file] )
+ rescue
+ raise
+ ensure
+ @plugin_manager.post_mock_generate( arg_hash )
+ end
+ end
+
+ # test_filepath may be either preprocessed test file or original test file
+ def generate_test_runner(context, test_filepath, runner_filepath)
+ arg_hash = {:context => context, :test_file => test_filepath, :runner_file => runner_filepath}
+ @plugin_manager.pre_runner_generate(arg_hash)
+
+ # collect info we need
+ module_name = File.basename(arg_hash[:test_file])
+ test_cases = @generator_test_runner.find_test_cases( @file_finder.find_test_from_runner_path(runner_filepath) )
+ mock_list = @test_includes_extractor.lookup_raw_mock_list(arg_hash[:test_file])
+
+ @streaminator.stdout_puts("Generating runner for #{module_name}...", Verbosity::NORMAL)
+
+ # build runner file
+ begin
+ @generator_test_runner.generate(module_name, runner_filepath, test_cases, mock_list)
+ rescue
+ raise
+ ensure
+ @plugin_manager.post_runner_generate(arg_hash)
+ end
+ end
+
+ def generate_object_file(tool, context, source, object, list='')
+ shell_result = {}
+ arg_hash = {:tool => tool, :context => context, :source => source, :object => object, :list => list}
+ @plugin_manager.pre_compile_execute(arg_hash)
+
+ @streaminator.stdout_puts("Compiling #{File.basename(arg_hash[:source])}...", Verbosity::NORMAL)
+ command =
+ @tool_executor.build_command_line( arg_hash[:tool],
+ arg_hash[:source],
+ arg_hash[:object],
+ arg_hash[:list],
+ @flaginator.flag_down( OPERATION_COMPILE_SYM, context, source ) )
+
+ begin
+ shell_result = @tool_executor.exec( command[:line], command[:options] )
+ rescue ShellExecutionException => ex
+ shell_result = ex.shell_result
+ raise ''
+ ensure
+ arg_hash[:shell_result] = shell_result
+ @plugin_manager.post_compile_execute(arg_hash)
+ end
+ end
+
+ def generate_executable_file(tool, context, objects, executable, map='')
+ shell_result = {}
+ arg_hash = {:tool => tool, :context => context, :objects => objects, :executable => executable, :map => map}
+ @plugin_manager.pre_link_execute(arg_hash)
+
+ @streaminator.stdout_puts("Linking #{File.basename(arg_hash[:executable])}...", Verbosity::NORMAL)
+ command =
+ @tool_executor.build_command_line( arg_hash[:tool],
+ arg_hash[:objects],
+ arg_hash[:executable],
+ arg_hash[:map],
+ @flaginator.flag_down( OPERATION_LINK_SYM, context, executable ) )
+
+ begin
+ shell_result = @tool_executor.exec( command[:line], command[:options] )
+ rescue ShellExecutionException => ex
+ notice = "\n" +
+ "NOTICE: If the linker reports missing symbols, the following may be to blame:\n" +
+ " 1. Test lacks #include statements corresponding to needed source files.\n" +
+ " 2. Project search paths do not contain source files corresponding to #include statements in the test.\n"
+
+ if (@configurator.project_use_mocks)
+ notice += " 3. Test does not #include needed mocks.\n\n"
+ else
+ notice += "\n"
+ end
+
+ @streaminator.stderr_puts(notice, Verbosity::COMPLAIN)
+ shell_result = ex.shell_result
+ raise ''
+ ensure
+ arg_hash[:shell_result] = shell_result
+ @plugin_manager.post_link_execute(arg_hash)
+ end
+ end
+
+ def generate_test_results(tool, context, executable, result)
+ arg_hash = {:tool => tool, :context => context, :executable => executable, :result_file => result}
+ @plugin_manager.pre_test_fixture_execute(arg_hash)
+
+ @streaminator.stdout_puts("Running #{File.basename(arg_hash[:executable])}...", Verbosity::NORMAL)
+
+ # Unity's exit code is equivalent to the number of failed tests, so we tell @tool_executor not to fail out if there are failures
+ # so that we can run all tests and collect all results
+ command = @tool_executor.build_command_line(arg_hash[:tool], arg_hash[:executable])
+ command[:options][:boom] = false
+ shell_result = @tool_executor.exec( command[:line], command[:options] )
+
+ @generator_helper.test_results_error_handler(executable, shell_result)
+
+ processed = @generator_test_results.process_and_write_results( shell_result,
+ arg_hash[:result_file],
+ @file_finder.find_test_from_file_path(arg_hash[:executable]) )
+
+ arg_hash[:result_file] = processed[:result_file]
+ arg_hash[:results] = processed[:results]
+ arg_hash[:shell_result] = shell_result # for raw output display if no plugins for formatted display
+
+ @plugin_manager.post_test_fixture_execute(arg_hash)
+ end
+
+end
diff --git a/tests/vendor/ceedling/lib/generator_helper.rb b/tests/vendor/ceedling/lib/generator_helper.rb
new file mode 100644
index 000000000..481c226f3
--- /dev/null
+++ b/tests/vendor/ceedling/lib/generator_helper.rb
@@ -0,0 +1,40 @@
+require 'constants'
+
+
+class GeneratorHelper
+
+ constructor :streaminator
+
+
+ def test_results_error_handler(executable, shell_result)
+ notice = ''
+ error = false
+
+ if (shell_result[:output].nil? or shell_result[:output].strip.empty?)
+ error = true
+ # mirror style of generic tool_executor failure output
+ notice = "\n" +
+ "ERROR: Test executable \"#{File.basename(executable)}\" failed.\n" +
+ "> Produced no output to $stdout.\n"
+ elsif ((shell_result[:output] =~ TEST_STDOUT_STATISTICS_PATTERN).nil?)
+ error = true
+ # mirror style of generic tool_executor failure output
+ notice = "\n" +
+ "ERROR: Test executable \"#{File.basename(executable)}\" failed.\n" +
+ "> Produced no final test result counts in $stdout:\n" +
+ "#{shell_result[:output].strip}\n"
+ end
+
+ if (error)
+ # since we told the tool executor to ignore the exit code, handle it explicitly here
+ notice += "> And exited with status: [#{shell_result[:exit_code]}] (count of failed tests).\n" if (shell_result[:exit_code] != nil)
+ notice += "> And then likely crashed.\n" if (shell_result[:exit_code] == nil)
+
+ notice += "> This is often a symptom of a bad memory access in source or test code.\n\n"
+
+ @streaminator.stderr_puts(notice, Verbosity::COMPLAIN)
+ raise
+ end
+ end
+
+end
diff --git a/tests/vendor/ceedling/lib/generator_test_results.rb b/tests/vendor/ceedling/lib/generator_test_results.rb
new file mode 100644
index 000000000..71d63f218
--- /dev/null
+++ b/tests/vendor/ceedling/lib/generator_test_results.rb
@@ -0,0 +1,89 @@
+require 'rubygems'
+require 'rake' # for .ext()
+require 'constants'
+
+
+class GeneratorTestResults
+
+ constructor :configurator, :generator_test_results_sanity_checker, :yaml_wrapper
+
+ def process_and_write_results(unity_shell_result, results_file, test_file)
+ output_file = results_file
+
+ results = get_results_structure
+
+ results[:source][:path] = File.dirname(test_file)
+ results[:source][:file] = File.basename(test_file)
+
+ # process test statistics
+ if (unity_shell_result[:output] =~ TEST_STDOUT_STATISTICS_PATTERN)
+ results[:counts][:total] = $1.to_i
+ results[:counts][:failed] = $2.to_i
+ results[:counts][:ignored] = $3.to_i
+ results[:counts][:passed] = (results[:counts][:total] - results[:counts][:failed] - results[:counts][:ignored])
+ end
+
+ # remove test statistics lines
+ output_string = unity_shell_result[:output].sub(TEST_STDOUT_STATISTICS_PATTERN, '')
+
+ # bust up the output into individual lines
+ raw_unity_lines = output_string.split(/\n|\r\n/)
+
+ raw_unity_lines.each do |line|
+ # process unity output
+ case line
+ when /(:IGNORE)/
+ elements = extract_line_elements(line, results[:source][:file])
+ results[:ignores] << elements[0]
+ results[:stdout] << elements[1] if (!elements[1].nil?)
+ when /(:PASS$)/
+ elements = extract_line_elements(line, results[:source][:file])
+ results[:successes] << elements[0]
+ results[:stdout] << elements[1] if (!elements[1].nil?)
+ when /(:FAIL)/
+ elements = extract_line_elements(line, results[:source][:file])
+ results[:failures] << elements[0]
+ results[:stdout] << elements[1] if (!elements[1].nil?)
+ else # collect up all other
+ results[:stdout] << line.chomp
+ end
+ end
+
+ @generator_test_results_sanity_checker.verify(results, unity_shell_result[:exit_code])
+
+ output_file = results_file.ext(@configurator.extension_testfail) if (results[:counts][:failed] > 0)
+
+ @yaml_wrapper.dump(output_file, results)
+
+ return { :result_file => output_file, :result => results }
+ end
+
+ private
+
+ def get_results_structure
+ return {
+ :source => {:path => '', :file => ''},
+ :successes => [],
+ :failures => [],
+ :ignores => [],
+ :counts => {:total => 0, :passed => 0, :failed => 0, :ignored => 0},
+ :stdout => [],
+ }
+ end
+
+ def extract_line_elements(line, filename)
+ # handle anything preceding filename in line as extra output to be collected
+ stdout = nil
+ stdout_regex = /(.+)#{Regexp.escape(filename)}.+/i
+
+ if (line =~ stdout_regex)
+ stdout = $1.clone
+ line.sub!(/#{Regexp.escape(stdout)}/, '')
+ end
+
+ # collect up test results minus and extra output
+ elements = (line.strip.split(':'))[1..-1]
+ return {:test => elements[1], :line => elements[0].to_i, :message => (elements[3..-1].join(':')).strip}, stdout
+ end
+
+end
diff --git a/tests/vendor/ceedling/lib/generator_test_results_sanity_checker.rb b/tests/vendor/ceedling/lib/generator_test_results_sanity_checker.rb
new file mode 100644
index 000000000..9f1b65c6d
--- /dev/null
+++ b/tests/vendor/ceedling/lib/generator_test_results_sanity_checker.rb
@@ -0,0 +1,62 @@
+require 'constants'
+require 'rubygems'
+require 'rake' # for ext() method
+
+
+class GeneratorTestResultsSanityChecker
+
+ constructor :configurator, :streaminator
+
+ def verify(results, unity_exit_code)
+
+ # do no sanity checking if it's disabled
+ return if (@configurator.sanity_checks == TestResultsSanityChecks::NONE)
+
+ ceedling_ignores_count = results[:ignores].size
+ ceedling_failures_count = results[:failures].size
+ ceedling_tests_summation = (ceedling_ignores_count + ceedling_failures_count + results[:successes].size)
+
+ # Exit code handling is not a sanity check that can always be performed because
+ # command line simulators may or may not pass through Unity's exit code
+ if (@configurator.sanity_checks >= TestResultsSanityChecks::THOROUGH)
+ # many platforms limit exit codes to a maximum of 255
+ if ((ceedling_failures_count != unity_exit_code) and (unity_exit_code < 255))
+ sanity_check_warning(results[:source][:file], "Unity's exit code (#{unity_exit_code}) does not match Ceedling's summation of failed test cases (#{ceedling_failures_count}).")
+ end
+
+ if ((ceedling_failures_count < 255) and (unity_exit_code == 255))
+ sanity_check_warning(results[:source][:file], "Ceedling's summation of failed test cases (#{ceedling_failures_count}) is less than Unity's exit code (255 or more).")
+ end
+ end
+
+ if (ceedling_ignores_count != results[:counts][:ignored])
+ sanity_check_warning(results[:source][:file], "Unity's final ignore count (#{results[:counts][:ignored]}) does not match Ceedling's summation of ignored test cases (#{ceedling_ignores_count}).")
+ end
+
+ if (ceedling_failures_count != results[:counts][:failed])
+ sanity_check_warning(results[:source][:file], "Unity's final fail count (#{results[:counts][:failed]}) does not match Ceedling's summation of failed test cases (#{ceedling_failures_count}).")
+ end
+
+ if (ceedling_tests_summation != results[:counts][:total])
+ sanity_check_warning(results[:source][:file], "Unity's final test count (#{results[:counts][:total]}) does not match Ceedling's summation of all test cases (#{ceedling_tests_summation}).")
+ end
+
+ end
+
+ private
+
+ def sanity_check_warning(file, message)
+ notice = "\n" +
+ "ERROR: Internal sanity check for test fixture '#{file.ext(@configurator.extension_executable)}' finds that #{message}\n" +
+ " Possible causes:\n" +
+ " 1. Your test + source dereferenced a null pointer.\n" +
+ " 2. Your test + source indexed past the end of a buffer.\n" +
+ " 3. Your test + source committed a memory access violation.\n" +
+ " 4. Your test fixture produced an exit code of 0 despite execution ending prematurely.\n" +
+ " Sanity check failures of test results are usually a symptom of interrupted test execution.\n\n"
+
+ @streaminator.stderr_puts( notice )
+ raise
+ end
+
+end
diff --git a/tests/vendor/ceedling/lib/generator_test_runner.rb b/tests/vendor/ceedling/lib/generator_test_runner.rb
new file mode 100644
index 000000000..bc01e5a03
--- /dev/null
+++ b/tests/vendor/ceedling/lib/generator_test_runner.rb
@@ -0,0 +1,63 @@
+
+class GeneratorTestRunner
+
+ constructor :configurator, :file_path_utils, :file_wrapper
+
+ def find_test_cases(test_file)
+ tests = []
+ tests_and_line_numbers = []
+ lines = []
+
+ # if we don't have preprocessor assistance, do some basic preprocessing of our own
+ if (not @configurator.project_use_test_preprocessor)
+ source = @file_wrapper.read(test_file)
+
+ # remove line comments
+ source = source.gsub(/\/\/.*$/, '')
+ # remove block comments
+ source = source.gsub(/\/\*.*?\*\//m, '')
+
+ # treat preprocessor directives as a logical line
+ lines = source.split(/(^\s*\#.*$) | (;|\{|\}) /x) # match ;, {, and } as end of lines
+ # otherwise, read the preprocessed file raw
+ else
+ lines = @file_wrapper.read( @file_path_utils.form_preprocessed_file_filepath(test_file) ).split(/;|\{|\}/)
+ end
+
+ # step 1. find test functions in (possibly preprocessed) file
+ # (note that lines are not broken up at end of lines)
+ lines.each do |line|
+ if (line =~ /^\s*void\s+((T|t)est.*)\s*\(\s*(void)?\s*\)/m)
+ tests << ($1.strip)
+ end
+ end
+
+ # step 2. associate test functions with line numbers in (non-preprocessed) original file
+ # (note that this time we must scan file contents broken up by end of lines)
+ raw_lines = @file_wrapper.read(test_file).split("\n")
+ raw_index = 0
+
+ tests.each do |test|
+ raw_lines[raw_index..-1].each_with_index do |line, index|
+ # test function might be declared across lines; look for it by its name followed
+ # by a few tell-tale signs
+ if (line =~ /#{test}\s*($|\(|\()/)
+ raw_index += (index + 1)
+ tests_and_line_numbers << {:test => test, :line_number => raw_index}
+ break
+ end
+ end
+ end
+
+ return tests_and_line_numbers
+ end
+
+ def generate(module_name, runner_filepath, test_cases, mock_list)
+ require 'generate_test_runner.rb'
+ @test_runner_generator ||= UnityTestRunnerGenerator.new( @configurator.get_runner_config )
+ @test_runner_generator.generate( module_name,
+ runner_filepath,
+ test_cases,
+ mock_list)
+ end
+end
diff --git a/tests/vendor/ceedling/lib/loginator.rb b/tests/vendor/ceedling/lib/loginator.rb
new file mode 100644
index 000000000..92276e1df
--- /dev/null
+++ b/tests/vendor/ceedling/lib/loginator.rb
@@ -0,0 +1,31 @@
+
+class Loginator
+
+ constructor :configurator, :project_file_loader, :project_config_manager, :file_wrapper, :system_wrapper
+
+
+ def setup_log_filepath
+ config_files = []
+ config_files << @project_file_loader.main_file
+ config_files << @project_file_loader.user_file
+ config_files.concat( @project_config_manager.options_files )
+ config_files.compact!
+ config_files.map! { |file| file.ext('') }
+
+ log_name = config_files.join( '_' )
+
+ @project_log_filepath = File.join( @configurator.project_log_path, log_name.ext('.log') )
+ end
+
+
+ def log(string, heading=nil)
+ return if (not @configurator.project_logging)
+
+ output = "\n[#{@system_wrapper.time_now}]"
+ output += " :: #{heading}" if (not heading.nil?)
+ output += "\n#{string.strip}\n"
+
+ @file_wrapper.write(@project_log_filepath, output, 'a')
+ end
+
+end
diff --git a/tests/vendor/ceedling/lib/makefile.rb b/tests/vendor/ceedling/lib/makefile.rb
new file mode 100644
index 000000000..c3d7496d2
--- /dev/null
+++ b/tests/vendor/ceedling/lib/makefile.rb
@@ -0,0 +1,46 @@
+
+# modified version of Rake's provided make-style dependency loader
+# customizations:
+# (1) handles windows drives in paths -- colons don't confuse task demarcation
+# (2) handles spaces in directory paths
+
+module Rake
+
+ # Makefile loader to be used with the import file loader.
+ class MakefileLoader
+
+ # Load the makefile dependencies in +fn+.
+ def load(fn)
+ open(fn) do |mf|
+ lines = mf.read
+ lines.gsub!(/#[^\n]*\n/m, "") # remove comments
+ lines.gsub!(/\\\n/, ' ') # string together line continuations into single line
+ lines.split("\n").each do |line|
+ process_line(line)
+ end
+ end
+ end
+
+ private
+
+ # Process one logical line of makefile data.
+ def process_line(line)
+ # split on presence of task demaractor followed by space (i.e don't get confused by a colon in a win path)
+ file_tasks, args = line.split(/:\s/)
+
+ return if args.nil?
+
+ # split at non-escaped space boundary between files (i.e. escaped spaces in paths are left alone)
+ dependents = args.split(/\b\s+/)
+ # replace escaped spaces and clean up any extra whitespace
+ dependents.map! { |path| path.gsub(/\\ /, ' ').strip }
+
+ file_tasks.strip.split.each do |file_task|
+ file file_task => dependents
+ end
+ end
+ end
+
+ # Install the handler
+ Rake.application.add_loader('mf', MakefileLoader.new)
+end
diff --git a/tests/vendor/ceedling/lib/objects.yml b/tests/vendor/ceedling/lib/objects.yml
new file mode 100644
index 000000000..a6f189b6c
--- /dev/null
+++ b/tests/vendor/ceedling/lib/objects.yml
@@ -0,0 +1,307 @@
+
+file_wrapper:
+
+file_system_wrapper:
+
+stream_wrapper:
+
+rake_wrapper:
+
+yaml_wrapper:
+
+system_wrapper:
+
+cmock_builder:
+
+reportinator:
+
+rake_utils:
+ compose:
+ - rake_wrapper
+
+system_utils:
+ compose:
+ - system_wrapper
+
+file_path_utils:
+ compose:
+ - configurator
+ - file_wrapper
+
+file_system_utils:
+ compose: file_wrapper
+
+project_file_loader:
+ compose:
+ - yaml_wrapper
+ - stream_wrapper
+ - system_wrapper
+ - file_wrapper
+
+project_config_manager:
+ compose:
+ - cacheinator
+ - yaml_wrapper
+
+cacheinator:
+ compose:
+ - cacheinator_helper
+ - file_path_utils
+ - file_wrapper
+ - yaml_wrapper
+
+cacheinator_helper:
+ compose:
+ - file_wrapper
+ - yaml_wrapper
+
+tool_executor:
+ compose:
+ - configurator
+ - tool_executor_helper
+ - streaminator
+ - system_wrapper
+
+tool_executor_helper:
+ compose:
+ - streaminator
+ - system_utils
+ - system_wrapper
+
+configurator:
+ compose:
+ - configurator_setup
+ - configurator_plugins
+ - configurator_builder
+ - cmock_builder
+ - yaml_wrapper
+ - system_wrapper
+
+configurator_setup:
+ compose:
+ - configurator_builder
+ - configurator_validator
+ - configurator_plugins
+ - stream_wrapper
+
+configurator_plugins:
+ compose:
+ - stream_wrapper
+ - file_wrapper
+ - system_wrapper
+
+configurator_validator:
+ compose:
+ - file_wrapper
+ - stream_wrapper
+ - system_wrapper
+
+configurator_builder:
+ compose:
+ - file_system_utils
+ - file_wrapper
+ - system_wrapper
+
+loginator:
+ compose:
+ - configurator
+ - project_file_loader
+ - project_config_manager
+ - file_wrapper
+ - system_wrapper
+
+streaminator:
+ compose:
+ - streaminator_helper
+ - verbosinator
+ - loginator
+ - stream_wrapper
+
+streaminator_helper:
+
+setupinator:
+
+plugin_builder:
+
+plugin_manager:
+ compose:
+ - configurator
+ - plugin_manager_helper
+ - streaminator
+ - reportinator
+ - system_wrapper
+
+plugin_manager_helper:
+
+plugin_reportinator:
+ compose:
+ - plugin_reportinator_helper
+ - plugin_manager
+ - reportinator
+
+plugin_reportinator_helper:
+ compose:
+ - configurator
+ - streaminator
+ - yaml_wrapper
+ - file_wrapper
+
+verbosinator:
+ compose: configurator
+
+file_finder:
+ compose:
+ - configurator
+ - file_finder_helper
+ - cacheinator
+ - file_path_utils
+ - file_wrapper
+ - yaml_wrapper
+
+file_finder_helper:
+ compose: streaminator
+
+test_includes_extractor:
+ compose:
+ - configurator
+ - yaml_wrapper
+ - file_wrapper
+
+task_invoker:
+ compose:
+ - dependinator
+ - rake_utils
+ - rake_wrapper
+
+flaginator:
+ compose:
+ - configurator
+
+generator:
+ compose:
+ - configurator
+ - generator_helper
+ - preprocessinator
+ - cmock_builder
+ - generator_test_runner
+ - generator_test_results
+ - flaginator
+ - test_includes_extractor
+ - tool_executor
+ - file_finder
+ - file_path_utils
+ - streaminator
+ - plugin_manager
+ - file_wrapper
+
+generator_helper:
+ compose:
+ - streaminator
+
+generator_test_results:
+ compose:
+ - configurator
+ - generator_test_results_sanity_checker
+ - yaml_wrapper
+
+generator_test_results_sanity_checker:
+ compose:
+ - configurator
+ - streaminator
+
+generator_test_runner:
+ compose:
+ - configurator
+ - file_path_utils
+ - file_wrapper
+
+dependinator:
+ compose:
+ - configurator
+ - project_config_manager
+ - test_includes_extractor
+ - file_path_utils
+ - rake_wrapper
+ - file_wrapper
+
+preprocessinator:
+ compose:
+ - preprocessinator_helper
+ - preprocessinator_includes_handler
+ - preprocessinator_file_handler
+ - task_invoker
+ - file_path_utils
+ - yaml_wrapper
+
+preprocessinator_helper:
+ compose:
+ - configurator
+ - test_includes_extractor
+ - task_invoker
+ - file_finder
+ - file_path_utils
+
+preprocessinator_includes_handler:
+ compose:
+ - configurator
+ - tool_executor
+ - task_invoker
+ - file_path_utils
+ - yaml_wrapper
+ - file_wrapper
+
+preprocessinator_file_handler:
+ compose:
+ - preprocessinator_extractor
+ - configurator
+ - tool_executor
+ - file_path_utils
+ - file_wrapper
+
+preprocessinator_extractor:
+
+test_invoker:
+ compose:
+ - configurator
+ - test_invoker_helper
+ - plugin_manager
+ - streaminator
+ - preprocessinator
+ - task_invoker
+ - dependinator
+ - project_config_manager
+ - build_invoker_utils
+ - file_path_utils
+ - file_wrapper
+
+test_invoker_helper:
+ compose:
+ - configurator
+ - task_invoker
+ - test_includes_extractor
+ - file_finder
+ - file_path_utils
+ - file_wrapper
+
+release_invoker:
+ compose:
+ - configurator
+ - release_invoker_helper
+ - build_invoker_utils
+ - dependinator
+ - task_invoker
+ - file_path_utils
+ - file_wrapper
+
+release_invoker_helper:
+ compose:
+ - configurator
+ - dependinator
+ - task_invoker
+
+build_invoker_utils:
+ compose:
+ - configurator
+ - streaminator
+
+erb_wrapper:
diff --git a/tests/vendor/ceedling/lib/par_map.rb b/tests/vendor/ceedling/lib/par_map.rb
new file mode 100644
index 000000000..98198a2ce
--- /dev/null
+++ b/tests/vendor/ceedling/lib/par_map.rb
@@ -0,0 +1,19 @@
+
+
+def par_map(n, things, &block)
+ queue = Queue.new
+ things.each { |thing| queue << thing }
+ threads = (1..n).collect do
+ Thread.new do
+ begin
+ while true
+ yield queue.pop(true)
+ end
+ rescue ThreadError
+
+ end
+ end
+ end
+ threads.each { |t| t.join }
+end
+
diff --git a/tests/vendor/ceedling/lib/plugin.rb b/tests/vendor/ceedling/lib/plugin.rb
new file mode 100644
index 000000000..adce7ac20
--- /dev/null
+++ b/tests/vendor/ceedling/lib/plugin.rb
@@ -0,0 +1,80 @@
+
+class String
+ # reformat a multiline string to have given number of whitespace columns;
+ # helpful for formatting heredocs
+ def left_margin(margin=0)
+ non_whitespace_column = 0
+ new_lines = []
+
+ # find first line with non-whitespace and count left columns of whitespace
+ self.each_line do |line|
+ if (line =~ /^\s*\S/)
+ non_whitespace_column = $&.length - 1
+ break
+ end
+ end
+
+ # iterate through each line, chopping off leftmost whitespace columns and add back the desired whitespace margin
+ self.each_line do |line|
+ columns = []
+ margin.times{columns << ' '}
+ # handle special case of line being narrower than width to be lopped off
+ if (non_whitespace_column < line.length)
+ new_lines << "#{columns.join}#{line[non_whitespace_column..-1]}"
+ else
+ new_lines << "\n"
+ end
+ end
+
+ return new_lines.join
+ end
+end
+
+class Plugin
+ attr_reader :name, :environment
+ attr_accessor :plugin_objects
+
+ def initialize(system_objects, name)
+ @environment = []
+ @ceedling = system_objects
+ @name = name
+ self.setup
+ end
+
+ def setup; end
+
+ # mock generation
+ def pre_mock_generate(arg_hash); end
+ def post_mock_generate(arg_hash); end
+
+ # test runner generation
+ def pre_runner_generate(arg_hash); end
+ def post_runner_generate(arg_hash); end
+
+ # compilation (test or source)
+ def pre_compile_execute(arg_hash); end
+ def post_compile_execute(arg_hash); end
+
+ # linking (test or source)
+ def pre_link_execute(arg_hash); end
+ def post_link_execute(arg_hash); end
+
+ # test fixture execution
+ def pre_test_fixture_execute(arg_hash); end
+ def post_test_fixture_execute(arg_hash); end
+
+ # test task
+ def pre_test; end
+ def post_test; end
+
+ # release task
+ def pre_release; end
+ def post_release; end
+
+ # whole shebang (any use of Ceedling)
+ def pre_build; end
+ def post_build; end
+
+ def summary; end
+
+end
diff --git a/tests/vendor/ceedling/lib/plugin_builder.rb b/tests/vendor/ceedling/lib/plugin_builder.rb
new file mode 100644
index 000000000..e86d32148
--- /dev/null
+++ b/tests/vendor/ceedling/lib/plugin_builder.rb
@@ -0,0 +1,53 @@
+require 'plugin'
+
+class PluginBuilder
+
+ attr_accessor :plugin_objects
+
+ def construct_plugin(plugin_name, object_map_yaml, system_objects)
+ # @streaminator.stdout_puts("Constructing plugin #{plugin_name}...", Verbosity::OBNOXIOUS)
+ object_map = {}
+ @plugin_objects = {}
+ @system_objects = system_objects
+
+ if object_map_yaml
+ @object_map = YAML.load(object_map_yaml)
+ @object_map.each_key do |obj|
+ construct_object(obj)
+ end
+ else
+ raise "Invalid object map for plugin #{plugin_name}!"
+ end
+
+ return @plugin_objects
+ end
+
+ private
+
+ def camelize(underscored_name)
+ return underscored_name.gsub(/(_|^)([a-z0-9])/) {$2.upcase}
+ end
+
+ def construct_object(obj)
+ if @plugin_objects[obj].nil?
+ if @object_map[obj] && @object_map[obj]['compose']
+ @object_map[obj]['compose'].each do |dep|
+ construct_object(dep)
+ end
+ end
+ build_object(obj)
+ end
+ end
+
+ def build_object(new_object)
+ if @plugin_objects[new_object.to_sym].nil?
+ # @streaminator.stdout_puts("Building plugin object #{new_object}", Verbosity::OBNOXIOUS)
+ require new_object
+ class_name = camelize(new_object)
+ new_instance = eval("#{class_name}.new(@system_objects, class_name.to_s)")
+ new_instance.plugin_objects = @plugin_objects
+ @plugin_objects[new_object.to_sym] = new_instance
+ end
+ end
+
+end
\ No newline at end of file
diff --git a/tests/vendor/ceedling/lib/plugin_manager.rb b/tests/vendor/ceedling/lib/plugin_manager.rb
new file mode 100644
index 000000000..699e6b862
--- /dev/null
+++ b/tests/vendor/ceedling/lib/plugin_manager.rb
@@ -0,0 +1,107 @@
+require 'constants'
+require 'set'
+
+class PluginManager
+
+ constructor :configurator, :plugin_manager_helper, :streaminator, :reportinator, :system_wrapper
+
+ def setup
+ @build_fail_registry = []
+ @plugin_objects = [] # so we can preserve order
+ end
+
+ def load_plugin_scripts(script_plugins, system_objects)
+ environment = []
+
+ script_plugins.each do |plugin|
+ # protect against instantiating object multiple times due to processing config multiple times (option files, etc)
+ next if (@plugin_manager_helper.include?(@plugin_objects, plugin))
+ begin
+ @system_wrapper.require_file( "#{plugin}.rb" )
+ object = @plugin_manager_helper.instantiate_plugin_script( camelize(plugin), system_objects, plugin )
+ @plugin_objects << object
+ environment += object.environment
+
+ # add plugins to hash of all system objects
+ system_objects[plugin.downcase.to_sym] = object
+ rescue
+ puts "Exception raised while trying to load plugin: #{plugin}"
+ raise
+ end
+ end
+
+ yield( { :environment => environment } ) if (environment.size > 0)
+ end
+
+ def plugins_failed?
+ return (@build_fail_registry.size > 0)
+ end
+
+ def print_plugin_failures
+ if (@build_fail_registry.size > 0)
+ report = @reportinator.generate_banner('BUILD FAILURE SUMMARY')
+
+ @build_fail_registry.each do |failure|
+ report += "#{' - ' if (@build_fail_registry.size > 1)}#{failure}\n"
+ end
+
+ report += "\n"
+
+ @streaminator.stderr_puts(report, Verbosity::ERRORS)
+ end
+ end
+
+ def register_build_failure(message)
+ @build_fail_registry << message if (message and not message.empty?)
+ end
+
+ #### execute all plugin methods ####
+
+ def pre_mock_generate(arg_hash); execute_plugins(:pre_mock_generate, arg_hash); end
+ def post_mock_generate(arg_hash); execute_plugins(:post_mock_generate, arg_hash); end
+
+ def pre_runner_generate(arg_hash); execute_plugins(:pre_runner_generate, arg_hash); end
+ def post_runner_generate(arg_hash); execute_plugins(:post_runner_generate, arg_hash); end
+
+ def pre_compile_execute(arg_hash); execute_plugins(:pre_compile_execute, arg_hash); end
+ def post_compile_execute(arg_hash); execute_plugins(:post_compile_execute, arg_hash); end
+
+ def pre_link_execute(arg_hash); execute_plugins(:pre_link_execute, arg_hash); end
+ def post_link_execute(arg_hash); execute_plugins(:post_link_execute, arg_hash); end
+
+ def pre_test_fixture_execute(arg_hash); execute_plugins(:pre_test_fixture_execute, arg_hash); end
+ def post_test_fixture_execute(arg_hash)
+ # special arbitration: raw test results are printed or taken over by plugins handling the job
+ @streaminator.stdout_puts(arg_hash[:shell_result][:output]) if (@configurator.plugins_display_raw_test_results)
+ execute_plugins(:post_test_fixture_execute, arg_hash)
+ end
+
+ def pre_test; execute_plugins(:pre_test); end
+ def post_test; execute_plugins(:post_test); end
+
+ def pre_release; execute_plugins(:pre_release); end
+ def post_release; execute_plugins(:post_release); end
+
+ def pre_build; execute_plugins(:pre_build); end
+ def post_build; execute_plugins(:post_build); end
+
+ def summary; execute_plugins(:summary); end
+
+ private ####################################
+
+ def camelize(underscored_name)
+ return underscored_name.gsub(/(_|^)([a-z0-9])/) {$2.upcase}
+ end
+
+ def execute_plugins(method, *args)
+ @plugin_objects.each do |plugin|
+ begin
+ plugin.send(method, *args)
+ rescue
+ puts "Exception raised in plugin: #{plugin.name}, in method #{method}"
+ raise
+ end
+ end
+ end
+
+end
diff --git a/tests/vendor/ceedling/lib/plugin_manager_helper.rb b/tests/vendor/ceedling/lib/plugin_manager_helper.rb
new file mode 100644
index 000000000..b18248a65
--- /dev/null
+++ b/tests/vendor/ceedling/lib/plugin_manager_helper.rb
@@ -0,0 +1,19 @@
+
+class PluginManagerHelper
+
+ def include?(plugins, name)
+ include = false
+ plugins.each do |plugin|
+ if (plugin.name == name)
+ include = true
+ break
+ end
+ end
+ return include
+ end
+
+ def instantiate_plugin_script(plugin, system_objects, name)
+ return eval("#{plugin}.new(system_objects, name)")
+ end
+
+end
diff --git a/tests/vendor/ceedling/lib/plugin_reportinator.rb b/tests/vendor/ceedling/lib/plugin_reportinator.rb
new file mode 100644
index 000000000..b08801aa3
--- /dev/null
+++ b/tests/vendor/ceedling/lib/plugin_reportinator.rb
@@ -0,0 +1,75 @@
+require 'constants'
+require 'defaults'
+
+class PluginReportinator
+
+ constructor :plugin_reportinator_helper, :plugin_manager, :reportinator
+
+ def setup
+ @test_results_template = nil
+ end
+
+
+ def set_system_objects(system_objects)
+ @plugin_reportinator_helper.ceedling = system_objects
+ end
+
+
+ def fetch_results(results_path, test, options={:boom => false})
+ return @plugin_reportinator_helper.fetch_results( File.join(results_path, test), options )
+ end
+
+
+ def generate_banner(message)
+ return @reportinator.generate_banner(message)
+ end
+
+
+ def assemble_test_results(results_list, options={:boom => false})
+ aggregated_results = get_results_structure
+
+ results_list.each do |result_path|
+ results = @plugin_reportinator_helper.fetch_results( result_path, options )
+ @plugin_reportinator_helper.process_results(aggregated_results, results)
+ end
+
+ return aggregated_results
+ end
+
+
+ def register_test_results_template(template)
+ @test_results_template = template if (@test_results_template.nil?)
+ end
+
+
+ def run_test_results_report(hash, verbosity=Verbosity::NORMAL, &block)
+ run_report( $stdout,
+ ((@test_results_template.nil?) ? DEFAULT_TESTS_RESULTS_REPORT_TEMPLATE : @test_results_template),
+ hash,
+ verbosity,
+ &block )
+ end
+
+
+ def run_report(stream, template, hash=nil, verbosity=Verbosity::NORMAL)
+ failure = nil
+ failure = yield() if block_given?
+
+ @plugin_manager.register_build_failure( failure )
+
+ @plugin_reportinator_helper.run_report( stream, template, hash, verbosity )
+ end
+
+ private ###############################
+
+ def get_results_structure
+ return {
+ :successes => [],
+ :failures => [],
+ :ignores => [],
+ :stdout => [],
+ :counts => {:total => 0, :passed => 0, :failed => 0, :ignored => 0, :stdout => 0}
+ }
+ end
+
+end
\ No newline at end of file
diff --git a/tests/vendor/ceedling/lib/plugin_reportinator_helper.rb b/tests/vendor/ceedling/lib/plugin_reportinator_helper.rb
new file mode 100644
index 000000000..c30a83366
--- /dev/null
+++ b/tests/vendor/ceedling/lib/plugin_reportinator_helper.rb
@@ -0,0 +1,52 @@
+require 'constants'
+require 'erb'
+require 'rubygems'
+require 'rake' # for ext()
+
+
+class PluginReportinatorHelper
+
+ attr_writer :ceedling
+
+ constructor :configurator, :streaminator, :yaml_wrapper, :file_wrapper
+
+ def fetch_results(results_path, options)
+ pass_path = File.join(results_path.ext( @configurator.extension_testpass ))
+ fail_path = File.join(results_path.ext( @configurator.extension_testfail ))
+
+ if (@file_wrapper.exist?(fail_path))
+ return @yaml_wrapper.load(fail_path)
+ elsif (@file_wrapper.exist?(pass_path))
+ return @yaml_wrapper.load(pass_path)
+ else
+ if (options[:boom])
+ @streaminator.stderr_puts("Could find no test results for '#{File.basename(results_path).ext(@configurator.extension_source)}'", Verbosity::ERRORS)
+ raise
+ end
+ end
+
+ return {}
+ end
+
+
+ def process_results(aggregate_results, results)
+ return if (results.empty?)
+
+ aggregate_results[:successes] << { :source => results[:source].clone, :collection => results[:successes].clone } if (results[:successes].size > 0)
+ aggregate_results[:failures] << { :source => results[:source].clone, :collection => results[:failures].clone } if (results[:failures].size > 0)
+ aggregate_results[:ignores] << { :source => results[:source].clone, :collection => results[:ignores].clone } if (results[:ignores].size > 0)
+ aggregate_results[:stdout] << { :source => results[:source].clone, :collection => results[:stdout].clone } if (results[:stdout].size > 0)
+ aggregate_results[:counts][:total] += results[:counts][:total]
+ aggregate_results[:counts][:passed] += results[:counts][:passed]
+ aggregate_results[:counts][:failed] += results[:counts][:failed]
+ aggregate_results[:counts][:ignored] += results[:counts][:ignored]
+ aggregate_results[:counts][:stdout] += results[:stdout].size
+ end
+
+
+ def run_report(stream, template, hash, verbosity)
+ output = ERB.new(template, 0, "%<>")
+ @streaminator.stream_puts(stream, output.result(binding()), verbosity)
+ end
+
+end
\ No newline at end of file
diff --git a/tests/vendor/ceedling/lib/preprocessinator.rb b/tests/vendor/ceedling/lib/preprocessinator.rb
new file mode 100644
index 000000000..e5c46c373
--- /dev/null
+++ b/tests/vendor/ceedling/lib/preprocessinator.rb
@@ -0,0 +1,43 @@
+
+class Preprocessinator
+
+ attr_reader :preprocess_file_proc
+
+ constructor :preprocessinator_helper, :preprocessinator_includes_handler, :preprocessinator_file_handler, :task_invoker, :file_path_utils, :yaml_wrapper
+
+
+ def setup
+ # fashion ourselves callbacks @preprocessinator_helper can use
+ @preprocess_includes_proc = Proc.new { |filepath| self.preprocess_shallow_includes(filepath) }
+ @preprocess_file_proc = Proc.new { |filepath| self.preprocess_file(filepath) }
+ end
+
+
+ def preprocess_test_and_invoke_test_mocks(test)
+ @preprocessinator_helper.preprocess_includes(test, @preprocess_includes_proc)
+
+ mocks_list = @preprocessinator_helper.assemble_mocks_list(test)
+
+ @preprocessinator_helper.preprocess_mockable_headers(mocks_list, @preprocess_file_proc)
+
+ @task_invoker.invoke_test_mocks(mocks_list)
+
+ @preprocessinator_helper.preprocess_test_file(test, @preprocess_file_proc)
+
+ return mocks_list
+ end
+
+ def preprocess_shallow_includes(filepath)
+ dependencies_rule = @preprocessinator_includes_handler.form_shallow_dependencies_rule(filepath)
+ includes = @preprocessinator_includes_handler.extract_shallow_includes(dependencies_rule)
+
+ @preprocessinator_includes_handler.write_shallow_includes_list(
+ @file_path_utils.form_preprocessed_includes_list_filepath(filepath), includes)
+ end
+
+ def preprocess_file(filepath)
+ @preprocessinator_includes_handler.invoke_shallow_includes_list(filepath)
+ @preprocessinator_file_handler.preprocess_file( filepath, @yaml_wrapper.load(@file_path_utils.form_preprocessed_includes_list_filepath(filepath)) )
+ end
+
+end
diff --git a/tests/vendor/ceedling/lib/preprocessinator_extractor.rb b/tests/vendor/ceedling/lib/preprocessinator_extractor.rb
new file mode 100644
index 000000000..fd53a91f1
--- /dev/null
+++ b/tests/vendor/ceedling/lib/preprocessinator_extractor.rb
@@ -0,0 +1,30 @@
+class PreprocessinatorExtractor
+ def extract_base_file_from_preprocessed_expansion(filepath)
+ # preprocessing by way of toolchain preprocessor expands macros, eliminates
+ # comments, strips out #ifdef code, etc. however, it also expands in place
+ # each #include'd file. so, we must extract only the lines of the file
+ # that belong to the file originally preprocessed
+
+ # iterate through all lines and alternate between extract and ignore modes
+ # all lines between a '#'line containing file name of our filepath and the
+ # next '#'line should be extracted
+
+ base_name = File.basename(filepath)
+ not_pragma = /^#(?!pragma\b)/ # preprocessor directive that's not a #pragma
+ pattern = /^#.*(\s|\/|\\|\")#{Regexp.escape(base_name)}/
+ found_file = false # have we found the file we care about?
+
+ lines = []
+ File.readlines(filepath).each do |line|
+ if found_file and not line.match(not_pragma)
+ lines << line
+ else
+ found_file = false
+ end
+
+ found_file = true if line.match(pattern)
+ end
+
+ return lines
+ end
+end
diff --git a/tests/vendor/ceedling/lib/preprocessinator_file_handler.rb b/tests/vendor/ceedling/lib/preprocessinator_file_handler.rb
new file mode 100644
index 000000000..65020ed7a
--- /dev/null
+++ b/tests/vendor/ceedling/lib/preprocessinator_file_handler.rb
@@ -0,0 +1,21 @@
+
+
+class PreprocessinatorFileHandler
+
+ constructor :preprocessinator_extractor, :configurator, :tool_executor, :file_path_utils, :file_wrapper
+
+
+ def preprocess_file(filepath, includes)
+ preprocessed_filepath = @file_path_utils.form_preprocessed_file_filepath(filepath)
+
+ command = @tool_executor.build_command_line(@configurator.tools_test_file_preprocessor, filepath, preprocessed_filepath)
+ @tool_executor.exec(command[:line], command[:options])
+
+ contents = @preprocessinator_extractor.extract_base_file_from_preprocessed_expansion(preprocessed_filepath)
+
+ includes.each{|include| contents.unshift("#include \"#{include}\"")}
+
+ @file_wrapper.write(preprocessed_filepath, contents.join("\n"))
+ end
+
+end
diff --git a/tests/vendor/ceedling/lib/preprocessinator_helper.rb b/tests/vendor/ceedling/lib/preprocessinator_helper.rb
new file mode 100644
index 000000000..174f86d28
--- /dev/null
+++ b/tests/vendor/ceedling/lib/preprocessinator_helper.rb
@@ -0,0 +1,46 @@
+
+
+class PreprocessinatorHelper
+
+ constructor :configurator, :test_includes_extractor, :task_invoker, :file_finder, :file_path_utils
+
+
+ def preprocess_includes(test, preprocess_includes_proc)
+ if (@configurator.project_use_test_preprocessor)
+ preprocessed_includes_list = @file_path_utils.form_preprocessed_includes_list_filepath(test)
+ preprocess_includes_proc.call( @file_finder.find_test_from_file_path(preprocessed_includes_list) )
+ @test_includes_extractor.parse_includes_list(preprocessed_includes_list)
+ else
+ @test_includes_extractor.parse_test_file(test)
+ end
+ end
+
+ def assemble_mocks_list(test)
+ return @file_path_utils.form_mocks_source_filelist( @test_includes_extractor.lookup_raw_mock_list(test) )
+ end
+
+ def preprocess_mockable_headers(mock_list, preprocess_file_proc)
+ if (@configurator.project_use_test_preprocessor)
+ preprocess_files_smartly(
+ @file_path_utils.form_preprocessed_mockable_headers_filelist(mock_list),
+ preprocess_file_proc ) { |file| @file_finder.find_header_file(file) }
+ end
+ end
+
+ def preprocess_test_file(test, preprocess_file_proc)
+ return if (!@configurator.project_use_test_preprocessor)
+
+ preprocess_file_proc.call(test)
+ end
+
+ private ############################
+
+ def preprocess_files_smartly(file_list, preprocess_file_proc)
+ if (@configurator.project_use_deep_dependencies)
+ @task_invoker.invoke_test_preprocessed_files(file_list)
+ else
+ file_list.each { |file| preprocess_file_proc.call( yield(file) ) }
+ end
+ end
+
+end
diff --git a/tests/vendor/ceedling/lib/preprocessinator_includes_handler.rb b/tests/vendor/ceedling/lib/preprocessinator_includes_handler.rb
new file mode 100644
index 000000000..6199e4cc7
--- /dev/null
+++ b/tests/vendor/ceedling/lib/preprocessinator_includes_handler.rb
@@ -0,0 +1,55 @@
+
+
+class PreprocessinatorIncludesHandler
+
+ constructor :configurator, :tool_executor, :task_invoker, :file_path_utils, :yaml_wrapper, :file_wrapper
+
+ # shallow includes: only those headers a source file explicitly includes
+
+ def invoke_shallow_includes_list(filepath)
+ @task_invoker.invoke_test_shallow_include_lists( [@file_path_utils.form_preprocessed_includes_list_filepath(filepath)] )
+ end
+
+ # ask the preprocessor for a make-style dependency rule of only the headers the source file immediately includes
+ def form_shallow_dependencies_rule(filepath)
+ # change filename (prefix of '_') to prevent preprocessor from finding include files in temp directory containing file it's scanning
+ temp_filepath = @file_path_utils.form_temp_path(filepath, '_')
+
+ # read the file and replace all include statements with a decorated version
+ # (decorating the names creates file names that don't exist, thus preventing the preprocessor
+ # from snaking out and discovering the entire include path that winds through the code)
+ contents = @file_wrapper.read(filepath)
+ contents.gsub!( /#include\s+\"\s*(\S+)\s*\"/, "#include \"\\1\"\n#include \"@@@@\\1\"" )
+ @file_wrapper.write( temp_filepath, contents )
+
+ # extract the make-style dependency rule telling the preprocessor to
+ # ignore the fact that it can't find the included files
+ command = @tool_executor.build_command_line(@configurator.tools_test_includes_preprocessor, temp_filepath)
+ shell_result = @tool_executor.exec(command[:line], command[:options])
+
+ return shell_result[:output]
+ end
+
+ # headers only; ignore any crazy .c includes
+ def extract_shallow_includes(make_rule)
+ list = []
+ header_extension = @configurator.extension_header
+
+ headers = make_rule.scan(/(\S+#{'\\'+header_extension})/).flatten # escape slashes before dot file extension
+ headers.uniq!
+ headers.map! { |header| header.sub(/(@@@@)|(.+\/)/, '') }
+ headers.sort!
+
+ headers.each_with_index do |header, index|
+ break if (headers.size == (index-1))
+ list << header if (header == headers[index + 1])
+ end
+
+ return list
+ end
+
+ def write_shallow_includes_list(filepath, list)
+ @yaml_wrapper.dump(filepath, list)
+ end
+
+end
diff --git a/tests/vendor/ceedling/lib/project_config_manager.rb b/tests/vendor/ceedling/lib/project_config_manager.rb
new file mode 100644
index 000000000..3599689ed
--- /dev/null
+++ b/tests/vendor/ceedling/lib/project_config_manager.rb
@@ -0,0 +1,38 @@
+require 'constants'
+
+
+class ProjectConfigManager
+
+ attr_reader :options_files, :release_config_changed, :test_config_changed
+ attr_accessor :config_hash
+
+ constructor :cacheinator, :yaml_wrapper
+
+
+ def setup
+ @options_files = []
+ @release_config_changed = false
+ @test_config_changed = false
+ end
+
+
+ def merge_options(config_hash, option_filepath)
+ @options_files << File.basename( option_filepath )
+ config_hash.deep_merge( @yaml_wrapper.load( option_filepath ) )
+ return config_hash
+ end
+
+
+
+ def process_release_config_change
+ # has project configuration changed since last release build
+ @release_config_changed = @cacheinator.diff_cached_release_config?( @config_hash )
+ end
+
+
+ def process_test_config_change
+ # has project configuration changed since last test build
+ @test_config_changed = @cacheinator.diff_cached_test_config?( @config_hash )
+ end
+
+end
diff --git a/tests/vendor/ceedling/lib/project_file_loader.rb b/tests/vendor/ceedling/lib/project_file_loader.rb
new file mode 100644
index 000000000..b0ef8c5dc
--- /dev/null
+++ b/tests/vendor/ceedling/lib/project_file_loader.rb
@@ -0,0 +1,64 @@
+require 'constants'
+
+
+class ProjectFileLoader
+
+ attr_reader :main_file, :user_file
+
+ constructor :yaml_wrapper, :stream_wrapper, :system_wrapper, :file_wrapper
+
+ def setup
+ @main_file = nil
+ @user_file = nil
+
+ @main_project_filepath = ''
+ @user_project_filepath = ''
+ end
+
+
+ def find_project_files
+ # first go hunting for optional user project file by looking for environment variable and then default location on disk
+ user_filepath = @system_wrapper.env_get('CEEDLING_USER_PROJECT_FILE')
+
+ if ( not user_filepath.nil? and @file_wrapper.exist?(user_filepath) )
+ @user_project_filepath = user_filepath
+ elsif (@file_wrapper.exist?(DEFAULT_CEEDLING_USER_PROJECT_FILE))
+ @user_project_filepath = DEFAULT_CEEDLING_USER_PROJECT_FILE
+ end
+
+ # next check for main project file by looking for environment variable and then default location on disk;
+ # blow up if we don't find this guy -- like, he's so totally important
+ main_filepath = @system_wrapper.env_get('CEEDLING_MAIN_PROJECT_FILE')
+
+ if ( not main_filepath.nil? and @file_wrapper.exist?(main_filepath) )
+ @main_project_filepath = main_filepath
+ elsif (@file_wrapper.exist?(DEFAULT_CEEDLING_MAIN_PROJECT_FILE))
+ @main_project_filepath = DEFAULT_CEEDLING_MAIN_PROJECT_FILE
+ else
+ # no verbosity checking since this is lowest level reporting anyhow &
+ # verbosity checking depends on configurator which in turns needs this class (circular dependency)
+ @stream_wrapper.stderr_puts('Found no Ceedling project file (*.yml)')
+ raise
+ end
+
+ @main_file = File.basename( @main_project_filepath )
+ @user_file = File.basename( @user_project_filepath ) if ( not @user_project_filepath.empty? )
+ end
+
+
+ def load_project_config
+ config_hash = {}
+
+ # if there's no user project file, then just provide hash from project file
+ if (@user_project_filepath.empty?)
+ config_hash = @yaml_wrapper.load(@main_project_filepath)
+ # if there is a user project file, load it too and merge it on top of the project file,
+ # superseding anything that's common between them
+ else
+ config_hash = (@yaml_wrapper.load(@main_project_filepath)).merge(@yaml_wrapper.load(@user_project_filepath))
+ end
+
+ return config_hash
+ end
+
+end
diff --git a/tests/vendor/ceedling/lib/rake_utils.rb b/tests/vendor/ceedling/lib/rake_utils.rb
new file mode 100644
index 000000000..3f667c852
--- /dev/null
+++ b/tests/vendor/ceedling/lib/rake_utils.rb
@@ -0,0 +1,17 @@
+
+class RakeUtils
+
+ constructor :rake_wrapper
+
+ def task_invoked?(task_regex)
+ task_invoked = false
+ @rake_wrapper.task_list.each do |task|
+ if ((task.already_invoked) and (task.to_s =~ task_regex))
+ task_invoked = true
+ break
+ end
+ end
+ return task_invoked
+ end
+
+end
diff --git a/tests/vendor/ceedling/lib/rake_wrapper.rb b/tests/vendor/ceedling/lib/rake_wrapper.rb
new file mode 100644
index 000000000..346936545
--- /dev/null
+++ b/tests/vendor/ceedling/lib/rake_wrapper.rb
@@ -0,0 +1,33 @@
+require 'rubygems'
+require 'rake'
+require 'makefile' # our replacement for rake's make-style dependency loader
+
+include Rake::DSL if defined?(Rake::DSL)
+
+class Rake::Task
+ attr_reader :already_invoked
+end
+
+class RakeWrapper
+
+ def initialize
+ @makefile_loader = Rake::MakefileLoader.new # use our custom replacement noted above
+ end
+
+ def [](task)
+ return Rake::Task[task]
+ end
+
+ def task_list
+ return Rake::Task.tasks
+ end
+
+ def create_file_task(file_task, dependencies)
+ file(file_task => dependencies)
+ end
+
+ def load_dependencies(dependencies_path)
+ @makefile_loader.load(dependencies_path)
+ end
+
+end
diff --git a/tests/vendor/ceedling/lib/rakefile.rb b/tests/vendor/ceedling/lib/rakefile.rb
new file mode 100644
index 000000000..153c0bdee
--- /dev/null
+++ b/tests/vendor/ceedling/lib/rakefile.rb
@@ -0,0 +1,74 @@
+require 'fileutils'
+
+# get directory containing this here file, back up one directory, and expand to full path
+CEEDLING_ROOT = File.expand_path(File.dirname(__FILE__) + '/..')
+CEEDLING_LIB = File.join(CEEDLING_ROOT, 'lib')
+CEEDLING_VENDOR = File.join(CEEDLING_ROOT, 'vendor')
+CEEDLING_RELEASE = File.join(CEEDLING_ROOT, 'release')
+
+$LOAD_PATH.unshift( CEEDLING_LIB )
+$LOAD_PATH.unshift( File.join(CEEDLING_VENDOR, 'unity/auto') )
+$LOAD_PATH.unshift( File.join(CEEDLING_VENDOR, 'diy/lib') )
+$LOAD_PATH.unshift( File.join(CEEDLING_VENDOR, 'constructor/lib') )
+$LOAD_PATH.unshift( File.join(CEEDLING_VENDOR, 'cmock/lib') )
+$LOAD_PATH.unshift( File.join(CEEDLING_VENDOR, 'deep_merge/lib') )
+
+require 'rake'
+
+require 'diy'
+require 'constructor'
+
+require 'constants'
+require 'target_loader'
+
+
+# construct all our objects
+@ceedling = DIY::Context.from_yaml( File.read( File.join(CEEDLING_LIB, 'objects.yml') ) )
+@ceedling.build_everything
+
+# one-stop shopping for all our setup and such after construction
+@ceedling[:setupinator].ceedling = @ceedling
+
+project_config =
+ begin
+ cfg = @ceedling[:setupinator].load_project_files
+ TargetLoader.inspect(cfg, ENV['TARGET'])
+ rescue TargetLoader::NoTargets
+ cfg
+ rescue TargetLoader::RequestReload
+ @ceedling[:setupinator].load_project_files
+ end
+
+@ceedling[:setupinator].do_setup( project_config )
+
+
+# tell all our plugins we're about to do something
+@ceedling[:plugin_manager].pre_build
+
+# load rakefile component files (*.rake)
+PROJECT_RAKEFILE_COMPONENT_FILES.each { |component| load(component) }
+
+# tell rake to shut up by default (overridden in verbosity / debug tasks as appropriate)
+verbose(false)
+
+
+# end block always executed following rake run
+END {
+ # cache our input configurations to use in comparison upon next execution
+ @ceedling[:cacheinator].cache_test_config( @ceedling[:setupinator].config_hash ) if (@ceedling[:task_invoker].test_invoked?)
+ @ceedling[:cacheinator].cache_release_config( @ceedling[:setupinator].config_hash ) if (@ceedling[:task_invoker].release_invoked?)
+
+ # delete all temp files unless we're in debug mode
+ if (not @ceedling[:configurator].project_debug)
+ @ceedling[:file_wrapper].rm_f( @ceedling[:file_wrapper].directory_listing( File.join(@ceedling[:configurator].project_temp_path, '*') ))
+ end
+
+ # only perform these final steps if we got here without runtime exceptions or errors
+ if (@ceedling[:system_wrapper].ruby_success)
+
+ # tell all our plugins the build is done and process results
+ @ceedling[:plugin_manager].post_build
+ @ceedling[:plugin_manager].print_plugin_failures
+ exit(1) if (@ceedling[:plugin_manager].plugins_failed?)
+ end
+}
diff --git a/tests/vendor/ceedling/lib/release_invoker.rb b/tests/vendor/ceedling/lib/release_invoker.rb
new file mode 100644
index 000000000..d51bf9b39
--- /dev/null
+++ b/tests/vendor/ceedling/lib/release_invoker.rb
@@ -0,0 +1,58 @@
+require 'constants'
+
+
+class ReleaseInvoker
+
+ constructor :configurator, :release_invoker_helper, :build_invoker_utils, :dependinator, :task_invoker, :file_path_utils, :file_wrapper
+
+
+ def setup_and_invoke_c_objects( c_files )
+ objects = @file_path_utils.form_release_build_c_objects_filelist( c_files )
+
+ begin
+ @release_invoker_helper.process_deep_dependencies( @file_path_utils.form_release_dependencies_filelist( c_files ) )
+
+ @dependinator.enhance_release_file_dependencies( objects )
+ @task_invoker.invoke_release_objects( objects )
+ rescue => e
+ @build_invoker_utils.process_exception( e, RELEASE_SYM, false )
+ end
+
+ return objects
+ end
+
+
+ def setup_and_invoke_asm_objects( asm_files )
+ objects = @file_path_utils.form_release_build_asm_objects_filelist( asm_files )
+
+ begin
+ @dependinator.enhance_release_file_dependencies( objects )
+ @task_invoker.invoke_release_objects( objects )
+ rescue => e
+ @build_invoker_utils.process_exception( e, RELEASE_SYM, false )
+ end
+
+ return objects
+ end
+
+
+ def refresh_c_deep_dependencies
+ return if (not @configurator.project_use_deep_dependencies)
+
+ @file_wrapper.rm_f(
+ @file_wrapper.directory_listing(
+ File.join( @configurator.project_release_dependencies_path, '*' + @configurator.extension_dependencies ) ) )
+
+ @release_invoker_helper.process_deep_dependencies(
+ @file_path_utils.form_release_dependencies_filelist(
+ @configurator.collection_all_source ) )
+ end
+
+
+ def artifactinate( *files )
+ files.flatten.each do |file|
+ @file_wrapper.cp( file, @configurator.project_release_artifacts_path ) if @file_wrapper.exist?( file )
+ end
+ end
+
+end
diff --git a/tests/vendor/ceedling/lib/release_invoker_helper.rb b/tests/vendor/ceedling/lib/release_invoker_helper.rb
new file mode 100644
index 000000000..8257aab73
--- /dev/null
+++ b/tests/vendor/ceedling/lib/release_invoker_helper.rb
@@ -0,0 +1,16 @@
+
+
+class ReleaseInvokerHelper
+
+ constructor :configurator, :dependinator, :task_invoker
+
+
+ def process_deep_dependencies(dependencies_list)
+ return if (not @configurator.project_use_deep_dependencies)
+
+ @dependinator.enhance_release_file_dependencies( dependencies_list )
+ @task_invoker.invoke_release_dependencies_files( dependencies_list )
+ @dependinator.load_release_object_deep_dependencies( dependencies_list )
+ end
+
+end
diff --git a/tests/vendor/ceedling/lib/reportinator.rb b/tests/vendor/ceedling/lib/reportinator.rb
new file mode 100644
index 000000000..a41e9a015
--- /dev/null
+++ b/tests/vendor/ceedling/lib/reportinator.rb
@@ -0,0 +1,9 @@
+
+class Reportinator
+
+ def generate_banner(message, width=nil)
+ dash_count = ((width.nil?) ? message.strip.length : width)
+ return "#{'-' * dash_count}\n#{message}\n#{'-' * dash_count}\n"
+ end
+
+end
diff --git a/tests/vendor/ceedling/lib/rules_cmock.rake b/tests/vendor/ceedling/lib/rules_cmock.rake
new file mode 100644
index 000000000..1e2da0536
--- /dev/null
+++ b/tests/vendor/ceedling/lib/rules_cmock.rake
@@ -0,0 +1,9 @@
+
+
+rule(/#{CMOCK_MOCK_PREFIX}.+#{'\\'+EXTENSION_SOURCE}$/ => [
+ proc do |task_name|
+ @ceedling[:file_finder].find_header_input_for_mock_file(task_name)
+ end
+ ]) do |mock|
+ @ceedling[:generator].generate_mock(TEST_SYM, mock.source)
+end
diff --git a/tests/vendor/ceedling/lib/rules_preprocess.rake b/tests/vendor/ceedling/lib/rules_preprocess.rake
new file mode 100644
index 000000000..c29111272
--- /dev/null
+++ b/tests/vendor/ceedling/lib/rules_preprocess.rake
@@ -0,0 +1,26 @@
+
+
+# invocations against this rule should only happen when enhanced dependencies are enabled;
+# otherwise, dependency tracking will be too shallow and preprocessed files could intermittently
+# fail to be updated when they actually need to be.
+rule(/#{PROJECT_TEST_PREPROCESS_FILES_PATH}\/.+/ => [
+ proc do |task_name|
+ @ceedling[:file_finder].find_test_or_source_or_header_file(task_name)
+ end
+ ]) do |file|
+ if (not @ceedling[:configurator].project_use_deep_dependencies)
+ raise 'ERROR: Ceedling preprocessing rule invoked though neccessary auxiliary dependency support not enabled.'
+ end
+ @ceedling[:generator].generate_preprocessed_file(TEST_SYM, file.source)
+end
+
+
+# invocations against this rule can always happen as there are no deeper dependencies to consider
+rule(/#{PROJECT_TEST_PREPROCESS_INCLUDES_PATH}\/.+/ => [
+ proc do |task_name|
+ @ceedling[:file_finder].find_test_or_source_or_header_file(task_name)
+ end
+ ]) do |file|
+ @ceedling[:generator].generate_shallow_includes_list(TEST_SYM, file.source)
+end
+
diff --git a/tests/vendor/ceedling/lib/rules_release.rake b/tests/vendor/ceedling/lib/rules_release.rake
new file mode 100644
index 000000000..00326aba2
--- /dev/null
+++ b/tests/vendor/ceedling/lib/rules_release.rake
@@ -0,0 +1,79 @@
+
+RELEASE_COMPILE_TASK_ROOT = RELEASE_TASK_ROOT + 'compile:'
+RELEASE_ASSEMBLE_TASK_ROOT = RELEASE_TASK_ROOT + 'assemble:'
+
+
+if (RELEASE_BUILD_USE_ASSEMBLY)
+rule(/#{PROJECT_RELEASE_BUILD_OUTPUT_ASM_PATH}\/#{'.+\\'+EXTENSION_OBJECT}$/ => [
+ proc do |task_name|
+ @ceedling[:file_finder].find_assembly_file(task_name)
+ end
+ ]) do |object|
+ @ceedling[:generator].generate_object_file(
+ TOOLS_RELEASE_ASSEMBLER,
+ RELEASE_SYM,
+ object.source,
+ object.name )
+end
+end
+
+
+rule(/#{PROJECT_RELEASE_BUILD_OUTPUT_C_PATH}\/#{'.+\\'+EXTENSION_OBJECT}$/ => [
+ proc do |task_name|
+ @ceedling[:file_finder].find_compilation_input_file(task_name)
+ end
+ ]) do |object|
+ @ceedling[:generator].generate_object_file(
+ TOOLS_RELEASE_COMPILER,
+ RELEASE_SYM,
+ object.source,
+ object.name,
+ @ceedling[:file_path_utils].form_release_build_c_list_filepath( object.name ) )
+end
+
+
+rule(/#{PROJECT_RELEASE_BUILD_TARGET}/) do |bin_file|
+ map_file = @ceedling[:configurator].project_release_build_map
+ @ceedling[:generator].generate_executable_file(
+ TOOLS_RELEASE_LINKER,
+ RELEASE_SYM,
+ bin_file.prerequisites,
+ bin_file.name,
+ map_file )
+ @ceedling[:release_invoker].artifactinate( bin_file.name, map_file, @ceedling[:configurator].release_build_artifacts )
+end
+
+
+namespace RELEASE_SYM do
+ # use rules to increase efficiency for large projects (instead of iterating through all sources and creating defined tasks)
+
+ namespace :compile do
+ rule(/^#{RELEASE_COMPILE_TASK_ROOT}\S+#{'\\'+EXTENSION_SOURCE}$/ => [ # compile task names by regex
+ proc do |task_name|
+ source = task_name.sub(/#{RELEASE_COMPILE_TASK_ROOT}/, '')
+ @ceedling[:file_finder].find_source_file(source, :error)
+ end
+ ]) do |compile|
+ @ceedling[:rake_wrapper][:directories].invoke
+ @ceedling[:project_config_manager].process_release_config_change
+ @ceedling[:release_invoker].setup_and_invoke_c_objects( [compile.source] )
+ end
+ end
+
+ if (RELEASE_BUILD_USE_ASSEMBLY)
+ namespace :assemble do
+ rule(/^#{RELEASE_ASSEMBLE_TASK_ROOT}\S+#{'\\'+EXTENSION_ASSEMBLY}$/ => [ # assemble task names by regex
+ proc do |task_name|
+ source = task_name.sub(/#{RELEASE_ASSEMBLE_TASK_ROOT}/, '')
+ @ceedling[:file_finder].find_assembly_file(source)
+ end
+ ]) do |assemble|
+ @ceedling[:rake_wrapper][:directories].invoke
+ @ceedling[:project_config_manager].process_release_config_change
+ @ceedling[:release_invoker].setup_and_invoke_asm_objects( [assemble.source] )
+ end
+ end
+ end
+
+end
+
diff --git a/tests/vendor/ceedling/lib/rules_release_deep_dependencies.rake b/tests/vendor/ceedling/lib/rules_release_deep_dependencies.rake
new file mode 100644
index 000000000..dd8fb8472
--- /dev/null
+++ b/tests/vendor/ceedling/lib/rules_release_deep_dependencies.rake
@@ -0,0 +1,15 @@
+
+
+rule(/#{PROJECT_RELEASE_DEPENDENCIES_PATH}\/#{'.+\\'+EXTENSION_DEPENDENCIES}$/ => [
+ proc do |task_name|
+ @ceedling[:file_finder].find_compilation_input_file(task_name)
+ end
+ ]) do |dep|
+ @ceedling[:generator].generate_dependencies_file(
+ TOOLS_RELEASE_DEPENDENCIES_GENERATOR,
+ RELEASE_SYM,
+ dep.source,
+ @ceedling[:file_path_utils].form_release_build_c_object_filepath(dep.source),
+ dep.name)
+end
+
diff --git a/tests/vendor/ceedling/lib/rules_tests.rake b/tests/vendor/ceedling/lib/rules_tests.rake
new file mode 100644
index 000000000..3cc1a3d54
--- /dev/null
+++ b/tests/vendor/ceedling/lib/rules_tests.rake
@@ -0,0 +1,59 @@
+
+
+rule(/#{PROJECT_TEST_FILE_PREFIX}#{'.+'+TEST_RUNNER_FILE_SUFFIX}#{'\\'+EXTENSION_SOURCE}$/ => [
+ proc do |task_name|
+ @ceedling[:file_finder].find_test_input_for_runner_file(task_name)
+ end
+ ]) do |runner|
+ @ceedling[:generator].generate_test_runner(TEST_SYM, runner.source, runner.name)
+end
+
+
+rule(/#{PROJECT_TEST_BUILD_OUTPUT_PATH}\/#{'.+\\'+EXTENSION_OBJECT}$/ => [
+ proc do |task_name|
+ @ceedling[:file_finder].find_compilation_input_file(task_name)
+ end
+ ]) do |object|
+ @ceedling[:generator].generate_object_file(
+ TOOLS_TEST_COMPILER,
+ TEST_SYM,
+ object.source,
+ object.name,
+ @ceedling[:file_path_utils].form_test_build_list_filepath( object.name ) )
+end
+
+
+rule(/#{PROJECT_TEST_BUILD_OUTPUT_PATH}\/#{'.+\\'+EXTENSION_EXECUTABLE}$/) do |bin_file|
+ @ceedling[:generator].generate_executable_file(
+ TOOLS_TEST_LINKER,
+ TEST_SYM,
+ bin_file.prerequisites,
+ bin_file.name,
+ @ceedling[:file_path_utils].form_test_build_map_filepath( bin_file.name ) )
+end
+
+
+rule(/#{PROJECT_TEST_RESULTS_PATH}\/#{'.+\\'+EXTENSION_TESTPASS}$/ => [
+ proc do |task_name|
+ @ceedling[:file_path_utils].form_test_executable_filepath(task_name)
+ end
+ ]) do |test_result|
+ @ceedling[:generator].generate_test_results(TOOLS_TEST_FIXTURE, TEST_SYM, test_result.source, test_result.name)
+end
+
+
+namespace TEST_SYM do
+ # use rules to increase efficiency for large projects (instead of iterating through all sources and creating defined tasks)
+
+ rule(/^#{TEST_TASK_ROOT}\S+$/ => [ # test task names by regex
+ proc do |task_name|
+ test = task_name.sub(/#{TEST_TASK_ROOT}/, '')
+ test = "#{PROJECT_TEST_FILE_PREFIX}#{test}" if not (test.start_with?(PROJECT_TEST_FILE_PREFIX))
+ @ceedling[:file_finder].find_test_from_file_path(test)
+ end
+ ]) do |test|
+ @ceedling[:rake_wrapper][:directories].invoke
+ @ceedling[:test_invoker].setup_and_invoke([test.source])
+ end
+end
+
diff --git a/tests/vendor/ceedling/lib/rules_tests_deep_dependencies.rake b/tests/vendor/ceedling/lib/rules_tests_deep_dependencies.rake
new file mode 100644
index 000000000..d282b433f
--- /dev/null
+++ b/tests/vendor/ceedling/lib/rules_tests_deep_dependencies.rake
@@ -0,0 +1,15 @@
+
+
+rule(/#{PROJECT_TEST_DEPENDENCIES_PATH}\/#{'.+\\'+EXTENSION_DEPENDENCIES}$/ => [
+ proc do |task_name|
+ @ceedling[:file_finder].find_compilation_input_file(task_name)
+ end
+ ]) do |dep|
+ @ceedling[:generator].generate_dependencies_file(
+ TOOLS_TEST_DEPENDENCIES_GENERATOR,
+ TEST_SYM,
+ dep.source,
+ @ceedling[:file_path_utils].form_test_build_object_filepath(dep.source),
+ dep.name)
+end
+
diff --git a/tests/vendor/ceedling/lib/setupinator.rb b/tests/vendor/ceedling/lib/setupinator.rb
new file mode 100644
index 000000000..14e31aa92
--- /dev/null
+++ b/tests/vendor/ceedling/lib/setupinator.rb
@@ -0,0 +1,51 @@
+
+class Setupinator
+
+ attr_reader :config_hash
+ attr_writer :ceedling
+
+ def setup
+ @ceedling = {}
+ @config_hash = {}
+ end
+
+ def load_project_files
+ @ceedling[:project_file_loader].find_project_files
+ return @ceedling[:project_file_loader].load_project_config
+ end
+
+ def do_setup(config_hash)
+ @config_hash = config_hash
+
+ # load up all the constants and accessors our rake files, objects, & external scripts will need;
+ # note: configurator modifies the cmock section of the hash with a couple defaults to tie
+ # project together - the modified hash is used to build cmock object
+ @ceedling[:configurator].populate_defaults( config_hash )
+ @ceedling[:configurator].populate_cmock_defaults( config_hash )
+ @ceedling[:configurator].find_and_merge_plugins( config_hash )
+ @ceedling[:configurator].tools_setup( config_hash )
+ @ceedling[:configurator].eval_environment_variables( config_hash )
+ @ceedling[:configurator].eval_paths( config_hash )
+ @ceedling[:configurator].standardize_paths( config_hash )
+ @ceedling[:configurator].validate( config_hash )
+ @ceedling[:configurator].build( config_hash, :environment )
+
+ @ceedling[:configurator].insert_rake_plugins( @ceedling[:configurator].rake_plugins )
+ @ceedling[:configurator].tools_supplement_arguments( config_hash )
+
+ # merge in any environment variables plugins specify, after the main build
+ @ceedling[:plugin_manager].load_plugin_scripts( @ceedling[:configurator].script_plugins, @ceedling ) do |env|
+ @ceedling[:configurator].eval_environment_variables( env )
+ @ceedling[:configurator].build_supplement( config_hash, env )
+ end
+
+ @ceedling[:plugin_reportinator].set_system_objects( @ceedling )
+ @ceedling[:file_finder].prepare_search_sources
+ @ceedling[:loginator].setup_log_filepath
+ @ceedling[:project_config_manager].config_hash = config_hash
+ end
+
+ def reset_defaults(config_hash)
+ @ceedling[:configurator].reset_defaults( config_hash )
+ end
+end
diff --git a/tests/vendor/ceedling/lib/stream_wrapper.rb b/tests/vendor/ceedling/lib/stream_wrapper.rb
new file mode 100644
index 000000000..33d3c10b1
--- /dev/null
+++ b/tests/vendor/ceedling/lib/stream_wrapper.rb
@@ -0,0 +1,20 @@
+
+class StreamWrapper
+
+ def stdout_puts(string)
+ $stdout.puts(string)
+ end
+
+ def stdout_flush
+ $stdout.flush
+ end
+
+ def stderr_puts(string)
+ $stderr.puts(string)
+ end
+
+ def stderr_flush
+ $stderr.flush
+ end
+
+end
diff --git a/tests/vendor/ceedling/lib/streaminator.rb b/tests/vendor/ceedling/lib/streaminator.rb
new file mode 100644
index 000000000..abbc9b865
--- /dev/null
+++ b/tests/vendor/ceedling/lib/streaminator.rb
@@ -0,0 +1,41 @@
+
+class Streaminator
+
+ require 'constants'
+
+ constructor :streaminator_helper, :verbosinator, :loginator, :stream_wrapper
+
+ # for those objects for whom the configurator has already been instantiated,
+ # Streaminator is a convenience object for handling verbosity and writing to the std streams
+
+ def stdout_puts(string, verbosity=Verbosity::NORMAL)
+ if (@verbosinator.should_output?(verbosity))
+ @stream_wrapper.stdout_puts(string)
+ @stream_wrapper.stdout_flush
+ end
+
+ # write to log as though Verbosity::OBNOXIOUS
+ @loginator.log( string, @streaminator_helper.extract_name($stdout) )
+ end
+
+ def stderr_puts(string, verbosity=Verbosity::NORMAL)
+ if (@verbosinator.should_output?(verbosity))
+ @stream_wrapper.stderr_puts(string)
+ @stream_wrapper.stderr_flush
+ end
+
+ # write to log as though Verbosity::OBNOXIOUS
+ @loginator.log( string, @streaminator_helper.extract_name($stderr) )
+ end
+
+ def stream_puts(stream, string, verbosity=Verbosity::NORMAL)
+ if (@verbosinator.should_output?(verbosity))
+ stream.puts(string)
+ stream.flush
+ end
+
+ # write to log as though Verbosity::OBNOXIOUS
+ @loginator.log( string, @streaminator_helper.extract_name(stream) )
+ end
+
+end
diff --git a/tests/vendor/ceedling/lib/streaminator_helper.rb b/tests/vendor/ceedling/lib/streaminator_helper.rb
new file mode 100644
index 000000000..9fb5cc0b7
--- /dev/null
+++ b/tests/vendor/ceedling/lib/streaminator_helper.rb
@@ -0,0 +1,15 @@
+
+class StreaminatorHelper
+
+ def extract_name(stream)
+ name = case (stream.fileno)
+ when 0 then '#'
+ when 1 then '#'
+ when 2 then '#'
+ else stream.inspect
+ end
+
+ return name
+ end
+
+end
diff --git a/tests/vendor/ceedling/lib/system_utils.rb b/tests/vendor/ceedling/lib/system_utils.rb
new file mode 100644
index 000000000..cb5216b8c
--- /dev/null
+++ b/tests/vendor/ceedling/lib/system_utils.rb
@@ -0,0 +1,32 @@
+
+class Object
+ def deep_clone
+ Marshal::load(Marshal.dump(self))
+ end
+end
+
+
+class SystemUtils
+
+ constructor :system_wrapper
+
+ def setup
+ @tcsh_shell = nil
+ end
+
+ def tcsh_shell?
+ # once run a single time, return state determined at that execution
+ return @tcsh_shell if not @tcsh_shell.nil?
+
+ result = @system_wrapper.shell_backticks('echo $version')
+
+ if ((result[:exit_code] == 0) and (result[:output].strip =~ /^tcsh/))
+ @tcsh_shell = true
+ else
+ @tcsh_shell = false
+ end
+
+ return @tcsh_shell
+ end
+
+end
diff --git a/tests/vendor/ceedling/lib/system_wrapper.rb b/tests/vendor/ceedling/lib/system_wrapper.rb
new file mode 100644
index 000000000..1cccba203
--- /dev/null
+++ b/tests/vendor/ceedling/lib/system_wrapper.rb
@@ -0,0 +1,76 @@
+require 'rbconfig'
+
+class SystemWrapper
+
+ # static method for use in defaults
+ def self.windows?
+ return ((RbConfig::CONFIG['host_os'] =~ /mswin|mingw/) ? true : false) if defined?(RbConfig)
+ return ((Config::CONFIG['host_os'] =~ /mswin|mingw/) ? true : false)
+ end
+
+ # class method so as to be mockable for tests
+ def windows?
+ return SystemWrapper.windows?
+ end
+
+ def module_eval(string)
+ return Object.module_eval("\"" + string + "\"")
+ end
+
+ def eval(string)
+ return eval(string)
+ end
+
+ def search_paths
+ return ENV['PATH'].split(File::PATH_SEPARATOR)
+ end
+
+ def cmdline_args
+ return ARGV
+ end
+
+ def env_set(name, value)
+ ENV[name] = value
+ end
+
+ def env_get(name)
+ return ENV[name]
+ end
+
+ def time_now
+ return Time.now.asctime
+ end
+
+ def shell_backticks(command)
+ return {
+ :output => `#{command}`.freeze,
+ :exit_code => ($?.exitstatus).freeze
+ }
+ end
+
+ def shell_system(command)
+ system( command )
+ return {
+ :output => ''.freeze,
+ :exit_code => ($?.exitstatus).freeze
+ }
+ end
+
+ def add_load_path(path)
+ $LOAD_PATH.unshift(path)
+ end
+
+ def require_file(path)
+ require(path)
+ end
+
+ def ruby_success
+ return ($!.nil? || $!.is_a?(SystemExit) && $!.success?)
+ end
+
+ def constants_include?(item)
+ # forcing to strings provides consistency across Ruby versions
+ return Object.constants.map{|constant| constant.to_s}.include?(item.to_s)
+ end
+
+end
diff --git a/tests/vendor/ceedling/lib/target_loader.rb b/tests/vendor/ceedling/lib/target_loader.rb
new file mode 100644
index 000000000..0402dc38b
--- /dev/null
+++ b/tests/vendor/ceedling/lib/target_loader.rb
@@ -0,0 +1,38 @@
+module TargetLoader
+ class NoTargets < Exception; end
+ class NoDirectory < Exception; end
+ class NoDefault < Exception; end
+ class NoSuchTarget < Exception; end
+
+ class RequestReload < Exception; end
+
+ def self.inspect(config, target_name=nil)
+ unless config[:targets]
+ raise NoTargets
+ end
+
+ targets = config[:targets]
+ unless targets[:targets_directory]
+ raise NoDirectory("No targets directory specified.")
+ end
+ unless targets[:default_target]
+ raise NoDefault("No default target specified.")
+ end
+
+ target_path = lambda {|name| File.join(targets[:targets_directory], name + ".yml")}
+
+ target = if target_name
+ target_path.call(target_name)
+ else
+ target_path.call(targets[:default_target])
+ end
+
+ unless File.exists? target
+ raise NoSuchTarget.new("No such target: #{target}")
+ end
+
+ ENV['CEEDLING_MAIN_PROJECT_FILE'] = target
+
+ raise RequestReload
+ end
+end
diff --git a/tests/vendor/ceedling/lib/task_invoker.rb b/tests/vendor/ceedling/lib/task_invoker.rb
new file mode 100644
index 000000000..c69f2a6c4
--- /dev/null
+++ b/tests/vendor/ceedling/lib/task_invoker.rb
@@ -0,0 +1,89 @@
+require "par_map"
+
+class TaskInvoker
+
+ constructor :dependinator, :rake_utils, :rake_wrapper
+
+ def setup
+ @test_regexs = [/^#{TEST_ROOT_NAME}:/]
+ @release_regexs = [/^#{RELEASE_ROOT_NAME}(:|$)/]
+ end
+
+ def add_test_task_regex(regex)
+ @test_regexs << regex
+ end
+
+ def add_release_task_regex(regex)
+ @release_regexs << regex
+ end
+
+ def test_invoked?
+ invoked = false
+
+ @test_regexs.each do |regex|
+ invoked = true if (@rake_utils.task_invoked?(regex))
+ break if invoked
+ end
+
+ return invoked
+ end
+
+ def release_invoked?
+ invoked = false
+
+ @release_regexs.each do |regex|
+ invoked = true if (@rake_utils.task_invoked?(regex))
+ break if invoked
+ end
+
+ return invoked
+ end
+
+ def invoked?(regex)
+ return @rake_utils.task_invoked?(regex)
+ end
+
+
+ def invoke_test_mocks(mocks)
+ @dependinator.enhance_mock_dependencies( mocks )
+ mocks.each { |mock| @rake_wrapper[mock].invoke }
+ end
+
+ def invoke_test_runner(runner)
+ @dependinator.enhance_runner_dependencies( runner )
+ @rake_wrapper[runner].invoke
+ end
+
+ def invoke_test_shallow_include_lists(files)
+ @dependinator.enhance_shallow_include_lists_dependencies( files )
+ files.each { |file| @rake_wrapper[file].invoke }
+ end
+
+ def invoke_test_preprocessed_files(files)
+ @dependinator.enhance_preprocesed_file_dependencies( files )
+ files.each { |file| @rake_wrapper[file].invoke }
+ end
+
+ def invoke_test_dependencies_files(files)
+ @dependinator.enhance_dependencies_dependencies( files )
+ files.each { |file| @rake_wrapper[file].invoke }
+ end
+
+ def invoke_test_results(result)
+ @dependinator.enhance_results_dependencies( result )
+ @rake_wrapper[result].invoke
+ end
+
+ def invoke_release_dependencies_files(files)
+ par_map(PROJECT_COMPILE_THREADS, files) do |file|
+ @rake_wrapper[file].invoke
+ end
+ end
+
+ def invoke_release_objects(objects)
+ par_map(PROJECT_COMPILE_THREADS, objects) do |object|
+ @rake_wrapper[object].invoke
+ end
+ end
+
+end
diff --git a/tests/vendor/ceedling/lib/tasks_base.rake b/tests/vendor/ceedling/lib/tasks_base.rake
new file mode 100644
index 000000000..e87174e97
--- /dev/null
+++ b/tests/vendor/ceedling/lib/tasks_base.rake
@@ -0,0 +1,104 @@
+require 'constants'
+require 'file_path_utils'
+
+
+desc "Display build environment version info."
+task :version do
+ tools = [
+ [' Ceedling', CEEDLING_ROOT],
+ ['CException', File.join( CEEDLING_VENDOR, CEXCEPTION_ROOT_PATH)],
+ [' CMock', File.join( CEEDLING_VENDOR, CMOCK_ROOT_PATH)],
+ [' Unity', File.join( CEEDLING_VENDOR, UNITY_ROOT_PATH)],
+ ]
+
+ tools.each do |tool|
+ name = tool[0]
+ base_path = tool[1]
+
+ version_string = @ceedling[:file_wrapper].read( File.join(base_path, 'release', 'version.info') ).strip
+ build_string = @ceedling[:file_wrapper].read( File.join(base_path, 'release', 'build.info') ).strip
+ puts "#{name}:: #{version_string.empty? ? '#.#.' : (version_string + '.')}#{build_string.empty? ? '?' : build_string}"
+ end
+end
+
+
+desc "Set verbose output (silent:[#{Verbosity::SILENT}] - obnoxious:[#{Verbosity::OBNOXIOUS}])."
+task :verbosity, :level do |t, args|
+ verbosity_level = args.level.to_i
+
+ if (PROJECT_USE_MOCKS)
+ # don't store verbosity level in setupinator's config hash, use a copy;
+ # otherwise, the input configuration will change and trigger entire project rebuilds
+ hash = @ceedling[:setupinator].config_hash[:cmock].clone
+ hash[:verbosity] = verbosity_level
+
+ @ceedling[:cmock_builder].manufacture( hash )
+ end
+
+ @ceedling[:configurator].project_verbosity = verbosity_level
+
+ # control rake's verbosity with new setting
+ verbose( ((verbosity_level >= Verbosity::OBNOXIOUS) ? true : false) )
+end
+
+
+desc "Enable logging"
+task :logging do
+ @ceedling[:configurator].project_logging = true
+end
+
+
+# non advertised debug task
+task :debug do
+ Rake::Task[:verbosity].invoke(Verbosity::DEBUG)
+ Rake.application.options.trace = true
+ @ceedling[:configurator].project_debug = true
+end
+
+
+# non advertised sanity checking task
+task :sanity_checks, :level do |t, args|
+ check_level = args.level.to_i
+ @ceedling[:configurator].sanity_checks = check_level
+end
+
+
+# list expanded environment variables
+if (not ENVIRONMENT.empty?)
+desc "List all configured environment variables."
+task :environment do
+ ENVIRONMENT.each do |env|
+ env.each_key do |key|
+ name = key.to_s.upcase
+ puts " - #{name}: \"#{env[key]}\""
+ end
+ end
+end
+end
+
+
+namespace :options do
+
+ COLLECTION_PROJECT_OPTIONS.each do |option_path|
+ option = File.basename(option_path, '.yml')
+
+ desc "Merge #{option} project options."
+ task option.downcase.to_sym do
+ # @ceedling[:setupinator].reset_defaults( @ceedling[:setupinator].config_hash )
+ hash = @ceedling[:project_config_manager].merge_options( @ceedling[:setupinator].config_hash, option_path )
+ @ceedling[:setupinator].do_setup( hash )
+ end
+ end
+
+end
+
+
+# do not present task if there's no plugins
+if (not PLUGINS_ENABLED.empty?)
+desc "Execute plugin result summaries (no build triggering)."
+task :summary do
+ @ceedling[:plugin_manager].summary
+ puts "\nNOTE: Summaries may be out of date with project sources.\n\n"
+end
+end
+
diff --git a/tests/vendor/ceedling/lib/tasks_filesystem.rake b/tests/vendor/ceedling/lib/tasks_filesystem.rake
new file mode 100644
index 000000000..f8048e6e6
--- /dev/null
+++ b/tests/vendor/ceedling/lib/tasks_filesystem.rake
@@ -0,0 +1,91 @@
+
+# rather than require 'rake/clean' & try to override, we replicate for finer control
+CLEAN = Rake::FileList["**/*~", "**/*.bak"]
+CLOBBER = Rake::FileList.new
+
+CLEAN.clear_exclude.exclude { |fn| fn.pathmap("%f") == 'core' && File.directory?(fn) }
+
+CLEAN.include(File.join(PROJECT_TEST_BUILD_OUTPUT_PATH, '*'))
+CLEAN.include(File.join(PROJECT_TEST_RESULTS_PATH, '*'))
+CLEAN.include(File.join(PROJECT_TEST_DEPENDENCIES_PATH, '*'))
+CLEAN.include(File.join(PROJECT_BUILD_RELEASE_ROOT, '*.*'))
+CLEAN.include(File.join(PROJECT_RELEASE_BUILD_OUTPUT_PATH, '*'))
+CLEAN.include(File.join(PROJECT_RELEASE_DEPENDENCIES_PATH, '*'))
+
+CLOBBER.include(File.join(PROJECT_BUILD_ARTIFACTS_ROOT, '**/*'))
+CLOBBER.include(File.join(PROJECT_BUILD_TESTS_ROOT, '**/*'))
+CLOBBER.include(File.join(PROJECT_BUILD_RELEASE_ROOT, '**/*'))
+CLOBBER.include(File.join(PROJECT_LOG_PATH, '**/*'))
+CLOBBER.include(File.join(PROJECT_TEMP_PATH, '**/*'))
+
+# because of cmock config, mock path can optionally exist apart from standard test build paths
+CLOBBER.include(File.join(CMOCK_MOCK_PATH, '*'))
+
+REMOVE_FILE_PROC = Proc.new { |fn| rm_r fn rescue nil }
+
+# redefine clean so we can override how it advertises itself
+desc "Delete all build artifacts and temporary products."
+task(:clean) do
+ # because :clean is a prerequisite for :clobber, intelligently display the progress message
+ if (not @ceedling[:task_invoker].invoked?(/^clobber$/))
+ @ceedling[:streaminator].stdout_puts("\nCleaning build artifacts...\n(For large projects, this task may take a long time to complete)\n\n")
+ end
+ CLEAN.each { |fn| REMOVE_FILE_PROC.call(fn) }
+end
+
+# redefine clobber so we can override how it advertises itself
+desc "Delete all generated files (and build artifacts)."
+task(:clobber => [:clean]) do
+ @ceedling[:streaminator].stdout_puts("\nClobbering all generated files...\n(For large projects, this task may take a long time to complete)\n\n")
+ CLOBBER.each { |fn| REMOVE_FILE_PROC.call(fn) }
+end
+
+
+PROJECT_BUILD_PATHS.each { |path| directory(path) }
+
+# create directories that hold build output and generated files & touching rebuild dependency sources
+task(:directories => PROJECT_BUILD_PATHS) { @ceedling[:dependinator].touch_force_rebuild_files }
+
+
+# list paths discovered at load time
+namespace :paths do
+
+ paths = @ceedling[:setupinator].config_hash[:paths]
+ paths.each_key do |section|
+ name = section.to_s.downcase
+ path_list = Object.const_get("COLLECTION_PATHS_#{name.upcase}")
+
+ if (path_list.size != 0)
+ desc "List all collected #{name} paths."
+ task(name.to_sym) { puts "#{name} paths:"; path_list.sort.each {|path| puts " - #{path}" } }
+ end
+ end
+
+end
+
+
+# list files & file counts discovered at load time
+namespace :files do
+
+ categories = [
+ ['test', COLLECTION_ALL_TESTS],
+ ['source', COLLECTION_ALL_SOURCE],
+ ['header', COLLECTION_ALL_HEADERS]
+ ]
+ categories << ['assembly', COLLECTION_ALL_ASSEMBLY] if (RELEASE_BUILD_USE_ASSEMBLY)
+
+ categories.each do |category|
+ name = category[0]
+ collection = category[1]
+
+ desc "List all collected #{name} files."
+ task(name.to_sym) do
+ puts "#{name} files:"
+ collection.sort.each { |filepath| puts " - #{filepath}" }
+ puts "file count: #{collection.size}"
+ end
+ end
+
+end
+
+
diff --git a/tests/vendor/ceedling/lib/tasks_release.rake b/tests/vendor/ceedling/lib/tasks_release.rake
new file mode 100644
index 000000000..c0e0ef108
--- /dev/null
+++ b/tests/vendor/ceedling/lib/tasks_release.rake
@@ -0,0 +1,28 @@
+require 'constants'
+require 'file_path_utils'
+
+
+desc "Build release target."
+task RELEASE_SYM => [:directories] do
+ header = "Release build '#{File.basename(PROJECT_RELEASE_BUILD_TARGET)}'"
+ @ceedling[:streaminator].stdout_puts("\n\n#{header}\n#{'-' * header.length}")
+
+ begin
+ @ceedling[:plugin_manager].pre_release
+
+ core_objects = []
+ extra_objects = @ceedling[:file_path_utils].form_release_build_c_objects_filelist( COLLECTION_RELEASE_ARTIFACT_EXTRA_LINK_OBJECTS )
+
+ @ceedling[:project_config_manager].process_release_config_change
+ core_objects.concat( @ceedling[:release_invoker].setup_and_invoke_c_objects( COLLECTION_ALL_SOURCE ) )
+
+ # if assembler use isn't enabled, COLLECTION_ALL_ASSEMBLY is empty array & nothing happens
+ core_objects.concat( @ceedling[:release_invoker].setup_and_invoke_asm_objects( COLLECTION_ALL_ASSEMBLY ) )
+
+ file( PROJECT_RELEASE_BUILD_TARGET => (core_objects + extra_objects) )
+ Rake::Task[PROJECT_RELEASE_BUILD_TARGET].invoke
+ ensure
+ @ceedling[:plugin_manager].post_release
+ end
+end
+
diff --git a/tests/vendor/ceedling/lib/tasks_release_deep_dependencies.rake b/tests/vendor/ceedling/lib/tasks_release_deep_dependencies.rake
new file mode 100644
index 000000000..01fadede1
--- /dev/null
+++ b/tests/vendor/ceedling/lib/tasks_release_deep_dependencies.rake
@@ -0,0 +1,9 @@
+require 'constants'
+
+namespace REFRESH_SYM do
+
+ task RELEASE_SYM do
+ @ceedling[:release_invoker].refresh_c_deep_dependencies
+ end
+
+end
diff --git a/tests/vendor/ceedling/lib/tasks_tests.rake b/tests/vendor/ceedling/lib/tasks_tests.rake
new file mode 100644
index 000000000..a6b8414c6
--- /dev/null
+++ b/tests/vendor/ceedling/lib/tasks_tests.rake
@@ -0,0 +1,52 @@
+require 'constants'
+
+
+namespace TEST_SYM do
+
+ desc "Run all unit tests."
+ task :all => [:directories] do
+ @ceedling[:test_invoker].setup_and_invoke(COLLECTION_ALL_TESTS)
+ end
+
+ desc "Run single test ([*] real test or source file name, no path)."
+ task :* do
+ message = "\nOops! '#{TEST_ROOT_NAME}:*' isn't a real task. " +
+ "Use a real test or source file name (no path) in place of the wildcard.\n" +
+ "Example: rake #{TEST_ROOT_NAME}:foo.c\n\n"
+
+ @ceedling[:streaminator].stdout_puts( message )
+ end
+
+ desc "Run tests for changed files."
+ task :delta => [:directories] do
+ @ceedling[:test_invoker].setup_and_invoke(COLLECTION_ALL_TESTS, TEST_SYM, {:force_run => false})
+ end
+
+ desc "Run tests by matching regular expression pattern."
+ task :pattern, [:regex] => [:directories] do |t, args|
+ matches = []
+
+ COLLECTION_ALL_TESTS.each { |test| matches << test if (test =~ /#{args.regex}/) }
+
+ if (matches.size > 0)
+ @ceedling[:test_invoker].setup_and_invoke(matches, TEST_SYM, {:force_run => false})
+ else
+ @ceedling[:streaminator].stdout_puts("\nFound no tests matching pattern /#{args.regex}/.")
+ end
+ end
+
+ desc "Run tests whose test path contains [dir] or [dir] substring."
+ task :path, [:dir] => [:directories] do |t, args|
+ matches = []
+
+ COLLECTION_ALL_TESTS.each { |test| matches << test if File.dirname(test).include?(args.dir.gsub(/\\/, '/')) }
+
+ if (matches.size > 0)
+ @ceedling[:test_invoker].setup_and_invoke(matches, TEST_SYM, {:force_run => false})
+ else
+ @ceedling[:streaminator].stdout_puts("\nFound no tests including the given path or path component.")
+ end
+ end
+
+end
+
diff --git a/tests/vendor/ceedling/lib/tasks_tests_deep_dependencies.rake b/tests/vendor/ceedling/lib/tasks_tests_deep_dependencies.rake
new file mode 100644
index 000000000..67d6ce577
--- /dev/null
+++ b/tests/vendor/ceedling/lib/tasks_tests_deep_dependencies.rake
@@ -0,0 +1,9 @@
+require 'constants'
+
+namespace REFRESH_SYM do
+
+ task TEST_SYM do
+ @ceedling[:test_invoker].refresh_deep_dependencies
+ end
+
+end
diff --git a/tests/vendor/ceedling/lib/tasks_vendor.rake b/tests/vendor/ceedling/lib/tasks_vendor.rake
new file mode 100644
index 000000000..0d07154b7
--- /dev/null
+++ b/tests/vendor/ceedling/lib/tasks_vendor.rake
@@ -0,0 +1,36 @@
+require 'constants'
+require 'file_path_utils'
+
+# create file dependencies to ensure C-based components of vendor tools are recompiled when they are updated with new versions
+# forming these explicitly rather than depend on auxiliary dependencies so all scenarios are explicitly covered
+
+file( @ceedling[:file_path_utils].form_test_build_object_filepath( UNITY_C_FILE ) => [
+ FilePathUtils.form_ceedling_vendor_path( UNITY_LIB_PATH, UNITY_C_FILE ),
+ FilePathUtils.form_ceedling_vendor_path( UNITY_LIB_PATH, UNITY_H_FILE ),
+ FilePathUtils.form_ceedling_vendor_path( UNITY_LIB_PATH, UNITY_INTERNALS_H_FILE ) ]
+ )
+
+
+if (PROJECT_USE_MOCKS)
+file( @ceedling[:file_path_utils].form_test_build_object_filepath( CMOCK_C_FILE ) => [
+ FilePathUtils.form_ceedling_vendor_path( CMOCK_LIB_PATH, CMOCK_C_FILE ),
+ FilePathUtils.form_ceedling_vendor_path( CMOCK_LIB_PATH, CMOCK_H_FILE ) ]
+ )
+end
+
+
+if (PROJECT_USE_EXCEPTIONS)
+file( @ceedling[:file_path_utils].form_test_build_object_filepath( CEXCEPTION_C_FILE ) => [
+ FilePathUtils.form_ceedling_vendor_path( CEXCEPTION_LIB_PATH, CEXCEPTION_C_FILE ),
+ FilePathUtils.form_ceedling_vendor_path( CEXCEPTION_LIB_PATH, CEXCEPTION_H_FILE ) ]
+ )
+end
+
+
+if (PROJECT_USE_EXCEPTIONS and PROJECT_RELEASE_BUILD)
+file( @ceedling[:file_path_utils].form_release_build_c_object_filepath( CEXCEPTION_C_FILE ) => [
+ FilePathUtils.form_ceedling_vendor_path( CEXCEPTION_LIB_PATH, CEXCEPTION_C_FILE ),
+ FilePathUtils.form_ceedling_vendor_path( CEXCEPTION_LIB_PATH, CEXCEPTION_H_FILE ) ]
+ )
+end
+
diff --git a/tests/vendor/ceedling/lib/test_includes_extractor.rb b/tests/vendor/ceedling/lib/test_includes_extractor.rb
new file mode 100644
index 000000000..35f7c53da
--- /dev/null
+++ b/tests/vendor/ceedling/lib/test_includes_extractor.rb
@@ -0,0 +1,81 @@
+
+class TestIncludesExtractor
+
+ constructor :configurator, :yaml_wrapper, :file_wrapper
+
+
+ def setup
+ @includes = {}
+ @mocks = {}
+ end
+
+
+ # for includes_list file, slurp up array from yaml file and sort & store includes
+ def parse_includes_list(includes_list)
+ gather_and_store_includes( includes_list, @yaml_wrapper.load(includes_list) )
+ end
+
+ # open, scan for, and sort & store includes of test file
+ def parse_test_file(test)
+ gather_and_store_includes( test, extract_from_file(test) )
+ end
+
+ # mocks with no file extension
+ def lookup_raw_mock_list(test)
+ file_key = form_file_key(test)
+ return [] if @mocks[file_key].nil?
+ return @mocks[file_key]
+ end
+
+ # includes with file extension
+ def lookup_includes_list(file)
+ file_key = form_file_key(file)
+ return [] if (@includes[file_key]).nil?
+ return @includes[file_key]
+ end
+
+ private #################################
+
+ def form_file_key(filepath)
+ return File.basename(filepath).to_sym
+ end
+
+ def extract_from_file(file)
+ includes = []
+ header_extension = @configurator.extension_header
+
+ contents = @file_wrapper.read(file)
+
+ # remove line comments
+ contents = contents.gsub(/\/\/.*$/, '')
+ # remove block comments
+ contents = contents.gsub(/\/\*.*?\*\//m, '')
+
+ contents.split("\n").each do |line|
+ # look for include statement
+ scan_results = line.scan(/#include\s+\"\s*(.+#{'\\'+header_extension})\s*\"/)
+
+ includes << scan_results[0][0] if (scan_results.size > 0)
+ end
+
+ return includes.uniq
+ end
+
+ def gather_and_store_includes(file, includes)
+ mock_prefix = @configurator.cmock_mock_prefix
+ header_extension = @configurator.extension_header
+ file_key = form_file_key(file)
+ @mocks[file_key] = []
+
+ # add includes to lookup hash
+ @includes[file_key] = includes
+
+ includes.each do |include_file|
+ # check if include is a mock
+ scan_results = include_file.scan(/(#{mock_prefix}.+)#{'\\'+header_extension}/)
+ # add mock to lookup hash
+ @mocks[file_key] << scan_results[0][0] if (scan_results.size > 0)
+ end
+ end
+
+end
diff --git a/tests/vendor/ceedling/lib/test_invoker.rb b/tests/vendor/ceedling/lib/test_invoker.rb
new file mode 100644
index 000000000..a7a41ee6f
--- /dev/null
+++ b/tests/vendor/ceedling/lib/test_invoker.rb
@@ -0,0 +1,97 @@
+require 'constants'
+
+
+class TestInvoker
+
+ attr_reader :sources, :tests, :mocks
+
+ constructor :configurator,
+ :test_invoker_helper,
+ :plugin_manager,
+ :streaminator,
+ :preprocessinator,
+ :task_invoker,
+ :dependinator,
+ :project_config_manager,
+ :build_invoker_utils,
+ :file_path_utils,
+ :file_wrapper
+
+ def setup
+ @sources = []
+ @tests = []
+ @mocks = []
+ end
+
+ def setup_and_invoke(tests, context=TEST_SYM, options={:force_run => true})
+
+ @tests = tests
+
+ @project_config_manager.process_test_config_change
+
+ @tests.each do |test|
+ # announce beginning of test run
+ header = "Test '#{File.basename(test)}'"
+ @streaminator.stdout_puts("\n\n#{header}\n#{'-' * header.length}")
+
+ begin
+ @plugin_manager.pre_test
+
+ # collect up test fixture pieces & parts
+ runner = @file_path_utils.form_runner_filepath_from_test( test )
+ mock_list = @preprocessinator.preprocess_test_and_invoke_test_mocks( test )
+ sources = @test_invoker_helper.extract_sources( test )
+ extras = @configurator.collection_test_fixture_extra_link_objects
+ core = [test] + mock_list + sources
+ objects = @file_path_utils.form_test_build_objects_filelist( [runner] + core + extras )
+ results_pass = @file_path_utils.form_pass_results_filepath( test )
+ results_fail = @file_path_utils.form_fail_results_filepath( test )
+
+ # clean results files so we have a missing file with which to kick off rake's dependency rules
+ @test_invoker_helper.clean_results( {:pass => results_pass, :fail => results_fail}, options )
+
+ # load up auxiliary dependencies so deep changes cause rebuilding appropriately
+ @test_invoker_helper.process_deep_dependencies( core ) do |dependencies_list|
+ @dependinator.load_test_object_deep_dependencies( dependencies_list )
+ end
+
+ # tell rake to create test runner if needed
+ @task_invoker.invoke_test_runner( runner )
+
+ # enhance object file dependencies to capture externalities influencing regeneration
+ @dependinator.enhance_test_build_object_dependencies( objects )
+
+ # associate object files with executable
+ @dependinator.setup_test_executable_dependencies( test, objects )
+
+ # 3, 2, 1... launch
+ @task_invoker.invoke_test_results( results_pass )
+ rescue => e
+ @build_invoker_utils.process_exception( e, context )
+ ensure
+ @plugin_manager.post_test
+ end
+
+ # store away what's been processed
+ @mocks.concat( mock_list )
+ @sources.concat( sources )
+ end
+
+ # post-process collected mock list
+ @mocks.uniq!
+
+ # post-process collected sources list
+ @sources.uniq!
+ end
+
+
+ def refresh_deep_dependencies
+ @file_wrapper.rm_f(
+ @file_wrapper.directory_listing(
+ File.join( @configurator.project_test_dependencies_path, '*' + @configurator.extension_dependencies ) ) )
+
+ @test_invoker_helper.process_deep_dependencies(
+ @configurator.collection_all_tests + @configurator.collection_all_source )
+ end
+
+end
diff --git a/tests/vendor/ceedling/lib/test_invoker_helper.rb b/tests/vendor/ceedling/lib/test_invoker_helper.rb
new file mode 100644
index 000000000..001608ee0
--- /dev/null
+++ b/tests/vendor/ceedling/lib/test_invoker_helper.rb
@@ -0,0 +1,28 @@
+
+class TestInvokerHelper
+
+ constructor :configurator, :task_invoker, :test_includes_extractor, :file_finder, :file_path_utils, :file_wrapper
+
+ def clean_results(results, options)
+ @file_wrapper.rm_f( results[:fail] )
+ @file_wrapper.rm_f( results[:pass] ) if (options[:force_run])
+ end
+
+ def process_deep_dependencies(files)
+ return if (not @configurator.project_use_deep_dependencies)
+
+ dependencies_list = @file_path_utils.form_test_dependencies_filelist( files )
+ @task_invoker.invoke_test_dependencies_files( dependencies_list )
+ yield( dependencies_list ) if block_given?
+ end
+
+ def extract_sources(test)
+ sources = []
+ includes = @test_includes_extractor.lookup_includes_list(test)
+
+ includes.each { |include| sources << @file_finder.find_compilation_input_file(include, :ignore) }
+
+ return sources.compact
+ end
+
+end
diff --git a/tests/vendor/ceedling/lib/tool_executor.rb b/tests/vendor/ceedling/lib/tool_executor.rb
new file mode 100644
index 000000000..f4bccc42b
--- /dev/null
+++ b/tests/vendor/ceedling/lib/tool_executor.rb
@@ -0,0 +1,212 @@
+require 'constants'
+
+class ShellExecutionException < RuntimeError
+ attr_reader :shell_result
+ def initialize(shell_result)
+ @shell_result = shell_result
+ end
+end
+
+class ToolExecutor
+
+ constructor :configurator, :tool_executor_helper, :streaminator, :system_wrapper
+
+ def setup
+ @tool_name = ''
+ @executable = ''
+ end
+
+ # build up a command line from yaml provided config
+ def build_command_line(tool_config, *args)
+ @tool_name = tool_config[:name]
+ @executable = tool_config[:executable]
+
+ command = {}
+
+ # basic premise is to iterate top to bottom through arguments using '$' as
+ # a string replacement indicator to expand globals or inline yaml arrays
+ # into command line arguments via substitution strings
+ command[:line] = [
+ @tool_executor_helper.osify_path_separators( expandify_element(@executable, *args) ),
+ build_arguments(tool_config[:arguments], *args),
+ ].join(' ').strip
+
+ command[:options] = {
+ :stderr_redirect => @tool_executor_helper.stderr_redirection(tool_config, @configurator.project_logging),
+ :background_exec => tool_config[:background_exec]
+ }
+
+ return command
+ end
+
+
+ # shell out, execute command, and return response
+ def exec(command, options={}, args=[])
+ options[:boom] = true if (options[:boom].nil?)
+ options[:stderr_redirect] = StdErrRedirect::NONE if (options[:stderr_redirect].nil?)
+ options[:background_exec] = BackgroundExec::NONE if (options[:background_exec].nil?)
+
+ # build command line
+ command_line = [
+ @tool_executor_helper.background_exec_cmdline_prepend( options ),
+ command.strip,
+ args,
+ @tool_executor_helper.stderr_redirect_cmdline_append( options ),
+ @tool_executor_helper.background_exec_cmdline_append( options ),
+ ].flatten.compact.join(' ')
+
+ shell_result = {}
+
+ # depending on background exec option, we shell out differently
+ if (options[:background_exec] != BackgroundExec::NONE)
+ shell_result = @system_wrapper.shell_system( command_line )
+ else
+ shell_result = @system_wrapper.shell_backticks( command_line )
+ end
+
+ @tool_executor_helper.print_happy_results( command_line, shell_result, options[:boom] )
+ @tool_executor_helper.print_error_results( command_line, shell_result, options[:boom] )
+
+ # go boom if exit code isn't 0 (but in some cases we don't want a non-0 exit code to raise)
+ raise ShellExecutionException.new(shell_result) if ((shell_result[:exit_code] != 0) and options[:boom])
+
+ return shell_result
+ end
+
+
+ private #############################
+
+
+ def build_arguments(config, *args)
+ build_string = ''
+
+ return nil if (config.nil?)
+
+ # iterate through each argument
+
+ # the yaml blob array needs to be flattened so that yaml substitution
+ # is handled correctly, since it creates a nested array when an anchor is
+ # dereferenced
+ config.flatten.each do |element|
+ argument = ''
+
+ case(element)
+ # if we find a simple string then look for string replacement operators
+ # and expand with the parameters in this method's argument list
+ when String then argument = expandify_element(element, *args)
+ # if we find a hash, then we grab the key as a substitution string and expand the
+ # hash's value(s) within that substitution string
+ when Hash then argument = dehashify_argument_elements(element)
+ end
+
+ build_string.concat("#{argument} ") if (argument.length > 0)
+ end
+
+ build_string.strip!
+ return build_string if (build_string.length > 0)
+ return nil
+ end
+
+
+ # handle simple text string argument & argument array string replacement operators
+ def expandify_element(element, *args)
+ match = //
+ to_process = nil
+ args_index = 0
+
+ # handle ${#} input replacement
+ if (element =~ TOOL_EXECUTOR_ARGUMENT_REPLACEMENT_PATTERN)
+ args_index = ($2.to_i - 1)
+
+ if (args.nil? or args[args_index].nil?)
+ @streaminator.stderr_puts("ERROR: Tool '#{@tool_name}' expected valid argument data to accompany replacement operator #{$1}.", Verbosity::ERRORS)
+ raise
+ end
+
+ match = /#{Regexp.escape($1)}/
+ to_process = args[args_index]
+ end
+
+ # simple string argument: replace escaped '\$' and strip
+ element.sub!(/\\\$/, '$')
+ element.strip!
+
+ # handle inline ruby execution
+ if (element =~ RUBY_EVAL_REPLACEMENT_PATTERN)
+ element.replace(eval($1))
+ end
+
+ build_string = ''
+
+ # handle array or anything else passed into method to be expanded in place of replacement operators
+ case (to_process)
+ when Array then to_process.each {|value| build_string.concat( "#{element.sub(match, value.to_s)} " ) } if (to_process.size > 0)
+ else build_string.concat( element.sub(match, to_process.to_s) )
+ end
+
+ # handle inline ruby string substitution
+ if (build_string =~ RUBY_STRING_REPLACEMENT_PATTERN)
+ build_string.replace(@system_wrapper.module_eval(build_string))
+ end
+
+ return build_string.strip
+ end
+
+
+ # handle argument hash: keys are substitution strings, values are data to be expanded within substitution strings
+ def dehashify_argument_elements(hash)
+ build_string = ''
+ elements = []
+
+ # grab the substitution string (hash key)
+ substitution = hash.keys[0].to_s
+ # grab the string(s) to squirt into the substitution string (hash value)
+ expand = hash[hash.keys[0]]
+
+ if (expand.nil?)
+ @streaminator.stderr_puts("ERROR: Tool '#{@tool_name}' could not expand nil elements for substitution string '#{substitution}'.", Verbosity::ERRORS)
+ raise
+ end
+
+ # array-ify expansion input if only a single string
+ expansion = ((expand.class == String) ? [expand] : expand)
+
+ expansion.each do |item|
+ # code eval substitution
+ if (item =~ RUBY_EVAL_REPLACEMENT_PATTERN)
+ elements << eval($1)
+ # string eval substitution
+ elsif (item =~ RUBY_STRING_REPLACEMENT_PATTERN)
+ elements << @system_wrapper.module_eval(item)
+ # global constants
+ elsif (@system_wrapper.constants_include?(item))
+ const = Object.const_get(item)
+ if (const.nil?)
+ @streaminator.stderr_puts("ERROR: Tool '#{@tool_name}' found constant '#{item}' to be nil.", Verbosity::ERRORS)
+ raise
+ else
+ elements << const
+ end
+ elsif (item.class == Array)
+ elements << item
+ elsif (item.class == String)
+ @streaminator.stderr_puts("ERROR: Tool '#{@tool_name}' cannot expand nonexistent value '#{item}' for substitution string '#{substitution}'.", Verbosity::ERRORS)
+ raise
+ else
+ @streaminator.stderr_puts("ERROR: Tool '#{@tool_name}' cannot expand value having type '#{item.class}' for substitution string '#{substitution}'.", Verbosity::ERRORS)
+ raise
+ end
+ end
+
+ # expand elements (whether string or array) into substitution string & replace escaped '\$'
+ elements.flatten!
+ elements.each do |element|
+ build_string.concat( substitution.sub(/([^\\]*)\$/, "\\1#{element}") ) # don't replace escaped '\$' but allow us to replace just a lonesome '$'
+ build_string.gsub!(/\\\$/, '$')
+ build_string.concat(' ')
+ end
+
+ return build_string.strip
+ end
+
+end
diff --git a/tests/vendor/ceedling/lib/tool_executor_helper.rb b/tests/vendor/ceedling/lib/tool_executor_helper.rb
new file mode 100644
index 000000000..c2ccaa387
--- /dev/null
+++ b/tests/vendor/ceedling/lib/tool_executor_helper.rb
@@ -0,0 +1,115 @@
+require 'constants' # for Verbosity enumeration & $stderr redirect enumeration
+
+class ToolExecutorHelper
+
+ constructor :streaminator, :system_utils, :system_wrapper
+
+ def stderr_redirection(tool_config, logging)
+ # if there's no logging enabled, return :stderr_redirect unmodified
+ return tool_config[:stderr_redirect] if (not logging)
+
+ # if there is logging enabled but the redirect is a custom value (not enum), return the custom string
+ return tool_config[:stderr_redirect] if (tool_config[:stderr_redirect].class == String)
+
+ # if logging is enabled but there's no custom string, return the AUTO enumeration so $stderr goes into the log
+ return StdErrRedirect::AUTO
+ end
+
+ def background_exec_cmdline_prepend(tool_config)
+ return nil if (tool_config[:background_exec].nil?)
+
+ config_exec = tool_config[:background_exec]
+
+ if ((config_exec == BackgroundExec::AUTO) and (@system_wrapper.windows?))
+ return 'start'
+ end
+
+ if (config_exec == BackgroundExec::WIN)
+ return 'start'
+ end
+
+ return nil
+ end
+
+ def osify_path_separators(executable)
+ return executable.gsub(/\//, '\\') if (@system_wrapper.windows?)
+ return executable
+ end
+
+ def stderr_redirect_cmdline_append(tool_config)
+ return nil if (tool_config[:stderr_redirect].nil?)
+
+ config_redirect = tool_config[:stderr_redirect]
+ redirect = StdErrRedirect::NONE
+
+ if (config_redirect == StdErrRedirect::AUTO)
+ if (@system_wrapper.windows?)
+ redirect = StdErrRedirect::WIN
+ else
+ if (@system_utils.tcsh_shell?)
+ redirect = StdErrRedirect::TCSH
+ else
+ redirect = StdErrRedirect::UNIX
+ end
+ end
+ end
+
+ case redirect
+ # we may need more complicated processing after some learning with various environments
+ when StdErrRedirect::NONE then nil
+ when StdErrRedirect::WIN then '2>&1'
+ when StdErrRedirect::UNIX then '2>&1'
+ when StdErrRedirect::TCSH then '|&'
+ else redirect.to_s
+ end
+ end
+
+ def background_exec_cmdline_append(tool_config)
+ return nil if (tool_config[:background_exec].nil?)
+
+ config_exec = tool_config[:background_exec]
+
+ # if :auto & windows, then we already prepended 'start' and should append nothing
+ return nil if ((config_exec == BackgroundExec::AUTO) and (@system_wrapper.windows?))
+
+ # if :auto & not windows, then we append standard '&'
+ return '&' if ((config_exec == BackgroundExec::AUTO) and (not @system_wrapper.windows?))
+
+ # if explicitly Unix, then append '&'
+ return '&' if (config_exec == BackgroundExec::UNIX)
+
+ # all other cases, including :none, :win, & anything unrecognized, append nothing
+ return nil
+ end
+
+ # if command succeeded and we have verbosity cranked up, spill our guts
+ def print_happy_results(command_str, shell_result, boom=true)
+ if ((shell_result[:exit_code] == 0) or ((shell_result[:exit_code] != 0) and not boom))
+ output = "> Shell executed command:\n"
+ output += "#{command_str}\n"
+ output += "> Produced output:\n" if (not shell_result[:output].empty?)
+ output += "#{shell_result[:output].strip}\n" if (not shell_result[:output].empty?)
+ output += "> And exited with status: [#{shell_result[:exit_code]}].\n" if (shell_result[:exit_code] != 0)
+ output += "\n"
+
+ @streaminator.stdout_puts(output, Verbosity::OBNOXIOUS)
+ end
+ end
+
+ # if command failed and we have verbosity set to minimum error level, spill our guts
+ def print_error_results(command_str, shell_result, boom=true)
+ if ((shell_result[:exit_code] != 0) and boom)
+ output = "ERROR: Shell command failed.\n"
+ output += "> Shell executed command:\n"
+ output += "'#{command_str}'\n"
+ output += "> Produced output:\n" if (not shell_result[:output].empty?)
+ output += "#{shell_result[:output].strip}\n" if (not shell_result[:output].empty?)
+ output += "> And exited with status: [#{shell_result[:exit_code]}].\n" if (shell_result[:exit_code] != nil)
+ output += "> And then likely crashed.\n" if (shell_result[:exit_code] == nil)
+ output += "\n"
+
+ @streaminator.stderr_puts(output, Verbosity::ERRORS)
+ end
+ end
+
+end
diff --git a/tests/vendor/ceedling/lib/verbosinator.rb b/tests/vendor/ceedling/lib/verbosinator.rb
new file mode 100644
index 000000000..e8ed38d78
--- /dev/null
+++ b/tests/vendor/ceedling/lib/verbosinator.rb
@@ -0,0 +1,10 @@
+
+class Verbosinator
+
+ constructor :configurator
+
+ def should_output?(level)
+ return (level <= @configurator.project_verbosity)
+ end
+
+end
diff --git a/tests/vendor/ceedling/lib/yaml_wrapper.rb b/tests/vendor/ceedling/lib/yaml_wrapper.rb
new file mode 100644
index 000000000..77cef59f7
--- /dev/null
+++ b/tests/vendor/ceedling/lib/yaml_wrapper.rb
@@ -0,0 +1,16 @@
+require 'yaml'
+
+
+class YamlWrapper
+
+ def load(filepath)
+ return YAML.load(File.read(filepath))
+ end
+
+ def dump(filepath, structure)
+ File.open(filepath, 'w') do |output|
+ YAML.dump(structure, output)
+ end
+ end
+
+end
diff --git a/tests/vendor/ceedling/plugins/bullseye/assets/template.erb b/tests/vendor/ceedling/plugins/bullseye/assets/template.erb
new file mode 100644
index 000000000..504f85583
--- /dev/null
+++ b/tests/vendor/ceedling/plugins/bullseye/assets/template.erb
@@ -0,0 +1,15 @@
+% function_string = hash[:coverage][:functions].to_s
+% branch_string = hash[:coverage][:branches].to_s
+% format_string = "%#{[function_string.length, branch_string.length].max}i"
+<%=@ceedling[:plugin_reportinator].generate_banner("#{hash[:header]}: CODE COVERAGE SUMMARY")%>
+% if (!hash[:coverage][:functions].nil?)
+FUNCTIONS: <%=sprintf(format_string, hash[:coverage][:functions])%>%
+% else
+FUNCTIONS: none
+% end
+% if (!hash[:coverage][:branches].nil?)
+BRANCHES: <%=sprintf(format_string, hash[:coverage][:branches])%>%
+% else
+BRANCHES: none
+% end
+
diff --git a/tests/vendor/ceedling/plugins/bullseye/bullseye.rake b/tests/vendor/ceedling/plugins/bullseye/bullseye.rake
new file mode 100644
index 000000000..5ee4ff479
--- /dev/null
+++ b/tests/vendor/ceedling/plugins/bullseye/bullseye.rake
@@ -0,0 +1,162 @@
+
+directory(BULLSEYE_BUILD_OUTPUT_PATH)
+directory(BULLSEYE_RESULTS_PATH)
+directory(BULLSEYE_ARTIFACTS_PATH)
+directory(BULLSEYE_DEPENDENCIES_PATH)
+
+CLEAN.include(File.join(BULLSEYE_BUILD_OUTPUT_PATH, '*'))
+CLEAN.include(File.join(BULLSEYE_RESULTS_PATH, '*'))
+CLEAN.include(File.join(BULLSEYE_DEPENDENCIES_PATH, '*'))
+
+CLOBBER.include(File.join(BULLSEYE_BUILD_PATH, '**/*'))
+
+
+rule(/#{BULLSEYE_BUILD_OUTPUT_PATH}\/#{'.+\\'+EXTENSION_OBJECT}$/ => [
+ proc do |task_name|
+ @ceedling[:file_finder].find_compilation_input_file(task_name)
+ end
+ ]) do |object|
+
+ if (File.basename(object.source) =~ /^(#{PROJECT_TEST_FILE_PREFIX}|#{CMOCK_MOCK_PREFIX}|#{BULLSEYE_IGNORE_SOURCES.join('|')})/i)
+ @ceedling[:generator].generate_object_file(
+ TOOLS_BULLSEYE_COMPILER,
+ BULLSEYE_SYM,
+ object.source,
+ object.name,
+ @ceedling[:file_path_utils].form_test_build_list_filepath( object.name ) )
+ else
+ @ceedling[BULLSEYE_SYM].generate_coverage_object_file(object.source, object.name)
+ end
+
+end
+
+rule(/#{BULLSEYE_BUILD_OUTPUT_PATH}\/#{'.+\\'+EXTENSION_EXECUTABLE}$/) do |bin_file|
+ @ceedling[:generator].generate_executable_file(
+ TOOLS_BULLSEYE_LINKER,
+ BULLSEYE_SYM,
+ bin_file.prerequisites,
+ bin_file.name,
+ @ceedling[:file_path_utils].form_test_build_map_filepath(bin_file.name))
+end
+
+rule(/#{BULLSEYE_RESULTS_PATH}\/#{'.+\\'+EXTENSION_TESTPASS}$/ => [
+ proc do |task_name|
+ @ceedling[:file_path_utils].form_test_executable_filepath(task_name)
+ end
+ ]) do |test_result|
+ @ceedling[:generator].generate_test_results(TOOLS_BULLSEYE_FIXTURE, BULLSEYE_SYM, test_result.source, test_result.name)
+end
+
+rule(/#{BULLSEYE_DEPENDENCIES_PATH}\/#{'.+\\'+EXTENSION_DEPENDENCIES}$/ => [
+ proc do |task_name|
+ @ceedling[:file_finder].find_compilation_input_file(task_name)
+ end
+ ]) do |dep|
+ @ceedling[:generator].generate_dependencies_file(
+ TOOLS_TEST_DEPENDENCIES_GENERATOR,
+ BULLSEYE_SYM,
+ dep.source,
+ File.join(BULLSEYE_BUILD_OUTPUT_PATH, File.basename(dep.source).ext(EXTENSION_OBJECT) ),
+ dep.name)
+end
+
+task :directories => [BULLSEYE_BUILD_OUTPUT_PATH, BULLSEYE_RESULTS_PATH, BULLSEYE_DEPENDENCIES_PATH, BULLSEYE_ARTIFACTS_PATH]
+
+namespace BULLSEYE_SYM do
+
+ task :source_coverage => COLLECTION_ALL_SOURCE.pathmap("#{BULLSEYE_BUILD_OUTPUT_PATH}/%n#{@ceedling[:configurator].extension_object}")
+
+ desc "Run code coverage for all tests"
+ task :all => [:directories] do
+ @ceedling[:configurator].replace_flattened_config(@ceedling[BULLSEYE_SYM].config)
+ @ceedling[:test_invoker].setup_and_invoke(COLLECTION_ALL_TESTS, BULLSEYE_SYM)
+ @ceedling[:configurator].restore_config
+ end
+
+ desc "Run single test w/ coverage ([*] real test or source file name, no path)."
+ task :* do
+ message = "\nOops! '#{BULLSEYE_ROOT_NAME}:*' isn't a real task. " +
+ "Use a real test or source file name (no path) in place of the wildcard.\n" +
+ "Example: rake #{BULLSEYE_ROOT_NAME}:foo.c\n\n"
+
+ @ceedling[:streaminator].stdout_puts( message )
+ end
+
+ desc "Run tests by matching regular expression pattern."
+ task :pattern, [:regex] => [:directories] do |t, args|
+ matches = []
+
+ COLLECTION_ALL_TESTS.each do |test|
+ matches << test if test =~ /#{args.regex}/
+ end
+
+ if (matches.size > 0)
+ @ceedling[:configurator].replace_flattened_config(@ceedling[BULLSEYE_SYM].config)
+ @ceedling[:test_invoker].setup_and_invoke(matches, BULLSEYE_SYM, {:force_run => false})
+ @ceedling[:configurator].restore_config
+ else
+ @ceedling[:streaminator].stdout_puts("\nFound no tests matching pattern /#{args.regex}/.")
+ end
+ end
+
+ desc "Run tests whose test path contains [dir] or [dir] substring."
+ task :path, [:dir] => [:directories] do |t, args|
+ matches = []
+
+ COLLECTION_ALL_TESTS.each do |test|
+ matches << test if File.dirname(test).include?(args.dir.gsub(/\\/, '/'))
+ end
+
+ if (matches.size > 0)
+ @ceedling[:configurator].replace_flattened_config(@ceedling[BULLSEYE_SYM].config)
+ @ceedling[:test_invoker].setup_and_invoke(matches, BULLSEYE_SYM, {:force_run => false})
+ @ceedling[:configurator].restore_config
+ else
+ @ceedling[:streaminator].stdout_puts("\nFound no tests including the given path or path component.")
+ end
+ end
+
+ desc "Run code coverage for changed files"
+ task :delta => [:directories] do
+ @ceedling[:configurator].replace_flattened_config(@ceedling[BULLSEYE_SYM].config)
+ @ceedling[:test_invoker].setup_and_invoke(COLLECTION_ALL_TESTS, BULLSEYE_SYM, {:force_run => false})
+ @ceedling[:configurator].restore_config
+ end
+
+ # use a rule to increase efficiency for large projects
+ # bullseye test tasks by regex
+ rule(/^#{BULLSEYE_TASK_ROOT}\S+$/ => [
+ proc do |task_name|
+ test = task_name.sub(/#{BULLSEYE_TASK_ROOT}/, '')
+ test = "#{PROJECT_TEST_FILE_PREFIX}#{test}" if not (test.start_with?(PROJECT_TEST_FILE_PREFIX))
+ @ceedling[:file_finder].find_test_from_file_path(test)
+ end
+ ]) do |test|
+ @ceedling[:rake_wrapper][:directories].invoke
+ @ceedling[:configurator].replace_flattened_config(@ceedling[BULLSEYE_SYM].config)
+ @ceedling[:test_invoker].setup_and_invoke([test.source], BULLSEYE_SYM)
+ @ceedling[:configurator].restore_config
+ end
+
+end
+
+if PROJECT_USE_DEEP_DEPENDENCIES
+namespace REFRESH_SYM do
+ task BULLSEYE_SYM do
+ @ceedling[:configurator].replace_flattened_config(@ceedling[BULLSEYE_SYM].config)
+ @ceedling[:test_invoker].refresh_deep_dependencies
+ @ceedling[:configurator].restore_config
+ end
+end
+end
+
+namespace UTILS_SYM do
+
+ desc "Open Bullseye code coverage browser"
+ task BULLSEYE_SYM do
+ command = @ceedling[:tool_executor].build_command_line(TOOLS_BULLSEYE_BROWSER)
+ @ceedling[:tool_executor].exec(command[:line], command[:options])
+ end
+
+end
+
diff --git a/tests/vendor/ceedling/plugins/bullseye/config/defaults.yml b/tests/vendor/ceedling/plugins/bullseye/config/defaults.yml
new file mode 100644
index 000000000..b4f07834e
--- /dev/null
+++ b/tests/vendor/ceedling/plugins/bullseye/config/defaults.yml
@@ -0,0 +1,53 @@
+---
+
+:paths:
+ :bullseye_toolchain_include: []
+
+:tools:
+ :bullseye_instrumentation:
+ :executable: covc
+ :arguments:
+ - '--file $': ENVIRONMENT_COVFILE
+ - -q
+ - ${1}
+ :bullseye_compiler:
+ :executable: gcc
+ :arguments:
+ - -g
+ - -I"$": COLLECTION_PATHS_TEST_SUPPORT_SOURCE_INCLUDE_VENDOR
+ - -I"$": COLLECTION_PATHS_BULLSEYE_TOOLCHAIN_INCLUDE
+ - -D$: COLLECTION_DEFINES_TEST_AND_VENDOR
+ - -DBULLSEYE_COMPILER
+ - -c "${1}"
+ - -o "${2}"
+ :bullseye_linker:
+ :executable: gcc
+ :arguments:
+ - ${1}
+ - -o ${2}
+ - -L$: PLUGINS_BULLSEYE_LIB_PATH
+ - -lcov
+ :bullseye_fixture:
+ :executable: ${1}
+ :bullseye_report_covsrc:
+ :executable: covsrc
+ :arguments:
+ - '--file $': ENVIRONMENT_COVFILE
+ - -q
+ - -w140
+ :bullseye_report_covfn:
+ :executable: covfn
+ :stderr_redirect: :auto
+ :arguments:
+ - '--file $': ENVIRONMENT_COVFILE
+ - --width 120
+ - --no-source
+ - '"${1}"'
+ :bullseye_browser:
+ :executable: CoverageBrowser
+ :background_exec: :auto
+ :optional: TRUE
+ :arguments:
+ - '"$"': ENVIRONMENT_COVFILE
+
+...
diff --git a/tests/vendor/ceedling/plugins/bullseye/lib/bullseye.rb b/tests/vendor/ceedling/plugins/bullseye/lib/bullseye.rb
new file mode 100644
index 000000000..02149c4de
--- /dev/null
+++ b/tests/vendor/ceedling/plugins/bullseye/lib/bullseye.rb
@@ -0,0 +1,172 @@
+require 'plugin'
+require 'constants'
+
+BULLSEYE_ROOT_NAME = 'bullseye'
+BULLSEYE_TASK_ROOT = BULLSEYE_ROOT_NAME + ':'
+BULLSEYE_SYM = BULLSEYE_ROOT_NAME.to_sym
+
+BULLSEYE_BUILD_PATH = "#{PROJECT_BUILD_ROOT}/#{BULLSEYE_ROOT_NAME}"
+BULLSEYE_BUILD_OUTPUT_PATH = "#{BULLSEYE_BUILD_PATH}/out"
+BULLSEYE_RESULTS_PATH = "#{BULLSEYE_BUILD_PATH}/results"
+BULLSEYE_DEPENDENCIES_PATH = "#{BULLSEYE_BUILD_PATH}/dependencies"
+BULLSEYE_ARTIFACTS_PATH = "#{PROJECT_BUILD_ARTIFACTS_ROOT}/#{BULLSEYE_ROOT_NAME}"
+
+BULLSEYE_IGNORE_SOURCES = ['unity', 'cmock', 'cexception']
+
+
+class Bullseye < Plugin
+
+ def setup
+ @result_list = []
+ @environment = [ {:covfile => File.join( BULLSEYE_ARTIFACTS_PATH, 'test.cov' )} ]
+ @plugin_root = File.expand_path(File.join(File.dirname(__FILE__), '..'))
+ @coverage_template_all = @ceedling[:file_wrapper].read(File.join(@plugin_root, 'assets/template.erb'))
+ end
+
+ def config
+ {
+ :project_test_build_output_path => BULLSEYE_BUILD_OUTPUT_PATH,
+ :project_test_results_path => BULLSEYE_RESULTS_PATH,
+ :project_test_dependencies_path => BULLSEYE_DEPENDENCIES_PATH,
+ :defines_test => DEFINES_TEST + ['CODE_COVERAGE'],
+ :collection_defines_test_and_vendor => COLLECTION_DEFINES_TEST_AND_VENDOR + ['CODE_COVERAGE']
+ }
+ end
+
+ def generate_coverage_object_file(source, object)
+ arg_hash = {:tool => TOOLS_BULLSEYE_INSTRUMENTATION, :context => BULLSEYE_SYM, :source => source, :object => object}
+ @ceedling[:plugin_manager].pre_compile_execute(arg_hash)
+
+ @ceedling[:streaminator].stdout_puts("Compiling #{File.basename(source)} with coverage...")
+ compile_command =
+ @ceedling[:tool_executor].build_command_line(
+ TOOLS_BULLSEYE_COMPILER,
+ source,
+ object,
+ @ceedling[:file_path_utils].form_test_build_list_filepath( object ) )
+ coverage_command = @ceedling[:tool_executor].build_command_line(TOOLS_BULLSEYE_INSTRUMENTATION, compile_command[:line] )
+
+ shell_result = @ceedling[:tool_executor].exec( coverage_command[:line], coverage_command[:options] )
+
+ arg_hash[:shell_result] = shell_result
+ @ceedling[:plugin_manager].post_compile_execute(arg_hash)
+ end
+
+ def post_test_fixture_execute(arg_hash)
+ result_file = arg_hash[:result_file]
+
+ if ((result_file =~ /#{BULLSEYE_RESULTS_PATH}/) and (not @result_list.include?(result_file)))
+ @result_list << arg_hash[:result_file]
+ end
+ end
+
+ def post_build
+ return if (not @ceedling[:task_invoker].invoked?(/^#{BULLSEYE_TASK_ROOT}/))
+
+ # test results
+ results = @ceedling[:plugin_reportinator].assemble_test_results(@result_list)
+ hash = {
+ :header => BULLSEYE_ROOT_NAME.upcase,
+ :results => results
+ }
+
+ @ceedling[:plugin_reportinator].run_test_results_report(hash) do
+ message = ''
+ message = 'Unit test failures.' if (results[:counts][:failed] > 0)
+ message
+ end
+
+ # coverage results
+ return if (verify_coverage_file() == false)
+ if (@ceedling[:task_invoker].invoked?(/^#{BULLSEYE_TASK_ROOT}(all|delta)/))
+ command = @ceedling[:tool_executor].build_command_line(TOOLS_BULLSEYE_REPORT_COVSRC)
+ shell_result = @ceedling[:tool_executor].exec(command[:line], command[:options])
+ report_coverage_results_all(shell_result[:output])
+ else
+ report_per_function_coverage_results(@ceedling[:test_invoker].sources)
+ end
+ end
+
+ def summary
+ return if (verify_coverage_file() == false)
+ result_list = @ceedling[:file_path_utils].form_pass_results_filelist( BULLSEYE_RESULTS_PATH, COLLECTION_ALL_TESTS )
+
+ # test results
+ # get test results for only those tests in our configuration and of those only tests with results on disk
+ hash = {
+ :header => BULLSEYE_ROOT_NAME.upcase,
+ :results => @ceedling[:plugin_reportinator].assemble_test_results(result_list, {:boom => false})
+ }
+
+ @ceedling[:plugin_reportinator].run_test_results_report(hash)
+
+ # coverage results
+ command = @ceedling[:tool_executor].build_command_line(TOOLS_BULLSEYE_REPORT_COVSRC)
+ shell_result = @ceedling[:tool_executor].exec(command[:line], command[:options])
+ report_coverage_results_all(shell_result[:output])
+ end
+
+ private ###################################
+
+ def report_coverage_results_all(coverage)
+ results = {
+ :header => BULLSEYE_ROOT_NAME.upcase,
+ :coverage => {
+ :functions => nil,
+ :branches => nil
+ }
+ }
+
+ if (coverage =~ /^Total.*?=\s+([0-9]+)\%/)
+ results[:coverage][:functions] = $1.to_i
+ end
+
+ if (coverage =~ /^Total.*=\s+([0-9]+)\%\s*$/)
+ results[:coverage][:branches] = $1.to_i
+ end
+
+ @ceedling[:plugin_reportinator].run_report($stdout, @coverage_template_all, results)
+ end
+
+ def report_per_function_coverage_results(sources)
+ banner = @ceedling[:plugin_reportinator].generate_banner( "#{BULLSEYE_ROOT_NAME.upcase}: CODE COVERAGE SUMMARY" )
+ @ceedling[:streaminator].stdout_puts "\n" + banner
+
+ coverage_sources = sources.clone
+ coverage_sources.delete_if {|item| item =~ /#{CMOCK_MOCK_PREFIX}.+#{EXTENSION_SOURCE}$/}
+ coverage_sources.delete_if {|item| item =~ /#{BULLSEYE_IGNORE_SOURCES.join('|')}#{EXTENSION_SOURCE}$/}
+
+ coverage_sources.each do |source|
+ command = @ceedling[:tool_executor].build_command_line(TOOLS_BULLSEYE_REPORT_COVFN, source)
+ shell_results = @ceedling[:tool_executor].exec(command[:line], command[:options])
+ coverage_results = shell_results[:output].deep_clone
+ coverage_results.sub!(/.*\n.*\n/,'') # Remove the Bullseye tool banner
+ if (coverage_results =~ /warning cov814: report is empty/)
+ coverage_results = "WARNING: #{source} contains no coverage data!\n\n"
+ @ceedling[:streaminator].stdout_puts(coverage_results, Verbosity::COMPLAIN)
+ else
+ coverage_results += "\n"
+ @ceedling[:streaminator].stdout_puts(coverage_results)
+ end
+ end
+ end
+
+ def verify_coverage_file
+ exist = @ceedling[:file_wrapper].exist?( ENVIRONMENT_COVFILE )
+
+ if (!exist)
+ banner = @ceedling[:plugin_reportinator].generate_banner( "#{BULLSEYE_ROOT_NAME.upcase}: CODE COVERAGE SUMMARY" )
+ @ceedling[:streaminator].stdout_puts "\n" + banner + "\nNo coverage file.\n\n"
+ end
+
+ return exist
+ end
+
+end
+
+
+# end blocks always executed following rake run
+END {
+ # cache our input configurations to use in comparison upon next execution
+ @ceedling[:cacheinator].cache_test_config( @ceedling[:setupinator].config_hash ) if (@ceedling[:task_invoker].invoked?(/^#{BULLSEYE_TASK_ROOT}/))
+}
diff --git a/tests/vendor/ceedling/plugins/bullseye/readme.txt b/tests/vendor/ceedling/plugins/bullseye/readme.txt
new file mode 100644
index 000000000..e69de29bb
diff --git a/tests/vendor/ceedling/plugins/gcov/defaults.yml b/tests/vendor/ceedling/plugins/gcov/defaults.yml
new file mode 100644
index 000000000..78be97204
--- /dev/null
+++ b/tests/vendor/ceedling/plugins/gcov/defaults.yml
@@ -0,0 +1,34 @@
+---
+
+:tools:
+ :gcov_compiler:
+ :executable: gcc
+ :arguments:
+ - -g
+ - -fprofile-arcs
+ - -ftest-coverage
+ - -I"$": COLLECTION_PATHS_TEST_SUPPORT_SOURCE_INCLUDE_VENDOR
+ - -I"$": COLLECTION_PATHS_TEST_TOOLCHAIN_INCLUDE
+ - -D$: COLLECTION_DEFINES_TEST_AND_VENDOR
+ - -DGCOV_COMPILER
+ - -c "${1}"
+ - -o "${2}"
+ :gcov_linker:
+ :executable: gcc
+ :arguments:
+ - -fprofile-arcs
+ - -ftest-coverage
+ - ${1}
+ - -o ${2}
+ :gcov_fixture:
+ :executable: ${1}
+ :gcov_report:
+ :executable: gcov
+ :arguments:
+ - -n
+ - -p
+ - -b
+ - -o "$": GCOV_BUILD_OUTPUT_PATH
+ - "\"${1}\""
+
+...
diff --git a/tests/vendor/ceedling/plugins/gcov/gcov.rake b/tests/vendor/ceedling/plugins/gcov/gcov.rake
new file mode 100644
index 000000000..197a064fd
--- /dev/null
+++ b/tests/vendor/ceedling/plugins/gcov/gcov.rake
@@ -0,0 +1,152 @@
+
+directory(GCOV_BUILD_OUTPUT_PATH)
+directory(GCOV_RESULTS_PATH)
+directory(GCOV_ARTIFACTS_PATH)
+directory(GCOV_DEPENDENCIES_PATH)
+
+CLEAN.include(File.join(GCOV_BUILD_OUTPUT_PATH, '*'))
+CLEAN.include(File.join(GCOV_RESULTS_PATH, '*'))
+CLEAN.include(File.join(GCOV_DEPENDENCIES_PATH, '*'))
+
+CLOBBER.include(File.join(GCOV_BUILD_PATH, '**/*'))
+
+
+rule(/#{GCOV_BUILD_OUTPUT_PATH}\/#{'.+\\'+EXTENSION_OBJECT}$/ => [
+ proc do |task_name|
+ @ceedling[:file_finder].find_compilation_input_file(task_name)
+ end
+ ]) do |object|
+
+ if (File.basename(object.source) =~ /^(#{PROJECT_TEST_FILE_PREFIX}|#{CMOCK_MOCK_PREFIX}|#{GCOV_IGNORE_SOURCES.join('|')})/i)
+ @ceedling[:generator].generate_object_file(
+ TOOLS_GCOV_COMPILER,
+ GCOV_SYM,
+ object.source,
+ object.name,
+ @ceedling[:file_path_utils].form_test_build_list_filepath( object.name ) )
+ else
+ @ceedling[GCOV_SYM].generate_coverage_object_file(object.source, object.name)
+ end
+
+end
+
+rule(/#{GCOV_BUILD_OUTPUT_PATH}\/#{'.+\\'+EXTENSION_EXECUTABLE}$/) do |bin_file|
+ @ceedling[:generator].generate_executable_file(
+ TOOLS_GCOV_LINKER,
+ GCOV_SYM,
+ bin_file.prerequisites,
+ bin_file.name,
+ @ceedling[:file_path_utils].form_test_build_map_filepath(bin_file.name))
+end
+
+rule(/#{GCOV_RESULTS_PATH}\/#{'.+\\'+EXTENSION_TESTPASS}$/ => [
+ proc do |task_name|
+ @ceedling[:file_path_utils].form_test_executable_filepath(task_name)
+ end
+ ]) do |test_result|
+ @ceedling[:generator].generate_test_results(TOOLS_GCOV_FIXTURE, GCOV_SYM, test_result.source, test_result.name)
+end
+
+rule(/#{GCOV_DEPENDENCIES_PATH}\/#{'.+\\'+EXTENSION_DEPENDENCIES}$/ => [
+ proc do |task_name|
+ @ceedling[:file_finder].find_compilation_input_file(task_name)
+ end
+ ]) do |dep|
+ @ceedling[:generator].generate_dependencies_file(
+ TOOLS_TEST_DEPENDENCIES_GENERATOR,
+ GCOV_SYM,
+ dep.source,
+ File.join(GCOV_BUILD_OUTPUT_PATH, File.basename(dep.source).ext(EXTENSION_OBJECT) ),
+ dep.name)
+end
+
+task :directories => [GCOV_BUILD_OUTPUT_PATH, GCOV_RESULTS_PATH, GCOV_DEPENDENCIES_PATH, GCOV_ARTIFACTS_PATH]
+
+namespace GCOV_SYM do
+
+ task :source_coverage => COLLECTION_ALL_SOURCE.pathmap("#{GCOV_BUILD_OUTPUT_PATH}/%n#{@ceedling[:configurator].extension_object}")
+
+ desc "Run code coverage for all tests"
+ task :all => [:directories] do
+ @ceedling[:configurator].replace_flattened_config(@ceedling[GCOV_SYM].config)
+ @ceedling[:test_invoker].setup_and_invoke(COLLECTION_ALL_TESTS, GCOV_SYM)
+ @ceedling[:configurator].restore_config
+ end
+
+ desc "Run single test w/ coverage ([*] real test or source file name, no path)."
+ task :* do
+ message = "\nOops! '#{GCOV_ROOT_NAME}:*' isn't a real task. " +
+ "Use a real test or source file name (no path) in place of the wildcard.\n" +
+ "Example: rake #{GCOV_ROOT_NAME}:foo.c\n\n"
+
+ @ceedling[:streaminator].stdout_puts( message )
+ end
+
+ desc "Run tests by matching regular expression pattern."
+ task :pattern, [:regex] => [:directories] do |t, args|
+ matches = []
+
+ COLLECTION_ALL_TESTS.each do |test|
+ matches << test if test =~ /#{args.regex}/
+ end
+
+ if (matches.size > 0)
+ @ceedling[:configurator].replace_flattened_config(@ceedling[GCOV_SYM].config)
+ @ceedling[:test_invoker].setup_and_invoke(matches, GCOV_SYM, {:force_run => false})
+ @ceedling[:configurator].restore_config
+ else
+ @ceedling[:streaminator].stdout_puts("\nFound no tests matching pattern /#{args.regex}/.")
+ end
+ end
+
+ desc "Run tests whose test path contains [dir] or [dir] substring."
+ task :path, [:dir] => [:directories] do |t, args|
+ matches = []
+
+ COLLECTION_ALL_TESTS.each do |test|
+ matches << test if File.dirname(test).include?(args.dir.gsub(/\\/, '/'))
+ end
+
+ if (matches.size > 0)
+ @ceedling[:configurator].replace_flattened_config(@ceedling[GCOV_SYM].config)
+ @ceedling[:test_invoker].setup_and_invoke(matches, GCOV_SYM, {:force_run => false})
+ @ceedling[:configurator].restore_config
+ else
+ @ceedling[:streaminator].stdout_puts("\nFound no tests including the given path or path component.")
+ end
+ end
+
+ desc "Run code coverage for changed files"
+ task :delta => [:directories] do
+ @ceedling[:configurator].replace_flattened_config(@ceedling[GCOV_SYM].config)
+ @ceedling[:test_invoker].setup_and_invoke(COLLECTION_ALL_TESTS, GCOV_SYM, {:force_run => false})
+ @ceedling[:configurator].restore_config
+ end
+
+ # use a rule to increase efficiency for large projects
+ # gcov test tasks by regex
+ rule(/^#{GCOV_TASK_ROOT}\S+$/ => [
+ proc do |task_name|
+ test = task_name.sub(/#{GCOV_TASK_ROOT}/, '')
+ test = "#{PROJECT_TEST_FILE_PREFIX}#{test}" if not (test.start_with?(PROJECT_TEST_FILE_PREFIX))
+ @ceedling[:file_finder].find_test_from_file_path(test)
+ end
+ ]) do |test|
+ @ceedling[:rake_wrapper][:directories].invoke
+ @ceedling[:configurator].replace_flattened_config(@ceedling[GCOV_SYM].config)
+ @ceedling[:test_invoker].setup_and_invoke([test.source], GCOV_SYM)
+ @ceedling[:configurator].restore_config
+ end
+
+end
+
+if PROJECT_USE_DEEP_DEPENDENCIES
+namespace REFRESH_SYM do
+ task GCOV_SYM do
+ @ceedling[:configurator].replace_flattened_config(@ceedling[GCOV_SYM].config)
+ @ceedling[:test_invoker].refresh_deep_dependencies
+ @ceedling[:configurator].restore_config
+ end
+end
+end
+
diff --git a/tests/vendor/ceedling/plugins/gcov/gcov.rb b/tests/vendor/ceedling/plugins/gcov/gcov.rb
new file mode 100644
index 000000000..d34cecaa6
--- /dev/null
+++ b/tests/vendor/ceedling/plugins/gcov/gcov.rb
@@ -0,0 +1,128 @@
+require 'plugin'
+require 'constants'
+
+GCOV_ROOT_NAME = 'gcov'
+GCOV_TASK_ROOT = GCOV_ROOT_NAME + ':'
+GCOV_SYM = GCOV_ROOT_NAME.to_sym
+
+GCOV_BUILD_PATH = "#{PROJECT_BUILD_ROOT}/#{GCOV_ROOT_NAME}"
+GCOV_BUILD_OUTPUT_PATH = "#{GCOV_BUILD_PATH}/out"
+GCOV_RESULTS_PATH = "#{GCOV_BUILD_PATH}/results"
+GCOV_DEPENDENCIES_PATH = "#{GCOV_BUILD_PATH}/dependencies"
+GCOV_ARTIFACTS_PATH = "#{PROJECT_BUILD_ARTIFACTS_ROOT}/#{GCOV_ROOT_NAME}"
+
+GCOV_IGNORE_SOURCES = ['unity', 'cmock', 'cexception']
+
+
+class Gcov < Plugin
+
+ attr_reader :config
+
+ def setup
+ @result_list = []
+
+ @config = {
+ :project_test_build_output_path => GCOV_BUILD_OUTPUT_PATH,
+ :project_test_results_path => GCOV_RESULTS_PATH,
+ :project_test_dependencies_path => GCOV_DEPENDENCIES_PATH,
+ :defines_test => DEFINES_TEST + ['CODE_COVERAGE'],
+ :collection_defines_test_and_vendor => COLLECTION_DEFINES_TEST_AND_VENDOR + ['CODE_COVERAGE']
+ }
+
+ @coverage_template_all = @ceedling[:file_wrapper].read( File.join( PLUGINS_GCOV_PATH, 'template.erb') )
+ end
+
+ def generate_coverage_object_file(source, object)
+ compile_command =
+ @ceedling[:tool_executor].build_command_line(
+ TOOLS_GCOV_COMPILER,
+ source,
+ object,
+ @ceedling[:file_path_utils].form_test_build_list_filepath( object ) )
+ @ceedling[:streaminator].stdout_puts("Compiling #{File.basename(source)} with coverage...")
+ @ceedling[:tool_executor].exec( compile_command[:line], compile_command[:options] )
+ end
+
+ def post_test_fixture_execute(arg_hash)
+ result_file = arg_hash[:result_file]
+
+ if ((result_file =~ /#{GCOV_RESULTS_PATH}/) and (not @result_list.include?(result_file)))
+ @result_list << arg_hash[:result_file]
+ end
+ end
+
+ def post_build
+ return if (not @ceedling[:task_invoker].invoked?(/^#{GCOV_TASK_ROOT}/))
+
+ # test results
+ results = @ceedling[:plugin_reportinator].assemble_test_results(@result_list)
+ hash = {
+ :header => GCOV_ROOT_NAME.upcase,
+ :results => results
+ }
+
+ @ceedling[:plugin_reportinator].run_test_results_report(hash) do
+ message = ''
+ message = 'Unit test failures.' if (results[:counts][:failed] > 0)
+ message
+ end
+
+ if (@ceedling[:task_invoker].invoked?(/^#{GCOV_TASK_ROOT}(all|delta)/))
+ report_coverage_results_summary(@ceedling[:test_invoker].sources)
+ else
+ report_per_file_coverage_results(@ceedling[:test_invoker].sources)
+ end
+ end
+
+ def summary
+ result_list = @ceedling[:file_path_utils].form_pass_results_filelist( GCOV_RESULTS_PATH, COLLECTION_ALL_TESTS )
+
+ # test results
+ # get test results for only those tests in our configuration and of those only tests with results on disk
+ hash = {
+ :header => GCOV_ROOT_NAME.upcase,
+ :results => @ceedling[:plugin_reportinator].assemble_test_results(result_list, {:boom => false})
+ }
+
+ @ceedling[:plugin_reportinator].run_test_results_report(hash)
+
+ # coverage results
+ # command = @ceedling[:tool_executor].build_command_line(TOOLS_GCOV_REPORT_COVSRC)
+ # shell_result = @ceedling[:tool_executor].exec(command[:line], command[:options])
+ # report_coverage_results_all(shell_result[:output])
+ end
+
+ private ###################################
+
+ def report_coverage_results_summary(sources)
+
+ end
+
+ def report_per_file_coverage_results(sources)
+ banner = @ceedling[:plugin_reportinator].generate_banner "#{GCOV_ROOT_NAME.upcase}: CODE COVERAGE SUMMARY"
+ @ceedling[:streaminator].stdout_puts "\n" + banner
+
+ coverage_sources = sources.clone
+ coverage_sources.delete_if {|item| item =~ /#{CMOCK_MOCK_PREFIX}.+#{EXTENSION_SOURCE}$/}
+ coverage_sources.delete_if {|item| item =~ /#{GCOV_IGNORE_SOURCES.join('|')}#{EXTENSION_SOURCE}$/}
+
+ coverage_sources.each do |source|
+ basename = File.basename(source)
+ command = @ceedling[:tool_executor].build_command_line(TOOLS_GCOV_REPORT, basename)
+ shell_results = @ceedling[:tool_executor].exec(command[:line], command[:options])
+ coverage_results = shell_results[:output]
+
+ if (coverage_results.strip =~ /(File\s+'#{Regexp.escape(source)}'.+$)/m)
+ report = ((($1.lines.to_a)[1..-1])).map{|line| basename + ' ' + line}.join('')
+ @ceedling[:streaminator].stdout_puts(report + "\n\n")
+ end
+ end
+ end
+
+end
+
+# end blocks always executed following rake run
+END {
+ # cache our input configurations to use in comparison upon next execution
+ @ceedling[:cacheinator].cache_test_config( @ceedling[:setupinator].config_hash ) if (@ceedling[:task_invoker].invoked?(/^#{GCOV_TASK_ROOT}/))
+}
diff --git a/tests/vendor/ceedling/plugins/gcov/readme.txt b/tests/vendor/ceedling/plugins/gcov/readme.txt
new file mode 100644
index 000000000..e69de29bb
diff --git a/tests/vendor/ceedling/plugins/gcov/template.erb b/tests/vendor/ceedling/plugins/gcov/template.erb
new file mode 100644
index 000000000..a6d692977
--- /dev/null
+++ b/tests/vendor/ceedling/plugins/gcov/template.erb
@@ -0,0 +1,15 @@
+% function_string = hash[:coverage][:functions].to_s
+% branch_string = hash[:coverage][:branches].to_s
+% format_string = "%#{[function_string.length, branch_string.length].max}i"
+<%=@ceedling[:plugin_reportinator].generate_banner("#{BULLSEYE_ROOT_NAME.upcase}: CODE COVERAGE SUMMARY")%>
+% if (!hash[:coverage][:functions].nil?)
+FUNCTIONS: <%=sprintf(format_string, hash[:coverage][:functions])%>%
+% else
+FUNCTIONS: none
+% end
+% if (!hash[:coverage][:branches].nil?)
+BRANCHES: <%=sprintf(format_string, hash[:coverage][:branches])%>%
+% else
+BRANCHES: none
+% end
+
diff --git a/tests/vendor/ceedling/plugins/module_generator/config/module_generator.yml b/tests/vendor/ceedling/plugins/module_generator/config/module_generator.yml
new file mode 100644
index 000000000..cdb2da2eb
--- /dev/null
+++ b/tests/vendor/ceedling/plugins/module_generator/config/module_generator.yml
@@ -0,0 +1,4 @@
+:module_generator:
+ :project_root: ./
+ :source_root: src/
+ :test_root: test/
\ No newline at end of file
diff --git a/tests/vendor/ceedling/plugins/module_generator/lib/module_generator.rb b/tests/vendor/ceedling/plugins/module_generator/lib/module_generator.rb
new file mode 100644
index 000000000..c41783caa
--- /dev/null
+++ b/tests/vendor/ceedling/plugins/module_generator/lib/module_generator.rb
@@ -0,0 +1,144 @@
+require 'plugin'
+require 'constants'
+require 'erb'
+require 'fileutils'
+
+class ModuleGenerator < Plugin
+
+ attr_reader :config
+
+ def setup
+
+ #---- New module templates
+
+ @test_template = (<<-EOS).left_margin
+ #include "unity.h"
+ <%if defined?(MODULE_GENERATOR_TEST_INCLUDES) && (MODULE_GENERATOR_TEST_INCLUDES.class == Array) && !MODULE_GENERATOR_TEST_INCLUDES.empty?%>
+ <%MODULE_GENERATOR_TEST_INCLUDES.each do |header_file|%>
+ #include "<%=header_file%>"
+ <%end%>
+ <%end%>
+ #include "<%=@context[:headername]%>"
+
+ void setUp(void)
+ {
+ }
+
+ void tearDown(void)
+ {
+ }
+
+ void test_<%=name%>_needs_to_be_implemented(void)
+ {
+ <%="\t"%>TEST_IGNORE_MESSAGE("Implement me!");
+ }
+ EOS
+
+ @source_template = (<<-EOS).left_margin
+ <%if defined?(MODULE_GENERATOR_SOURCE_INCLUDES) && (MODULE_GENERATOR_SOURCE_INCLUDES.class == Array) && !MODULE_GENERATOR_SOURCE_INCLUDES.empty?%>
+ <%MODULE_GENERATOR_SOURCE_INCLUDES.each do |header_file|%>
+ #include "<%=header_file%>"
+ <%end%>
+ <%end%>
+ #include "<%=@context[:headername]%>"
+ EOS
+
+ @header_template = (<<-EOS).left_margin
+ #ifndef <%=@context[:name]%>_H
+ #define <%=@context[:name]%>_H
+
+ <%if defined?(MODULE_GENERATOR_HEADER_INCLUDES) && (MODULE_GENERATOR_HEADER_INCLUDES.class == Array) && !MODULE_GENERATOR_HEADER_INCLUDES.empty?%>
+ <%MODULE_GENERATOR_HEADER_INCLUDES.each do |header_file|%>
+ #include "<%=header_file%>"
+ <%end%>
+ <%end%>
+
+ #endif // <%=@context[:name]%>_H
+ EOS
+ end
+
+ def create(path, optz={})
+
+ extract_context(path, optz)
+
+ if !optz.nil? && (optz[:destroy] == true)
+ @ceedling[:streaminator].stdout_puts "Destroying '#{path}'..."
+ @files.each do |file|
+ if File.exist?(file[:path])
+ @ceedling[:streaminator].stdout_puts "File #{file[:path]} deleted"
+ else
+ @ceedling[:streaminator].stdout_puts "File #{file[:path]} does not exist!"
+ end
+ end
+ exit
+ end
+
+ @ceedling[:streaminator].stdout_puts "Generating '#{path}'..."
+
+ [File.dirname(@files[0][:path]), File.dirname(@files[1][:path])].each do |dir|
+ makedirs(dir, {:verbose => true})
+ end
+
+ # define_name = headername.gsub(/\.h$/, '_H').upcase
+
+ @files[0][:template] = @test_template
+ @files[1][:template] = @source_template
+ @files[2][:template] = @header_template
+
+ @files.each do |file|
+ if File.exist?(file[:path])
+ @ceedling[:streaminator].stdout_puts "File #{file[:path]} already exists!"
+ else
+ File.open(file[:path], 'w') do |new_file|
+ new_file << ERB.new(file[:template], 0, "<>").result(binding)
+ end
+ @ceedling[:streaminator].stdout_puts "File #{file[:path]} created"
+ end
+ end
+
+ end
+
+ private
+
+ def extract_context(path, optz={})
+ if (!defined?(MODULE_GENERATOR_PROJECT_ROOT) ||
+ !defined?(MODULE_GENERATOR_SOURCE_ROOT) ||
+ !defined?(MODULE_GENERATOR_TEST_ROOT))
+ raise "You must have ':module_generator:project_root:', ':module_generator:source_root:' and ':module_generator:test_root:' defined in your Ceedling configuration file"
+ end
+
+ @context = {}
+
+ @context[:paths] = {
+ :base => @ceedling[:file_wrapper].get_expanded_path(MODULE_GENERATOR_PROJECT_ROOT).gsub('\\', '/').sub(/^\//, '').sub(/\/$/, ''),
+ :src => MODULE_GENERATOR_SOURCE_ROOT.gsub('\\', '/').sub(/^\//, '').sub(/\/$/, ''),
+ :test => MODULE_GENERATOR_TEST_ROOT.gsub('\\', '/').sub(/^\//, '').sub(/\/$/, '')
+ }
+
+ location = File.dirname(path.gsub('\\', '/'))
+ location.sub!(/^\/?#{@context[:paths][:base]}\/?/i, '')
+ location.sub!(/^\/?#{@context[:paths][:src]}\/?/i, '')
+ location.sub!(/^\/?#{@context[:paths][:test]}\/?/i, '')
+
+ @context[:location] = location
+
+ @context[:name] = File.basename(path).sub(/\.[ch]$/, '')
+
+ # p @context[:name]
+
+ @context[:testname] = "test_#{@context[:name]}.c"
+ @context[:sourcename] = "#{@context[:name]}.c"
+ @context[:headername] = "#{@context[:name]}.h"
+
+ # p @context
+
+ @files = [
+ {:path => File.join(MODULE_GENERATOR_PROJECT_ROOT, @context[:paths][:test], location, @context[:testname])},
+ {:path => File.join(MODULE_GENERATOR_PROJECT_ROOT, @context[:paths][:src], location, @context[:sourcename])},
+ {:path => File.join(MODULE_GENERATOR_PROJECT_ROOT, @context[:paths][:src], location, @context[:headername])}
+ ]
+
+ # p @files
+ end
+
+end
\ No newline at end of file
diff --git a/tests/vendor/ceedling/plugins/module_generator/module_generator.rake b/tests/vendor/ceedling/plugins/module_generator/module_generator.rake
new file mode 100644
index 000000000..731a08ea6
--- /dev/null
+++ b/tests/vendor/ceedling/plugins/module_generator/module_generator.rake
@@ -0,0 +1,14 @@
+
+namespace :module do
+
+ desc "Generate module (source, header and test files)"
+ task :create, :module_path do |t, args|
+ @ceedling[:module_generator].create(args[:module_path])
+ end
+
+ desc "Destroy module (source, header and test files)"
+ task :destroy, :module_path do |t, args|
+ @ceedling[:module_generator].create(args[:module_path], {:destroy => true})
+ end
+
+end
diff --git a/tests/vendor/ceedling/plugins/stdout_ide_tests_report/config/stdout_ide_tests_report.yml b/tests/vendor/ceedling/plugins/stdout_ide_tests_report/config/stdout_ide_tests_report.yml
new file mode 100644
index 000000000..c25acf511
--- /dev/null
+++ b/tests/vendor/ceedling/plugins/stdout_ide_tests_report/config/stdout_ide_tests_report.yml
@@ -0,0 +1,4 @@
+---
+:plugins:
+ # tell Ceedling we got results display taken care of
+ :display_raw_test_results: FALSE
diff --git a/tests/vendor/ceedling/plugins/stdout_ide_tests_report/lib/stdout_ide_tests_report.rb b/tests/vendor/ceedling/plugins/stdout_ide_tests_report/lib/stdout_ide_tests_report.rb
new file mode 100644
index 000000000..61db06286
--- /dev/null
+++ b/tests/vendor/ceedling/plugins/stdout_ide_tests_report/lib/stdout_ide_tests_report.rb
@@ -0,0 +1,44 @@
+require 'plugin'
+require 'defaults'
+
+class StdoutIdeTestsReport < Plugin
+
+ def setup
+ @result_list = []
+ end
+
+ def post_test_fixture_execute(arg_hash)
+ return if not (arg_hash[:context] == TEST_SYM)
+
+ @result_list << arg_hash[:result_file]
+ end
+
+ def post_build
+ return if (not @ceedling[:task_invoker].test_invoked?)
+
+ results = @ceedling[:plugin_reportinator].assemble_test_results(@result_list)
+ hash = {
+ :header => '',
+ :results => results
+ }
+
+ @ceedling[:plugin_reportinator].run_test_results_report(hash) do
+ message = ''
+ message = 'Unit test failures.' if (hash[:results][:counts][:failed] > 0)
+ message
+ end
+ end
+
+ def summary
+ result_list = @ceedling[:file_path_utils].form_pass_results_filelist( PROJECT_TEST_RESULTS_PATH, COLLECTION_ALL_TESTS )
+
+ # get test results for only those tests in our configuration and of those only tests with results on disk
+ hash = {
+ :header => '',
+ :results => @ceedling[:plugin_reportinator].assemble_test_results(result_list, {:boom => false})
+ }
+
+ @ceedling[:plugin_reportinator].run_test_results_report(hash)
+ end
+
+end
\ No newline at end of file
diff --git a/tests/vendor/ceedling/plugins/stdout_pretty_tests_report/assets/template.erb b/tests/vendor/ceedling/plugins/stdout_pretty_tests_report/assets/template.erb
new file mode 100644
index 000000000..4c9fb46a5
--- /dev/null
+++ b/tests/vendor/ceedling/plugins/stdout_pretty_tests_report/assets/template.erb
@@ -0,0 +1,59 @@
+% ignored = hash[:results][:counts][:ignored]
+% failed = hash[:results][:counts][:failed]
+% stdout_count = hash[:results][:counts][:stdout]
+% header_prepend = ((hash[:header].length > 0) ? "#{hash[:header]}: " : '')
+% banner_width = 25 + header_prepend.length # widest message
+
+% if (ignored > 0)
+<%=@ceedling[:plugin_reportinator].generate_banner(header_prepend + 'IGNORED UNIT TEST SUMMARY')%>
+% hash[:results][:ignores].each do |ignore|
+[<%=ignore[:source][:file]%>]
+% ignore[:collection].each do |item|
+ Test: <%=item[:test]%>
+% if (not item[:message].empty?)
+ At line (<%=item[:line]%>): "<%=item[:message]%>"
+% else
+ At line (<%=item[:line]%>)
+% end
+
+% end
+% end
+% end
+% if (failed > 0)
+<%=@ceedling[:plugin_reportinator].generate_banner(header_prepend + 'FAILED UNIT TEST SUMMARY')%>
+% hash[:results][:failures].each do |failure|
+[<%=failure[:source][:file]%>]
+% failure[:collection].each do |item|
+ Test: <%=item[:test]%>
+% if (not item[:message].empty?)
+ At line (<%=item[:line]%>): "<%=item[:message]%>"
+% else
+ At line (<%=item[:line]%>)
+% end
+
+% end
+% end
+% end
+% if (stdout_count > 0)
+<%=@ceedling[:plugin_reportinator].generate_banner(header_prepend + 'UNIT TEST OTHER OUTPUT')%>
+% hash[:results][:stdout].each do |string|
+[<%=string[:source][:file]%>]
+% string[:collection].each do |item|
+ - "<%=item%>"
+% end
+
+% end
+% end
+% total_string = hash[:results][:counts][:total].to_s
+% format_string = "%#{total_string.length}i"
+<%=@ceedling[:plugin_reportinator].generate_banner(header_prepend + 'OVERALL UNIT TEST SUMMARY')%>
+% if (hash[:results][:counts][:total] > 0)
+TESTED: <%=hash[:results][:counts][:total].to_s%>
+PASSED: <%=sprintf(format_string, hash[:results][:counts][:passed])%>
+FAILED: <%=sprintf(format_string, failed)%>
+IGNORED: <%=sprintf(format_string, ignored)%>
+% else
+
+No tests executed.
+% end
+
diff --git a/tests/vendor/ceedling/plugins/stdout_pretty_tests_report/config/stdout_pretty_tests_report.yml b/tests/vendor/ceedling/plugins/stdout_pretty_tests_report/config/stdout_pretty_tests_report.yml
new file mode 100644
index 000000000..c25acf511
--- /dev/null
+++ b/tests/vendor/ceedling/plugins/stdout_pretty_tests_report/config/stdout_pretty_tests_report.yml
@@ -0,0 +1,4 @@
+---
+:plugins:
+ # tell Ceedling we got results display taken care of
+ :display_raw_test_results: FALSE
diff --git a/tests/vendor/ceedling/plugins/stdout_pretty_tests_report/lib/stdout_pretty_tests_report.rb b/tests/vendor/ceedling/plugins/stdout_pretty_tests_report/lib/stdout_pretty_tests_report.rb
new file mode 100644
index 000000000..1e50fafaa
--- /dev/null
+++ b/tests/vendor/ceedling/plugins/stdout_pretty_tests_report/lib/stdout_pretty_tests_report.rb
@@ -0,0 +1,47 @@
+require 'plugin'
+require 'defaults'
+
+class StdoutPrettyTestsReport < Plugin
+
+ def setup
+ @result_list = []
+ @plugin_root = File.expand_path(File.join(File.dirname(__FILE__), '..'))
+ template = @ceedling[:file_wrapper].read(File.join(@plugin_root, 'assets/template.erb'))
+ @ceedling[:plugin_reportinator].register_test_results_template( template )
+ end
+
+ def post_test_fixture_execute(arg_hash)
+ return if not (arg_hash[:context] == TEST_SYM)
+
+ @result_list << arg_hash[:result_file]
+ end
+
+ def post_build
+ return if not (@ceedling[:task_invoker].test_invoked?)
+
+ results = @ceedling[:plugin_reportinator].assemble_test_results(@result_list)
+ hash = {
+ :header => '',
+ :results => results
+ }
+
+ @ceedling[:plugin_reportinator].run_test_results_report(hash) do
+ message = ''
+ message = 'Unit test failures.' if (results[:counts][:failed] > 0)
+ message
+ end
+ end
+
+ def summary
+ result_list = @ceedling[:file_path_utils].form_pass_results_filelist( PROJECT_TEST_RESULTS_PATH, COLLECTION_ALL_TESTS )
+
+ # get test results for only those tests in our configuration and of those only tests with results on disk
+ hash = {
+ :header => '',
+ :results => @ceedling[:plugin_reportinator].assemble_test_results(result_list, {:boom => false})
+ }
+
+ @ceedling[:plugin_reportinator].run_test_results_report(hash)
+ end
+
+end
\ No newline at end of file
diff --git a/tests/vendor/ceedling/plugins/warnings_report/warnings_report.rb b/tests/vendor/ceedling/plugins/warnings_report/warnings_report.rb
new file mode 100644
index 000000000..6f1a26615
--- /dev/null
+++ b/tests/vendor/ceedling/plugins/warnings_report/warnings_report.rb
@@ -0,0 +1,71 @@
+require 'plugin'
+require 'constants'
+
+class WarningsReport < Plugin
+
+ def setup
+ @stderr_redirect = nil
+ @log_paths = {}
+ end
+
+ def pre_compile_execute( arg_hash )
+ # at beginning of compile, override tool's stderr_redirect so we can parse $stderr + $stdout
+ set_stderr_redirect( arg_hash )
+ end
+
+ def post_compile_execute( arg_hash )
+ # after compilation, grab output for parsing/logging, restore stderr_redirect, log warning if it exists
+ output = arg_hash[:shell_result][:output]
+ restore_stderr_redirect( arg_hash )
+ write_warning_log( arg_hash[:context], output )
+ end
+
+ def pre_link_execute( arg_hash )
+ # at beginning of link, override tool's stderr_redirect so we can parse $stderr + $stdout
+ set_stderr_redirect( arg_hash )
+ end
+
+ def post_link_execute( arg_hash )
+ # after linking, grab output for parsing/logging, restore stderr_redirect, log warning if it exists
+ output = arg_hash[:shell_result][:output]
+ restore_stderr_redirect( arg_hash )
+ write_warning_log( arg_hash[:context], output )
+ end
+
+ private
+
+ def set_stderr_redirect( hash )
+ @stderr_redirect = hash[:tool][:stderr_redirect]
+ hash[:tool][:stderr_redirect] = StdErrRedirect::AUTO
+ end
+
+ def restore_stderr_redirect( hash )
+ hash[:tool][:stderr_redirect] = @stderr_redirect
+ end
+
+ def write_warning_log( context, output )
+ # if $stderr/$stdout contain "warning", log it
+ if (output =~ /warning/i)
+ # generate a log path & file io write flags
+ logging = generate_log_path( context )
+ @ceedling[:file_wrapper].write( logging[:path], output + "\n", logging[:flags] ) if (not logging.nil?)
+ end
+ end
+
+ def generate_log_path( context )
+ # if path has already been generated, return it & 'append' file io flags (append to log)
+ return { :path => @log_paths[context], :flags => 'a' } if (not @log_paths[context].nil?)
+
+ # first time through, generate path & 'write' file io flags (create new log)
+ base_path = File.join( PROJECT_BUILD_ARTIFACTS_ROOT, context.to_s )
+ file_path = File.join( base_path, 'warnings.log' )
+
+ if (@ceedling[:file_wrapper].exist?( base_path ))
+ @log_paths[context] = file_path
+ return { :path => file_path, :flags => 'w' }
+ end
+
+ return nil
+ end
+
+end
\ No newline at end of file
diff --git a/tests/vendor/ceedling/plugins/xml_tests_report/xml_tests_report.rb b/tests/vendor/ceedling/plugins/xml_tests_report/xml_tests_report.rb
new file mode 100644
index 000000000..97881a403
--- /dev/null
+++ b/tests/vendor/ceedling/plugins/xml_tests_report/xml_tests_report.rb
@@ -0,0 +1,110 @@
+require 'plugin'
+require 'constants'
+
+class XmlTestsReport < Plugin
+
+ def setup
+ @results_list = {}
+ @test_counter = 0
+ end
+
+ def post_test_fixture_execute(arg_hash)
+ context = arg_hash[:context]
+
+ @results_list[context] = [] if (@results_list[context].nil?)
+
+ @results_list[context] << arg_hash[:result_file]
+ end
+
+ def post_build
+ @results_list.each_key do |context|
+ results = @ceedling[:plugin_reportinator].assemble_test_results(@results_list[context])
+
+ file_path = File.join( PROJECT_BUILD_ARTIFACTS_ROOT, context.to_s, 'report.xml' )
+
+ @ceedling[:file_wrapper].open( file_path, 'w' ) do |f|
+ @test_counter = 1
+ write_results( results, f )
+ end
+ end
+ end
+
+ private
+
+ def write_results( results, stream )
+ write_header( stream )
+ write_failures( results[:failures], stream )
+ write_tests( results[:successes], stream, 'SuccessfulTests' )
+ write_tests( results[:ignores], stream, 'IgnoredTests' )
+ write_statistics( results[:counts], stream )
+ write_footer( stream )
+ end
+
+ def write_header( stream )
+ stream.puts ""
+ stream.puts ""
+ end
+
+ def write_failures( results, stream )
+ if (results.size == 0)
+ stream.puts "\t"
+ return
+ end
+
+ stream.puts "\t"
+
+ results.each do |result|
+ result[:collection].each do |item|
+ filename = File.join( result[:source][:path], result[:source][:file] )
+
+ stream.puts "\t\t"
+ stream.puts "\t\t\t#{filename}::#{item[:test]}"
+ stream.puts "\t\t\tAssertion"
+ stream.puts "\t\t\t"
+ stream.puts "\t\t\t\t#{filename}"
+ stream.puts "\t\t\t\t#{item[:line]}"
+ stream.puts "\t\t\t"
+ stream.puts "\t\t\t#{item[:message]}"
+ stream.puts "\t\t"
+ @test_counter += 1
+ end
+ end
+
+ stream.puts "\t"
+ end
+
+ def write_tests( results, stream, tag )
+ if (results.size == 0)
+ stream.puts "\t<#{tag}/>"
+ return
+ end
+
+ stream.puts "\t<#{tag}>"
+
+ results.each do |result|
+ result[:collection].each do |item|
+ stream.puts "\t\t"
+ stream.puts "\t\t\t#{File.join( result[:source][:path], result[:source][:file] )}::#{item[:test]}"
+ stream.puts "\t\t"
+ @test_counter += 1
+ end
+ end
+
+ stream.puts "\t#{tag}>"
+ end
+
+ def write_statistics( counts, stream )
+ stream.puts "\t"
+ stream.puts "\t\t#{counts[:total]}"
+ stream.puts "\t\t#{counts[:ignored]}"
+ stream.puts "\t\t#{counts[:failed]}"
+ stream.puts "\t\t0"
+ stream.puts "\t\t#{counts[:failed]}"
+ stream.puts "\t"
+ end
+
+ def write_footer( stream )
+ stream.puts ""
+ end
+
+end
\ No newline at end of file
diff --git a/tests/vendor/ceedling/release/build.info b/tests/vendor/ceedling/release/build.info
new file mode 100644
index 000000000..d41688c57
--- /dev/null
+++ b/tests/vendor/ceedling/release/build.info
@@ -0,0 +1,2 @@
+226
+
diff --git a/tests/vendor/ceedling/release/version.info b/tests/vendor/ceedling/release/version.info
new file mode 100644
index 000000000..688abaae7
--- /dev/null
+++ b/tests/vendor/ceedling/release/version.info
@@ -0,0 +1 @@
+0.10
\ No newline at end of file
diff --git a/tests/vendor/ceedling/vendor/c_exception/lib/CException.c b/tests/vendor/ceedling/vendor/c_exception/lib/CException.c
new file mode 100644
index 000000000..97e1b4133
--- /dev/null
+++ b/tests/vendor/ceedling/vendor/c_exception/lib/CException.c
@@ -0,0 +1,43 @@
+#include "CException.h"
+
+volatile CEXCEPTION_FRAME_T CExceptionFrames[CEXCEPTION_NUM_ID] = { 0 };
+
+//------------------------------------------------------------------------------------------
+// Throw
+//------------------------------------------------------------------------------------------
+void Throw(CEXCEPTION_T ExceptionID)
+{
+ unsigned int MY_ID = CEXCEPTION_GET_ID;
+ CExceptionFrames[MY_ID].Exception = ExceptionID;
+ if (CExceptionFrames[MY_ID].pFrame)
+ {
+ longjmp(*CExceptionFrames[MY_ID].pFrame, 1);
+ }
+ CEXCEPTION_NO_CATCH_HANDLER(MY_ID);
+}
+
+//------------------------------------------------------------------------------------------
+// Explanation of what it's all for:
+//------------------------------------------------------------------------------------------
+/*
+#define Try
+ { <- give us some local scope. most compilers are happy with this
+ jmp_buf *PrevFrame, NewFrame; <- prev frame points to the last try block's frame. new frame gets created on stack for this Try block
+ unsigned int MY_ID = CEXCEPTION_GET_ID; <- look up this task's id for use in frame array. always 0 if single-tasking
+ PrevFrame = CExceptionFrames[CEXCEPTION_GET_ID].pFrame; <- set pointer to point at old frame (which array is currently pointing at)
+ CExceptionFrames[MY_ID].pFrame = &NewFrame; <- set array to point at my new frame instead, now
+ CExceptionFrames[MY_ID].Exception = CEXCEPTION_NONE; <- initialize my exception id to be NONE
+ if (setjmp(NewFrame) == 0) { <- do setjmp. it returns 1 if longjump called, otherwise 0
+ if (&PrevFrame) <- this is here to force proper scoping. it requires braces or a single line to be but after Try, otherwise won't compile. This is always true at this point.
+
+#define Catch(e)
+ else { } <- this also forces proper scoping. Without this they could stick their own 'else' in and it would get ugly
+ CExceptionFrames[MY_ID].Exception = CEXCEPTION_NONE; <- no errors happened, so just set the exception id to NONE (in case it was corrupted)
+ }
+ else <- an exception occurred
+ { e = CExceptionFrames[MY_ID].Exception; e=e;} <- assign the caught exception id to the variable passed in.
+ CExceptionFrames[MY_ID].pFrame = PrevFrame; <- make the pointer in the array point at the previous frame again, as if NewFrame never existed.
+ } <- finish off that local scope we created to have our own variables
+ if (CExceptionFrames[CEXCEPTION_GET_ID].Exception != CEXCEPTION_NONE) <- start the actual 'catch' processing if we have an exception id saved away
+ */
+
diff --git a/tests/vendor/ceedling/vendor/c_exception/lib/CException.h b/tests/vendor/ceedling/vendor/c_exception/lib/CException.h
new file mode 100644
index 000000000..7e374291e
--- /dev/null
+++ b/tests/vendor/ceedling/vendor/c_exception/lib/CException.h
@@ -0,0 +1,86 @@
+#ifndef _CEXCEPTION_H
+#define _CEXCEPTION_H
+
+#include
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+
+//To Use CException, you have a number of options:
+//1. Just include it and run with the defaults
+//2. Define any of the following symbols at the command line to override them
+//3. Include a header file before CException.h everywhere which defines any of these
+//4. Create an Exception.h in your path, and just define EXCEPTION_USE_CONFIG_FILE first
+
+#ifdef CEXCEPTION_USE_CONFIG_FILE
+#include "CExceptionConfig.h"
+#endif
+
+//This is the value to assign when there isn't an exception
+#ifndef CEXCEPTION_NONE
+#define CEXCEPTION_NONE (0x5A5A5A5A)
+#endif
+
+//This is number of exception stacks to keep track of (one per task)
+#ifndef CEXCEPTION_NUM_ID
+#define CEXCEPTION_NUM_ID (1) //there is only the one stack by default
+#endif
+
+//This is the method of getting the current exception stack index (0 if only one stack)
+#ifndef CEXCEPTION_GET_ID
+#define CEXCEPTION_GET_ID (0) //use the first index always because there is only one anyway
+#endif
+
+//The type to use to store the exception values.
+#ifndef CEXCEPTION_T
+#define CEXCEPTION_T unsigned int
+#endif
+
+//This is an optional special handler for when there is no global Catch
+#ifndef CEXCEPTION_NO_CATCH_HANDLER
+#define CEXCEPTION_NO_CATCH_HANDLER(id)
+#endif
+
+//exception frame structures
+typedef struct {
+ jmp_buf* pFrame;
+ CEXCEPTION_T volatile Exception;
+} CEXCEPTION_FRAME_T;
+
+//actual root frame storage (only one if single-tasking)
+extern volatile CEXCEPTION_FRAME_T CExceptionFrames[];
+
+//Try (see C file for explanation)
+#define Try \
+ { \
+ jmp_buf *PrevFrame, NewFrame; \
+ unsigned int MY_ID = CEXCEPTION_GET_ID; \
+ PrevFrame = CExceptionFrames[CEXCEPTION_GET_ID].pFrame; \
+ CExceptionFrames[MY_ID].pFrame = (jmp_buf*)(&NewFrame); \
+ CExceptionFrames[MY_ID].Exception = CEXCEPTION_NONE; \
+ if (setjmp(NewFrame) == 0) { \
+ if (&PrevFrame)
+
+//Catch (see C file for explanation)
+#define Catch(e) \
+ else { } \
+ CExceptionFrames[MY_ID].Exception = CEXCEPTION_NONE; \
+ } \
+ else \
+ { e = CExceptionFrames[MY_ID].Exception; e=e; } \
+ CExceptionFrames[MY_ID].pFrame = PrevFrame; \
+ } \
+ if (CExceptionFrames[CEXCEPTION_GET_ID].Exception != CEXCEPTION_NONE)
+
+//Throw an Error
+void Throw(CEXCEPTION_T ExceptionID);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+
+#endif // _CEXCEPTION_H
diff --git a/tests/vendor/ceedling/vendor/c_exception/release/build.info b/tests/vendor/ceedling/vendor/c_exception/release/build.info
new file mode 100644
index 000000000..b5794c5ec
--- /dev/null
+++ b/tests/vendor/ceedling/vendor/c_exception/release/build.info
@@ -0,0 +1,2 @@
+16
+
diff --git a/tests/vendor/ceedling/vendor/c_exception/release/version.info b/tests/vendor/ceedling/vendor/c_exception/release/version.info
new file mode 100644
index 000000000..f99e724db
--- /dev/null
+++ b/tests/vendor/ceedling/vendor/c_exception/release/version.info
@@ -0,0 +1,2 @@
+1.2
+
diff --git a/tests/vendor/ceedling/vendor/cmock/config/production_environment.rb b/tests/vendor/ceedling/vendor/cmock/config/production_environment.rb
new file mode 100644
index 000000000..915582b79
--- /dev/null
+++ b/tests/vendor/ceedling/vendor/cmock/config/production_environment.rb
@@ -0,0 +1,14 @@
+# ==========================================
+# 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]
+# ==========================================
+
+# Setup our load path:
+[
+ 'lib',
+].each do |dir|
+ $LOAD_PATH.unshift( File.join( File.expand_path(File.dirname(__FILE__)) + '/../', dir) )
+end
+
+
diff --git a/tests/vendor/ceedling/vendor/cmock/config/test_environment.rb b/tests/vendor/ceedling/vendor/cmock/config/test_environment.rb
new file mode 100644
index 000000000..442e11057
--- /dev/null
+++ b/tests/vendor/ceedling/vendor/cmock/config/test_environment.rb
@@ -0,0 +1,16 @@
+# ==========================================
+# 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]
+# ==========================================
+
+# Setup our load path:
+[
+ 'lib',
+ 'vendor/behaviors/lib',
+ 'vendor/hardmock/lib',
+ 'vendor/unity/auto/',
+ 'test/system/'
+].each do |dir|
+ $LOAD_PATH.unshift( File.join( File.expand_path(File.dirname(__FILE__) + "/../"), dir) )
+end
diff --git a/tests/vendor/ceedling/vendor/cmock/lib/cmock.rb b/tests/vendor/ceedling/vendor/cmock/lib/cmock.rb
new file mode 100644
index 000000000..e332351c8
--- /dev/null
+++ b/tests/vendor/ceedling/vendor/cmock/lib/cmock.rb
@@ -0,0 +1,65 @@
+# ==========================================
+# 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]
+# ==========================================
+
+[ "../config/production_environment",
+ "cmock_header_parser",
+ "cmock_generator",
+ "cmock_file_writer",
+ "cmock_config",
+ "cmock_plugin_manager",
+ "cmock_generator_utils",
+ "cmock_unityhelper_parser"].each {|req| require "#{File.expand_path(File.dirname(__FILE__))}/#{req}"}
+
+class CMock
+
+ def initialize(options=nil)
+ cm_config = CMockConfig.new(options)
+ cm_unityhelper = CMockUnityHelperParser.new(cm_config)
+ cm_writer = CMockFileWriter.new(cm_config)
+ cm_gen_utils = CMockGeneratorUtils.new(cm_config, {:unity_helper => cm_unityhelper})
+ cm_gen_plugins = CMockPluginManager.new(cm_config, cm_gen_utils)
+ @cm_parser = CMockHeaderParser.new(cm_config)
+ @cm_generator = CMockGenerator.new(cm_config, cm_writer, cm_gen_utils, cm_gen_plugins)
+ @silent = (cm_config.verbosity < 2)
+ end
+
+ def setup_mocks(files)
+ [files].flatten.each do |src|
+ generate_mock src
+ end
+ end
+
+ private ###############################
+
+ def generate_mock(src)
+ name = File.basename(src, '.h')
+ puts "Creating mock for #{name}..." unless @silent
+ @cm_generator.create_mock(name, @cm_parser.parse(name, File.read(src)))
+ end
+end
+
+ # Command Line Support ###############################
+
+if ($0 == __FILE__)
+ usage = "usage: ruby #{__FILE__} (-oOptionsFile) File(s)ToMock"
+
+ if (!ARGV[0])
+ puts usage
+ exit 1
+ end
+
+ options = nil
+ filelist = []
+ ARGV.each do |arg|
+ if (arg =~ /^-o(\w*)/)
+ options = arg.gsub(/^-o/,'')
+ else
+ filelist << arg
+ end
+ end
+
+ CMock.new(options).setup_mocks(filelist)
+end
\ No newline at end of file
diff --git a/tests/vendor/ceedling/vendor/cmock/lib/cmock_config.rb b/tests/vendor/ceedling/vendor/cmock/lib/cmock_config.rb
new file mode 100644
index 000000000..ed9864b60
--- /dev/null
+++ b/tests/vendor/ceedling/vendor/cmock/lib/cmock_config.rb
@@ -0,0 +1,129 @@
+# ==========================================
+# 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 CMockConfig
+
+ CMockDefaultOptions =
+ {
+ :framework => :unity,
+ :mock_path => 'mocks',
+ :mock_prefix => 'Mock',
+ :plugins => [],
+ :strippables => ['(?:__attribute__\s*\(+.*?\)+)'],
+ :attributes => ['__ramfunc', '__irq', '__fiq', 'register', 'extern'],
+ :c_calling_conventions => ['__stdcall', '__cdecl', '__fastcall'],
+ :enforce_strict_ordering => false,
+ :unity_helper_path => false,
+ :treat_as => {},
+ :treat_as_void => [],
+ :memcmp_if_unknown => true,
+ :when_no_prototypes => :warn, #the options being :ignore, :warn, or :error
+ :when_ptr => :compare_data, #the options being :compare_ptr, :compare_data, or :smart
+ :verbosity => 2, #the options being 0 errors only, 1 warnings and errors, 2 normal info, 3 verbose
+ :treat_externs => :exclude, #the options being :include or :exclude
+ :ignore => :args_and_calls, #the options being :args_and_calls or :args_only
+ :callback_include_count => true,
+ :callback_after_arg_check => false,
+ :includes => nil,
+ :includes_h_pre_orig_header => nil,
+ :includes_h_post_orig_header => nil,
+ :includes_c_pre_header => nil,
+ :includes_c_post_header => nil
+ }
+
+ def initialize(options=nil)
+ case(options)
+ when NilClass then options = CMockDefaultOptions.clone
+ when String then options = CMockDefaultOptions.clone.merge(load_config_file_from_yaml(options))
+ when Hash then options = CMockDefaultOptions.clone.merge(options)
+ else raise "If you specify arguments, it should be a filename or a hash of options"
+ end
+
+ #do some quick type verification
+ [:plugins, :attributes, :treat_as_void].each do |opt|
+ unless (options[opt].class == Array)
+ options[opt] = []
+ puts "WARNING: :#{opt.to_s} should be an array." unless (options[:verbosity] < 1)
+ end
+ end
+ [:includes, :includes_h_pre_orig_header, :includes_h_post_orig_header, :includes_c_pre_header, :includes_c_post_header].each do |opt|
+ unless (options[opt].nil? or (options[opt].class == Array))
+ options[opt] = []
+ puts "WARNING: :#{opt.to_s} should be an array." unless (options[:verbosity] < 1)
+ end
+ end
+ options[:unity_helper_path] ||= options[:unity_helper]
+ options[:plugins].compact!
+ options[:plugins].map! {|p| p.to_sym}
+ @options = options
+
+ treat_as_map = standard_treat_as_map()#.clone
+ treat_as_map.merge!(@options[:treat_as])
+ @options[:treat_as] = treat_as_map
+
+ @options.each_key { |key| eval("def #{key.to_s}() return @options[:#{key.to_s}] end") }
+ end
+
+ def load_config_file_from_yaml yaml_filename
+ require 'yaml'
+ require 'fileutils'
+ YAML.load_file(yaml_filename)[:cmock]
+ end
+
+ def set_path(path)
+ @src_path = path
+ end
+
+ def load_unity_helper
+ return File.new(@options[:unity_helper_path]).read if (@options[:unity_helper_path])
+ return nil
+ end
+
+ def standard_treat_as_map
+ {
+ 'int' => 'INT',
+ 'char' => 'INT8',
+ 'short' => 'INT16',
+ 'long' => 'INT',
+ 'int8' => 'INT8',
+ 'int16' => 'INT16',
+ 'int32' => 'INT',
+ 'int8_t' => 'INT8',
+ 'int16_t' => 'INT16',
+ 'int32_t' => 'INT',
+ 'INT8_T' => 'INT8',
+ 'INT16_T' => 'INT16',
+ 'INT32_T' => 'INT',
+ 'bool' => 'INT',
+ 'bool_t' => 'INT',
+ 'BOOL' => 'INT',
+ 'BOOL_T' => 'INT',
+ 'unsigned int' => 'HEX32',
+ 'unsigned long' => 'HEX32',
+ 'uint32' => 'HEX32',
+ 'uint32_t' => 'HEX32',
+ 'UINT32' => 'HEX32',
+ 'UINT32_T' => 'HEX32',
+ 'void*' => 'PTR',
+ 'unsigned short' => 'HEX16',
+ 'uint16' => 'HEX16',
+ 'uint16_t' => 'HEX16',
+ 'UINT16' => 'HEX16',
+ 'UINT16_T' => 'HEX16',
+ 'unsigned char' => 'HEX8',
+ 'uint8' => 'HEX8',
+ 'uint8_t' => 'HEX8',
+ 'UINT8' => 'HEX8',
+ 'UINT8_T' => 'HEX8',
+ 'char*' => 'STRING',
+ 'pCHAR' => 'STRING',
+ 'cstring' => 'STRING',
+ 'CSTRING' => 'STRING',
+ 'float' => 'FLOAT',
+ 'double' => 'FLOAT'
+ }
+ end
+end
diff --git a/tests/vendor/ceedling/vendor/cmock/lib/cmock_file_writer.rb b/tests/vendor/ceedling/vendor/cmock/lib/cmock_file_writer.rb
new file mode 100644
index 000000000..63faee517
--- /dev/null
+++ b/tests/vendor/ceedling/vendor/cmock/lib/cmock_file_writer.rb
@@ -0,0 +1,33 @@
+# ==========================================
+# 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 CMockFileWriter
+
+ attr_reader :config
+
+ def initialize(config)
+ @config = config
+ end
+
+ def create_file(filename)
+ raise "Where's the block of data to create?" unless block_given?
+ full_file_name_temp = "#{@config.mock_path}/#{filename}.new"
+ full_file_name_done = "#{@config.mock_path}/#{filename}"
+ File.open(full_file_name_temp, 'w') do |file|
+ yield(file, filename)
+ end
+ update_file(full_file_name_done, full_file_name_temp)
+ end
+
+ private ###################################
+
+ def update_file(dest, src)
+ require 'fileutils'
+ FileUtils.rm(dest) if (File.exist?(dest))
+ FileUtils.cp(src, dest)
+ FileUtils.rm(src)
+ end
+end
diff --git a/tests/vendor/ceedling/vendor/cmock/lib/cmock_generator.rb b/tests/vendor/ceedling/vendor/cmock/lib/cmock_generator.rb
new file mode 100644
index 000000000..7cd0eeae8
--- /dev/null
+++ b/tests/vendor/ceedling/vendor/cmock/lib/cmock_generator.rb
@@ -0,0 +1,194 @@
+# ==========================================
+# 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]
+# ==========================================
+
+$here = File.dirname __FILE__
+
+class CMockGenerator
+
+ attr_accessor :config, :file_writer, :module_name, :mock_name, :utils, :plugins, :ordered
+
+ def initialize(config, file_writer, utils, plugins)
+ @file_writer = file_writer
+ @utils = utils
+ @plugins = plugins
+ @config = config
+ @prefix = @config.mock_prefix
+ @ordered = @config.enforce_strict_ordering
+ @framework = @config.framework.to_s
+
+ @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}\""}
+ end
+
+ def create_mock(module_name, parsed_stuff)
+ @module_name = module_name
+ @mock_name = @prefix + @module_name
+ create_mock_header_file(parsed_stuff)
+ create_mock_source_file(parsed_stuff)
+ end
+
+ private if $ThisIsOnlyATest.nil? ##############################
+
+ def create_mock_header_file(parsed_stuff)
+ @file_writer.create_file(@mock_name + ".h") 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") do |file, filename|
+ create_source_header_section(file, filename)
+ 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 = filename.gsub(/\.h/, "_h").upcase
+ orig_filename = filename.gsub(@config.mock_prefix, "")
+ file << "/* AUTOGENERATED FILE. DO NOT EDIT. */\n"
+ file << "#ifndef _#{define_name}\n"
+ file << "#define _#{define_name}\n\n"
+ @includes_h_pre_orig_header.each {|inc| file << "#include #{inc}\n"}
+ file << "#include \"#{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"
+ 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 #{@mock_name}_Init(void);\n"
+ file << "void #{@mock_name}_Destroy(void);\n"
+ file << "void #{@mock_name}_Verify(void);\n\n"
+ end
+
+ def create_mock_header_footer(header)
+ header << "\n#endif\n"
+ end
+
+ def create_source_header_section(file, filename)
+ header_file = filename.gsub(".c",".h")
+ file << "/* AUTOGENERATED FILE. DO NOT EDIT. */\n"
+ file << "#include \n"
+ file << "#include \n"
+ file << "#include \n"
+ file << "#include \"#{@framework}.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"
+ 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 #{@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 #{@mock_name}_Verify(void)\n{\n"
+ verifications = functions.collect {|function| @plugins.run(:mock_verify, function)}.join
+ file << " UNITY_LINE_TYPE cmock_line = TEST_LINE_NUM;\n" unless verifications.empty?
+ file << verifications
+ file << "}\n\n"
+ end
+
+ def create_mock_init_function(file)
+ file << "void #{@mock_name}_Init(void)\n{\n"
+ file << " #{@mock_name}_Destroy();\n"
+ file << "}\n\n"
+ end
+
+ def create_mock_destroy_function(file, functions)
+ file << "void #{@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
+ 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
+ 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 = (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, \"Function '#{function[:name]}' called more times than expected.\");\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, \"Function '#{function[:name]}' called earlier than expected.\");\n"
+ file << " if (cmock_call_instance->CallOrder < GlobalVerifyOrder)\n"
+ file << " UNITY_TEST_FAIL(cmock_line, \"Function '#{function[:name]}' called later than expected.\");\n"
+ # file << " UNITY_TEST_ASSERT((cmock_call_instance->CallOrder == ++GlobalVerifyOrder), cmock_line, \"Out of order function calls. Function '#{function[:name]}'\");\n"
+ end
+ file << @plugins.run(:mock_implementation, function)
+ 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
diff --git a/tests/vendor/ceedling/vendor/cmock/lib/cmock_generator_plugin_array.rb b/tests/vendor/ceedling/vendor/cmock/lib/cmock_generator_plugin_array.rb
new file mode 100644
index 000000000..25045a21b
--- /dev/null
+++ b/tests/vendor/ceedling/vendor/cmock/lib/cmock_generator_plugin_array.rb
@@ -0,0 +1,57 @@
+# ==========================================
+# 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 CMockGeneratorPluginArray
+
+ attr_reader :priority
+ attr_accessor :config, :utils, :unity_helper, :ordered
+ def initialize(config, utils)
+ @config = config
+ @ptr_handling = @config.when_ptr
+ @ordered = @config.enforce_strict_ordering
+ @utils = utils
+ @unity_helper = @utils.helpers[:unity_helper]
+ @priority = 8
+ end
+
+ def instance_typedefs(function)
+ function[:args].inject("") do |all, arg|
+ (arg[:ptr?]) ? all + " int Expected_#{arg[:name]}_Depth;\n" : all
+ end
+ end
+
+ def mock_function_declarations(function)
+ return nil unless function[:contains_ptr?]
+ args_call = function[:args].map{|m| m[:ptr?] ? "#{m[:name]}, #{m[:name]}_Depth" : "#{m[:name]}"}.join(', ')
+ args_string = function[:args].map{|m| m[:ptr?] ? "#{m[:type]} #{m[:name]}, int #{m[:name]}_Depth" : "#{m[:type]} #{m[:name]}"}.join(', ')
+ if (function[:return][:void?])
+ return "#define #{function[:name]}_ExpectWithArray(#{args_call}) #{function[:name]}_CMockExpectWithArray(__LINE__, #{args_call})\n" +
+ "void #{function[:name]}_CMockExpectWithArray(UNITY_LINE_TYPE cmock_line, #{args_string});\n"
+ else
+ return "#define #{function[:name]}_ExpectWithArrayAndReturn(#{args_call}, cmock_retval) #{function[:name]}_CMockExpectWithArrayAndReturn(__LINE__, #{args_call}, cmock_retval)\n" +
+ "void #{function[:name]}_CMockExpectWithArrayAndReturn(UNITY_LINE_TYPE cmock_line, #{args_string}, #{function[:return][:str]});\n"
+ end
+ end
+
+ def mock_interfaces(function)
+ return nil unless function[:contains_ptr?]
+ lines = []
+ func_name = function[:name]
+ args_string = function[:args].map{|m| m[:ptr?] ? "#{m[:type]} #{m[:name]}, int #{m[:name]}_Depth" : "#{m[:type]} #{m[:name]}"}.join(', ')
+ call_string = function[:args].map{|m| m[:ptr?] ? "#{m[:name]}, #{m[:name]}_Depth" : m[:name]}.join(', ')
+ if (function[:return][:void?])
+ lines << "void #{func_name}_CMockExpectWithArray(UNITY_LINE_TYPE cmock_line, #{args_string})\n"
+ else
+ lines << "void #{func_name}_CMockExpectWithArrayAndReturn(UNITY_LINE_TYPE cmock_line, #{args_string}, #{function[:return][:str]})\n"
+ end
+ lines << "{\n"
+ lines << @utils.code_add_base_expectation(func_name)
+ lines << " CMockExpectParameters_#{func_name}(cmock_call_instance, #{call_string});\n"
+ lines << " cmock_call_instance->ReturnVal = cmock_to_return;\n" unless (function[:return][:void?])
+ lines << "}\n\n"
+ end
+
+end
diff --git a/tests/vendor/ceedling/vendor/cmock/lib/cmock_generator_plugin_callback.rb b/tests/vendor/ceedling/vendor/cmock/lib/cmock_generator_plugin_callback.rb
new file mode 100644
index 000000000..f66539cd9
--- /dev/null
+++ b/tests/vendor/ceedling/vendor/cmock/lib/cmock_generator_plugin_callback.rb
@@ -0,0 +1,78 @@
+# ==========================================
+# 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 CMockGeneratorPluginCallback
+
+ attr_accessor :include_count
+ attr_reader :priority
+ attr_reader :config, :utils
+
+ def initialize(config, utils)
+ @config = config
+ @utils = utils
+ @priority = 6
+
+ @include_count = @config.callback_include_count
+ if (@config.callback_after_arg_check)
+ alias :mock_implementation :mock_implementation_for_callbacks
+ alias :mock_implementation_precheck :nothing
+ else
+ alias :mock_implementation_precheck :mock_implementation_for_callbacks
+ alias :mock_implementation :nothing
+ end
+ end
+
+ def instance_structure(function)
+ func_name = function[:name]
+ " 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][:const?] ? "const #{function[:return][:type]}" : function[:return][:type]
+ 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]});\nvoid #{func_name}_StubWithCallback(CMOCK_#{func_name}_CALLBACK Callback);\n"
+ end
+
+ def mock_implementation_for_callbacks(function)
+ func_name = function[:name]
+ style = (@include_count ? 1 : 0) | (function[:args].empty? ? 0 : 2) | (function[:return][:void?] ? 0 : 4)
+ " if (Mock.#{func_name}_CallbackFunctionPointer != NULL)\n {\n" +
+ case(style)
+ when 0 then " Mock.#{func_name}_CallbackFunctionPointer();\n return;\n }\n"
+ when 1 then " Mock.#{func_name}_CallbackFunctionPointer(Mock.#{func_name}_CallbackCalls++);\n return;\n }\n"
+ when 2 then " Mock.#{func_name}_CallbackFunctionPointer(#{function[:args].map{|m| m[:name]}.join(', ')});\n return;\n }\n"
+ when 3 then " Mock.#{func_name}_CallbackFunctionPointer(#{function[:args].map{|m| m[:name]}.join(', ')}, Mock.#{func_name}_CallbackCalls++);\n return;\n }\n"
+ when 4 then " return Mock.#{func_name}_CallbackFunctionPointer();\n }\n"
+ when 5 then " return Mock.#{func_name}_CallbackFunctionPointer(Mock.#{func_name}_CallbackCalls++);\n }\n"
+ when 6 then " return Mock.#{func_name}_CallbackFunctionPointer(#{function[:args].map{|m| m[:name]}.join(', ')});\n }\n"
+ when 7 then " return Mock.#{func_name}_CallbackFunctionPointer(#{function[:args].map{|m| m[:name]}.join(', ')}, Mock.#{func_name}_CallbackCalls++);\n }\n"
+ end
+ end
+
+ def nothing(function)
+ return ""
+ end
+
+ def mock_interfaces(function)
+ func_name = function[:name]
+ "void #{func_name}_StubWithCallback(CMOCK_#{func_name}_CALLBACK Callback)\n{\n" +
+ " Mock.#{func_name}_CallbackFunctionPointer = Callback;\n}\n\n"
+ end
+
+ def mock_destroy(function)
+ " Mock.#{function[:name]}_CallbackFunctionPointer = NULL;\n" +
+ " Mock.#{function[:name]}_CallbackCalls = 0;\n"
+ end
+
+ def mock_verify(function)
+ func_name = function[:name]
+ " if (Mock.#{func_name}_CallbackFunctionPointer != NULL)\n Mock.#{func_name}_CallInstance = CMOCK_GUTS_NONE;\n"
+ end
+
+end
diff --git a/tests/vendor/ceedling/vendor/cmock/lib/cmock_generator_plugin_cexception.rb b/tests/vendor/ceedling/vendor/cmock/lib/cmock_generator_plugin_cexception.rb
new file mode 100644
index 000000000..fdf31db11
--- /dev/null
+++ b/tests/vendor/ceedling/vendor/cmock/lib/cmock_generator_plugin_cexception.rb
@@ -0,0 +1,51 @@
+# ==========================================
+# 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 CMockGeneratorPluginCexception
+
+ attr_reader :priority
+ attr_reader :config, :utils
+
+ def initialize(config, utils)
+ @config = config
+ @utils = utils
+ @priority = 7
+ end
+
+ def include_files
+ return "#include \"CException.h\"\n"
+ end
+
+ def instance_typedefs(function)
+ " CEXCEPTION_T ExceptionToThrow;\n"
+ end
+
+ def mock_function_declarations(function)
+ if (function[:args_string] == "void")
+ return "#define #{function[:name]}_ExpectAndThrow(cmock_to_throw) #{function[:name]}_CMockExpectAndThrow(__LINE__, cmock_to_throw)\n" +
+ "void #{function[:name]}_CMockExpectAndThrow(UNITY_LINE_TYPE cmock_line, CEXCEPTION_T cmock_to_throw);\n"
+ else
+ return "#define #{function[:name]}_ExpectAndThrow(#{function[:args_call]}, cmock_to_throw) #{function[:name]}_CMockExpectAndThrow(__LINE__, #{function[:args_call]}, cmock_to_throw)\n" +
+ "void #{function[:name]}_CMockExpectAndThrow(UNITY_LINE_TYPE cmock_line, #{function[:args_string]}, CEXCEPTION_T cmock_to_throw);\n"
+ end
+ end
+
+ def mock_implementation(function)
+ " if (cmock_call_instance->ExceptionToThrow != CEXCEPTION_NONE)\n {\n" +
+ " Throw(cmock_call_instance->ExceptionToThrow);\n }\n"
+ end
+
+ def mock_interfaces(function)
+ arg_insert = (function[:args_string] == "void") ? "" : "#{function[:args_string]}, "
+ call_string = function[:args].map{|m| m[:name]}.join(', ')
+ [ "void #{function[:name]}_CMockExpectAndThrow(UNITY_LINE_TYPE cmock_line, #{arg_insert}CEXCEPTION_T cmock_to_throw)\n{\n",
+ @utils.code_add_base_expectation(function[:name]),
+ @utils.code_call_argument_loader(function),
+ " cmock_call_instance->ExceptionToThrow = cmock_to_throw;\n",
+ "}\n\n" ].join
+ end
+
+end
diff --git a/tests/vendor/ceedling/vendor/cmock/lib/cmock_generator_plugin_expect.rb b/tests/vendor/ceedling/vendor/cmock/lib/cmock_generator_plugin_expect.rb
new file mode 100644
index 000000000..5651cd942
--- /dev/null
+++ b/tests/vendor/ceedling/vendor/cmock/lib/cmock_generator_plugin_expect.rb
@@ -0,0 +1,86 @@
+# ==========================================
+# 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 CMockGeneratorPluginExpect
+
+ attr_reader :priority
+ attr_accessor :config, :utils, :unity_helper, :ordered
+
+ def initialize(config, utils)
+ @config = config
+ @ptr_handling = @config.when_ptr
+ @ordered = @config.enforce_strict_ordering
+ @utils = utils
+ @unity_helper = @utils.helpers[:unity_helper]
+ @priority = 5
+ end
+
+ def instance_typedefs(function)
+ lines = ""
+ lines << " #{function[:return][:type]} ReturnVal;\n" unless (function[:return][:void?])
+ lines << " int CallOrder;\n" if (@ordered)
+ function[:args].each do |arg|
+ lines << " #{arg[:type]} Expected_#{arg[:name]};\n"
+ end
+ lines
+ end
+
+ def mock_function_declarations(function)
+ if (function[:args].empty?)
+ if (function[:return][:void?])
+ return "#define #{function[:name]}_Expect() #{function[:name]}_CMockExpect(__LINE__)\n" +
+ "void #{function[:name]}_CMockExpect(UNITY_LINE_TYPE cmock_line);\n"
+ else
+ return "#define #{function[:name]}_ExpectAndReturn(cmock_retval) #{function[:name]}_CMockExpectAndReturn(__LINE__, cmock_retval)\n" +
+ "void #{function[:name]}_CMockExpectAndReturn(UNITY_LINE_TYPE cmock_line, #{function[:return][:str]});\n"
+ end
+ else
+ if (function[:return][:void?])
+ return "#define #{function[:name]}_Expect(#{function[:args_call]}) #{function[:name]}_CMockExpect(__LINE__, #{function[:args_call]})\n" +
+ "void #{function[:name]}_CMockExpect(UNITY_LINE_TYPE cmock_line, #{function[:args_string]});\n"
+ else
+ return "#define #{function[:name]}_ExpectAndReturn(#{function[:args_call]}, cmock_retval) #{function[:name]}_CMockExpectAndReturn(__LINE__, #{function[:args_call]}, cmock_retval)\n" +
+ "void #{function[:name]}_CMockExpectAndReturn(UNITY_LINE_TYPE cmock_line, #{function[:args_string]}, #{function[:return][:str]});\n"
+ end
+ end
+ end
+
+ def mock_implementation(function)
+ lines = ""
+ function[:args].each do |arg|
+ lines << @utils.code_verify_an_arg_expectation(function, arg)
+ end
+ lines
+ end
+
+ def mock_interfaces(function)
+ lines = ""
+ func_name = function[:name]
+ if (function[:return][:void?])
+ if (function[:args_string] == "void")
+ lines << "void #{func_name}_CMockExpect(UNITY_LINE_TYPE cmock_line)\n{\n"
+ else
+ lines << "void #{func_name}_CMockExpect(UNITY_LINE_TYPE cmock_line, #{function[:args_string]})\n{\n"
+ end
+ else
+ if (function[:args_string] == "void")
+ lines << "void #{func_name}_CMockExpectAndReturn(UNITY_LINE_TYPE cmock_line, #{function[:return][:str]})\n{\n"
+ else
+ lines << "void #{func_name}_CMockExpectAndReturn(UNITY_LINE_TYPE cmock_line, #{function[:args_string]}, #{function[:return][:str]})\n{\n"
+ end
+ end
+ lines << @utils.code_add_base_expectation(func_name)
+ lines << @utils.code_call_argument_loader(function)
+ lines << @utils.code_assign_argument_quickly("cmock_call_instance->ReturnVal", function[:return]) unless (function[:return][:void?])
+ lines << "}\n\n"
+ end
+
+ def mock_verify(function)
+ func_name = function[:name]
+ " UNITY_TEST_ASSERT(CMOCK_GUTS_NONE == Mock.#{func_name}_CallInstance, cmock_line, \"Function '#{func_name}' called less times than expected.\");\n"
+ end
+
+end
diff --git a/tests/vendor/ceedling/vendor/cmock/lib/cmock_generator_plugin_ignore.rb b/tests/vendor/ceedling/vendor/cmock/lib/cmock_generator_plugin_ignore.rb
new file mode 100644
index 000000000..e81de3c67
--- /dev/null
+++ b/tests/vendor/ceedling/vendor/cmock/lib/cmock_generator_plugin_ignore.rb
@@ -0,0 +1,95 @@
+# ==========================================
+# 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 CMockGeneratorPluginIgnore
+
+ attr_reader :priority
+ attr_reader :config, :utils
+
+ def initialize(config, utils)
+ @config = config
+ if (@config.ignore == :args_and_calls)
+ alias :mock_implementation_precheck :mock_implementation_for_ignores
+ alias :mock_implementation :nothing
+ alias :mock_verify :mock_conditionally_verify_counts
+ else
+ alias :mock_implementation :mock_implementation_for_ignores
+ alias :mock_implementation_precheck :nothing
+ alias :mock_verify :nothing
+ end
+ @utils = utils
+ @priority = 2
+ end
+
+ def instance_structure(function)
+ if (function[:return][:void?])
+ " int #{function[:name]}_IgnoreBool;\n"
+ else
+ " int #{function[:name]}_IgnoreBool;\n #{function[:return][:type]} #{function[:name]}_FinalReturn;\n"
+ end
+ end
+
+ def mock_function_declarations(function)
+ if (function[:return][:void?])
+ if (@config.ignore == :args_only)
+ return "#define #{function[:name]}_Ignore() #{function[:name]}_CMockIgnore(__LINE__)\n" +
+ "void #{function[:name]}_CMockIgnore(UNITY_LINE_TYPE cmock_line);\n"
+ else
+ return "#define #{function[:name]}_Ignore() #{function[:name]}_CMockIgnore()\n" +
+ "void #{function[:name]}_CMockIgnore(void);\n"
+ end
+ else
+ return "#define #{function[:name]}_IgnoreAndReturn(cmock_retval) #{function[:name]}_CMockIgnoreAndReturn(__LINE__, cmock_retval)\n" +
+ "void #{function[:name]}_CMockIgnoreAndReturn(UNITY_LINE_TYPE cmock_line, #{function[:return][:str]});\n"
+ end
+ end
+
+ def mock_implementation_for_ignores(function)
+ lines = " if (Mock.#{function[:name]}_IgnoreBool)\n {\n"
+ if (function[:return][:void?])
+ lines << " return;\n }\n"
+ else
+ retval = function[:return].merge( { :name => "cmock_call_instance->ReturnVal"} )
+ lines << " if (cmock_call_instance == NULL)\n return Mock.#{function[:name]}_FinalReturn;\n"
+ lines << " " + @utils.code_assign_argument_quickly("Mock.#{function[:name]}_FinalReturn", retval) unless (retval[:void?])
+ lines << " return cmock_call_instance->ReturnVal;\n }\n"
+ end
+ lines
+ end
+
+ def mock_interfaces(function)
+ lines = ""
+ args_only = (@config.ignore == :args_only)
+ if (function[:return][:void?])
+ if (args_only)
+ lines << "void #{function[:name]}_CMockIgnore(UNITY_LINE_TYPE cmock_line)\n{\n"
+ else
+ lines << "void #{function[:name]}_CMockIgnore(void)\n{\n"
+ end
+ else
+ lines << "void #{function[:name]}_CMockIgnoreAndReturn(UNITY_LINE_TYPE cmock_line, #{function[:return][:str]})\n{\n"
+ end
+ if (args_only)
+ lines << @utils.code_add_base_expectation(function[:name], true)
+ elsif (!function[:return][:void?])
+ lines << @utils.code_add_base_expectation(function[:name], false)
+ end
+ unless (function[:return][:void?])
+ lines << " cmock_call_instance->ReturnVal = cmock_to_return;\n"
+ end
+ lines << " Mock.#{function[:name]}_IgnoreBool = (int)1;\n"
+ lines << "}\n\n"
+ end
+
+ def mock_conditionally_verify_counts(function)
+ func_name = function[:name]
+ " if (Mock.#{func_name}_IgnoreBool)\n Mock.#{func_name}_CallInstance = CMOCK_GUTS_NONE;\n"
+ end
+
+ def nothing(function)
+ return ""
+ end
+end
diff --git a/tests/vendor/ceedling/vendor/cmock/lib/cmock_generator_utils.rb b/tests/vendor/ceedling/vendor/cmock/lib/cmock_generator_utils.rb
new file mode 100644
index 000000000..444497932
--- /dev/null
+++ b/tests/vendor/ceedling/vendor/cmock/lib/cmock_generator_utils.rb
@@ -0,0 +1,177 @@
+# ==========================================
+# 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 CMockGeneratorUtils
+
+ attr_accessor :config, :helpers, :ordered, :ptr_handling, :arrays, :cexception
+
+ def initialize(config, helpers={})
+ @config = config
+ @ptr_handling = @config.when_ptr
+ @ordered = @config.enforce_strict_ordering
+ @arrays = @config.plugins.include? :array
+ @cexception = @config.plugins.include? :cexception
+ @treat_as = @config.treat_as
+ @helpers = helpers
+
+ if (@arrays)
+ case(@ptr_handling)
+ when :smart then alias :code_verify_an_arg_expectation :code_verify_an_arg_expectation_with_smart_arrays
+ when :compare_data then alias :code_verify_an_arg_expectation :code_verify_an_arg_expectation_with_normal_arrays
+ when :compare_ptr then raise "ERROR: the array plugin doesn't enjoy working with :compare_ptr only. Disable one option."
+ end
+ else
+ alias :code_verify_an_arg_expectation :code_verify_an_arg_expectation_with_no_arrays
+ end
+ end
+
+ def code_add_base_expectation(func_name, global_ordering_supported=true)
+ lines = " CMOCK_MEM_INDEX_TYPE cmock_guts_index = CMock_Guts_MemNew(sizeof(CMOCK_#{func_name}_CALL_INSTANCE));\n"
+ lines << " CMOCK_#{func_name}_CALL_INSTANCE* cmock_call_instance = (CMOCK_#{func_name}_CALL_INSTANCE*)CMock_Guts_GetAddressFor(cmock_guts_index);\n"
+ lines << " UNITY_TEST_ASSERT_NOT_NULL(cmock_call_instance, cmock_line, \"CMock has run out of memory. Please allocate more.\");\n"
+ lines << " Mock.#{func_name}_CallInstance = CMock_Guts_MemChain(Mock.#{func_name}_CallInstance, cmock_guts_index);\n"
+ lines << " cmock_call_instance->LineNumber = cmock_line;\n"
+ lines << " cmock_call_instance->CallOrder = ++GlobalExpectCount;\n" if (@ordered and global_ordering_supported)
+ lines << " cmock_call_instance->ExceptionToThrow = CEXCEPTION_NONE;\n" if (@cexception)
+ lines
+ end
+
+ def code_add_an_arg_expectation(arg, depth=1)
+ lines = code_assign_argument_quickly("cmock_call_instance->Expected_#{arg[:name]}", arg)
+ lines << " cmock_call_instance->Expected_#{arg[:name]}_Depth = #{arg[:name]}_Depth;\n" if (@arrays and (depth.class == String))
+ lines
+ end
+
+ def code_assign_argument_quickly(dest, arg)
+ if (arg[:ptr?] or @treat_as.include?(arg[:type]))
+ " #{dest} = #{arg[:const?] ? "(#{arg[:type]})" : ''}#{arg[:name]};\n"
+ else
+ " memcpy({dest}, {arg[:name]}, sizeof(#{arg[:type]}));\n"
+ end
+ end
+
+ def code_add_argument_loader(function)
+ if (function[:args_string] != "void")
+ if (@arrays)
+ args_string = function[:args].map do |m|
+ const_str = m[ :const? ] ? 'const ' : ''
+ m[:ptr?] ? "#{const_str}#{m[:type]} #{m[:name]}, int #{m[:name]}_Depth" : "#{const_str}#{m[:type]} #{m[:name]}"
+ end.join(', ')
+ "void CMockExpectParameters_#{function[:name]}(CMOCK_#{function[:name]}_CALL_INSTANCE* cmock_call_instance, #{args_string})\n{\n" +
+ function[:args].inject("") { |all, arg| all + code_add_an_arg_expectation(arg, (arg[:ptr?] ? "#{arg[:name]}_Depth" : 1) ) } +
+ "}\n\n"
+ else
+ "void CMockExpectParameters_#{function[:name]}(CMOCK_#{function[:name]}_CALL_INSTANCE* cmock_call_instance, #{function[:args_string]})\n{\n" +
+ function[:args].inject("") { |all, arg| all + code_add_an_arg_expectation(arg) } +
+ "}\n\n"
+ end
+ else
+ ""
+ end
+ end
+
+ def code_call_argument_loader(function)
+ if (function[:args_string] != "void")
+ args = function[:args].map do |m|
+ (@arrays and m[:ptr?]) ? "#{m[:name]}, 1" : m[:name]
+ end
+ " CMockExpectParameters_#{function[:name]}(cmock_call_instance, #{args.join(', ')});\n"
+ else
+ ""
+ end
+ end
+
+ #private ######################
+
+ def lookup_expect_type(function, arg)
+ c_type = arg[:type]
+ arg_name = arg[:name]
+ expected = "cmock_call_instance->Expected_#{arg_name}"
+ unity_func = if ((arg[:ptr?]) and ((c_type =~ /\*\*/) or (@ptr_handling == :compare_ptr)))
+ ['UNITY_TEST_ASSERT_EQUAL_PTR', '']
+ else
+ (@helpers.nil? or @helpers[:unity_helper].nil?) ? ["UNITY_TEST_ASSERT_EQUAL",''] : @helpers[:unity_helper].get_helper(c_type)
+ end
+ unity_msg = "Function '#{function[:name]}' called with unexpected value for argument '#{arg_name}'."
+ return c_type, arg_name, expected, unity_func[0], unity_func[1], unity_msg
+ end
+
+ def code_verify_an_arg_expectation_with_no_arrays(function, arg)
+ c_type, arg_name, expected, unity_func, pre, unity_msg = lookup_expect_type(function, arg)
+ case(unity_func)
+ when "UNITY_TEST_ASSERT_EQUAL_MEMORY"
+ c_type_local = c_type.gsub(/\*$/,'')
+ return " UNITY_TEST_ASSERT_EQUAL_MEMORY((void*)(#{pre}#{expected}), (void*)(#{pre}#{arg_name}), sizeof(#{c_type_local}), cmock_line, \"#{unity_msg}\");\n"
+ when "UNITY_TEST_ASSERT_EQUAL_MEMORY"
+ [ " if (#{pre}#{expected} == NULL)",
+ " { UNITY_TEST_ASSERT_NULL(#{pre}#{arg_name}, cmock_line, \"Expected NULL. #{unity_msg}\"); }",
+ " else",
+ " { UNITY_TEST_ASSERT_EQUAL_MEMORY((void*)(#{pre}#{expected}), (void*)(#{pre}#{arg_name}), sizeof(#{c_type.sub('*','')}), cmock_line, \"#{unity_msg}\"); }\n"].join("\n")
+ when /_ARRAY/
+ [ " if (#{pre}#{expected} == NULL)",
+ " { UNITY_TEST_ASSERT_NULL(#{pre}#{arg_name}, cmock_line, \"Expected NULL. #{unity_msg}\"); }",
+ " else",
+ " { #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, 1, cmock_line, \"#{unity_msg}\"); }\n"].join("\n")
+ else
+ return " #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, cmock_line, \"#{unity_msg}\");\n"
+ end
+ end
+
+ def code_verify_an_arg_expectation_with_normal_arrays(function, arg)
+ c_type, arg_name, expected, unity_func, pre, unity_msg = lookup_expect_type(function, arg)
+ depth_name = (arg[:ptr?]) ? "cmock_call_instance->Expected_#{arg_name}_Depth" : 1
+ case(unity_func)
+ when "UNITY_TEST_ASSERT_EQUAL_MEMORY"
+ c_type_local = c_type.gsub(/\*$/,'')
+ return " UNITY_TEST_ASSERT_EQUAL_MEMORY((void*)(#{pre}#{expected}), (void*)(#{pre}#{arg_name}), sizeof(#{c_type_local}), cmock_line, \"#{unity_msg}\");\n"
+ when "UNITY_TEST_ASSERT_EQUAL_MEMORY_ARRAY"
+ [ " if (#{pre}#{expected} == NULL)",
+ " { UNITY_TEST_ASSERT_NULL(#{pre}#{arg_name}, cmock_line, \"Expected NULL. #{unity_msg}\"); }",
+ " else",
+ " { UNITY_TEST_ASSERT_EQUAL_MEMORY_ARRAY((void*)(#{pre}#{expected}), (void*)(#{pre}#{arg_name}), sizeof(#{c_type.sub('*','')}), #{depth_name}, cmock_line, \"#{unity_msg}\"); }\n"].compact.join("\n")
+ when /_ARRAY/
+ if (pre == '&')
+ " #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, #{depth_name}, cmock_line, \"#{unity_msg}\");\n"
+ else
+ [ " if (#{pre}#{expected} == NULL)",
+ " { UNITY_TEST_ASSERT_NULL(#{pre}#{arg_name}, cmock_line, \"Expected NULL. #{unity_msg}\"); }",
+ " else",
+ " { #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, #{depth_name}, cmock_line, \"#{unity_msg}\"); }\n"].compact.join("\n")
+ end
+ else
+ return " #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, cmock_line, \"#{unity_msg}\");\n"
+ end
+ end
+
+ def code_verify_an_arg_expectation_with_smart_arrays(function, arg)
+ c_type, arg_name, expected, unity_func, pre, unity_msg = lookup_expect_type(function, arg)
+ depth_name = (arg[:ptr?]) ? "cmock_call_instance->Expected_#{arg_name}_Depth" : 1
+ case(unity_func)
+ when "UNITY_TEST_ASSERT_EQUAL_MEMORY"
+ c_type_local = c_type.gsub(/\*$/,'')
+ return " UNITY_TEST_ASSERT_EQUAL_MEMORY((void*)(#{pre}#{expected}), (void*)(#{pre}#{arg_name}), sizeof(#{c_type_local}), cmock_line, \"#{unity_msg}\");\n"
+ when "UNITY_TEST_ASSERT_EQUAL_MEMORY_ARRAY"
+ [ " if (#{pre}#{expected} == NULL)",
+ " { UNITY_TEST_ASSERT_NULL(#{arg_name}, cmock_line, \"Expected NULL. #{unity_msg}\"); }",
+ ((depth_name != 1) ? " else if (#{depth_name} == 0)\n { UNITY_TEST_ASSERT_EQUAL_PTR(#{pre}#{expected}, #{pre}#{arg_name}, cmock_line, \"#{unity_msg}\"); }" : nil),
+ " else",
+ " { UNITY_TEST_ASSERT_EQUAL_MEMORY_ARRAY((void*)(#{pre}#{expected}), (void*)(#{pre}#{arg_name}), sizeof(#{c_type.sub('*','')}), #{depth_name}, cmock_line, \"#{unity_msg}\"); }\n"].compact.join("\n")
+ when /_ARRAY/
+ if (pre == '&')
+ " #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, #{depth_name}, cmock_line, \"#{unity_msg}\");\n"
+ else
+ [ " if (#{pre}#{expected} == NULL)",
+ " { UNITY_TEST_ASSERT_NULL(#{pre}#{arg_name}, cmock_line, \"Expected NULL. #{unity_msg}\"); }",
+ ((depth_name != 1) ? " else if (#{depth_name} == 0)\n { UNITY_TEST_ASSERT_EQUAL_PTR(#{pre}#{expected}, #{pre}#{arg_name}, cmock_line, \"#{unity_msg}\"); }" : nil),
+ " else",
+ " { #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, #{depth_name}, cmock_line, \"#{unity_msg}\"); }\n"].compact.join("\n")
+ end
+ else
+ return " #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, cmock_line, \"#{unity_msg}\");\n"
+ end
+ end
+
+end
\ No newline at end of file
diff --git a/tests/vendor/ceedling/vendor/cmock/lib/cmock_header_parser.rb b/tests/vendor/ceedling/vendor/cmock/lib/cmock_header_parser.rb
new file mode 100644
index 000000000..864e4c7d5
--- /dev/null
+++ b/tests/vendor/ceedling/vendor/cmock/lib/cmock_header_parser.rb
@@ -0,0 +1,277 @@
+# ==========================================
+# 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 CMockHeaderParser
+
+ attr_accessor :funcs, :c_attributes, :treat_as_void, :treat_externs
+
+ def initialize(cfg)
+ @funcs = []
+ @c_strippables = cfg.strippables
+ @c_attributes = (['const'] + cfg.attributes).uniq
+ @c_calling_conventions = cfg.c_calling_conventions.uniq
+ @treat_as_void = (['void'] + cfg.treat_as_void).uniq
+ @declaration_parse_matcher = /([\d\w\s\*\(\),\[\]]+??)\(([\d\w\s\*\(\),\.\[\]+-]*)\)$/m
+ @standards = (['int','short','char','long','unsigned','signed'] + cfg.treat_as.keys).uniq
+ @when_no_prototypes = cfg.when_no_prototypes
+ @local_as_void = @treat_as_void
+ @verbosity = cfg.verbosity
+ @treat_externs = cfg.treat_externs
+ @c_strippables += ['extern'] if (@treat_externs == :include) #we'll need to remove the attribute if we're allowing externs
+ end
+
+ def parse(name, source)
+ @module_name = name.gsub(/\W/,'')
+ @typedefs = []
+ @funcs = []
+ function_names = []
+
+ parse_functions( import_source(source) ).map do |decl|
+ func = parse_declaration(decl)
+ unless (function_names.include? func[:name])
+ @funcs << func
+ function_names << func[:name]
+ end
+ end
+
+ { :includes => nil,
+ :functions => @funcs,
+ :typedefs => @typedefs
+ }
+ end
+
+ private if $ThisIsOnlyATest.nil? ################
+
+ def import_source(source)
+
+ # void must be void for cmock _ExpectAndReturn calls to process properly, not some weird typedef which equates to void
+ # to a certain extent, this action assumes we're chewing on pre-processed header files, otherwise we'll most likely just get stuff from @treat_as_void
+ @local_as_void = @treat_as_void
+ void_types = source.scan(/typedef\s+(?:\(\s*)?void(?:\s*\))?\s+([\w\d]+)\s*;/)
+ if void_types
+ @local_as_void += void_types.flatten.uniq.compact
+ end
+
+ # smush multiline macros into single line (checking for continuation character at end of line '\')
+ source.gsub!(/\s*\\\s*/m, ' ')
+
+ #remove comments (block and line, in three steps to ensure correct precedence)
+ source.gsub!(/\/\/(?:.+\/\*|\*(?:$|[^\/])).*$/, '') # remove line comments that comment out the start of blocks
+ source.gsub!(/\/\*.*?\*\//m, '') # remove block comments
+ source.gsub!(/\/\/.*$/, '') # remove line comments (all that remain)
+
+ # remove assembler pragma sections
+ source.gsub!(/^\s*#\s*pragma\s+asm\s+.*?#\s*pragma\s+endasm/m, '')
+
+ # remove gcc's __attribute__ tags
+ source.gsub(/__attrbute__\s*\(\(\.*\)\)/, '')
+
+ # remove preprocessor statements and extern "C"
+ source.gsub!(/^\s*#.*/, '')
+ source.gsub!(/extern\s+\"C\"\s+\{/, '')
+
+ # enums, unions, structs, and typedefs can all contain things (e.g. function pointers) that parse like function prototypes, so yank them
+ # forward declared structs are removed before struct definitions so they don't mess up real thing later. we leave structs keywords in function prototypes
+ source.gsub!(/^[\w\s]*struct[^;\{\}\(\)]+;/m, '') # remove forward declared structs
+ source.gsub!(/^[\w\s]*(enum|union|struct|typepdef)[\w\s]*\{[^\}]+\}[\w\s\*\,]*;/m, '') # remove struct, union, and enum definitions and typedefs with braces
+ source.gsub!(/(\W)(?:register|auto|static|restrict)(\W)/, '\1\2') # remove problem keywords
+ source.gsub!(/\s*=\s*['"a-zA-Z0-9_\.]+\s*/, '') # remove default value statements from argument lists
+ source.gsub!(/^(?:[\w\s]*\W)?typedef\W.*/, '') # remove typedef statements
+ source.gsub!(/(^|\W+)(?:#{@c_strippables.join('|')})(?=$|\W+)/,'\1') unless @c_strippables.empty? # remove known attributes slated to be stripped
+
+ #scan for functions which return function pointers, because they are a pain
+ source.gsub!(/([\w\s\*]+)\(*\(\s*\*([\w\s\*]+)\s*\(([\w\s\*,]*)\)\)\s*\(([\w\s\*,]*)\)\)*/) do |m|
+ functype = "cmock_#{@module_name}_func_ptr#{@typedefs.size + 1}"
+ @typedefs << "typedef #{$1.strip}(*#{functype})(#{$4});"
+ "#{functype} #{$2.strip}(#{$3});"
+ end
+
+ #drop extra white space to make the rest go faster
+ source.gsub!(/^\s+/, '') # remove extra white space from beginning of line
+ source.gsub!(/\s+$/, '') # remove extra white space from end of line
+ source.gsub!(/\s*\(\s*/, '(') # remove extra white space from before left parens
+ source.gsub!(/\s*\)\s*/, ')') # remove extra white space from before right parens
+ source.gsub!(/\s+/, ' ') # remove remaining extra white space
+
+ #split lines on semicolons and remove things that are obviously not what we are looking for
+ src_lines = source.split(/\s*;\s*/)
+ src_lines.delete_if {|line| line.strip.length == 0} # remove blank lines
+ src_lines.delete_if {|line| !(line =~ /[\w\s\*]+\(+\s*\*[\*\s]*[\w\s]+(?:\[[\w\s]*\]\s*)+\)+\s*\((?:[\w\s\*]*,?)*\s*\)/).nil?} #remove function pointer arrays
+ if (@treat_externs == :include)
+ src_lines.delete_if {|line| !(line =~ /(?:^|\s+)(?:inline)\s+/).nil?} # remove inline functions
+ else
+ src_lines.delete_if {|line| !(line =~ /(?:^|\s+)(?:extern|inline)\s+/).nil?} # remove inline and extern functions
+ end
+ end
+
+ def parse_functions(source)
+ funcs = []
+ source.each {|line| funcs << line.strip.gsub(/\s+/, ' ') if (line =~ @declaration_parse_matcher)}
+ if funcs.empty?
+ case @when_no_prototypes
+ when :error
+ raise "ERROR: No function prototypes found!"
+ when :warn
+ puts "WARNING: No function prototypes found!" unless (@verbosity < 1)
+ end
+ end
+ return funcs
+ end
+
+ def parse_args(arg_list)
+ args = []
+ arg_list.split(',').each do |arg|
+ arg.strip!
+ return args if (arg =~ /^\s*((\.\.\.)|(void))\s*$/) # we're done if we reach void by itself or ...
+ arg_array = arg.split
+ arg_elements = arg_array - @c_attributes # split up words and remove known attributes
+ args << { :type => (arg_type =arg_elements[0..-2].join(' ')),
+ :name => arg_elements[-1],
+ :ptr? => divine_ptr(arg_type),
+ :const? => arg_array.include?('const')
+ }
+ end
+ return args
+ end
+
+ def divine_ptr(arg_type)
+ return false unless arg_type.include? '*'
+ return false if arg_type.gsub(/(const|char|\*|\s)+/,'').empty?
+ return true
+ end
+
+ def clean_args(arg_list)
+ if ((@local_as_void.include?(arg_list.strip)) or (arg_list.empty?))
+ return 'void'
+ else
+ c=0
+ arg_list.gsub!(/(\w+)(?:\s*\[[\s\d\w+-]*\])+/,'*\1') # magically turn brackets into asterisks
+ arg_list.gsub!(/\s+\*/,'*') # remove space to place asterisks with type (where they belong)
+ arg_list.gsub!(/\*(\w)/,'* \1') # pull asterisks away from arg to place asterisks with type (where they belong)
+
+ #scan argument list for function pointers and replace them with custom types
+ arg_list.gsub!(/([\w\s\*]+)\(+\s*\*[\*\s]*([\w\s]*)\s*\)+\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*'])
+ if ((parts.size < 2) or (parts[-1][-1].chr == '*') or (@standards.include?(parts[-1])))
+ "#{arg} cmock_arg#{c+=1}"
+ else
+ arg
+ end
+ }.join(', ')
+ end
+ end
+
+ def parse_declaration(declaration)
+ decl = {}
+
+ regex_match = @declaration_parse_matcher.match(declaration)
+ raise "Failed parsing function declaration: '#{declaration}'" if regex_match.nil?
+
+ #grab argument list
+ args = regex_match[2].strip
+
+ #process function attributes, return type, and name
+ descriptors = regex_match[1]
+ descriptors.gsub!(/\s+\*/,'*') #remove space to place asterisks with return type (where they belong)
+ descriptors.gsub!(/\*(\w)/,'* \1') #pull asterisks away from function name to place asterisks with return type (where they belong)
+ descriptors = descriptors.split #array of all descriptor strings
+
+ #grab name
+ decl[:name] = descriptors[-1] #snag name as last array item
+
+ #build attribute and return type strings
+ decl[:modifier] = []
+ rettype = []
+ descriptors[0..-2].each do |word|
+ if @c_attributes.include?(word)
+ decl[:modifier] << word
+ elsif @c_calling_conventions.include?(word)
+ decl[:c_calling_convention] = word
+ else
+ rettype << word
+ end
+ end
+ decl[:modifier] = decl[:modifier].join(' ')
+ rettype = rettype.join(' ')
+ rettype = 'void' if (@local_as_void.include?(rettype.strip))
+ decl[:return] = { :type => rettype,
+ :name => 'cmock_to_return',
+ :ptr? => divine_ptr(rettype),
+ :const? => rettype.split(/\s/).include?('const'),
+ :str => "#{rettype} cmock_to_return",
+ :void? => (rettype == 'void')
+ }
+
+ #remove default argument statements from mock definitions
+ args.gsub!(/=\s*[a-zA-Z0-9_\.]+\s*/, ' ')
+
+ #check for var args
+ if (args =~ /\.\.\./)
+ decl[:var_arg] = args.match( /[\w\s]*\.\.\./ ).to_s.strip
+ if (args =~ /\,[\w\s]*\.\.\./)
+ args = args.gsub!(/\,[\w\s]*\.\.\./,'')
+ else
+ args = 'void'
+ end
+ else
+ decl[:var_arg] = nil
+ end
+ args = clean_args(args)
+ decl[:args_string] = args
+ decl[:args] = parse_args(args)
+ decl[:args_call] = decl[:args].map{|a| a[:name]}.join(', ')
+ decl[:contains_ptr?] = decl[:args].inject(false) {|ptr, arg| arg[:ptr?] ? true : ptr }
+
+ if (decl[:return][:type].nil? or decl[:name].nil? or decl[:args].nil? or
+ decl[:return][:type].empty? or decl[:name].empty?)
+ raise "Failed Parsing Declaration Prototype!\n" +
+ " declaration: '#{declaration}'\n" +
+ " modifier: '#{decl[:modifier]}'\n" +
+ " return: #{prototype_inspect_hash(decl[:return])}\n" +
+ " function: '#{decl[:name]}'\n" +
+ " args: #{prototype_inspect_array_of_hashes(decl[:args])}\n"
+ end
+
+ return decl
+ end
+
+ def prototype_inspect_hash(hash)
+ pairs = []
+ hash.each_pair { |name, value| pairs << ":#{name} => #{"'" if (value.class == String)}#{value}#{"'" if (value.class == String)}" }
+ return "{#{pairs.join(', ')}}"
+ end
+
+ def prototype_inspect_array_of_hashes(array)
+ hashes = []
+ array.each { |hash| hashes << prototype_inspect_hash(hash) }
+ case (array.size)
+ when 0
+ return "[]"
+ when 1
+ return "[#{hashes[0]}]"
+ else
+ return "[\n #{hashes.join("\n ")}\n ]\n"
+ end
+ end
+
+end
diff --git a/tests/vendor/ceedling/vendor/cmock/lib/cmock_plugin_manager.rb b/tests/vendor/ceedling/vendor/cmock/lib/cmock_plugin_manager.rb
new file mode 100644
index 000000000..eb8f9e81c
--- /dev/null
+++ b/tests/vendor/ceedling/vendor/cmock/lib/cmock_plugin_manager.rb
@@ -0,0 +1,40 @@
+# ==========================================
+# 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 CMockPluginManager
+
+ attr_accessor :plugins
+
+ def initialize(config, utils)
+ @plugins = []
+ plugins_to_load = [:expect, config.plugins].flatten.uniq.compact
+ plugins_to_load.each do |plugin|
+ plugin_name = plugin.to_s
+ object_name = "CMockGeneratorPlugin" + camelize(plugin_name)
+ begin
+ unless (Object.const_defined? object_name)
+ require "#{File.expand_path(File.dirname(__FILE__))}/cmock_generator_plugin_#{plugin_name.downcase}.rb"
+ end
+ @plugins << eval("#{object_name}.new(config, utils)")
+ rescue
+ raise "ERROR: CMock unable to load plugin '#{plugin_name}'"
+ end
+ end
+ @plugins.sort! {|a,b| a.priority <=> b.priority }
+ end
+
+ def run(method, args=nil)
+ if args.nil?
+ return @plugins.collect{ |plugin| plugin.send(method) if plugin.respond_to?(method) }.flatten.join
+ else
+ return @plugins.collect{ |plugin| plugin.send(method, args) if plugin.respond_to?(method) }.flatten.join
+ end
+ end
+
+ def camelize(lower_case_and_underscored_word)
+ lower_case_and_underscored_word.gsub(/\/(.?)/) { "::" + $1.upcase }.gsub(/(^|_)(.)/) { $2.upcase }
+ end
+end
diff --git a/tests/vendor/ceedling/vendor/cmock/lib/cmock_unityhelper_parser.rb b/tests/vendor/ceedling/vendor/cmock/lib/cmock_unityhelper_parser.rb
new file mode 100644
index 000000000..c22db7aa9
--- /dev/null
+++ b/tests/vendor/ceedling/vendor/cmock/lib/cmock_unityhelper_parser.rb
@@ -0,0 +1,75 @@
+# ==========================================
+# 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 CMockUnityHelperParser
+
+ attr_accessor :c_types
+
+ def initialize(config)
+ @config = config
+ @fallback = @config.plugins.include?(:array) ? 'UNITY_TEST_ASSERT_EQUAL_MEMORY_ARRAY' : 'UNITY_TEST_ASSERT_EQUAL_MEMORY'
+ @c_types = map_C_types.merge(import_source)
+ end
+
+ def get_helper(ctype)
+ lookup = ctype.gsub(/(?:^|(\S?)(\s*)|(\W))const(?:$|(\s*)(\S)|(\W))/,'\1\3\5\6').strip.gsub(/\s+/,'_')
+ return [@c_types[lookup], ''] if (@c_types[lookup])
+ if (lookup =~ /\*$/)
+ lookup = lookup.gsub(/\*$/,'')
+ return [@c_types[lookup], '*'] if (@c_types[lookup])
+ else
+ lookup = lookup + '*'
+ return [@c_types[lookup], '&'] if (@c_types[lookup])
+ end
+ return ['UNITY_TEST_ASSERT_EQUAL_PTR', ''] if (ctype =~ /cmock_\w+_ptr\d+/)
+ raise("Don't know how to test #{ctype} and memory tests are disabled!") unless @config.memcmp_if_unknown
+ return (lookup =~ /\*$/) ? [@fallback, '&'] : [@fallback, '']
+ end
+
+ private ###########################
+
+ def map_C_types
+ c_types = {}
+ @config.treat_as.each_pair do |ctype, expecttype|
+ c_type = ctype.gsub(/\s+/,'_')
+ if (expecttype =~ /\*/)
+ c_types[c_type] = "UNITY_TEST_ASSERT_EQUAL_#{expecttype.gsub(/\*/,'')}_ARRAY"
+ else
+ c_types[c_type] = "UNITY_TEST_ASSERT_EQUAL_#{expecttype}"
+ c_types[c_type+'*'] ||= "UNITY_TEST_ASSERT_EQUAL_#{expecttype}_ARRAY"
+ end
+ end
+ c_types
+ end
+
+ def import_source
+ source = @config.load_unity_helper
+ return {} if source.nil?
+ c_types = {}
+ source = source.gsub(/\/\/.*$/, '') #remove line comments
+ source = source.gsub(/\/\*.*?\*\//m, '') #remove block comments
+
+ #scan for comparison helpers
+ match_regex = Regexp.new('^\s*#define\s+(UNITY_TEST_ASSERT_EQUAL_(\w+))\s*\(' + Array.new(4,'\s*\w+\s*').join(',') + '\)')
+ pairs = source.scan(match_regex).flatten.compact
+ (pairs.size/2).times do |i|
+ expect = pairs[i*2]
+ ctype = pairs[(i*2)+1]
+ c_types[ctype] = expect unless expect.include?("_ARRAY")
+ end
+
+ #scan for array variants of those helpers
+ match_regex = Regexp.new('^\s*#define\s+(UNITY_TEST_ASSERT_EQUAL_(\w+_ARRAY))\s*\(' + Array.new(5,'\s*\w+\s*').join(',') + '\)')
+ pairs = source.scan(match_regex).flatten.compact
+ (pairs.size/2).times do |i|
+ expect = pairs[i*2]
+ ctype = pairs[(i*2)+1]
+ c_types[ctype.gsub('_ARRAY','*')] = expect
+ end
+
+ c_types
+ end
+end
diff --git a/tests/vendor/ceedling/vendor/cmock/release/build.info b/tests/vendor/ceedling/vendor/cmock/release/build.info
new file mode 100644
index 000000000..1f25cde38
--- /dev/null
+++ b/tests/vendor/ceedling/vendor/cmock/release/build.info
@@ -0,0 +1,2 @@
+212
+
diff --git a/tests/vendor/ceedling/vendor/cmock/release/version.info b/tests/vendor/ceedling/vendor/cmock/release/version.info
new file mode 100644
index 000000000..0d71c0841
--- /dev/null
+++ b/tests/vendor/ceedling/vendor/cmock/release/version.info
@@ -0,0 +1,2 @@
+2.0
+
diff --git a/tests/vendor/ceedling/vendor/cmock/src/cmock.c b/tests/vendor/ceedling/vendor/cmock/src/cmock.c
new file mode 100644
index 000000000..558e19a8e
--- /dev/null
+++ b/tests/vendor/ceedling/vendor/cmock/src/cmock.c
@@ -0,0 +1,186 @@
+/* ==========================================
+ 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]
+========================================== */
+
+#include "unity.h"
+#include "cmock.h"
+
+//define CMOCK_MEM_DYNAMIC to grab memory as needed with malloc
+//when you do that, CMOCK_MEM_SIZE is used for incremental size instead of total
+#ifdef CMOCK_MEM_STATIC
+#undef CMOCK_MEM_DYNAMIC
+#endif
+
+#ifdef CMOCK_MEM_DYNAMIC
+#include
+#endif
+
+//this is used internally during pointer arithmetic. make sure this type is the same size as the target's pointer type
+#ifndef CMOCK_MEM_PTR_AS_INT
+#define CMOCK_MEM_PTR_AS_INT unsigned long
+#endif
+
+//0 for no alignment, 1 for 16-bit, 2 for 32-bit, 3 for 64-bit
+#ifndef CMOCK_MEM_ALIGN
+#define CMOCK_MEM_ALIGN (2)
+#endif
+
+//amount of memory to allow cmock to use in its internal heap
+#ifndef CMOCK_MEM_SIZE
+#define CMOCK_MEM_SIZE (32768)
+#endif
+
+//automatically calculated defs for easier reading
+#define CMOCK_MEM_ALIGN_SIZE (1u << CMOCK_MEM_ALIGN)
+#define CMOCK_MEM_ALIGN_MASK (CMOCK_MEM_ALIGN_SIZE - 1)
+#define CMOCK_MEM_INDEX_SIZE ((sizeof(CMOCK_MEM_INDEX_TYPE) > CMOCK_MEM_ALIGN_SIZE) ? sizeof(CMOCK_MEM_INDEX_TYPE) : CMOCK_MEM_ALIGN_SIZE)
+
+//private variables
+#ifdef CMOCK_MEM_DYNAMIC
+static unsigned char* CMock_Guts_Buffer = NULL;
+static CMOCK_MEM_INDEX_TYPE CMock_Guts_BufferSize = CMOCK_MEM_ALIGN_SIZE;
+static CMOCK_MEM_INDEX_TYPE CMock_Guts_FreePtr;
+#else
+static unsigned char CMock_Guts_Buffer[CMOCK_MEM_SIZE + CMOCK_MEM_ALIGN_SIZE];
+static CMOCK_MEM_INDEX_TYPE CMock_Guts_BufferSize = CMOCK_MEM_SIZE + CMOCK_MEM_ALIGN_SIZE;
+static CMOCK_MEM_INDEX_TYPE CMock_Guts_FreePtr;
+#endif
+//-------------------------------------------------------
+// CMock_Guts_MemNew
+//-------------------------------------------------------
+CMOCK_MEM_INDEX_TYPE CMock_Guts_MemNew(CMOCK_MEM_INDEX_TYPE size)
+{
+ CMOCK_MEM_INDEX_TYPE index;
+
+ //verify arguments valid (we must be allocating space for at least 1 byte, and the existing chain must be in memory somewhere)
+ if (size < 1)
+ return CMOCK_GUTS_NONE;
+
+ //verify we have enough room
+ size = size + CMOCK_MEM_INDEX_SIZE;
+ if (size & CMOCK_MEM_ALIGN_MASK)
+ size = (size + CMOCK_MEM_ALIGN_MASK) & ~CMOCK_MEM_ALIGN_MASK;
+ if ((CMock_Guts_BufferSize - CMock_Guts_FreePtr) < size)
+ {
+#ifdef CMOCK_MEM_DYNAMIC
+ CMock_Guts_BufferSize += CMOCK_MEM_SIZE + size;
+ CMock_Guts_Buffer = realloc(CMock_Guts_Buffer, CMock_Guts_BufferSize);
+ if (CMock_Guts_Buffer == NULL)
+#endif //yes that if will continue to the return below if TRUE
+ return CMOCK_GUTS_NONE;
+ }
+
+ //determine where we're putting this new block, and init its pointer to be the end of the line
+ index = CMock_Guts_FreePtr + CMOCK_MEM_INDEX_SIZE;
+ *(CMOCK_MEM_INDEX_TYPE*)(&CMock_Guts_Buffer[CMock_Guts_FreePtr]) = CMOCK_GUTS_NONE;
+ CMock_Guts_FreePtr += size;
+
+ return index;
+}
+
+//-------------------------------------------------------
+// CMock_Guts_MemChain
+//-------------------------------------------------------
+CMOCK_MEM_INDEX_TYPE CMock_Guts_MemChain(CMOCK_MEM_INDEX_TYPE root_index, CMOCK_MEM_INDEX_TYPE obj_index)
+{
+ CMOCK_MEM_INDEX_TYPE index;
+ void* root;
+ void* obj;
+ void* next;
+
+ if (root_index == CMOCK_GUTS_NONE)
+ {
+ //if there is no root currently, we return this object as the root of the chain
+ return obj_index;
+ }
+ else
+ {
+ //reject illegal nodes
+ if ((root_index < CMOCK_MEM_ALIGN_SIZE) || (root_index >= CMock_Guts_FreePtr))
+ {
+ return CMOCK_GUTS_NONE;
+ }
+ if ((obj_index < CMOCK_MEM_ALIGN_SIZE) || (obj_index >= CMock_Guts_FreePtr))
+ {
+ return CMOCK_GUTS_NONE;
+ }
+
+ root = (void*)(&CMock_Guts_Buffer[root_index]);
+ obj = (void*)(&CMock_Guts_Buffer[obj_index]);
+
+ //find the end of the existing chain and add us
+ next = root;
+ do {
+ index = *(CMOCK_MEM_INDEX_TYPE*)((CMOCK_MEM_PTR_AS_INT)next - CMOCK_MEM_INDEX_SIZE);
+ if (index >= CMock_Guts_FreePtr)
+ return CMOCK_GUTS_NONE;
+ if (index > 0)
+ next = (void*)(&CMock_Guts_Buffer[index]);
+ } while (index > 0);
+ *(CMOCK_MEM_INDEX_TYPE*)((CMOCK_MEM_PTR_AS_INT)next - CMOCK_MEM_INDEX_SIZE) = ((CMOCK_MEM_PTR_AS_INT)obj - (CMOCK_MEM_PTR_AS_INT)CMock_Guts_Buffer);
+ return root_index;
+ }
+}
+
+//-------------------------------------------------------
+// CMock_Guts_MemNext
+//-------------------------------------------------------
+CMOCK_MEM_INDEX_TYPE CMock_Guts_MemNext(CMOCK_MEM_INDEX_TYPE previous_item_index)
+{
+ CMOCK_MEM_INDEX_TYPE index;
+ void* previous_item;
+
+ //There is nothing "next" if the pointer isn't from our buffer
+ if ((previous_item_index < CMOCK_MEM_ALIGN_SIZE) || (previous_item_index >= CMock_Guts_FreePtr))
+ return CMOCK_GUTS_NONE;
+ previous_item = (void*)(&CMock_Guts_Buffer[previous_item_index]);
+
+ //if the pointer is good, then use it to look up the next index
+ //(we know the first element always goes in zero, so NEXT must always be > 1)
+ index = *(CMOCK_MEM_INDEX_TYPE*)((CMOCK_MEM_PTR_AS_INT)previous_item - CMOCK_MEM_INDEX_SIZE);
+ if ((index > 1) && (index < CMock_Guts_FreePtr))
+ return index;
+ else
+ return CMOCK_GUTS_NONE;
+}
+
+//-------------------------------------------------------
+// CMock_GetAddressFor
+//-------------------------------------------------------
+void* CMock_Guts_GetAddressFor(CMOCK_MEM_INDEX_TYPE index)
+{
+ if ((index >= CMOCK_MEM_ALIGN_SIZE) && (index < CMock_Guts_FreePtr))
+ {
+ return (void*)(&CMock_Guts_Buffer[index]);
+ }
+ else
+ {
+ return NULL;
+ }
+}
+
+//-------------------------------------------------------
+// CMock_Guts_MemBytesFree
+//-------------------------------------------------------
+CMOCK_MEM_INDEX_TYPE CMock_Guts_MemBytesFree(void)
+{
+ return CMock_Guts_BufferSize - CMock_Guts_FreePtr;
+}
+
+//-------------------------------------------------------
+// CMock_Guts_MemBytesUsed
+//-------------------------------------------------------
+CMOCK_MEM_INDEX_TYPE CMock_Guts_MemBytesUsed(void)
+{
+ return CMock_Guts_FreePtr - CMOCK_MEM_ALIGN_SIZE;
+}
+
+//-------------------------------------------------------
+// CMock_Guts_MemFreeAll
+//-------------------------------------------------------
+void CMock_Guts_MemFreeAll(void)
+{
+ CMock_Guts_FreePtr = CMOCK_MEM_ALIGN_SIZE; //skip the very beginning
+}
diff --git a/tests/vendor/ceedling/vendor/cmock/src/cmock.h b/tests/vendor/ceedling/vendor/cmock/src/cmock.h
new file mode 100644
index 000000000..a43e9e054
--- /dev/null
+++ b/tests/vendor/ceedling/vendor/cmock/src/cmock.h
@@ -0,0 +1,30 @@
+/* ==========================================
+ 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]
+========================================== */
+
+#ifndef CMOCK_FRAMEWORK_H
+#define CMOCK_FRAMEWORK_H
+
+//should be big enough to index full range of CMOCK_MEM_MAX
+#ifndef CMOCK_MEM_INDEX_TYPE
+#define CMOCK_MEM_INDEX_TYPE unsigned int
+#endif
+
+#define CMOCK_GUTS_NONE (0)
+
+//-------------------------------------------------------
+// Memory API
+//-------------------------------------------------------
+CMOCK_MEM_INDEX_TYPE CMock_Guts_MemNew(CMOCK_MEM_INDEX_TYPE size);
+CMOCK_MEM_INDEX_TYPE CMock_Guts_MemChain(CMOCK_MEM_INDEX_TYPE root_index, CMOCK_MEM_INDEX_TYPE obj_index);
+CMOCK_MEM_INDEX_TYPE CMock_Guts_MemNext(CMOCK_MEM_INDEX_TYPE previous_item_index);
+
+void* CMock_Guts_GetAddressFor(CMOCK_MEM_INDEX_TYPE index);
+
+CMOCK_MEM_INDEX_TYPE CMock_Guts_MemBytesFree(void);
+CMOCK_MEM_INDEX_TYPE CMock_Guts_MemBytesUsed(void);
+void CMock_Guts_MemFreeAll(void);
+
+#endif //CMOCK_FRAMEWORK
diff --git a/tests/vendor/ceedling/vendor/constructor/lib/constructor.rb b/tests/vendor/ceedling/vendor/constructor/lib/constructor.rb
new file mode 100644
index 000000000..87eb6dd13
--- /dev/null
+++ b/tests/vendor/ceedling/vendor/constructor/lib/constructor.rb
@@ -0,0 +1,127 @@
+CONSTRUCTOR_VERSION = '1.0.4' #:nodoc:#
+
+class Class #:nodoc:#
+ def constructor(*attrs, &block)
+ call_block = ''
+ if block_given?
+ @constructor_block = block
+ call_block = 'self.instance_eval(&self.class.constructor_block)'
+ end
+ # Look for embedded options in the listing:
+ opts = attrs.find { |a| a.kind_of?(Hash) and attrs.delete(a) }
+ do_acc = opts.nil? ? false : opts[:accessors] == true
+ do_reader = opts.nil? ? false : opts[:readers] == true
+ require_args = opts.nil? ? true : opts[:strict] != false
+ super_args = opts.nil? ? nil : opts[:super]
+
+ # Incorporate superclass's constructor keys, if our superclass
+ if superclass.constructor_keys
+ similar_keys = superclass.constructor_keys & attrs
+ raise "Base class already has keys #{similar_keys.inspect}" unless similar_keys.empty?
+ attrs = [attrs,superclass.constructor_keys].flatten
+ end
+ # Generate ivar assigner code lines
+ assigns = ''
+ attrs.each do |k|
+ assigns += "@#{k.to_s} = args[:#{k.to_s}]\n"
+ end
+
+ # If accessors option is on, declare accessors for the attributes:
+ if do_acc
+ add_accessors = "attr_accessor " + attrs.reject {|x| superclass.constructor_keys.include?(x.to_sym)}.map {|x| ":#{x.to_s}"}.join(',')
+ #add_accessors = "attr_accessor " + attrs.map {|x| ":#{x.to_s}"}.join(',')
+ self.class_eval add_accessors
+ end
+
+ # If readers option is on, declare readers for the attributes:
+ if do_reader
+ self.class_eval "attr_reader " + attrs.reject {|x| superclass.constructor_keys.include?(x.to_sym)}.map {|x| ":#{x.to_s}"}.join(',')
+ end
+
+ # If user supplied super-constructor hints:
+ super_call = ''
+ if super_args
+ list = super_args.map do |a|
+ case a
+ when String
+ %|"#{a}"|
+ when Symbol
+ %|:#{a}|
+ end
+ end
+ super_call = %|super(#{list.join(',')})|
+ end
+
+ # If strict is on, define the constructor argument validator method,
+ # and setup the initializer to invoke the validator method.
+ # Otherwise, insert lax code into the initializer.
+ validation_code = "return if args.nil?"
+ if require_args
+ self.class_eval do
+ def _validate_constructor_args(args)
+ # First, make sure we've got args of some kind
+ unless args and args.keys and args.keys.size > 0
+ raise ConstructorArgumentError.new(self.class.constructor_keys)
+ end
+ # Scan for missing keys in the argument hash
+ a_keys = args.keys
+ missing = []
+ self.class.constructor_keys.each do |ck|
+ unless a_keys.member?(ck)
+ missing << ck
+ end
+ a_keys.delete(ck) # Delete inbound keys as we address them
+ end
+ if missing.size > 0 || a_keys.size > 0
+ raise ConstructorArgumentError.new(missing,a_keys)
+ end
+ end
+ end
+ # Setup the code to insert into the initializer:
+ validation_code = "_validate_constructor_args args "
+ end
+
+ # Generate the initializer code
+ self.class_eval %{
+ def initialize(args=nil)
+ #{super_call}
+ #{validation_code}
+ #{assigns}
+ setup if respond_to?(:setup)
+ #{call_block}
+ end
+ }
+
+ # Remember our constructor keys
+ @_ctor_keys = attrs
+ end
+
+ # Access the constructor keys for this class
+ def constructor_keys; @_ctor_keys ||=[]; end
+
+ def constructor_block #:nodoc:#
+ @constructor_block
+ end
+
+end
+
+# Fancy validation exception, based on missing and extraneous keys.
+class ConstructorArgumentError < RuntimeError #:nodoc:#
+ def initialize(missing,rejected=[])
+ err_msg = ''
+ if missing.size > 0
+ err_msg = "Missing constructor args [#{missing.join(',')}]"
+ end
+ if rejected.size > 0
+ # Some inbound keys were not addressed earlier; this means they're unwanted
+ if err_msg
+ err_msg << "; " # Appending to earlier message about missing items
+ else
+ err_msg = ''
+ end
+ # Enumerate the rejected key names
+ err_msg << "Rejected constructor args [#{rejected.join(',')}]"
+ end
+ super err_msg
+ end
+end
diff --git a/tests/vendor/ceedling/vendor/constructor/lib/constructor_struct.rb b/tests/vendor/ceedling/vendor/constructor/lib/constructor_struct.rb
new file mode 100644
index 000000000..e97ff629e
--- /dev/null
+++ b/tests/vendor/ceedling/vendor/constructor/lib/constructor_struct.rb
@@ -0,0 +1,33 @@
+class ConstructorStruct
+ def self.new(*accessors, &block)
+ defaults = {:accessors => true, :strict => false}
+
+ accessor_names = accessors.dup
+ if accessors.last.is_a? Hash
+ accessor_names.pop
+ user_opts = accessors.last
+ user_opts.delete(:accessors)
+ defaults.each do |k,v|
+ user_opts[k] ||= v
+ end
+ else
+ accessors << defaults
+ end
+
+ Class.new do
+ constructor *accessors
+
+ class_eval(&block) if block
+
+ comparator_code = accessor_names.map { |fname| "self.#{fname} == o.#{fname}" }.join(" && ")
+ eval %|
+ def ==(o)
+ (self.class == o.class) && #{comparator_code}
+ end
+ def eql?(o)
+ (self.class == o.class) && #{comparator_code}
+ end
+ |
+ end
+ end
+end
diff --git a/tests/vendor/ceedling/vendor/deep_merge/lib/deep_merge.rb b/tests/vendor/ceedling/vendor/deep_merge/lib/deep_merge.rb
new file mode 100644
index 000000000..4c4b7610b
--- /dev/null
+++ b/tests/vendor/ceedling/vendor/deep_merge/lib/deep_merge.rb
@@ -0,0 +1,211 @@
+module DeepMerge
+
+ MAJOR_VERSION = 0
+ MINOR_VERSION = 1
+ FIX_VERSION = 0
+ VERSION = "#{MAJOR_VERSION}.#{MINOR_VERSION}.#{FIX_VERSION}"
+
+ class InvalidParameter < StandardError; end
+
+ DEFAULT_FIELD_KNOCKOUT_PREFIX = '--'
+
+ module DeepMergeHash
+ # ko_hash_merge! will merge and knockout elements prefixed with DEFAULT_FIELD_KNOCKOUT_PREFIX
+ def ko_deep_merge!(source, options = {})
+ default_opts = {:knockout_prefix => "--", :preserve_unmergeables => false}
+ DeepMerge::deep_merge!(source, self, default_opts.merge(options))
+ end
+
+ # deep_merge! will merge and overwrite any unmergeables in destination hash
+ def deep_merge!(source, options = {})
+ default_opts = {:preserve_unmergeables => false}
+ DeepMerge::deep_merge!(source, self, default_opts.merge(options))
+ end
+
+ # deep_merge will merge and skip any unmergeables in destination hash
+ def deep_merge(source, options = {})
+ default_opts = {:preserve_unmergeables => true}
+ DeepMerge::deep_merge!(source, self, default_opts.merge(options))
+ end
+
+ end # DeepMergeHashExt
+
+ # Deep Merge core documentation.
+ # deep_merge! method permits merging of arbitrary child elements. The two top level
+ # elements must be hashes. These hashes can contain unlimited (to stack limit) levels
+ # of child elements. These child elements to not have to be of the same types.
+ # Where child elements are of the same type, deep_merge will attempt to merge them together.
+ # Where child elements are not of the same type, deep_merge will skip or optionally overwrite
+ # the destination element with the contents of the source element at that level.
+ # So if you have two hashes like this:
+ # source = {:x => [1,2,3], :y => 2}
+ # dest = {:x => [4,5,'6'], :y => [7,8,9]}
+ # dest.deep_merge!(source)
+ # Results: {:x => [1,2,3,4,5,'6'], :y => 2}
+ # By default, "deep_merge!" will overwrite any unmergeables and merge everything else.
+ # To avoid this, use "deep_merge" (no bang/exclamation mark)
+ #
+ # Options:
+ # Options are specified in the last parameter passed, which should be in hash format:
+ # hash.deep_merge!({:x => [1,2]}, {:knockout_prefix => '--'})
+ # :preserve_unmergeables DEFAULT: false
+ # Set to true to skip any unmergeable elements from source
+ # :knockout_prefix DEFAULT: nil
+ # Set to string value to signify prefix which deletes elements from existing element
+ # :sort_merged_arrays DEFAULT: false
+ # Set to true to sort all arrays that are merged together
+ # :unpack_arrays DEFAULT: nil
+ # Set to string value to run "Array::join" then "String::split" against all arrays
+ # :merge_debug DEFAULT: false
+ # Set to true to get console output of merge process for debugging
+ #
+ # Selected Options Details:
+ # :knockout_prefix => The purpose of this is to provide a way to remove elements
+ # from existing Hash by specifying them in a special way in incoming hash
+ # source = {:x => ['--1', '2']}
+ # dest = {:x => ['1', '3']}
+ # dest.ko_deep_merge!(source)
+ # Results: {:x => ['2','3']}
+ # Additionally, if the knockout_prefix is passed alone as a string, it will cause
+ # the entire element to be removed:
+ # source = {:x => '--'}
+ # dest = {:x => [1,2,3]}
+ # dest.ko_deep_merge!(source)
+ # Results: {:x => ""}
+ # :unpack_arrays => The purpose of this is to permit compound elements to be passed
+ # in as strings and to be converted into discrete array elements
+ # irsource = {:x => ['1,2,3', '4']}
+ # dest = {:x => ['5','6','7,8']}
+ # dest.deep_merge!(source, {:unpack_arrays => ','})
+ # Results: {:x => ['1','2','3','4','5','6','7','8'}
+ # Why: If receiving data from an HTML form, this makes it easy for a checkbox
+ # to pass multiple values from within a single HTML element
+ #
+ # There are many tests for this library - and you can learn more about the features
+ # and usages of deep_merge! by just browsing the test examples
+ def DeepMerge.deep_merge!(source, dest, options = {})
+ # turn on this line for stdout debugging text
+ merge_debug = options[:merge_debug] || false
+ overwrite_unmergeable = !options[:preserve_unmergeables]
+ knockout_prefix = options[:knockout_prefix] || nil
+ if knockout_prefix == "" then raise InvalidParameter, "knockout_prefix cannot be an empty string in deep_merge!"; end
+ if knockout_prefix && !overwrite_unmergeable then raise InvalidParameter, "overwrite_unmergeable must be true if knockout_prefix is specified in deep_merge!"; end
+ # if present: we will split and join arrays on this char before merging
+ array_split_char = options[:unpack_arrays] || false
+ # request that we sort together any arrays when they are merged
+ sort_merged_arrays = options[:sort_merged_arrays] || false
+ di = options[:debug_indent] || ''
+ # do nothing if source is nil
+ if source.nil? || (source.respond_to?(:blank?) && source.blank?) then return dest; end
+ # if dest doesn't exist, then simply copy source to it
+ if dest.nil? && overwrite_unmergeable then dest = source; return dest; end
+
+ puts "#{di}Source class: #{source.class.inspect} :: Dest class: #{dest.class.inspect}" if merge_debug
+ if source.kind_of?(Hash)
+ puts "#{di}Hashes: #{source.inspect} :: #{dest.inspect}" if merge_debug
+ source.each do |src_key, src_value|
+ if dest.kind_of?(Hash)
+ puts "#{di} looping: #{src_key.inspect} => #{src_value.inspect} :: #{dest.inspect}" if merge_debug
+ if not dest[src_key].nil?
+ puts "#{di} ==>merging: #{src_key.inspect} => #{src_value.inspect} :: #{dest[src_key].inspect}" if merge_debug
+ dest[src_key] = deep_merge!(src_value, dest[src_key], options.merge(:debug_indent => di + ' '))
+ else # dest[src_key] doesn't exist so we want to create and overwrite it (but we do this via deep_merge!)
+ puts "#{di} ==>merging over: #{src_key.inspect} => #{src_value.inspect}" if merge_debug
+ # note: we rescue here b/c some classes respond to "dup" but don't implement it (Numeric, TrueClass, FalseClass, NilClass among maybe others)
+ begin
+ src_dup = src_value.dup # we dup src_value if possible because we're going to merge into it (since dest is empty)
+ rescue TypeError
+ src_dup = src_value
+ end
+ dest[src_key] = deep_merge!(src_value, src_dup, options.merge(:debug_indent => di + ' '))
+ end
+ else # dest isn't a hash, so we overwrite it completely (if permitted)
+ if overwrite_unmergeable
+ puts "#{di} overwriting dest: #{src_key.inspect} => #{src_value.inspect} -over-> #{dest.inspect}" if merge_debug
+ dest = overwrite_unmergeables(source, dest, options)
+ end
+ end
+ end
+ elsif source.kind_of?(Array)
+ puts "#{di}Arrays: #{source.inspect} :: #{dest.inspect}" if merge_debug
+ # if we are instructed, join/split any source arrays before processing
+ if array_split_char
+ puts "#{di} split/join on source: #{source.inspect}" if merge_debug
+ source = source.join(array_split_char).split(array_split_char)
+ if dest.kind_of?(Array) then dest = dest.join(array_split_char).split(array_split_char); end
+ end
+ # if there's a naked knockout_prefix in source, that means we are to truncate dest
+ if source.index(knockout_prefix) then dest = clear_or_nil(dest); source.delete(knockout_prefix); end
+ if dest.kind_of?(Array)
+ if knockout_prefix
+ print "#{di} knocking out: " if merge_debug
+ # remove knockout prefix items from both source and dest
+ source.delete_if do |ko_item|
+ retval = false
+ item = ko_item.respond_to?(:gsub) ? ko_item.gsub(%r{^#{knockout_prefix}}, "") : ko_item
+ if item != ko_item
+ print "#{ko_item} - " if merge_debug
+ dest.delete(item)
+ dest.delete(ko_item)
+ retval = true
+ end
+ retval
+ end
+ puts if merge_debug
+ end
+ puts "#{di} merging arrays: #{source.inspect} :: #{dest.inspect}" if merge_debug
+ dest = dest | source
+ if sort_merged_arrays then dest.sort!; end
+ elsif overwrite_unmergeable
+ puts "#{di} overwriting dest: #{source.inspect} -over-> #{dest.inspect}" if merge_debug
+ dest = overwrite_unmergeables(source, dest, options)
+ end
+ else # src_hash is not an array or hash, so we'll have to overwrite dest
+ puts "#{di}Others: #{source.inspect} :: #{dest.inspect}" if merge_debug
+ dest = overwrite_unmergeables(source, dest, options)
+ end
+ puts "#{di}Returning #{dest.inspect}" if merge_debug
+ dest
+ end # deep_merge!
+
+ # allows deep_merge! to uniformly handle overwriting of unmergeable entities
+ def DeepMerge::overwrite_unmergeables(source, dest, options)
+ merge_debug = options[:merge_debug] || false
+ overwrite_unmergeable = !options[:preserve_unmergeables]
+ knockout_prefix = options[:knockout_prefix] || false
+ di = options[:debug_indent] || ''
+ if knockout_prefix && overwrite_unmergeable
+ if source.kind_of?(String) # remove knockout string from source before overwriting dest
+ src_tmp = source.gsub(%r{^#{knockout_prefix}},"")
+ elsif source.kind_of?(Array) # remove all knockout elements before overwriting dest
+ src_tmp = source.delete_if {|ko_item| ko_item.kind_of?(String) && ko_item.match(%r{^#{knockout_prefix}}) }
+ else
+ src_tmp = source
+ end
+ if src_tmp == source # if we didn't find a knockout_prefix then we just overwrite dest
+ puts "#{di}#{src_tmp.inspect} -over-> #{dest.inspect}" if merge_debug
+ dest = src_tmp
+ else # if we do find a knockout_prefix, then we just delete dest
+ puts "#{di}\"\" -over-> #{dest.inspect}" if merge_debug
+ dest = ""
+ end
+ elsif overwrite_unmergeable
+ dest = source
+ end
+ dest
+ end
+
+ def DeepMerge::clear_or_nil(obj)
+ if obj.respond_to?(:clear)
+ obj.clear
+ else
+ obj = nil
+ end
+ obj
+ end
+
+end # module DeepMerge
+
+class Hash
+ include DeepMerge::DeepMergeHash
+end
diff --git a/tests/vendor/ceedling/vendor/diy/lib/diy.rb b/tests/vendor/ceedling/vendor/diy/lib/diy.rb
new file mode 100644
index 000000000..581afc7e6
--- /dev/null
+++ b/tests/vendor/ceedling/vendor/diy/lib/diy.rb
@@ -0,0 +1,403 @@
+require 'diy/factory.rb'
+require 'yaml'
+require 'set'
+
+module DIY #:nodoc:#
+ VERSION = '1.1.2'
+ class Context
+
+ class << self
+ # Enable / disable automatic requiring of libraries. Default: true
+ attr_accessor :auto_require
+ end
+ @auto_require = true
+
+ # Accepts a Hash defining the object context (usually loaded from objects.yml), and an additional
+ # Hash containing objects to inject into the context.
+ def initialize(context_hash, extra_inputs={})
+ raise "Nil context hash" unless context_hash
+ raise "Need a hash" unless context_hash.kind_of?(Hash)
+ [ "[]", "keys" ].each do |mname|
+ unless extra_inputs.respond_to?(mname)
+ raise "Extra inputs must respond to hash-like [] operator and methods #keys and #each"
+ end
+ end
+
+ # store extra inputs
+ if extra_inputs.kind_of?(Hash)
+ @extra_inputs= {}
+ extra_inputs.each { |k,v| @extra_inputs[k.to_s] = v } # smooth out the names
+ else
+ @extra_inputs = extra_inputs
+ end
+
+ collect_object_and_subcontext_defs context_hash
+
+ # init the cache
+ @cache = {}
+ @cache['this_context'] = self
+ end
+
+
+ # Convenience: create a new DIY::Context by loading from a String (or open file handle.)
+ def self.from_yaml(io_or_string, extra_inputs={})
+ raise "nil input to YAML" unless io_or_string
+ Context.new(YAML.load(io_or_string), extra_inputs)
+ end
+
+ # Convenience: create a new DIY::Context by loading from the named file.
+ def self.from_file(fname, extra_inputs={})
+ raise "nil file name" unless fname
+ self.from_yaml(File.read(fname), extra_inputs)
+ end
+
+ # Return a reference to the object named. If necessary, the object will
+ # be instantiated on first use. If the object is non-singleton, a new
+ # object will be produced each time.
+ def get_object(obj_name)
+ key = obj_name.to_s
+ obj = @cache[key]
+ unless obj
+ if extra_inputs_has(key)
+ obj = @extra_inputs[key]
+ else
+ case @defs[key]
+ when MethodDef
+ obj = construct_method(key)
+ when FactoryDef
+ obj = construct_factory(key)
+ @cache[key] = obj
+ else
+ obj = construct_object(key)
+ @cache[key] = obj if @defs[key].singleton?
+ end
+ end
+ end
+ obj
+ end
+ alias :[] :get_object
+
+ # Inject a named object into the Context. This must be done before the Context has instantiated the
+ # object in question.
+ def set_object(obj_name,obj)
+ key = obj_name.to_s
+ raise "object '#{key}' already exists in context" if @cache.keys.include?(key)
+ @cache[key] = obj
+ end
+ alias :[]= :set_object
+
+ # Provide a listing of object names
+ def keys
+ (@defs.keys.to_set + @extra_inputs.keys.to_set).to_a
+ end
+
+ # Instantiate and yield the named subcontext
+ def within(sub_context_name)
+ # Find the subcontext definitaion:
+ context_def = @sub_context_defs[sub_context_name.to_s]
+ raise "No sub-context named #{sub_context_name}" unless context_def
+ # Instantiate a new context using self as parent:
+ context = Context.new( context_def, self )
+
+ yield context
+ end
+
+ # Returns true if the context contains an object with the given name
+ def contains_object(obj_name)
+ key = obj_name.to_s
+ @defs.keys.member?(key) or extra_inputs_has(key)
+ end
+
+ # Every top level object in the Context is instantiated. This is especially useful for
+ # systems that have "floating observers"... objects that are never directly accessed, who
+ # would thus never be instantiated by coincedence. This does not build any subcontexts
+ # that may exist.
+ def build_everything
+ @defs.keys.each { |k| self[k] }
+ end
+ alias :build_all :build_everything
+ alias :preinstantiate_singletons :build_everything
+
+ private
+
+ def collect_object_and_subcontext_defs(context_hash)
+ @defs = {}
+ @sub_context_defs = {}
+ get_defs_from context_hash
+ end
+
+ def get_defs_from(hash, namespace=nil)
+ hash.each do |name,info|
+ # we modify the info hash below so it's important to have a new
+ # instance to play with
+ info = info.dup if info
+
+ # see if we are building a factory
+ if info and info.has_key?('builds')
+ unless info.has_key?('auto_require')
+ info['auto_require'] = self.class.auto_require
+ end
+
+ if namespace
+ info['builds'] = namespace.build_classname(info['builds'])
+ end
+ @defs[name] = FactoryDef.new({:name => name,
+ :target => info['builds'],
+ :library => info['library'],
+ :auto_require => info['auto_require']})
+ next
+ end
+
+ name = name.to_s
+ case name
+ when /^\+/
+ # subcontext
+ @sub_context_defs[name.gsub(/^\+/,'')] = info
+
+ when /^using_namespace/
+ # namespace: use a module(s) prefix for the classname of contained object defs
+ # NOTE: namespacing is NOT scope... it's just a convenient way to setup class names for a group of objects.
+ get_defs_from info, parse_namespace(name)
+ when /^method\s/
+ key_name = name.gsub(/^method\s/, "")
+ @defs[key_name] = MethodDef.new(:name => key_name,
+ :object => info['object'],
+ :method => info['method'],
+ :attach => info['attach'])
+ else
+ # Normal object def
+ info ||= {}
+ if extra_inputs_has(name)
+ raise ConstructionError.new(name, "Object definition conflicts with parent context")
+ end
+ unless info.has_key?('auto_require')
+ info['auto_require'] = self.class.auto_require
+ end
+ if namespace
+ if info['class']
+ info['class'] = namespace.build_classname(info['class'])
+ else
+ info['class'] = namespace.build_classname(name)
+ end
+ end
+
+ @defs[name] = ObjectDef.new(:name => name, :info => info)
+
+ end
+ end
+ end
+
+ def construct_method(key)
+ method_definition = @defs[key]
+ object = get_object(method_definition.object)
+ method = object.method(method_definition.method)
+
+ unless method_definition.attach.nil?
+ instance_var_name = "@__diy_#{method_definition.object}"
+
+ method_definition.attach.each do |object_key|
+ get_object(object_key).instance_eval do
+ instance_variable_set(instance_var_name, object)
+ eval %|def #{key}(*args)
+ #{instance_var_name}.#{method_definition.method}(*args)
+ end|
+ end
+ end
+ end
+
+ return method
+ rescue Exception => oops
+ build_and_raise_construction_error(key, oops)
+ end
+
+ def construct_object(key)
+ # Find the object definition
+ obj_def = @defs[key]
+ raise "No object definition for '#{key}'" unless obj_def
+ # If object def mentions a library, load it
+ require obj_def.library if obj_def.library
+
+ # Resolve all components for the object
+ arg_hash = {}
+ obj_def.components.each do |name,value|
+ case value
+ when Lookup
+ arg_hash[name.to_sym] = get_object(value.name)
+ when StringValue
+ arg_hash[name.to_sym] = value.literal_value
+ else
+ raise "Cannot cope with component definition '#{value.inspect}'"
+ end
+ end
+ # Get a reference to the class for the object
+ big_c = get_class_for_name_with_module_delimeters(obj_def.class_name)
+ # Make and return the instance
+ if obj_def.use_class_directly?
+ return big_c
+ elsif arg_hash.keys.size > 0
+ return big_c.new(arg_hash)
+ else
+ return big_c.new
+ end
+ rescue Exception => oops
+ build_and_raise_construction_error(key, oops)
+ end
+
+ def build_and_raise_construction_error(key, oops)
+ cerr = ConstructionError.new(key,oops)
+ cerr.set_backtrace(oops.backtrace)
+ raise cerr
+ end
+
+ def get_class_for_name_with_module_delimeters(class_name)
+ class_name.split(/::/).inject(Object) do |mod,const_name| mod.const_get(const_name) end
+ end
+
+ def extra_inputs_has(key)
+ if key.nil? or key.strip == ''
+ raise ArgumentError.new("Cannot lookup objects with nil keys")
+ end
+ @extra_inputs.keys.member?(key) or @extra_inputs.keys.member?(key.to_sym)
+ end
+
+ def parse_namespace(str)
+ Namespace.new(str)
+ end
+ end
+
+ class Namespace #:nodoc:#
+ def initialize(str)
+ # 'using_namespace Animal Reptile'
+ parts = str.split(/\s+/)
+ raise "Namespace definitions must begin with 'using_namespace'" unless parts[0] == 'using_namespace'
+ parts.shift
+
+ if parts.length > 0 and parts[0] =~ /::/
+ parts = parts[0].split(/::/)
+ end
+
+ raise NamespaceError, "Namespace needs to indicate a module" if parts.empty?
+
+ @module_nest = parts
+ end
+
+ def build_classname(name)
+ [ @module_nest, Infl.camelize(name) ].flatten.join("::")
+ end
+ end
+
+ class Lookup #:nodoc:
+ attr_reader :name
+ def initialize(obj_name)
+ @name = obj_name
+ end
+ end
+
+ class MethodDef #:nodoc:
+ attr_accessor :name, :object, :method, :attach
+
+ def initialize(opts)
+ @name, @object, @method, @attach = opts[:name], opts[:object], opts[:method], opts[:attach]
+ end
+ end
+
+ class ObjectDef #:nodoc:
+ attr_accessor :name, :class_name, :library, :components
+ def initialize(opts)
+ name = opts[:name]
+ raise "Can't make an ObjectDef without a name" if name.nil?
+
+ info = opts[:info] || {}
+ info = info.clone
+
+ @components = {}
+
+ # Object name
+ @name = name
+
+ # Class name
+ @class_name = info.delete 'class'
+ @class_name ||= info.delete 'type'
+ @class_name ||= Infl.camelize(@name)
+
+ # Auto Require
+ @auto_require = info.delete 'auto_require'
+
+ # Library
+ @library = info.delete 'library'
+ @library ||= info.delete 'lib'
+ @library ||= Infl.underscore(@class_name) if @auto_require
+
+ # Use Class Directly
+ @use_class_directly = info.delete 'use_class_directly'
+
+ # Auto-compose
+ compose = info.delete 'compose'
+ if compose
+ case compose
+ when Array
+ auto_names = compose.map { |x| x.to_s }
+ when String
+ auto_names = compose.split(',').map { |x| x.to_s.strip }
+ when Symbol
+ auto_names = [ compose.to_s ]
+ else
+ raise "Cannot auto compose object #{@name}, bad 'compose' format: #{compose.inspect}"
+ end
+ end
+ auto_names ||= []
+ auto_names.each do |cname|
+ @components[cname] = Lookup.new(cname)
+ end
+
+ # Singleton status
+ if info['singleton'].nil?
+ @singleton = true
+ else
+ @singleton = info['singleton']
+ end
+ info.delete 'singleton'
+
+ # Remaining keys
+ info.each do |key,val|
+ @components[key.to_s] = Lookup.new(val.to_s)
+ end
+
+ end
+
+ def singleton?
+ @singleton
+ end
+
+ def use_class_directly?
+ @use_class_directly == true
+ end
+
+ end
+
+ class ConstructionError < RuntimeError #:nodoc:#
+ def initialize(object_name, cause=nil)
+ object_name = object_name
+ cause = cause
+ m = "Failed to construct '#{object_name}'"
+ if cause
+ m << "\n ...caused by:\n >>> #{cause}"
+ end
+ super m
+ end
+ end
+
+ class NamespaceError < RuntimeError #:nodoc:#
+ end
+
+ module Infl #:nodoc:#
+ # Ganked this from Inflector:
+ def self.camelize(lower_case_and_underscored_word)
+ lower_case_and_underscored_word.to_s.gsub(/\/(.?)/) { "::" + $1.upcase }.gsub(/(^|_)(.)/) { $2.upcase }
+ end
+ # Ganked this from Inflector:
+ def self.underscore(camel_cased_word)
+ camel_cased_word.to_s.gsub(/::/, '/').gsub(/([A-Z]+)([A-Z])/,'\1_\2').gsub(/([a-z\d])([A-Z])/,'\1_\2').downcase
+ end
+ end
+end
diff --git a/tests/vendor/ceedling/vendor/diy/lib/diy/factory.rb b/tests/vendor/ceedling/vendor/diy/lib/diy/factory.rb
new file mode 100644
index 000000000..d2566c5d1
--- /dev/null
+++ b/tests/vendor/ceedling/vendor/diy/lib/diy/factory.rb
@@ -0,0 +1,36 @@
+module DIY #:nodoc:#
+ class FactoryDef #:nodoc:
+ attr_accessor :name, :target, :class_name, :library
+
+ def initialize(opts)
+ @name, @target, @library, @auto_require =
+ opts[:name], opts[:target], opts[:library], opts[:auto_require]
+
+ @class_name = Infl.camelize(@target)
+ @library ||= Infl.underscore(@class_name) if @auto_require
+ end
+ end
+
+ class Context
+ def construct_factory(key)
+ factory_def = @defs[key]
+# puts "requiring #{factory_def.library}"
+ require factory_def.library if factory_def.library
+
+ big_c = get_class_for_name_with_module_delimeters(factory_def.class_name)
+
+ FactoryFactory.new(big_c)
+ end
+ end
+
+ class FactoryFactory
+ def initialize(clazz)
+ @class_to_create = clazz
+ end
+
+ def create(*args)
+ @class_to_create.new(*args)
+ end
+ end
+end
+
diff --git a/tests/vendor/ceedling/vendor/unity/auto/colour_prompt.rb b/tests/vendor/ceedling/vendor/unity/auto/colour_prompt.rb
new file mode 100644
index 000000000..81003dd59
--- /dev/null
+++ b/tests/vendor/ceedling/vendor/unity/auto/colour_prompt.rb
@@ -0,0 +1,94 @@
+# ==========================================
+# Unity Project - A Test Framework for C
+# Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams
+# [Released under MIT License. Please refer to license.txt for details]
+# ==========================================
+
+if RUBY_PLATFORM =~/(win|w)32$/
+ begin
+ require 'Win32API'
+ rescue LoadError
+ puts "ERROR! \"Win32API\" library not found"
+ puts "\"Win32API\" is required for colour on a windows machine"
+ puts " try => \"gem install Win32API\" on the command line"
+ puts
+ end
+ # puts
+ # puts 'Windows Environment Detected...'
+ # puts 'Win32API Library Found.'
+ # puts
+end
+
+class ColourCommandLine
+ def initialize
+ if RUBY_PLATFORM =~/(win|w)32$/
+ get_std_handle = Win32API.new("kernel32", "GetStdHandle", ['L'], 'L')
+ @set_console_txt_attrb =
+ Win32API.new("kernel32","SetConsoleTextAttribute",['L','N'], 'I')
+ @hout = get_std_handle.call(-11)
+ end
+ end
+
+ def change_to(new_colour)
+ if RUBY_PLATFORM =~/(win|w)32$/
+ @set_console_txt_attrb.call(@hout,self.win32_colour(new_colour))
+ else
+ "\033[30;#{posix_colour(new_colour)};22m"
+ end
+ end
+
+ def win32_colour(colour)
+ case colour
+ when :black then 0
+ when :dark_blue then 1
+ when :dark_green then 2
+ when :dark_cyan then 3
+ when :dark_red then 4
+ when :dark_purple then 5
+ when :dark_yellow, :narrative then 6
+ when :default_white, :default, :dark_white then 7
+ when :silver then 8
+ when :blue then 9
+ when :green, :success then 10
+ when :cyan, :output then 11
+ when :red, :failure then 12
+ when :purple then 13
+ when :yellow then 14
+ when :white then 15
+ else
+ 0
+ end
+ end
+
+ def posix_colour(colour)
+ case colour
+ when :black then 30
+ when :red, :failure then 31
+ when :green, :success then 32
+ when :yellow then 33
+ when :blue, :narrative then 34
+ when :purple, :magenta then 35
+ when :cyan, :output then 36
+ when :white, :default_white, :default then 37
+ else
+ 30
+ end
+ end
+
+ def out_c(mode, colour, str)
+ case RUBY_PLATFORM
+ when /(win|w)32$/
+ change_to(colour)
+ $stdout.puts str if mode == :puts
+ $stdout.print str if mode == :print
+ change_to(:default_white)
+ else
+ $stdout.puts("#{change_to(colour)}#{str}\033[0m") if mode == :puts
+ $stdout.print("#{change_to(colour)}#{str}\033[0m") if mode == :print
+ end
+ end
+end # ColourCommandLine
+
+def colour_puts(role,str) ColourCommandLine.new.out_c(:puts, role, str) end
+def colour_print(role,str) ColourCommandLine.new.out_c(:print, role, str) end
+
diff --git a/tests/vendor/ceedling/vendor/unity/auto/colour_reporter.rb b/tests/vendor/ceedling/vendor/unity/auto/colour_reporter.rb
new file mode 100644
index 000000000..5aa1d2775
--- /dev/null
+++ b/tests/vendor/ceedling/vendor/unity/auto/colour_reporter.rb
@@ -0,0 +1,39 @@
+# ==========================================
+# Unity Project - A Test Framework for C
+# Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams
+# [Released under MIT License. Please refer to license.txt for details]
+# ==========================================
+
+require "#{File.expand_path(File.dirname(__FILE__))}/colour_prompt"
+
+$colour_output = true
+
+def report(message)
+ if not $colour_output
+ $stdout.puts(message)
+ else
+ message = message.join('\n') if (message.class == Array)
+ message.each_line do |line|
+ line.chomp!
+ colour = case(line)
+ when /(?:total\s+)?tests:?\s+(\d+)\s+(?:total\s+)?failures:?\s+\d+\s+Ignored:?/i
+ ($1.to_i == 0) ? :green : :red
+ when /PASS/
+ :green
+ when /^OK$/
+ :green
+ when /(?:FAIL|ERROR)/
+ :red
+ when /IGNORE/
+ :yellow
+ when /^(?:Creating|Compiling|Linking)/
+ :white
+ else
+ :silver
+ end
+ colour_puts(colour, line)
+ end
+ end
+ $stdout.flush
+ $stderr.flush
+end
\ No newline at end of file
diff --git a/tests/vendor/ceedling/vendor/unity/auto/generate_config.yml b/tests/vendor/ceedling/vendor/unity/auto/generate_config.yml
new file mode 100644
index 000000000..4a5e47424
--- /dev/null
+++ b/tests/vendor/ceedling/vendor/unity/auto/generate_config.yml
@@ -0,0 +1,36 @@
+#this is a sample configuration file for generate_module
+#you would use it by calling generate_module with the -ygenerate_config.yml option
+#files like this are useful for customizing generate_module to your environment
+:generate_module:
+ :defaults:
+ #these defaults are used in place of any missing options at the command line
+ :path_src: ../src/
+ :path_inc: ../src/
+ :path_tst: ../test/
+ :update_svn: true
+ :includes:
+ #use [] for no additional includes, otherwise list the includes on separate lines
+ :src:
+ - Defs.h
+ - Board.h
+ :inc: []
+ :tst:
+ - Defs.h
+ - Board.h
+ - Exception.h
+ :boilerplates:
+ #these are inserted at the top of generated files.
+ #just comment out or remove if not desired.
+ #use %1$s where you would like the file name to appear (path/extension not included)
+ :src: |
+ //-------------------------------------------
+ // %1$s.c
+ //-------------------------------------------
+ :inc: |
+ //-------------------------------------------
+ // %1$s.h
+ //-------------------------------------------
+ :tst: |
+ //-------------------------------------------
+ // Test%1$s.c : Units tests for %1$s.c
+ //-------------------------------------------
diff --git a/tests/vendor/ceedling/vendor/unity/auto/generate_module.rb b/tests/vendor/ceedling/vendor/unity/auto/generate_module.rb
new file mode 100644
index 000000000..3db1a984c
--- /dev/null
+++ b/tests/vendor/ceedling/vendor/unity/auto/generate_module.rb
@@ -0,0 +1,202 @@
+# ==========================================
+# Unity Project - A Test Framework for C
+# Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams
+# [Released under MIT License. Please refer to license.txt for details]
+# ==========================================
+
+# This script creates all the files with start code necessary for a new module.
+# A simple module only requires a source file, header file, and test file.
+# Triad modules require a source, header, and test file for each triad type (like model, conductor, and hardware).
+
+require 'rubygems'
+require 'fileutils'
+
+HERE = File.expand_path(File.dirname(__FILE__)) + '/'
+
+#help text when requested
+HELP_TEXT = [ "\nGENERATE MODULE\n-------- ------",
+ "\nUsage: ruby generate_module [options] module_name",
+ " -i\"include\" sets the path to output headers to 'include' (DEFAULT ../src)",
+ " -s\"../src\" sets the path to output source to '../src' (DEFAULT ../src)",
+ " -t\"C:/test\" sets the path to output source to 'C:/test' (DEFAULT ../test)",
+ " -p\"MCH\" sets the output pattern to MCH.",
+ " dh - driver hardware.",
+ " dih - driver interrupt hardware.",
+ " mch - model conductor hardware.",
+ " mvp - model view presenter.",
+ " src - just a single source module. (DEFAULT)",
+ " -d destroy module instead of creating it.",
+ " -u update subversion too (requires subversion command line)",
+ " -y\"my.yml\" selects a different yaml config file for module generation",
+ "" ].join("\n")
+
+#Built in patterns
+PATTERNS = { 'src' => {'' => { :inc => [] } },
+ 'dh' => {'Driver' => { :inc => ['%1$sHardware.h'] },
+ 'Hardware' => { :inc => [] }
+ },
+ 'dih' => {'Driver' => { :inc => ['%1$sHardware.h', '%1$sInterrupt.h'] },
+ 'Interrupt'=> { :inc => ['%1$sHardware.h'] },
+ 'Hardware' => { :inc => [] }
+ },
+ 'mch' => {'Model' => { :inc => [] },
+ 'Conductor'=> { :inc => ['%1$sModel.h', '%1$sHardware.h'] },
+ 'Hardware' => { :inc => [] }
+ },
+ 'mvp' => {'Model' => { :inc => [] },
+ 'Presenter'=> { :inc => ['%1$sModel.h', '%1$sView.h'] },
+ 'View' => { :inc => [] }
+ }
+ }
+
+#TEMPLATE_TST
+TEMPLATE_TST = %q[#include "unity.h"
+%2$s#include "%1$s.h"
+
+void setUp(void)
+{
+}
+
+void tearDown(void)
+{
+}
+
+void test_%1$s_NeedToImplement(void)
+{
+ TEST_IGNORE();
+}
+]
+
+#TEMPLATE_SRC
+TEMPLATE_SRC = %q[%2$s#include "%1$s.h"
+]
+
+#TEMPLATE_INC
+TEMPLATE_INC = %q[#ifndef _%3$s_H
+#define _%3$s_H%2$s
+
+#endif // _%3$s_H
+]
+
+# Parse the command line parameters.
+ARGV.each do |arg|
+ case(arg)
+ when /^-d/ then @destroy = true
+ when /^-u/ then @update_svn = true
+ when /^-p(\w+)/ then @pattern = $1
+ when /^-s(.+)/ then @path_src = $1
+ when /^-i(.+)/ then @path_inc = $1
+ when /^-t(.+)/ then @path_tst = $1
+ when /^-y(.+)/ then @yaml_config = $1
+ when /^(\w+)/
+ raise "ERROR: You can't have more than one Module name specified!" unless @module_name.nil?
+ @module_name = arg
+ when /^-(h|-help)/
+ puts HELP_TEXT
+ exit
+ else
+ raise "ERROR: Unknown option specified '#{arg}'"
+ end
+end
+raise "ERROR: You must have a Module name specified! (use option -h for help)" if @module_name.nil?
+
+#load yaml file if one was requested
+if @yaml_config
+ require 'yaml'
+ cfg = YAML.load_file(HERE + @yaml_config)[:generate_module]
+ @path_src = cfg[:defaults][:path_src] if @path_src.nil?
+ @path_inc = cfg[:defaults][:path_inc] if @path_inc.nil?
+ @path_tst = cfg[:defaults][:path_tst] if @path_tst.nil?
+ @update_svn = cfg[:defaults][:update_svn] if @update_svn.nil?
+ @extra_inc = cfg[:includes]
+ @boilerplates = cfg[:boilerplates]
+else
+ @boilerplates = {}
+end
+
+# Create default file paths if none were provided
+@path_src = HERE + "../src/" if @path_src.nil?
+@path_inc = @path_src if @path_inc.nil?
+@path_tst = HERE + "../test/" if @path_tst.nil?
+@path_src += '/' unless (@path_src[-1] == 47)
+@path_inc += '/' unless (@path_inc[-1] == 47)
+@path_tst += '/' unless (@path_tst[-1] == 47)
+@pattern = 'src' if @pattern.nil?
+@includes = { :src => [], :inc => [], :tst => [] }
+@includes.merge!(@extra_inc) unless @extra_inc.nil?
+
+#create triad definition
+TRIAD = [ { :ext => '.c', :path => @path_src, :template => TEMPLATE_SRC, :inc => :src, :boilerplate => @boilerplates[:src] },
+ { :ext => '.h', :path => @path_inc, :template => TEMPLATE_INC, :inc => :inc, :boilerplate => @boilerplates[:inc] },
+ { :ext => '.c', :path => @path_tst+'Test', :template => TEMPLATE_TST, :inc => :tst, :boilerplate => @boilerplates[:tst] },
+ ]
+
+#prepare the pattern for use
+@patterns = PATTERNS[@pattern.downcase]
+raise "ERROR: The design pattern specified isn't one that I recognize!" if @patterns.nil?
+
+# Assemble the path/names of the files we need to work with.
+files = []
+TRIAD.each do |triad|
+ @patterns.each_pair do |pattern_file, pattern_traits|
+ files << {
+ :path => "#{triad[:path]}#{@module_name}#{pattern_file}#{triad[:ext]}",
+ :name => "#{@module_name}#{pattern_file}",
+ :template => triad[:template],
+ :boilerplate => triad[:boilerplate],
+ :includes => case(triad[:inc])
+ when :src then @includes[:src] | pattern_traits[:inc].map{|f| f % [@module_name]}
+ when :inc then @includes[:inc]
+ when :tst then @includes[:tst] | pattern_traits[:inc].map{|f| "Mock#{f}"% [@module_name]}
+ end
+ }
+ end
+end
+
+# destroy files if that was what was requested
+if @destroy
+ files.each do |filespec|
+ file = filespec[:path]
+ if File.exist?(file)
+ if @update_svn
+ `svn delete \"#{file}\" --force`
+ puts "File #{file} deleted and removed from source control"
+ else
+ FileUtils.remove(file)
+ puts "File #{file} deleted"
+ end
+ else
+ puts "File #{file} does not exist so cannot be removed."
+ end
+ end
+ puts "Destroy Complete"
+ exit
+end
+
+#Abort if any module already exists
+files.each do |file|
+ raise "ERROR: File #{file[:name]} already exists. Exiting." if File.exist?(file[:path])
+end
+
+# Create Source Modules
+files.each_with_index do |file, i|
+ File.open(file[:path], 'w') do |f|
+ f.write(file[:boilerplate] % [file[:name]]) unless file[:boilerplate].nil?
+ f.write(file[:template] % [ file[:name],
+ file[:includes].map{|f| "#include \"#{f}\"\n"}.join,
+ file[:name].upcase ]
+ )
+ end
+ if (@update_svn)
+ `svn add \"#{file[:path]}\"`
+ if $?.exitstatus == 0
+ puts "File #{file[:path]} created and added to source control"
+ else
+ puts "File #{file[:path]} created but FAILED adding to source control!"
+ end
+ else
+ puts "File #{file[:path]} created"
+ end
+end
+
+puts 'Generate Complete'
diff --git a/tests/vendor/ceedling/vendor/unity/auto/generate_test_runner.rb b/tests/vendor/ceedling/vendor/unity/auto/generate_test_runner.rb
new file mode 100644
index 000000000..0e05dfafe
--- /dev/null
+++ b/tests/vendor/ceedling/vendor/unity/auto/generate_test_runner.rb
@@ -0,0 +1,313 @@
+# ==========================================
+# Unity Project - A Test Framework for C
+# Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams
+# [Released under MIT License. Please refer to license.txt for details]
+# ==========================================
+
+File.expand_path(File.join(File.dirname(__FILE__),'colour_prompt'))
+
+class UnityTestRunnerGenerator
+
+ def initialize(options = nil)
+ @options = { :includes => [], :plugins => [], :framework => :unity }
+ case(options)
+ when NilClass then @options
+ when String then @options.merge!(UnityTestRunnerGenerator.grab_config(options))
+ when Hash then @options.merge!(options)
+ else raise "If you specify arguments, it should be a filename or a hash of options"
+ end
+ end
+
+ def self.grab_config(config_file)
+ options = { :includes => [], :plugins => [], :framework => :unity }
+ unless (config_file.nil? or config_file.empty?)
+ require 'yaml'
+ yaml_guts = YAML.load_file(config_file)
+ options.merge!(yaml_guts[:unity] ? yaml_guts[:unity] : yaml_guts[:cmock])
+ raise "No :unity or :cmock section found in #{config_file}" unless options
+ end
+ return(options)
+ end
+
+ def run(input_file, output_file, options=nil)
+ tests = []
+ testfile_includes = []
+ used_mocks = []
+
+ @options.merge!(options) unless options.nil?
+ module_name = File.basename(input_file)
+
+ #pull required data from source file
+ File.open(input_file, 'r') do |input|
+ tests = find_tests(input)
+ testfile_includes = find_includes(input)
+ used_mocks = find_mocks(testfile_includes)
+ end
+
+ #build runner file
+ generate(input_file, output_file, tests, used_mocks)
+
+ #determine which files were used to return them
+ all_files_used = [input_file, output_file]
+ all_files_used += testfile_includes.map {|filename| filename + '.c'} unless testfile_includes.empty?
+ all_files_used += @options[:includes] unless @options[:includes].empty?
+ return all_files_used.uniq
+ end
+
+ def generate(input_file, output_file, tests, used_mocks)
+ File.open(output_file, 'w') do |output|
+ create_header(output, used_mocks)
+ create_externs(output, tests, used_mocks)
+ create_mock_management(output, used_mocks)
+ create_suite_setup_and_teardown(output)
+ create_reset(output, used_mocks)
+ create_main(output, input_file, tests)
+ end
+ end
+
+ def find_tests(input_file)
+ tests_raw = []
+ tests_args = []
+ tests_and_line_numbers = []
+
+ input_file.rewind
+ source_raw = input_file.read
+ source_scrubbed = source_raw.gsub(/\/\/.*$/, '') # remove line comments
+ source_scrubbed = source_scrubbed.gsub(/\/\*.*?\*\//m, '') # remove block comments
+ lines = source_scrubbed.split(/(^\s*\#.*$) # Treat preprocessor directives as a logical line
+ | (;|\{|\}) /x) # Match ;, {, and } as end of lines
+
+ lines.each_with_index do |line, index|
+ #find tests
+ if line =~ /^((?:\s*TEST_CASE\s*\(.*?\)\s*)*)\s*void\s+(test.*?)\s*\(\s*(.*)\s*\)/
+ arguments = $1
+ name = $2
+ call = $3
+ args = nil
+ if (@options[:use_param_tests] and !arguments.empty?)
+ args = []
+ arguments.scan(/\s*TEST_CASE\s*\((.*)\)\s*$/) {|a| args << a[0]}
+ end
+ tests_and_line_numbers << { :test => name, :args => args, :call => call, :line_number => 0 }
+ tests_args = []
+ end
+ end
+
+ #determine line numbers and create tests to run
+ source_lines = source_raw.split("\n")
+ source_index = 0;
+ tests_and_line_numbers.size.times do |i|
+ source_lines[source_index..-1].each_with_index do |line, index|
+ if (line =~ /#{tests_and_line_numbers[i][:test]}/)
+ source_index += index
+ tests_and_line_numbers[i][:line_number] = source_index + 1
+ break
+ end
+ end
+ end
+
+ return tests_and_line_numbers
+ end
+
+ def find_includes(input_file)
+ input_file.rewind
+
+ #read in file
+ source = input_file.read
+
+ #remove comments (block and line, in three steps to ensure correct precedence)
+ source.gsub!(/\/\/(?:.+\/\*|\*(?:$|[^\/])).*$/, '') # remove line comments that comment out the start of blocks
+ source.gsub!(/\/\*.*?\*\//m, '') # remove block comments
+ source.gsub!(/\/\/.*$/, '') # remove line comments (all that remain)
+
+ #parse out includes
+ return source.scan(/^\s*#include\s+\"\s*(.+)\.[hH]\s*\"/).flatten
+ end
+
+ def find_mocks(includes)
+ mock_headers = []
+ includes.each do |include_file|
+ mock_headers << File.basename(include_file) if (include_file =~ /^mock/i)
+ end
+ return mock_headers
+ end
+
+ def create_header(output, mocks)
+ output.puts('/* AUTOGENERATED FILE. DO NOT EDIT. */')
+ create_runtest(output, mocks)
+ output.puts("\n//=======Automagically Detected Files To Include=====")
+ output.puts("#include \"#{@options[:framework].to_s}.h\"")
+ output.puts('#include "cmock.h"') unless (mocks.empty?)
+ @options[:includes].flatten.uniq.compact.each do |inc|
+ output.puts("#include #{inc.include?('<') ? inc : "\"#{inc.gsub('.h','')}.h\""}")
+ end
+ output.puts('#include ')
+ output.puts('#include ')
+ output.puts('#include "CException.h"') if @options[:plugins].include?(:cexception)
+ mocks.each do |mock|
+ output.puts("#include \"#{mock.gsub('.h','')}.h\"")
+ end
+ if @options[:enforce_strict_ordering]
+ output.puts('')
+ output.puts('int GlobalExpectCount;')
+ output.puts('int GlobalVerifyOrder;')
+ output.puts('char* GlobalOrderError;')
+ end
+ end
+
+ def create_externs(output, tests, mocks)
+ output.puts("\n//=======External Functions This Runner Calls=====")
+ output.puts("extern void setUp(void);")
+ output.puts("extern void tearDown(void);")
+ tests.each do |test|
+ output.puts("extern void #{test[:test]}(#{test[:call] || 'void'});")
+ end
+ output.puts('')
+ end
+
+ def create_mock_management(output, mocks)
+ unless (mocks.empty?)
+ output.puts("\n//=======Mock Management=====")
+ output.puts("static void CMock_Init(void)")
+ output.puts("{")
+ if @options[:enforce_strict_ordering]
+ output.puts(" GlobalExpectCount = 0;")
+ output.puts(" GlobalVerifyOrder = 0;")
+ output.puts(" GlobalOrderError = NULL;")
+ end
+ mocks.each do |mock|
+ output.puts(" #{mock}_Init();")
+ end
+ output.puts("}\n")
+
+ output.puts("static void CMock_Verify(void)")
+ output.puts("{")
+ mocks.each do |mock|
+ output.puts(" #{mock}_Verify();")
+ end
+ output.puts("}\n")
+
+ output.puts("static void CMock_Destroy(void)")
+ output.puts("{")
+ mocks.each do |mock|
+ output.puts(" #{mock}_Destroy();")
+ end
+ output.puts("}\n")
+ end
+ end
+
+ def create_suite_setup_and_teardown(output)
+ unless (@options[:suite_setup].nil?)
+ output.puts("\n//=======Suite Setup=====")
+ output.puts("static int suite_setup(void)")
+ output.puts("{")
+ output.puts(@options[:suite_setup])
+ output.puts("}")
+ end
+ unless (@options[:suite_teardown].nil?)
+ output.puts("\n//=======Suite Teardown=====")
+ output.puts("static int suite_teardown(int num_failures)")
+ output.puts("{")
+ output.puts(@options[:suite_teardown])
+ output.puts("}")
+ end
+ end
+
+ def create_runtest(output, used_mocks)
+ cexception = @options[:plugins].include? :cexception
+ va_args1 = @options[:use_param_tests] ? ', ...' : ''
+ va_args2 = @options[:use_param_tests] ? '__VA_ARGS__' : ''
+ output.puts("\n//=======Test Runner Used To Run Each Test Below=====")
+ output.puts("#define RUN_TEST_NO_ARGS") if @options[:use_param_tests]
+ output.puts("#define RUN_TEST(TestFunc, TestLineNum#{va_args1}) \\")
+ output.puts("{ \\")
+ output.puts(" Unity.CurrentTestName = #TestFunc#{va_args2.empty? ? '' : " \"(\" ##{va_args2} \")\""}; \\")
+ output.puts(" Unity.CurrentTestLineNumber = TestLineNum; \\")
+ output.puts(" Unity.NumberOfTests++; \\")
+ output.puts(" if (TEST_PROTECT()) \\")
+ output.puts(" { \\")
+ output.puts(" CEXCEPTION_T e; \\") if cexception
+ output.puts(" Try { \\") if cexception
+ output.puts(" CMock_Init(); \\") unless (used_mocks.empty?)
+ output.puts(" setUp(); \\")
+ output.puts(" TestFunc(#{va_args2}); \\")
+ output.puts(" CMock_Verify(); \\") unless (used_mocks.empty?)
+ output.puts(" } Catch(e) { TEST_ASSERT_EQUAL_HEX32_MESSAGE(CEXCEPTION_NONE, e, \"Unhandled Exception!\"); } \\") if cexception
+ output.puts(" } \\")
+ output.puts(" CMock_Destroy(); \\") unless (used_mocks.empty?)
+ output.puts(" if (TEST_PROTECT() && !TEST_IS_IGNORED) \\")
+ output.puts(" { \\")
+ output.puts(" tearDown(); \\")
+ output.puts(" } \\")
+ output.puts(" UnityConcludeTest(); \\")
+ output.puts("}\n")
+ end
+
+ def create_reset(output, used_mocks)
+ output.puts("\n//=======Test Reset Option=====")
+ output.puts("void resetTest()")
+ output.puts("{")
+ output.puts(" CMock_Verify();") unless (used_mocks.empty?)
+ output.puts(" CMock_Destroy();") unless (used_mocks.empty?)
+ output.puts(" tearDown();")
+ output.puts(" CMock_Init();") unless (used_mocks.empty?)
+ output.puts(" setUp();")
+ output.puts("}")
+ end
+
+ def create_main(output, filename, tests)
+ output.puts("\n\n//=======MAIN=====")
+ output.puts("int main(void)")
+ output.puts("{")
+ output.puts(" suite_setup();") unless @options[:suite_setup].nil?
+ output.puts(" Unity.TestFile = \"#{filename}\";")
+ output.puts(" UnityBegin();")
+ if (@options[:use_param_tests])
+ tests.each do |test|
+ if ((test[:args].nil?) or (test[:args].empty?))
+ output.puts(" RUN_TEST(#{test[:test]}, #{test[:line_number]}, RUN_TEST_NO_ARGS);")
+ else
+ test[:args].each {|args| output.puts(" RUN_TEST(#{test[:test]}, #{test[:line_number]}, #{args});")}
+ end
+ end
+ else
+ tests.each { |test| output.puts(" RUN_TEST(#{test[:test]}, #{test[:line_number]});") }
+ end
+ output.puts()
+ output.puts(" return #{@options[:suite_teardown].nil? ? "" : "suite_teardown"}(UnityEnd());")
+ output.puts("}")
+ end
+end
+
+
+if ($0 == __FILE__)
+ options = { :includes => [] }
+ yaml_file = nil
+
+ #parse out all the options first
+ ARGV.reject! do |arg|
+ case(arg)
+ when '-cexception'
+ options[:plugins] = [:cexception]; true
+ when /\.*\.yml/
+ options = UnityTestRunnerGenerator.grab_config(arg); true
+ else false
+ end
+ end
+
+ #make sure there is at least one parameter left (the input file)
+ if !ARGV[0]
+ puts ["usage: ruby #{__FILE__} (yaml) (options) input_test_file output_test_runner (includes)",
+ " blah.yml - will use config options in the yml file (see docs)",
+ " -cexception - include cexception support"].join("\n")
+ exit 1
+ end
+
+ #create the default test runner name if not specified
+ ARGV[1] = ARGV[0].gsub(".c","_Runner.c") if (!ARGV[1])
+
+ #everything else is an include file
+ options[:includes] ||= (ARGV.slice(2..-1).flatten.compact) if (ARGV.size > 2)
+
+ UnityTestRunnerGenerator.new(options).run(ARGV[0], ARGV[1])
+end
diff --git a/tests/vendor/ceedling/vendor/unity/auto/test_file_filter.rb b/tests/vendor/ceedling/vendor/unity/auto/test_file_filter.rb
new file mode 100644
index 000000000..3dbc26a28
--- /dev/null
+++ b/tests/vendor/ceedling/vendor/unity/auto/test_file_filter.rb
@@ -0,0 +1,23 @@
+# ==========================================
+# Unity Project - A Test Framework for C
+# Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams
+# [Released under MIT License. Please refer to license.txt for details]
+# ==========================================
+
+require'yaml'
+
+module RakefileHelpers
+ class TestFileFilter
+ def initialize(all_files = false)
+ @all_files = all_files
+ if not @all_files == true
+ if File.exist?('test_file_filter.yml')
+ filters = YAML.load_file( 'test_file_filter.yml' )
+ @all_files, @only_files, @exclude_files =
+ filters[:all_files], filters[:only_files], filters[:exclude_files]
+ end
+ end
+ end
+ attr_accessor :all_files, :only_files, :exclude_files
+ end
+end
diff --git a/tests/vendor/ceedling/vendor/unity/auto/unity_test_summary.rb b/tests/vendor/ceedling/vendor/unity/auto/unity_test_summary.rb
new file mode 100644
index 000000000..67f7a020b
--- /dev/null
+++ b/tests/vendor/ceedling/vendor/unity/auto/unity_test_summary.rb
@@ -0,0 +1,139 @@
+# ==========================================
+# Unity Project - A Test Framework for C
+# Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams
+# [Released under MIT License. Please refer to license.txt for details]
+# ==========================================
+
+#!/usr/bin/ruby
+#
+# unity_test_summary.rb
+#
+require 'fileutils'
+require 'set'
+
+class UnityTestSummary
+ include FileUtils::Verbose
+
+ attr_reader :report, :total_tests, :failures, :ignored
+
+ def initialize
+ @report = ''
+ @total_tests = 0
+ @failures = 0
+ @ignored = 0
+ end
+
+ def run
+ # Clean up result file names
+ results = @targets.map {|target| target.gsub(/\\/,'/')}
+
+ # Dig through each result file, looking for details on pass/fail:
+ failure_output = []
+ ignore_output = []
+
+ results.each do |result_file|
+ lines = File.readlines(result_file).map { |line| line.chomp }
+ if lines.length == 0
+ raise "Empty test result file: #{result_file}"
+ else
+ output = get_details(result_file, lines)
+ failure_output << output[:failures] unless output[:failures].empty?
+ ignore_output << output[:ignores] unless output[:ignores].empty?
+ tests,failures,ignored = parse_test_summary(lines)
+ @total_tests += tests
+ @failures += failures
+ @ignored += ignored
+ end
+ end
+
+ if @ignored > 0
+ @report += "\n"
+ @report += "--------------------------\n"
+ @report += "UNITY IGNORED TEST SUMMARY\n"
+ @report += "--------------------------\n"
+ @report += ignore_output.flatten.join("\n")
+ end
+
+ if @failures > 0
+ @report += "\n"
+ @report += "--------------------------\n"
+ @report += "UNITY FAILED TEST SUMMARY\n"
+ @report += "--------------------------\n"
+ @report += failure_output.flatten.join("\n")
+ end
+
+ @report += "\n"
+ @report += "--------------------------\n"
+ @report += "OVERALL UNITY TEST SUMMARY\n"
+ @report += "--------------------------\n"
+ @report += "#{@total_tests} TOTAL TESTS #{@failures} TOTAL FAILURES #{@ignored} IGNORED\n"
+ @report += "\n"
+ end
+
+ def set_targets(target_array)
+ @targets = target_array
+ end
+
+ def set_root_path(path)
+ @root = path
+ end
+
+ def usage(err_msg=nil)
+ puts "\nERROR: "
+ puts err_msg if err_msg
+ puts "\nUsage: unity_test_summary.rb result_file_directory/ root_path/"
+ puts " result_file_directory - The location of your results files."
+ puts " Defaults to current directory if not specified."
+ puts " Should end in / if specified."
+ puts " root_path - Helpful for producing more verbose output if using relative paths."
+ exit 1
+ end
+
+ protected
+
+ def get_details(result_file, lines)
+ results = { :failures => [], :ignores => [], :successes => [] }
+ lines.each do |line|
+ src_file,src_line,test_name,status,msg = line.split(/:/)
+ line_out = ((@root and (@root != 0)) ? "#{@root}#{line}" : line ).gsub(/\//, "\\")
+ case(status)
+ when 'IGNORE' then results[:ignores] << line_out
+ when 'FAIL' then results[:failures] << line_out
+ when 'PASS' then results[:successes] << line_out
+ end
+ end
+ return results
+ end
+
+ def parse_test_summary(summary)
+ if summary.find { |v| v =~ /(\d+) Tests (\d+) Failures (\d+) Ignored/ }
+ [$1.to_i,$2.to_i,$3.to_i]
+ else
+ raise "Couldn't parse test results: #{summary}"
+ end
+ end
+
+ def here; File.expand_path(File.dirname(__FILE__)); end
+
+end
+
+if $0 == __FILE__
+ uts = UnityTestSummary.new
+ begin
+ #look in the specified or current directory for result files
+ ARGV[0] ||= './'
+ targets = "#{ARGV[0].gsub(/\\/, '/')}*.test*"
+ results = Dir[targets]
+ raise "No *.testpass or *.testfail files found in '#{targets}'" if results.empty?
+ uts.set_targets(results)
+
+ #set the root path
+ ARGV[1] ||= File.expand_path(File.dirname(__FILE__)) + '/'
+ uts.set_root_path(ARGV[1])
+
+ #run the summarizer
+ puts uts.run
+ rescue Exception => e
+ uts.usage e.message
+ end
+end
diff --git a/tests/vendor/ceedling/vendor/unity/extras/fixture/readme.txt b/tests/vendor/ceedling/vendor/unity/extras/fixture/readme.txt
new file mode 100644
index 000000000..6b9a78c17
--- /dev/null
+++ b/tests/vendor/ceedling/vendor/unity/extras/fixture/readme.txt
@@ -0,0 +1,9 @@
+Copyright (c) 2010 James Grenning and Contributed to Unity Project
+
+Unity Project - A Test Framework for C
+Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams
+[Released under MIT License. Please refer to license.txt for details]
+
+This Framework is an optional add-on to Unity. By including unity_framework.h in place of unity.h,
+you may now work with Unity in a manner similar to CppUTest. This framework adds the concepts of
+test groups and gives finer control of your tests over the command line.
\ No newline at end of file
diff --git a/tests/vendor/ceedling/vendor/unity/extras/fixture/src/unity_fixture.c b/tests/vendor/ceedling/vendor/unity/extras/fixture/src/unity_fixture.c
new file mode 100644
index 000000000..fa2a298de
--- /dev/null
+++ b/tests/vendor/ceedling/vendor/unity/extras/fixture/src/unity_fixture.c
@@ -0,0 +1,377 @@
+//- Copyright (c) 2010 James Grenning and Contributed to Unity Project
+/* ==========================================
+ Unity Project - A Test Framework for C
+ Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams
+ [Released under MIT License. Please refer to license.txt for details]
+========================================== */
+
+#include "unity_fixture.h"
+#include "unity_internals.h"
+#include
+
+UNITY_FIXTURE_T UnityFixture;
+
+//If you decide to use the function pointer approach.
+int (*outputChar)(int) = putchar;
+
+int verbose = 0;
+
+void setUp(void) { /*does nothing*/ }
+void tearDown(void) { /*does nothing*/ }
+
+void announceTestRun(unsigned int runNumber)
+{
+ UnityPrint("Unity test run ");
+ UnityPrintNumber(runNumber+1);
+ UnityPrint(" of ");
+ UnityPrintNumber(UnityFixture.RepeatCount);
+ UNITY_OUTPUT_CHAR('\n');
+}
+
+int UnityMain(int argc, char* argv[], void (*runAllTests)())
+{
+ int result = UnityGetCommandLineOptions(argc, argv);
+ unsigned int r;
+ if (result != 0)
+ return result;
+
+ for (r = 0; r < UnityFixture.RepeatCount; r++)
+ {
+ announceTestRun(r);
+ UnityBegin();
+ runAllTests();
+ UNITY_OUTPUT_CHAR('\n');
+ UnityEnd();
+ }
+
+ return UnityFailureCount();
+}
+
+static int selected(const char * filter, const char * name)
+{
+ if (filter == 0)
+ return 1;
+ return strstr(name, filter) ? 1 : 0;
+}
+
+static int testSelected(const char* test)
+{
+ return selected(UnityFixture.NameFilter, test);
+}
+
+static int groupSelected(const char* group)
+{
+ return selected(UnityFixture.GroupFilter, group);
+}
+
+static void runTestCase()
+{
+
+}
+
+void UnityTestRunner(unityfunction* setup,
+ unityfunction* testBody,
+ unityfunction* teardown,
+ const char * printableName,
+ const char * group,
+ const char * name,
+ const char * file, int line)
+{
+ if (testSelected(name) && groupSelected(group))
+ {
+ Unity.CurrentTestFailed = 0;
+ Unity.TestFile = file;
+ Unity.CurrentTestName = printableName;
+ Unity.CurrentTestLineNumber = line;
+ if (!UnityFixture.Verbose)
+ UNITY_OUTPUT_CHAR('.');
+ else
+ UnityPrint(printableName);
+
+ Unity.NumberOfTests++;
+ UnityMalloc_StartTest();
+ UnityPointer_Init();
+
+ runTestCase();
+ if (TEST_PROTECT())
+ {
+ setup();
+ testBody();
+ }
+ if (TEST_PROTECT())
+ {
+ teardown();
+ }
+ if (TEST_PROTECT())
+ {
+ UnityPointer_UndoAllSets();
+ if (!Unity.CurrentTestFailed)
+ UnityMalloc_EndTest();
+ }
+ UnityConcludeFixtureTest();
+ }
+}
+
+void UnityIgnoreTest()
+{
+ Unity.NumberOfTests++;
+ Unity.CurrentTestIgnored = 1;
+ UNITY_OUTPUT_CHAR('!');
+}
+
+
+//-------------------------------------------------
+//Malloc and free stuff
+//
+#define MALLOC_DONT_FAIL -1
+static int malloc_count;
+static int malloc_fail_countdown = MALLOC_DONT_FAIL;
+
+void UnityMalloc_StartTest()
+{
+ malloc_count = 0;
+ malloc_fail_countdown = MALLOC_DONT_FAIL;
+}
+
+void UnityMalloc_EndTest()
+{
+ malloc_fail_countdown = MALLOC_DONT_FAIL;
+ if (malloc_count != 0)
+ {
+ TEST_FAIL_MESSAGE("This test leaks!");
+ }
+}
+
+void UnityMalloc_MakeMallocFailAfterCount(int countdown)
+{
+ malloc_fail_countdown = countdown;
+}
+
+#ifdef malloc
+#undef malloc
+#endif
+
+#ifdef free
+#undef free
+#endif
+
+#include
+#include
+
+typedef struct GuardBytes
+{
+ int size;
+ char guard[sizeof(int)];
+} Guard;
+
+
+static const char * end = "END";
+
+void * unity_malloc(size_t size)
+{
+ char* mem;
+ Guard* guard;
+
+ if (malloc_fail_countdown != MALLOC_DONT_FAIL)
+ {
+ if (malloc_fail_countdown == 0)
+ return 0;
+ malloc_fail_countdown--;
+ }
+
+ malloc_count++;
+
+ guard = (Guard*)malloc(size + sizeof(Guard) + 4);
+ guard->size = size;
+ mem = (char*)&(guard[1]);
+ memcpy(&mem[size], end, strlen(end) + 1);
+
+ return (void*)mem;
+}
+
+static int isOverrun(void * mem)
+{
+ Guard* guard = (Guard*)mem;
+ char* memAsChar = (char*)mem;
+ guard--;
+
+ return strcmp(&memAsChar[guard->size], end) != 0;
+}
+
+static void release_memory(void * mem)
+{
+ Guard* guard = (Guard*)mem;
+ guard--;
+
+ malloc_count--;
+ free(guard);
+}
+
+void unity_free(void * mem)
+{
+ int overrun = isOverrun(mem);//strcmp(&memAsChar[guard->size], end) != 0;
+ release_memory(mem);
+ if (overrun)
+ {
+ TEST_FAIL_MESSAGE("Buffer overrun detected during free()");
+ }
+}
+
+void* unity_calloc(size_t num, size_t size)
+{
+ void* mem = unity_malloc(num * size);
+ memset(mem, 0, num*size);
+ return mem;
+}
+
+void* unity_realloc(void * oldMem, size_t size)
+{
+ Guard* guard = (Guard*)oldMem;
+// char* memAsChar = (char*)oldMem;
+ void* newMem;
+
+ if (oldMem == 0)
+ return unity_malloc(size);
+
+ guard--;
+ if (isOverrun(oldMem))
+ {
+ release_memory(oldMem);
+ TEST_FAIL_MESSAGE("Buffer overrun detected during realloc()");
+ }
+
+ if (size == 0)
+ {
+ release_memory(oldMem);
+ return 0;
+ }
+
+ if (guard->size >= size)
+ return oldMem;
+
+ newMem = unity_malloc(size);
+ memcpy(newMem, oldMem, guard->size);
+ unity_free(oldMem);
+ return newMem;
+}
+
+
+//--------------------------------------------------------
+//Automatic pointer restoration functions
+typedef struct _PointerPair
+{
+ struct _PointerPair * next;
+ void ** pointer;
+ void * old_value;
+} PointerPair;
+
+enum {MAX_POINTERS=50};
+static PointerPair pointer_store[MAX_POINTERS];
+static int pointer_index = 0;
+
+void UnityPointer_Init()
+{
+ pointer_index = 0;
+}
+
+void UnityPointer_Set(void ** pointer, void * newValue)
+{
+ if (pointer_index >= MAX_POINTERS)
+ TEST_FAIL_MESSAGE("Too many pointers set");
+
+ pointer_store[pointer_index].pointer = pointer;
+ pointer_store[pointer_index].old_value = *pointer;
+ *pointer = newValue;
+ pointer_index++;
+}
+
+void UnityPointer_UndoAllSets()
+{
+ while (pointer_index > 0)
+ {
+ pointer_index--;
+ *(pointer_store[pointer_index].pointer) =
+ pointer_store[pointer_index].old_value;
+
+ }
+}
+
+int UnityFailureCount()
+{
+ return Unity.TestFailures;
+}
+
+int UnityGetCommandLineOptions(int argc, char* argv[])
+{
+ int i;
+ UnityFixture.Verbose = 0;
+ UnityFixture.GroupFilter = 0;
+ UnityFixture.NameFilter = 0;
+ UnityFixture.RepeatCount = 1;
+
+ if (argc == 1)
+ return 0;
+
+ for (i = 1; i < argc; )
+ {
+ if (strcmp(argv[i], "-v") == 0)
+ {
+ UnityFixture.Verbose = 1;
+ i++;
+ }
+ else if (strcmp(argv[i], "-g") == 0)
+ {
+ i++;
+ if (i >= argc)
+ return 1;
+ UnityFixture.GroupFilter = argv[i];
+ i++;
+ }
+ else if (strcmp(argv[i], "-n") == 0)
+ {
+ i++;
+ if (i >= argc)
+ return 1;
+ UnityFixture.NameFilter = argv[i];
+ i++;
+ }
+ else if (strcmp(argv[i], "-r") == 0)
+ {
+ UnityFixture.RepeatCount = 2;
+ i++;
+ if (i < argc)
+ {
+ if (*(argv[i]) >= '0' && *(argv[i]) <= '9')
+ {
+ UnityFixture.RepeatCount = atoi(argv[i]);
+ i++;
+ }
+ }
+ }
+ }
+ return 0;
+}
+
+void UnityConcludeFixtureTest()
+{
+ if (Unity.CurrentTestIgnored)
+ {
+ Unity.TestIgnores++;
+ }
+ else if (!Unity.CurrentTestFailed)
+ {
+ if (UnityFixture.Verbose)
+ {
+ UnityPrint(" PASS");
+ UNITY_OUTPUT_CHAR('\n');
+ }
+ }
+ else if (Unity.CurrentTestFailed)
+ {
+ Unity.TestFailures++;
+ }
+
+ Unity.CurrentTestFailed = 0;
+ Unity.CurrentTestIgnored = 0;
+}
+
diff --git a/tests/vendor/ceedling/vendor/unity/extras/fixture/src/unity_fixture.h b/tests/vendor/ceedling/vendor/unity/extras/fixture/src/unity_fixture.h
new file mode 100644
index 000000000..da1f871f8
--- /dev/null
+++ b/tests/vendor/ceedling/vendor/unity/extras/fixture/src/unity_fixture.h
@@ -0,0 +1,81 @@
+//- Copyright (c) 2010 James Grenning and Contributed to Unity Project
+/* ==========================================
+ Unity Project - A Test Framework for C
+ Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams
+ [Released under MIT License. Please refer to license.txt for details]
+========================================== */
+
+#ifndef UNITY_FIXTURE_H_
+#define UNITY_FIXTURE_H_
+
+#include "unity.h"
+#include "unity_internals.h"
+#include "unity_fixture_malloc_overrides.h"
+#include "unity_fixture_internals.h"
+
+int UnityMain(int argc, char* argv[], void (*runAllTests)());
+
+
+#define TEST_GROUP(group)\
+ int TEST_GROUP_##group = 0
+
+#define TEST_SETUP(group) void TEST_##group##_SETUP()
+
+#define TEST_TEAR_DOWN(group) void TEST_##group##_TEAR_DOWN()
+
+
+#define TEST(group, name) \
+ void TEST_##group##_##name##_();\
+ void TEST_##group##_##name##_run()\
+ {\
+ UnityTestRunner(TEST_##group##_SETUP,\
+ TEST_##group##_##name##_,\
+ TEST_##group##_TEAR_DOWN,\
+ "TEST(" #group ", " #name ")",\
+ #group, #name,\
+ __FILE__, __LINE__);\
+ }\
+ void TEST_##group##_##name##_()
+
+#define IGNORE_TEST(group, name) \
+ void TEST_##group##_##name##_();\
+ void TEST_##group##_##name##_run()\
+ {\
+ UnityIgnoreTest();\
+ }\
+ void TEST_##group##_##name##_()
+
+#define DECLARE_TEST_CASE(group, name) \
+ void TEST_##group##_##name##_run()
+
+#define RUN_TEST_CASE(group, name) \
+ DECLARE_TEST_CASE(group, name);\
+ TEST_##group##_##name##_run();
+
+//This goes at the bottom of each test file or in a separate c file
+#define TEST_GROUP_RUNNER(group)\
+ void TEST_##group##_GROUP_RUNNER_runAll();\
+ void TEST_##group##_GROUP_RUNNER()\
+ {\
+ TEST_##group##_GROUP_RUNNER_runAll();\
+ }\
+ void TEST_##group##_GROUP_RUNNER_runAll()
+
+//Call this from main
+#define RUN_TEST_GROUP(group)\
+ void TEST_##group##_GROUP_RUNNER();\
+ TEST_##group##_GROUP_RUNNER();
+
+//CppUTest Compatibility Macros
+#define UT_PTR_SET(ptr, newPointerValue) UnityPointer_Set((void**)&ptr, (void*)newPointerValue)
+#define TEST_ASSERT_POINTERS_EQUAL(expected, actual) TEST_ASSERT_EQUAL_PTR(expected, actual)
+#define TEST_ASSERT_BYTES_EQUAL(expected, actual) TEST_ASSERT_EQUAL_HEX8(0xff & (expected), 0xff & (actual))
+#define FAIL(message) TEST_FAIL((message))
+#define CHECK(condition) TEST_ASSERT_TRUE((condition))
+#define LONGS_EQUAL(expected, actual) TEST_ASSERT_EQUAL_INT((expected), (actual))
+#define STRCMP_EQUAL(expected, actual) TEST_ASSERT_EQUAL_STRING((expected), (actual))
+#define DOUBLES_EQUAL(expected, actual, delta) TEST_ASSERT_FLOAT_WITHIN(((expected), (actual), (delta))
+
+void UnityMalloc_MakeMallocFailAfterCount(int count);
+
+#endif /* UNITY_FIXTURE_H_ */
diff --git a/tests/vendor/ceedling/vendor/unity/extras/fixture/src/unity_fixture_internals.h b/tests/vendor/ceedling/vendor/unity/extras/fixture/src/unity_fixture_internals.h
new file mode 100644
index 000000000..db23f67c8
--- /dev/null
+++ b/tests/vendor/ceedling/vendor/unity/extras/fixture/src/unity_fixture_internals.h
@@ -0,0 +1,44 @@
+//- Copyright (c) 2010 James Grenning and Contributed to Unity Project
+/* ==========================================
+ Unity Project - A Test Framework for C
+ Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams
+ [Released under MIT License. Please refer to license.txt for details]
+========================================== */
+
+#ifndef UNITY_FIXTURE_INTERNALS_H_
+#define UNITY_FIXTURE_INTERNALS_H_
+
+typedef struct _UNITY_FIXTURE_T
+{
+ int Verbose;
+ unsigned int RepeatCount;
+ const char* NameFilter;
+ const char* GroupFilter;
+} UNITY_FIXTURE_T;
+
+typedef void unityfunction();
+void UnityTestRunner(unityfunction * setup,
+ unityfunction * body,
+ unityfunction * teardown,
+ const char * printableName,
+ const char * group,
+ const char * name,
+ const char * file, int line);
+
+void UnityIgnoreTest();
+void UnityMalloc_StartTest();
+void UnityMalloc_EndTest();
+int UnityFailureCount();
+int UnityGetCommandLineOptions(int argc, char* argv[]);
+void UnityConcludeFixtureTest();
+
+void UnityPointer_Set(void ** ptr, void * newValue);
+void UnityPointer_UndoAllSets();
+void UnityPointer_Init();
+
+void UnityAssertEqualPointer(const void * expected,
+ const void * actual,
+ const char* msg,
+ const UNITY_LINE_TYPE lineNumber);
+
+#endif /* UNITY_FIXTURE_INTERNALS_H_ */
diff --git a/tests/vendor/ceedling/vendor/unity/extras/fixture/src/unity_fixture_malloc_overrides.h b/tests/vendor/ceedling/vendor/unity/extras/fixture/src/unity_fixture_malloc_overrides.h
new file mode 100644
index 000000000..38f8e34d6
--- /dev/null
+++ b/tests/vendor/ceedling/vendor/unity/extras/fixture/src/unity_fixture_malloc_overrides.h
@@ -0,0 +1,16 @@
+//- Copyright (c) 2010 James Grenning and Contributed to Unity Project
+/* ==========================================
+ Unity Project - A Test Framework for C
+ Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams
+ [Released under MIT License. Please refer to license.txt for details]
+========================================== */
+
+#ifndef UNITY_FIXTURE_MALLOC_OVERRIDES_H_
+#define UNITY_FIXTURE_MALLOC_OVERRIDES_H_
+
+#define malloc unity_malloc
+#define calloc unity_calloc
+#define realloc unity_realloc
+#define free unity_free
+
+#endif /* UNITY_FIXTURE_MALLOC_OVERRIDES_H_ */
diff --git a/tests/vendor/ceedling/vendor/unity/release/build.info b/tests/vendor/ceedling/vendor/unity/release/build.info
new file mode 100644
index 000000000..7871b21d2
--- /dev/null
+++ b/tests/vendor/ceedling/vendor/unity/release/build.info
@@ -0,0 +1,2 @@
+118
+
diff --git a/tests/vendor/ceedling/vendor/unity/release/version.info b/tests/vendor/ceedling/vendor/unity/release/version.info
new file mode 100644
index 000000000..6b2d34907
--- /dev/null
+++ b/tests/vendor/ceedling/vendor/unity/release/version.info
@@ -0,0 +1,2 @@
+2.1.0
+
diff --git a/tests/vendor/ceedling/vendor/unity/src/unity.c b/tests/vendor/ceedling/vendor/unity/src/unity.c
new file mode 100644
index 000000000..82a9fb7da
--- /dev/null
+++ b/tests/vendor/ceedling/vendor/unity/src/unity.c
@@ -0,0 +1,979 @@
+/* ==========================================
+ Unity Project - A Test Framework for C
+ Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams
+ [Released under MIT License. Please refer to license.txt for details]
+========================================== */
+
+#include "unity.h"
+#include
+#include
+
+#define UNITY_FAIL_AND_BAIL { Unity.CurrentTestFailed = 1; UNITY_OUTPUT_CHAR('\n'); longjmp(Unity.AbortFrame, 1); }
+#define UNITY_IGNORE_AND_BAIL { Unity.CurrentTestIgnored = 1; UNITY_OUTPUT_CHAR('\n'); longjmp(Unity.AbortFrame, 1); }
+/// return prematurely if we are already in failure or ignore state
+#define UNITY_SKIP_EXECUTION { if ((Unity.CurrentTestFailed != 0) || (Unity.CurrentTestIgnored != 0)) {return;} }
+#define UNITY_PRINT_EOL { UNITY_OUTPUT_CHAR('\n'); }
+
+struct _Unity Unity = { 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , { 0 } };
+
+const char* UnityStrNull = "NULL";
+const char* UnityStrSpacer = ". ";
+const char* UnityStrExpected = " Expected ";
+const char* UnityStrWas = " Was ";
+const char* UnityStrTo = " To ";
+const char* UnityStrElement = " Element ";
+const char* UnityStrByte = " Byte ";
+const char* UnityStrMemory = " Memory Mismatch.";
+const char* UnityStrDelta = " Values Not Within Delta ";
+const char* UnityStrPointless= " You Asked Me To Compare Nothing, Which Was Pointless.";
+const char* UnityStrNullPointerForExpected= " Expected pointer to be NULL";
+const char* UnityStrNullPointerForActual = " Actual pointer was NULL";
+
+// compiler-generic print formatting masks
+const _U_UINT UnitySizeMask[] =
+{
+ 255u, // 0xFF
+ 65535u, // 0xFFFF
+ 65535u,
+ 4294967295u, // 0xFFFFFFFF
+ 4294967295u,
+ 4294967295u,
+ 4294967295u
+#ifdef UNITY_SUPPORT_64
+ ,0xFFFFFFFFFFFFFFFF
+#endif
+};
+
+void UnityPrintFail(void);
+void UnityPrintOk(void);
+
+//-----------------------------------------------
+// Pretty Printers & Test Result Output Handlers
+//-----------------------------------------------
+
+void UnityPrint(const char* string)
+{
+ const char* pch = string;
+
+ if (pch != NULL)
+ {
+ while (*pch)
+ {
+ // printable characters plus CR & LF are printed
+ if ((*pch <= 126) && (*pch >= 32))
+ {
+ UNITY_OUTPUT_CHAR(*pch);
+ }
+ //write escaped carriage returns
+ else if (*pch == 13)
+ {
+ UNITY_OUTPUT_CHAR('\\');
+ UNITY_OUTPUT_CHAR('r');
+ }
+ //write escaped line feeds
+ else if (*pch == 10)
+ {
+ UNITY_OUTPUT_CHAR('\\');
+ UNITY_OUTPUT_CHAR('n');
+ }
+ // unprintable characters are shown as codes
+ else
+ {
+ UNITY_OUTPUT_CHAR('\\');
+ UnityPrintNumberHex((_U_SINT)*pch, 2);
+ }
+ pch++;
+ }
+ }
+}
+
+//-----------------------------------------------
+void UnityPrintNumberByStyle(const _U_SINT number, const UNITY_DISPLAY_STYLE_T style)
+{
+ if ((style & UNITY_DISPLAY_RANGE_INT) == UNITY_DISPLAY_RANGE_INT)
+ {
+ UnityPrintNumber(number);
+ }
+ else if ((style & UNITY_DISPLAY_RANGE_UINT) == UNITY_DISPLAY_RANGE_UINT)
+ {
+ UnityPrintNumberUnsigned( (_U_UINT)number & UnitySizeMask[((_U_UINT)style & (_U_UINT)0x0F) - 1] );
+ }
+ else
+ {
+ UnityPrintNumberHex((_U_UINT)number, (style & 0x000F) << 1);
+ }
+}
+
+//-----------------------------------------------
+/// basically do an itoa using as little ram as possible
+void UnityPrintNumber(const _U_SINT number_to_print)
+{
+ _U_SINT divisor = 1;
+ _U_SINT next_divisor;
+ _U_SINT number = number_to_print;
+
+ if (number < 0)
+ {
+ UNITY_OUTPUT_CHAR('-');
+ number = -number;
+ }
+
+ // figure out initial divisor
+ while (number / divisor > 9)
+ {
+ next_divisor = divisor * 10;
+ if (next_divisor > divisor)
+ divisor = next_divisor;
+ else
+ break;
+ }
+
+ // now mod and print, then divide divisor
+ do
+ {
+ UNITY_OUTPUT_CHAR((char)('0' + (number / divisor % 10)));
+ divisor /= 10;
+ }
+ while (divisor > 0);
+}
+
+//-----------------------------------------------
+/// basically do an itoa using as little ram as possible
+void UnityPrintNumberUnsigned(const _U_UINT number)
+{
+ _U_UINT divisor = 1;
+ _U_UINT next_divisor;
+
+ // figure out initial divisor
+ while (number / divisor > 9)
+ {
+ next_divisor = divisor * 10;
+ if (next_divisor > divisor)
+ divisor = next_divisor;
+ else
+ break;
+ }
+
+ // now mod and print, then divide divisor
+ do
+ {
+ UNITY_OUTPUT_CHAR((char)('0' + (number / divisor % 10)));
+ divisor /= 10;
+ }
+ while (divisor > 0);
+}
+
+//-----------------------------------------------
+void UnityPrintNumberHex(const _U_UINT number, const char nibbles_to_print)
+{
+ _U_UINT nibble;
+ char nibbles = nibbles_to_print;
+ UNITY_OUTPUT_CHAR('0');
+ UNITY_OUTPUT_CHAR('x');
+
+ while (nibbles > 0)
+ {
+ nibble = (number >> (--nibbles << 2)) & 0x0000000F;
+ if (nibble <= 9)
+ {
+ UNITY_OUTPUT_CHAR((char)('0' + nibble));
+ }
+ else
+ {
+ UNITY_OUTPUT_CHAR((char)('A' - 10 + nibble));
+ }
+ }
+}
+
+//-----------------------------------------------
+void UnityPrintMask(const _U_UINT mask, const _U_UINT number)
+{
+ _U_UINT current_bit = (_U_UINT)1 << (UNITY_INT_WIDTH - 1);
+ _US32 i;
+
+ for (i = 0; i < UNITY_INT_WIDTH; i++)
+ {
+ if (current_bit & mask)
+ {
+ if (current_bit & number)
+ {
+ UNITY_OUTPUT_CHAR('1');
+ }
+ else
+ {
+ UNITY_OUTPUT_CHAR('0');
+ }
+ }
+ else
+ {
+ UNITY_OUTPUT_CHAR('X');
+ }
+ current_bit = current_bit >> 1;
+ }
+}
+
+//-----------------------------------------------
+#ifdef UNITY_FLOAT_VERBOSE
+void UnityPrintFloat(_UF number)
+{
+ char TempBuffer[32];
+ sprintf(TempBuffer, "%.6f", number);
+ UnityPrint(TempBuffer);
+}
+#endif
+
+//-----------------------------------------------
+
+void UnityPrintFail(void)
+{
+ UnityPrint("FAIL");
+}
+
+void UnityPrintOk(void)
+{
+ UnityPrint("OK");
+}
+
+//-----------------------------------------------
+void UnityTestResultsBegin(const char* file, const UNITY_LINE_TYPE line)
+{
+ UnityPrint(file);
+ UNITY_OUTPUT_CHAR(':');
+ UnityPrintNumber(line);
+ UNITY_OUTPUT_CHAR(':');
+ UnityPrint(Unity.CurrentTestName);
+ UNITY_OUTPUT_CHAR(':');
+}
+
+//-----------------------------------------------
+void UnityTestResultsFailBegin(const UNITY_LINE_TYPE line)
+{
+ UnityTestResultsBegin(Unity.TestFile, line);
+ UnityPrint("FAIL:");
+}
+
+//-----------------------------------------------
+void UnityConcludeTest(void)
+{
+ if (Unity.CurrentTestIgnored)
+ {
+ Unity.TestIgnores++;
+ }
+ else if (!Unity.CurrentTestFailed)
+ {
+ UnityTestResultsBegin(Unity.TestFile, Unity.CurrentTestLineNumber);
+ UnityPrint("PASS");
+ UNITY_PRINT_EOL;
+ }
+ else
+ {
+ Unity.TestFailures++;
+ }
+
+ Unity.CurrentTestFailed = 0;
+ Unity.CurrentTestIgnored = 0;
+}
+
+//-----------------------------------------------
+void UnityAddMsgIfSpecified(const char* msg)
+{
+ if (msg)
+ {
+ UnityPrint(UnityStrSpacer);
+ UnityPrint(msg);
+ }
+}
+
+//-----------------------------------------------
+void UnityPrintExpectedAndActualStrings(const char* expected, const char* actual)
+{
+ UnityPrint(UnityStrExpected);
+ if (expected != NULL)
+ {
+ UNITY_OUTPUT_CHAR('\'');
+ UnityPrint(expected);
+ UNITY_OUTPUT_CHAR('\'');
+ }
+ else
+ {
+ UnityPrint(UnityStrNull);
+ }
+ UnityPrint(UnityStrWas);
+ if (actual != NULL)
+ {
+ UNITY_OUTPUT_CHAR('\'');
+ UnityPrint(actual);
+ UNITY_OUTPUT_CHAR('\'');
+ }
+ else
+ {
+ UnityPrint(UnityStrNull);
+ }
+}
+
+//-----------------------------------------------
+// Assertion & Control Helpers
+//-----------------------------------------------
+
+int UnityCheckArraysForNull(const void* expected, const void* actual, const UNITY_LINE_TYPE lineNumber, const char* msg)
+{
+ //return true if they are both NULL
+ if ((expected == NULL) && (actual == NULL))
+ return 1;
+
+ //throw error if just expected is NULL
+ if (expected == NULL)
+ {
+ UnityTestResultsFailBegin(lineNumber);
+ UnityPrint(UnityStrNullPointerForExpected);
+ UnityAddMsgIfSpecified(msg);
+ UNITY_FAIL_AND_BAIL;
+ }
+
+ //throw error if just actual is NULL
+ if (actual == NULL)
+ {
+ UnityTestResultsFailBegin(lineNumber);
+ UnityPrint(UnityStrNullPointerForActual);
+ UnityAddMsgIfSpecified(msg);
+ UNITY_FAIL_AND_BAIL;
+ }
+
+ //return false if neither is NULL
+ return 0;
+}
+
+//-----------------------------------------------
+// Assertion Functions
+//-----------------------------------------------
+
+void UnityAssertBits(const _U_SINT mask,
+ const _U_SINT expected,
+ const _U_SINT actual,
+ const char* msg,
+ const UNITY_LINE_TYPE lineNumber)
+{
+ UNITY_SKIP_EXECUTION;
+
+ if ((mask & expected) != (mask & actual))
+ {
+ UnityTestResultsFailBegin(lineNumber);
+ UnityPrint(UnityStrExpected);
+ UnityPrintMask(mask, expected);
+ UnityPrint(UnityStrWas);
+ UnityPrintMask(mask, actual);
+ UnityAddMsgIfSpecified(msg);
+ UNITY_FAIL_AND_BAIL;
+ }
+}
+
+//-----------------------------------------------
+void UnityAssertEqualNumber(const _U_SINT expected,
+ const _U_SINT actual,
+ const char* msg,
+ const UNITY_LINE_TYPE lineNumber,
+ const UNITY_DISPLAY_STYLE_T style)
+{
+ UNITY_SKIP_EXECUTION;
+
+ if (expected != actual)
+ {
+ UnityTestResultsFailBegin(lineNumber);
+ UnityPrint(UnityStrExpected);
+ UnityPrintNumberByStyle(expected, style);
+ UnityPrint(UnityStrWas);
+ UnityPrintNumberByStyle(actual, style);
+ UnityAddMsgIfSpecified(msg);
+ UNITY_FAIL_AND_BAIL;
+ }
+}
+
+//-----------------------------------------------
+void UnityAssertEqualIntArray(const _U_SINT* expected,
+ const _U_SINT* actual,
+ const _UU32 num_elements,
+ const char* msg,
+ const UNITY_LINE_TYPE lineNumber,
+ const UNITY_DISPLAY_STYLE_T style)
+{
+ _UU32 elements = num_elements;
+ const _US8* ptr_exp = (_US8*)expected;
+ const _US8* ptr_act = (_US8*)actual;
+
+ UNITY_SKIP_EXECUTION;
+
+ if (elements == 0)
+ {
+ UnityTestResultsFailBegin(lineNumber);
+ UnityPrint(UnityStrPointless);
+ UnityAddMsgIfSpecified(msg);
+ UNITY_FAIL_AND_BAIL;
+ }
+
+ if (UnityCheckArraysForNull((void*)expected, (void*)actual, lineNumber, msg) == 1)
+ return;
+
+ switch(style)
+ {
+ case UNITY_DISPLAY_STYLE_HEX8:
+ case UNITY_DISPLAY_STYLE_INT8:
+ case UNITY_DISPLAY_STYLE_UINT8:
+ while (elements--)
+ {
+ if (*ptr_exp != *ptr_act)
+ {
+ UnityTestResultsFailBegin(lineNumber);
+ UnityPrint(UnityStrElement);
+ UnityPrintNumberByStyle((num_elements - elements - 1), UNITY_DISPLAY_STYLE_UINT);
+ UnityPrint(UnityStrExpected);
+ UnityPrintNumberByStyle(*ptr_exp, style);
+ UnityPrint(UnityStrWas);
+ UnityPrintNumberByStyle(*ptr_act, style);
+ UnityAddMsgIfSpecified(msg);
+ UNITY_FAIL_AND_BAIL;
+ }
+ ptr_exp += 1;
+ ptr_act += 1;
+ }
+ break;
+ case UNITY_DISPLAY_STYLE_HEX16:
+ case UNITY_DISPLAY_STYLE_INT16:
+ case UNITY_DISPLAY_STYLE_UINT16:
+ while (elements--)
+ {
+ if (*(_US16*)ptr_exp != *(_US16*)ptr_act)
+ {
+ UnityTestResultsFailBegin(lineNumber);
+ UnityPrint(UnityStrElement);
+ UnityPrintNumberByStyle((num_elements - elements - 1), UNITY_DISPLAY_STYLE_UINT);
+ UnityPrint(UnityStrExpected);
+ UnityPrintNumberByStyle(*(_US16*)ptr_exp, style);
+ UnityPrint(UnityStrWas);
+ UnityPrintNumberByStyle(*(_US16*)ptr_act, style);
+ UnityAddMsgIfSpecified(msg);
+ UNITY_FAIL_AND_BAIL;
+ }
+ ptr_exp += 2;
+ ptr_act += 2;
+ }
+ break;
+#ifdef UNITY_SUPPORT_64
+ case UNITY_DISPLAY_STYLE_HEX64:
+ case UNITY_DISPLAY_STYLE_INT64:
+ case UNITY_DISPLAY_STYLE_UINT64:
+ while (elements--)
+ {
+ if (*(_US64*)ptr_exp != *(_US64*)ptr_act)
+ {
+ UnityTestResultsFailBegin(lineNumber);
+ UnityPrint(UnityStrElement);
+ UnityPrintNumberByStyle((num_elements - elements - 1), UNITY_DISPLAY_STYLE_UINT);
+ UnityPrint(UnityStrExpected);
+ UnityPrintNumberByStyle(*(_US64*)ptr_exp, style);
+ UnityPrint(UnityStrWas);
+ UnityPrintNumberByStyle(*(_US64*)ptr_act, style);
+ UnityAddMsgIfSpecified(msg);
+ UNITY_FAIL_AND_BAIL;
+ }
+ ptr_exp += 8;
+ ptr_act += 8;
+ }
+ break;
+#endif
+ default:
+ while (elements--)
+ {
+ if (*(_US32*)ptr_exp != *(_US32*)ptr_act)
+ {
+ UnityTestResultsFailBegin(lineNumber);
+ UnityPrint(UnityStrElement);
+ UnityPrintNumberByStyle((num_elements - elements - 1), UNITY_DISPLAY_STYLE_UINT);
+ UnityPrint(UnityStrExpected);
+ UnityPrintNumberByStyle(*(_US32*)ptr_exp, style);
+ UnityPrint(UnityStrWas);
+ UnityPrintNumberByStyle(*(_US32*)ptr_act, style);
+ UnityAddMsgIfSpecified(msg);
+ UNITY_FAIL_AND_BAIL;
+ }
+ ptr_exp += 4;
+ ptr_act += 4;
+ }
+ break;
+ }
+}
+
+//-----------------------------------------------
+#ifndef UNITY_EXCLUDE_FLOAT
+void UnityAssertEqualFloatArray(const _UF* expected,
+ const _UF* actual,
+ const _UU32 num_elements,
+ const char* msg,
+ const UNITY_LINE_TYPE lineNumber)
+{
+ _UU32 elements = num_elements;
+ const _UF* ptr_expected = expected;
+ const _UF* ptr_actual = actual;
+ _UF diff, tol;
+
+ UNITY_SKIP_EXECUTION;
+
+ if (elements == 0)
+ {
+ UnityTestResultsFailBegin(lineNumber);
+ UnityPrint(UnityStrPointless);
+ UnityAddMsgIfSpecified(msg);
+ UNITY_FAIL_AND_BAIL;
+ }
+
+ if (UnityCheckArraysForNull((void*)expected, (void*)actual, lineNumber, msg) == 1)
+ return;
+
+ while (elements--)
+ {
+ diff = *ptr_expected - *ptr_actual;
+ if (diff < 0.0)
+ diff = 0.0 - diff;
+ tol = UNITY_FLOAT_PRECISION * *ptr_expected;
+ if (tol < 0.0)
+ tol = 0.0 - tol;
+ if (diff > tol)
+ {
+ UnityTestResultsFailBegin(lineNumber);
+ UnityPrint(UnityStrElement);
+ UnityPrintNumberByStyle((num_elements - elements - 1), UNITY_DISPLAY_STYLE_UINT);
+#ifdef UNITY_FLOAT_VERBOSE
+ UnityPrint(UnityStrExpected);
+ UnityPrintFloat(*ptr_expected);
+ UnityPrint(UnityStrWas);
+ UnityPrintFloat(*ptr_actual);
+#else
+ UnityPrint(UnityStrDelta);
+#endif
+ UnityAddMsgIfSpecified(msg);
+ UNITY_FAIL_AND_BAIL;
+ }
+ ptr_expected++;
+ ptr_actual++;
+ }
+}
+
+//-----------------------------------------------
+void UnityAssertFloatsWithin(const _UF delta,
+ const _UF expected,
+ const _UF actual,
+ const char* msg,
+ const UNITY_LINE_TYPE lineNumber)
+{
+ _UF diff = actual - expected;
+ _UF pos_delta = delta;
+
+ UNITY_SKIP_EXECUTION;
+
+ if (diff < 0)
+ {
+ diff = 0.0f - diff;
+ }
+ if (pos_delta < 0)
+ {
+ pos_delta = 0.0f - pos_delta;
+ }
+
+ if (pos_delta < diff)
+ {
+ UnityTestResultsFailBegin(lineNumber);
+#ifdef UNITY_FLOAT_VERBOSE
+ UnityPrint(UnityStrExpected);
+ UnityPrintFloat(expected);
+ UnityPrint(UnityStrWas);
+ UnityPrintFloat(actual);
+#else
+ UnityPrint(UnityStrDelta);
+#endif
+ UnityAddMsgIfSpecified(msg);
+ UNITY_FAIL_AND_BAIL;
+ }
+}
+
+#endif //not UNITY_EXCLUDE_FLOAT
+
+//-----------------------------------------------
+#ifndef UNITY_EXCLUDE_DOUBLE
+void UnityAssertEqualDoubleArray(const _UD* expected,
+ const _UD* actual,
+ const _UU32 num_elements,
+ const char* msg,
+ const UNITY_LINE_TYPE lineNumber)
+{
+ _UU32 elements = num_elements;
+ const _UD* ptr_expected = expected;
+ const _UD* ptr_actual = actual;
+ _UD diff, tol;
+
+ UNITY_SKIP_EXECUTION;
+
+ if (elements == 0)
+ {
+ UnityTestResultsFailBegin(lineNumber);
+ UnityPrint(UnityStrPointless);
+ UnityAddMsgIfSpecified(msg);
+ UNITY_FAIL_AND_BAIL;
+ }
+
+ if (UnityCheckArraysForNull((void*)expected, (void*)actual, lineNumber, msg) == 1)
+ return;
+
+ while (elements--)
+ {
+ diff = *ptr_expected - *ptr_actual;
+ if (diff < 0.0)
+ diff = 0.0 - diff;
+ tol = UNITY_DOUBLE_PRECISION * *ptr_expected;
+ if (tol < 0.0)
+ tol = 0.0 - tol;
+ if (diff > tol)
+ {
+ UnityTestResultsFailBegin(lineNumber);
+ UnityPrint(UnityStrElement);
+ UnityPrintNumberByStyle((num_elements - elements - 1), UNITY_DISPLAY_STYLE_UINT);
+#ifdef UNITY_DOUBLE_VERBOSE
+ UnityPrint(UnityStrExpected);
+ UnityPrintFloat((float)(*ptr_expected));
+ UnityPrint(UnityStrWas);
+ UnityPrintFloat((float)(*ptr_actual));
+#else
+ UnityPrint(UnityStrDelta);
+#endif
+ UnityAddMsgIfSpecified(msg);
+ UNITY_FAIL_AND_BAIL;
+ }
+ ptr_expected++;
+ ptr_actual++;
+ }
+}
+
+//-----------------------------------------------
+void UnityAssertDoublesWithin(const _UD delta,
+ const _UD expected,
+ const _UD actual,
+ const char* msg,
+ const UNITY_LINE_TYPE lineNumber)
+{
+ _UD diff = actual - expected;
+ _UD pos_delta = delta;
+
+ UNITY_SKIP_EXECUTION;
+
+ if (diff < 0)
+ {
+ diff = 0.0f - diff;
+ }
+ if (pos_delta < 0)
+ {
+ pos_delta = 0.0f - pos_delta;
+ }
+
+ if (pos_delta < diff)
+ {
+ UnityTestResultsFailBegin(lineNumber);
+#ifdef UNITY_DOUBLE_VERBOSE
+ UnityPrint(UnityStrExpected);
+ UnityPrintFloat((float)expected);
+ UnityPrint(UnityStrWas);
+ UnityPrintFloat((float)actual);
+#else
+ UnityPrint(UnityStrDelta);
+#endif
+ UnityAddMsgIfSpecified(msg);
+ UNITY_FAIL_AND_BAIL;
+ }
+}
+
+#endif // not UNITY_EXCLUDE_DOUBLE
+
+//-----------------------------------------------
+void UnityAssertNumbersWithin( const _U_SINT delta,
+ const _U_SINT expected,
+ const _U_SINT actual,
+ const char* msg,
+ const UNITY_LINE_TYPE lineNumber,
+ const UNITY_DISPLAY_STYLE_T style)
+{
+ UNITY_SKIP_EXECUTION;
+
+ if ((style & UNITY_DISPLAY_RANGE_INT) == UNITY_DISPLAY_RANGE_INT)
+ {
+ if (actual > expected)
+ Unity.CurrentTestFailed = ((actual - expected) > delta);
+ else
+ Unity.CurrentTestFailed = ((expected - actual) > delta);
+ }
+ else
+ {
+ if ((_U_UINT)actual > (_U_UINT)expected)
+ Unity.CurrentTestFailed = ((_U_UINT)(actual - expected) > (_U_UINT)delta);
+ else
+ Unity.CurrentTestFailed = ((_U_UINT)(expected - actual) > (_U_UINT)delta);
+ }
+
+ if (Unity.CurrentTestFailed)
+ {
+ UnityTestResultsFailBegin(lineNumber);
+ UnityPrint(UnityStrDelta);
+ UnityPrintNumberByStyle(delta, style);
+ UnityPrint(UnityStrExpected);
+ UnityPrintNumberByStyle(expected, style);
+ UnityPrint(UnityStrWas);
+ UnityPrintNumberByStyle(actual, style);
+ UnityAddMsgIfSpecified(msg);
+ UNITY_FAIL_AND_BAIL;
+ }
+}
+
+//-----------------------------------------------
+void UnityAssertEqualString(const char* expected,
+ const char* actual,
+ const char* msg,
+ const UNITY_LINE_TYPE lineNumber)
+{
+ _UU32 i;
+
+ UNITY_SKIP_EXECUTION;
+
+ // if both pointers not null compare the strings
+ if (expected && actual)
+ {
+ for (i = 0; expected[i] || actual[i]; i++)
+ {
+ if (expected[i] != actual[i])
+ {
+ Unity.CurrentTestFailed = 1;
+ break;
+ }
+ }
+ }
+ else
+ { // handle case of one pointers being null (if both null, test should pass)
+ if (expected != actual)
+ {
+ Unity.CurrentTestFailed = 1;
+ }
+ }
+
+ if (Unity.CurrentTestFailed)
+ {
+ UnityTestResultsFailBegin(lineNumber);
+ UnityPrintExpectedAndActualStrings(expected, actual);
+ UnityAddMsgIfSpecified(msg);
+ UNITY_FAIL_AND_BAIL;
+ }
+}
+
+//-----------------------------------------------
+void UnityAssertEqualStringArray( const char** expected,
+ const char** actual,
+ const _UU32 num_elements,
+ const char* msg,
+ const UNITY_LINE_TYPE lineNumber)
+{
+ _UU32 i, j = 0;
+
+ UNITY_SKIP_EXECUTION;
+
+ // if no elements, it's an error
+ if (num_elements == 0)
+ {
+ UnityTestResultsFailBegin(lineNumber);
+ UnityPrint(UnityStrPointless);
+ UnityAddMsgIfSpecified(msg);
+ UNITY_FAIL_AND_BAIL;
+ }
+
+ if (UnityCheckArraysForNull((void*)expected, (void*)actual, lineNumber, msg) == 1)
+ return;
+
+ do
+ {
+ // if both pointers not null compare the strings
+ if (expected[j] && actual[j])
+ {
+ for (i = 0; expected[j][i] || actual[j][i]; i++)
+ {
+ if (expected[j][i] != actual[j][i])
+ {
+ Unity.CurrentTestFailed = 1;
+ break;
+ }
+ }
+ }
+ else
+ { // handle case of one pointers being null (if both null, test should pass)
+ if (expected[j] != actual[j])
+ {
+ Unity.CurrentTestFailed = 1;
+ }
+ }
+
+ if (Unity.CurrentTestFailed)
+ {
+ UnityTestResultsFailBegin(lineNumber);
+ if (num_elements > 1)
+ {
+ UnityPrint(UnityStrElement);
+ UnityPrintNumberByStyle((num_elements - j - 1), UNITY_DISPLAY_STYLE_UINT);
+ }
+ UnityPrintExpectedAndActualStrings((const char*)(expected[j]), (const char*)(actual[j]));
+ UnityAddMsgIfSpecified(msg);
+ UNITY_FAIL_AND_BAIL;
+ }
+ } while (++j < num_elements);
+}
+
+//-----------------------------------------------
+void UnityAssertEqualMemory( const void* expected,
+ const void* actual,
+ const _UU32 length,
+ const _UU32 num_elements,
+ const char* msg,
+ const UNITY_LINE_TYPE lineNumber)
+{
+ unsigned char* ptr_exp = (unsigned char*)expected;
+ unsigned char* ptr_act = (unsigned char*)actual;
+ _UU32 elements = num_elements;
+ _UU32 bytes;
+
+ UNITY_SKIP_EXECUTION;
+
+ if ((elements == 0) || (length == 0))
+ {
+ UnityTestResultsFailBegin(lineNumber);
+ UnityPrint(UnityStrPointless);
+ UnityAddMsgIfSpecified(msg);
+ UNITY_FAIL_AND_BAIL;
+ }
+
+ if (UnityCheckArraysForNull((void*)expected, (void*)actual, lineNumber, msg) == 1)
+ return;
+
+ while (elements--)
+ {
+ /////////////////////////////////////
+ bytes = length;
+ while (bytes--)
+ {
+ if (*ptr_exp != *ptr_act)
+ {
+ UnityTestResultsFailBegin(lineNumber);
+ UnityPrint(UnityStrMemory);
+ if (num_elements > 1)
+ {
+ UnityPrint(UnityStrElement);
+ UnityPrintNumberByStyle((num_elements - elements - 1), UNITY_DISPLAY_STYLE_UINT);
+ }
+ UnityPrint(UnityStrByte);
+ UnityPrintNumberByStyle((length - bytes - 1), UNITY_DISPLAY_STYLE_UINT);
+ UnityPrint(UnityStrExpected);
+ UnityPrintNumberByStyle(*ptr_exp, UNITY_DISPLAY_STYLE_HEX8);
+ UnityPrint(UnityStrWas);
+ UnityPrintNumberByStyle(*ptr_act, UNITY_DISPLAY_STYLE_HEX8);
+ UnityAddMsgIfSpecified(msg);
+ UNITY_FAIL_AND_BAIL;
+ }
+ ptr_exp += 1;
+ ptr_act += 1;
+ }
+ /////////////////////////////////////
+
+ }
+}
+
+//-----------------------------------------------
+// Control Functions
+//-----------------------------------------------
+
+void UnityFail(const char* msg, const UNITY_LINE_TYPE line)
+{
+ UNITY_SKIP_EXECUTION;
+
+ UnityTestResultsBegin(Unity.TestFile, line);
+ UnityPrintFail();
+ if (msg != NULL)
+ {
+ UNITY_OUTPUT_CHAR(':');
+ if (msg[0] != ' ')
+ {
+ UNITY_OUTPUT_CHAR(' ');
+ }
+ UnityPrint(msg);
+ }
+ UNITY_FAIL_AND_BAIL;
+}
+
+//-----------------------------------------------
+void UnityIgnore(const char* msg, const UNITY_LINE_TYPE line)
+{
+ UNITY_SKIP_EXECUTION;
+
+ UnityTestResultsBegin(Unity.TestFile, line);
+ UnityPrint("IGNORE");
+ if (msg != NULL)
+ {
+ UNITY_OUTPUT_CHAR(':');
+ UNITY_OUTPUT_CHAR(' ');
+ UnityPrint(msg);
+ }
+ UNITY_IGNORE_AND_BAIL;
+}
+
+//-----------------------------------------------
+void setUp(void);
+void tearDown(void);
+void UnityDefaultTestRun(UnityTestFunction Func, const char* FuncName, const int FuncLineNum)
+{
+ Unity.CurrentTestName = FuncName;
+ Unity.CurrentTestLineNumber = FuncLineNum;
+ Unity.NumberOfTests++;
+ if (TEST_PROTECT())
+ {
+ setUp();
+ Func();
+ }
+ if (TEST_PROTECT() && !(Unity.CurrentTestIgnored))
+ {
+ tearDown();
+ }
+ UnityConcludeTest();
+}
+
+//-----------------------------------------------
+void UnityBegin(void)
+{
+ Unity.NumberOfTests = 0;
+ Unity.TestFailures = 0;
+ Unity.TestIgnores = 0;
+ Unity.CurrentTestFailed = 0;
+ Unity.CurrentTestIgnored = 0;
+}
+
+//-----------------------------------------------
+int UnityEnd(void)
+{
+ UnityPrint("-----------------------");
+ UNITY_PRINT_EOL;
+ UnityPrintNumber(Unity.NumberOfTests);
+ UnityPrint(" Tests ");
+ UnityPrintNumber(Unity.TestFailures);
+ UnityPrint(" Failures ");
+ UnityPrintNumber(Unity.TestIgnores);
+ UnityPrint(" Ignored");
+ UNITY_PRINT_EOL;
+ if (Unity.TestFailures == 0U)
+ {
+ UnityPrintOk();
+ }
+ else
+ {
+ UnityPrintFail();
+ }
+ UNITY_PRINT_EOL;
+ return Unity.TestFailures;
+}
diff --git a/tests/vendor/ceedling/vendor/unity/src/unity.h b/tests/vendor/ceedling/vendor/unity/src/unity.h
new file mode 100644
index 000000000..0b6887c20
--- /dev/null
+++ b/tests/vendor/ceedling/vendor/unity/src/unity.h
@@ -0,0 +1,232 @@
+/* ==========================================
+ Unity Project - A Test Framework for C
+ Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams
+ [Released under MIT License. Please refer to license.txt for details]
+========================================== */
+
+#ifndef UNITY_FRAMEWORK_H
+#define UNITY_FRAMEWORK_H
+
+#define UNITY
+
+#include "unity_internals.h"
+
+//-------------------------------------------------------
+// Configuration Options
+//-------------------------------------------------------
+
+// Integers
+// - Unity assumes 32 bit integers by default
+// - If your compiler treats ints of a different size, define UNITY_INT_WIDTH
+
+// Floats
+// - define UNITY_EXCLUDE_FLOAT to disallow floating point comparisons
+// - define UNITY_FLOAT_PRECISION to specify the precision to use when doing TEST_ASSERT_EQUAL_FLOAT
+// - define UNITY_FLOAT_TYPE to specify doubles instead of single precision floats
+// - define UNITY_FLOAT_VERBOSE to print floating point values in errors (uses sprintf)
+// - define UNITY_INCLUDE_DOUBLE to allow double floating point comparisons
+// - define UNITY_EXCLUDE_DOUBLE to disallow double floating point comparisons (default)
+// - define UNITY_DOUBLE_PRECISION to specify the precision to use when doing TEST_ASSERT_EQUAL_DOUBLE
+// - define UNITY_DOUBLE_TYPE to specify something other than double
+// - define UNITY_DOUBLE_VERBOSE to print floating point values in errors (uses sprintf)
+
+// Output
+// - by default, Unity prints to standard out with putchar. define UNITY_OUTPUT_CHAR(a) with a different function if desired
+
+// Optimization
+// - by default, line numbers are stored in unsigned shorts. Define UNITY_LINE_TYPE with a different type if your files are huge
+// - by default, test and failure counters are unsigned shorts. Define UNITY_COUNTER_TYPE with a different type if you want to save space or have more than 65535 Tests.
+
+// Test Cases
+// - define UNITY_SUPPORT_TEST_CASES to include the TEST_CASE macro, though really it's mostly about the runner generator script
+
+// Parameterized Tests
+// - you'll want to create a define of TEST_CASE(...) which basically evaluates to nothing
+
+//-------------------------------------------------------
+// Test Running Macros
+//-------------------------------------------------------
+
+#define TEST_PROTECT() (setjmp(Unity.AbortFrame) == 0)
+
+#define TEST_ABORT() {longjmp(Unity.AbortFrame, 1);}
+
+#ifndef RUN_TEST
+#define RUN_TEST(func, line_num) UnityDefaultTestRun(func, #func, line_num)
+#endif
+
+#define TEST_LINE_NUM (Unity.CurrentTestLineNumber)
+#define TEST_IS_IGNORED (Unity.CurrentTestIgnored)
+
+//-------------------------------------------------------
+// Basic Fail and Ignore
+//-------------------------------------------------------
+
+#define TEST_FAIL_MESSAGE(message) UNITY_TEST_FAIL(__LINE__, message)
+#define TEST_FAIL() UNITY_TEST_FAIL(__LINE__, NULL)
+#define TEST_IGNORE_MESSAGE(message) UNITY_TEST_IGNORE(__LINE__, message)
+#define TEST_IGNORE() UNITY_TEST_IGNORE(__LINE__, NULL)
+#define TEST_ONLY()
+
+//-------------------------------------------------------
+// Test Asserts (simple)
+//-------------------------------------------------------
+
+//Boolean
+#define TEST_ASSERT(condition) UNITY_TEST_ASSERT( (condition), __LINE__, " Expression Evaluated To FALSE")
+#define TEST_ASSERT_TRUE(condition) UNITY_TEST_ASSERT( (condition), __LINE__, " Expected TRUE Was FALSE")
+#define TEST_ASSERT_UNLESS(condition) UNITY_TEST_ASSERT( !(condition), __LINE__, " Expression Evaluated To TRUE")
+#define TEST_ASSERT_FALSE(condition) UNITY_TEST_ASSERT( !(condition), __LINE__, " Expected FALSE Was TRUE")
+#define TEST_ASSERT_NULL(pointer) UNITY_TEST_ASSERT_NULL( (pointer), __LINE__, " Expected NULL")
+#define TEST_ASSERT_NOT_NULL(pointer) UNITY_TEST_ASSERT_NOT_NULL((pointer), __LINE__, " Expected Non-NULL")
+
+//Integers (of all sizes)
+#define TEST_ASSERT_EQUAL_INT(expected, actual) UNITY_TEST_ASSERT_EQUAL_INT((expected), (actual), __LINE__, NULL)
+#define TEST_ASSERT_EQUAL_INT8(expected, actual) UNITY_TEST_ASSERT_EQUAL_INT8((expected), (actual), __LINE__, NULL)
+#define TEST_ASSERT_EQUAL_INT16(expected, actual) UNITY_TEST_ASSERT_EQUAL_INT16((expected), (actual), __LINE__, NULL)
+#define TEST_ASSERT_EQUAL_INT32(expected, actual) UNITY_TEST_ASSERT_EQUAL_INT32((expected), (actual), __LINE__, NULL)
+#define TEST_ASSERT_EQUAL_INT64(expected, actual) UNITY_TEST_ASSERT_EQUAL_INT64((expected), (actual), __LINE__, NULL)
+#define TEST_ASSERT_EQUAL(expected, actual) UNITY_TEST_ASSERT_EQUAL_INT((expected), (actual), __LINE__, NULL)
+#define TEST_ASSERT_NOT_EQUAL(expected, actual) UNITY_TEST_ASSERT(((expected) != (actual)), __LINE__, " Expected Not-Equal")
+#define TEST_ASSERT_EQUAL_UINT(expected, actual) UNITY_TEST_ASSERT_EQUAL_UINT( (expected), (actual), __LINE__, NULL)
+#define TEST_ASSERT_EQUAL_UINT8(expected, actual) UNITY_TEST_ASSERT_EQUAL_UINT8( (expected), (actual), __LINE__, NULL)
+#define TEST_ASSERT_EQUAL_UINT16(expected, actual) UNITY_TEST_ASSERT_EQUAL_UINT16( (expected), (actual), __LINE__, NULL)
+#define TEST_ASSERT_EQUAL_UINT32(expected, actual) UNITY_TEST_ASSERT_EQUAL_UINT32( (expected), (actual), __LINE__, NULL)
+#define TEST_ASSERT_EQUAL_UINT64(expected, actual) UNITY_TEST_ASSERT_EQUAL_UINT64( (expected), (actual), __LINE__, NULL)
+#define TEST_ASSERT_EQUAL_HEX(expected, actual) UNITY_TEST_ASSERT_EQUAL_HEX32((expected), (actual), __LINE__, NULL)
+#define TEST_ASSERT_EQUAL_HEX8(expected, actual) UNITY_TEST_ASSERT_EQUAL_HEX8( (expected), (actual), __LINE__, NULL)
+#define TEST_ASSERT_EQUAL_HEX16(expected, actual) UNITY_TEST_ASSERT_EQUAL_HEX16((expected), (actual), __LINE__, NULL)
+#define TEST_ASSERT_EQUAL_HEX32(expected, actual) UNITY_TEST_ASSERT_EQUAL_HEX32((expected), (actual), __LINE__, NULL)
+#define TEST_ASSERT_EQUAL_HEX64(expected, actual) UNITY_TEST_ASSERT_EQUAL_HEX64((expected), (actual), __LINE__, NULL)
+#define TEST_ASSERT_BITS(mask, expected, actual) UNITY_TEST_ASSERT_BITS((mask), (expected), (actual), __LINE__, NULL)
+#define TEST_ASSERT_BITS_HIGH(mask, actual) UNITY_TEST_ASSERT_BITS((mask), (_UU32)(-1), (actual), __LINE__, NULL)
+#define TEST_ASSERT_BITS_LOW(mask, actual) UNITY_TEST_ASSERT_BITS((mask), (_UU32)(0), (actual), __LINE__, NULL)
+#define TEST_ASSERT_BIT_HIGH(bit, actual) UNITY_TEST_ASSERT_BITS(((_UU32)1 << bit), (_UU32)(-1), (actual), __LINE__, NULL)
+#define TEST_ASSERT_BIT_LOW(bit, actual) UNITY_TEST_ASSERT_BITS(((_UU32)1 << bit), (_UU32)(0), (actual), __LINE__, NULL)
+
+//Integer Ranges (of all sizes)
+#define TEST_ASSERT_INT_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_INT_WITHIN(delta, expected, actual, __LINE__, NULL)
+#define TEST_ASSERT_UINT_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_UINT_WITHIN(delta, expected, actual, __LINE__, NULL)
+#define TEST_ASSERT_HEX_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_HEX32_WITHIN(delta, expected, actual, __LINE__, NULL)
+#define TEST_ASSERT_HEX8_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_HEX8_WITHIN(delta, expected, actual, __LINE__, NULL)
+#define TEST_ASSERT_HEX16_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_HEX16_WITHIN(delta, expected, actual, __LINE__, NULL)
+#define TEST_ASSERT_HEX32_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_HEX32_WITHIN(delta, expected, actual, __LINE__, NULL)
+#define TEST_ASSERT_HEX64_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_HEX64_WITHIN(delta, expected, actual, __LINE__, NULL)
+
+//Structs and Strings
+#define TEST_ASSERT_EQUAL_PTR(expected, actual) UNITY_TEST_ASSERT_EQUAL_PTR((expected), (actual), __LINE__, NULL)
+#define TEST_ASSERT_EQUAL_STRING(expected, actual) UNITY_TEST_ASSERT_EQUAL_STRING(expected, actual, __LINE__, NULL)
+#define TEST_ASSERT_EQUAL_MEMORY(expected, actual, len) UNITY_TEST_ASSERT_EQUAL_MEMORY(expected, actual, len, __LINE__, NULL)
+
+//Arrays
+#define TEST_ASSERT_EQUAL_INT_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_INT_ARRAY(expected, actual, num_elements, __LINE__, NULL)
+#define TEST_ASSERT_EQUAL_INT8_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_INT8_ARRAY(expected, actual, num_elements, __LINE__, NULL)
+#define TEST_ASSERT_EQUAL_INT16_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_INT16_ARRAY(expected, actual, num_elements, __LINE__, NULL)
+#define TEST_ASSERT_EQUAL_INT32_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_INT32_ARRAY(expected, actual, num_elements, __LINE__, NULL)
+#define TEST_ASSERT_EQUAL_INT64_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_INT64_ARRAY(expected, actual, num_elements, __LINE__, NULL)
+#define TEST_ASSERT_EQUAL_UINT_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_UINT_ARRAY(expected, actual, num_elements, __LINE__, NULL)
+#define TEST_ASSERT_EQUAL_UINT8_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_UINT8_ARRAY(expected, actual, num_elements, __LINE__, NULL)
+#define TEST_ASSERT_EQUAL_UINT16_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_UINT16_ARRAY(expected, actual, num_elements, __LINE__, NULL)
+#define TEST_ASSERT_EQUAL_UINT32_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_UINT32_ARRAY(expected, actual, num_elements, __LINE__, NULL)
+#define TEST_ASSERT_EQUAL_UINT64_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_UINT64_ARRAY(expected, actual, num_elements, __LINE__, NULL)
+#define TEST_ASSERT_EQUAL_HEX_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_HEX32_ARRAY(expected, actual, num_elements, __LINE__, NULL)
+#define TEST_ASSERT_EQUAL_HEX8_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_HEX8_ARRAY(expected, actual, num_elements, __LINE__, NULL)
+#define TEST_ASSERT_EQUAL_HEX16_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_HEX16_ARRAY(expected, actual, num_elements, __LINE__, NULL)
+#define TEST_ASSERT_EQUAL_HEX32_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_HEX32_ARRAY(expected, actual, num_elements, __LINE__, NULL)
+#define TEST_ASSERT_EQUAL_HEX64_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_HEX64_ARRAY(expected, actual, num_elements, __LINE__, NULL)
+#define TEST_ASSERT_EQUAL_PTR_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_PTR_ARRAY(expected, actual, num_elements, __LINE__, NULL)
+#define TEST_ASSERT_EQUAL_STRING_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_STRING_ARRAY(expected, actual, num_elements, __LINE__, NULL)
+#define TEST_ASSERT_EQUAL_MEMORY_ARRAY(expected, actual, len, num_elements) UNITY_TEST_ASSERT_EQUAL_MEMORY_ARRAY(expected, actual, len, num_elements, __LINE__, NULL)
+
+//Floating Point (If Enabled)
+#define TEST_ASSERT_FLOAT_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_FLOAT_WITHIN(delta, expected, actual, __LINE__, NULL)
+#define TEST_ASSERT_EQUAL_FLOAT(expected, actual) UNITY_TEST_ASSERT_EQUAL_FLOAT(expected, actual, __LINE__, NULL)
+#define TEST_ASSERT_EQUAL_FLOAT_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_FLOAT_ARRAY(expected, actual, num_elements, __LINE__, NULL)
+
+//Double (If Enabled)
+#define TEST_ASSERT_DOUBLE_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_DOUBLE_WITHIN(delta, expected, actual, __LINE__, NULL)
+#define TEST_ASSERT_EQUAL_DOUBLE(expected, actual) UNITY_TEST_ASSERT_EQUAL_DOUBLE(expected, actual, __LINE__, NULL)
+#define TEST_ASSERT_EQUAL_DOUBLE_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_DOUBLE_ARRAY(expected, actual, num_elements, __LINE__, NULL)
+
+
+//-------------------------------------------------------
+// Test Asserts (with additional messages)
+//-------------------------------------------------------
+
+//Boolean
+#define TEST_ASSERT_MESSAGE(condition, message) UNITY_TEST_ASSERT( (condition), __LINE__, message)
+#define TEST_ASSERT_TRUE_MESSAGE(condition, message) UNITY_TEST_ASSERT( (condition), __LINE__, message)
+#define TEST_ASSERT_UNLESS_MESSAGE(condition, message) UNITY_TEST_ASSERT( !(condition), __LINE__, message)
+#define TEST_ASSERT_FALSE_MESSAGE(condition, message) UNITY_TEST_ASSERT( !(condition), __LINE__, message)
+#define TEST_ASSERT_NULL_MESSAGE(pointer, message) UNITY_TEST_ASSERT_NULL( (pointer), __LINE__, message)
+#define TEST_ASSERT_NOT_NULL_MESSAGE(pointer, message) UNITY_TEST_ASSERT_NOT_NULL((pointer), __LINE__, message)
+
+//Integers (of all sizes)
+#define TEST_ASSERT_EQUAL_INT_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_INT((expected), (actual), __LINE__, message)
+#define TEST_ASSERT_EQUAL_INT8_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_INT8((expected), (actual), __LINE__, message)
+#define TEST_ASSERT_EQUAL_INT16_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_INT16((expected), (actual), __LINE__, message)
+#define TEST_ASSERT_EQUAL_INT32_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_INT32((expected), (actual), __LINE__, message)
+#define TEST_ASSERT_EQUAL_INT64_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_INT64((expected), (actual), __LINE__, message)
+#define TEST_ASSERT_EQUAL_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_INT((expected), (actual), __LINE__, message)
+#define TEST_ASSERT_NOT_EQUAL_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT(((expected) != (actual)), __LINE__, message)
+#define TEST_ASSERT_EQUAL_UINT_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_UINT( (expected), (actual), __LINE__, message)
+#define TEST_ASSERT_EQUAL_UINT8_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_UINT8( (expected), (actual), __LINE__, message)
+#define TEST_ASSERT_EQUAL_UINT16_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_UINT16( (expected), (actual), __LINE__, message)
+#define TEST_ASSERT_EQUAL_UINT32_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_UINT32( (expected), (actual), __LINE__, message)
+#define TEST_ASSERT_EQUAL_UINT64_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_UINT64( (expected), (actual), __LINE__, message)
+#define TEST_ASSERT_EQUAL_HEX_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_HEX32((expected), (actual), __LINE__, message)
+#define TEST_ASSERT_EQUAL_HEX8_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_HEX8( (expected), (actual), __LINE__, message)
+#define TEST_ASSERT_EQUAL_HEX16_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_HEX16((expected), (actual), __LINE__, message)
+#define TEST_ASSERT_EQUAL_HEX32_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_HEX32((expected), (actual), __LINE__, message)
+#define TEST_ASSERT_EQUAL_HEX64_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_HEX64((expected), (actual), __LINE__, message)
+#define TEST_ASSERT_BITS_MESSAGE(mask, expected, actual, message) UNITY_TEST_ASSERT_BITS((mask), (expected), (actual), __LINE__, message)
+#define TEST_ASSERT_BITS_HIGH_MESSAGE(mask, actual, message) UNITY_TEST_ASSERT_BITS((mask), (_UU32)(-1), (actual), __LINE__, message)
+#define TEST_ASSERT_BITS_LOW_MESSAGE(mask, actual, message) UNITY_TEST_ASSERT_BITS((mask), (_UU32)(0), (actual), __LINE__, message)
+#define TEST_ASSERT_BIT_HIGH_MESSAGE(bit, actual, message) UNITY_TEST_ASSERT_BITS(((_UU32)1 << bit), (_UU32)(-1), (actual), __LINE__, message)
+#define TEST_ASSERT_BIT_LOW_MESSAGE(bit, actual, message) UNITY_TEST_ASSERT_BITS(((_UU32)1 << bit), (_UU32)(0), (actual), __LINE__, message)
+
+//Integer Ranges (of all sizes)
+#define TEST_ASSERT_INT_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_INT_WITHIN(delta, expected, actual, __LINE__, message)
+#define TEST_ASSERT_UINT_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_UINT_WITHIN(delta, expected, actual, __LINE__, message)
+#define TEST_ASSERT_HEX_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_HEX32_WITHIN(delta, expected, actual, __LINE__, message)
+#define TEST_ASSERT_HEX8_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_HEX8_WITHIN(delta, expected, actual, __LINE__, message)
+#define TEST_ASSERT_HEX16_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_HEX16_WITHIN(delta, expected, actual, __LINE__, message)
+#define TEST_ASSERT_HEX32_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_HEX32_WITHIN(delta, expected, actual, __LINE__, message)
+#define TEST_ASSERT_HEX64_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_HEX64_WITHIN(delta, expected, actual, __LINE__, message)
+
+//Structs and Strings
+#define TEST_ASSERT_EQUAL_PTR_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_PTR(expected, actual, __LINE__, message)
+#define TEST_ASSERT_EQUAL_STRING_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_STRING(expected, actual, __LINE__, message)
+#define TEST_ASSERT_EQUAL_MEMORY_MESSAGE(expected, actual, len, message) UNITY_TEST_ASSERT_EQUAL_MEMORY(expected, actual, len, __LINE__, message)
+
+//Arrays
+#define TEST_ASSERT_EQUAL_INT_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_INT_ARRAY(expected, actual, num_elements, __LINE__, message)
+#define TEST_ASSERT_EQUAL_INT8_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_INT8_ARRAY(expected, actual, num_elements, __LINE__, message)
+#define TEST_ASSERT_EQUAL_INT16_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_INT16_ARRAY(expected, actual, num_elements, __LINE__, message)
+#define TEST_ASSERT_EQUAL_INT32_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_INT32_ARRAY(expected, actual, num_elements, __LINE__, message)
+#define TEST_ASSERT_EQUAL_INT64_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_INT64_ARRAY(expected, actual, num_elements, __LINE__, message)
+#define TEST_ASSERT_EQUAL_UINT_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_UINT_ARRAY(expected, actual, num_elements, __LINE__, message)
+#define TEST_ASSERT_EQUAL_UINT8_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_UINT8_ARRAY(expected, actual, num_elements, __LINE__, message)
+#define TEST_ASSERT_EQUAL_UINT16_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_UINT16_ARRAY(expected, actual, num_elements, __LINE__, message)
+#define TEST_ASSERT_EQUAL_UINT32_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_UINT32_ARRAY(expected, actual, num_elements, __LINE__, message)
+#define TEST_ASSERT_EQUAL_UINT64_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_UINT64_ARRAY(expected, actual, num_elements, __LINE__, message)
+#define TEST_ASSERT_EQUAL_HEX_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_HEX32_ARRAY(expected, actual, num_elements, __LINE__, message)
+#define TEST_ASSERT_EQUAL_HEX8_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_HEX8_ARRAY(expected, actual, num_elements, __LINE__, message)
+#define TEST_ASSERT_EQUAL_HEX16_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_HEX16_ARRAY(expected, actual, num_elements, __LINE__, message)
+#define TEST_ASSERT_EQUAL_HEX32_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_HEX32_ARRAY(expected, actual, num_elements, __LINE__, message)
+#define TEST_ASSERT_EQUAL_HEX64_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_HEX64_ARRAY(expected, actual, num_elements, __LINE__, message)
+#define TEST_ASSERT_EQUAL_PTR_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_PTR_ARRAY(expected, actual, num_elements, __LINE__, message)
+#define TEST_ASSERT_EQUAL_STRING_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_STRING_ARRAY(expected, actual, num_elements, __LINE__, message)
+#define TEST_ASSERT_EQUAL_MEMORY_ARRAY_MESSAGE(expected, actual, len, num_elements, message) UNITY_TEST_ASSERT_EQUAL_MEMORY_ARRAY(expected, actual, len, num_elements, __LINE__, message)
+
+//Floating Point (If Enabled)
+#define TEST_ASSERT_FLOAT_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_FLOAT_WITHIN(delta, expected, actual, __LINE__, message)
+#define TEST_ASSERT_EQUAL_FLOAT_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_FLOAT(expected, actual, __LINE__, message)
+#define TEST_ASSERT_EQUAL_FLOAT_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_FLOAT_ARRAY(expected, actual, num_elements, __LINE__, message)
+
+//Double (If Enabled)
+#define TEST_ASSERT_DOUBLE_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_DOUBLE_WITHIN(delta, expected, actual, __LINE__, message)
+#define TEST_ASSERT_EQUAL_DOUBLE_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_DOUBLE(expected, actual, __LINE__, message)
+#define TEST_ASSERT_EQUAL_DOUBLE_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_DOUBLE_ARRAY(expected, actual, num_elements, __LINE__, message)
+
+#endif
diff --git a/tests/vendor/ceedling/vendor/unity/src/unity_internals.h b/tests/vendor/ceedling/vendor/unity/src/unity_internals.h
new file mode 100644
index 000000000..9bf19fe4f
--- /dev/null
+++ b/tests/vendor/ceedling/vendor/unity/src/unity_internals.h
@@ -0,0 +1,512 @@
+/* ==========================================
+ Unity Project - A Test Framework for C
+ Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams
+ [Released under MIT License. Please refer to license.txt for details]
+========================================== */
+
+#ifndef UNITY_INTERNALS_H
+#define UNITY_INTERNALS_H
+
+#include
+#include
+
+//stdint.h is often automatically included.
+//Unity uses it to guess at the sizes of integer types, etc.
+#ifdef UNITY_USE_LIMITS_H
+#include
+#endif
+#ifndef UNITY_EXCLUDE_STDINT_H
+#include
+#endif
+
+//-------------------------------------------------------
+// Guess Widths If Not Specified
+//-------------------------------------------------------
+
+// If the INT Width hasn't been specified,
+// We first try to guess based on UINT_MAX (if it exists)
+// Otherwise we fall back on assuming 32-bit
+#ifndef UNITY_INT_WIDTH
+ #ifdef UINT_MAX
+ #if (UINT_MAX == 0xFFFF)
+ #define UNITY_INT_WIDTH (16)
+ #elif (UINT_MAX == 0xFFFFFFFF)
+ #define UNITY_INT_WIDTH (32)
+ #elif (UINT_MAX == 0xFFFFFFFFFFFFFFFF)
+ #define UNITY_INT_WIDTH (64)
+ #ifndef UNITY_SUPPORT_64
+ #define UNITY_SUPPORT_64
+ #endif
+ #else
+ #define UNITY_INT_WIDTH (32)
+ #endif
+ #else
+ #define UNITY_INT_WIDTH (32)
+ #endif
+#endif
+
+// If the Long Width hasn't been specified,
+// We first try to guess based on ULONG_MAX (if it exists)
+// Otherwise we fall back on assuming 32-bit
+#ifndef UNITY_LONG_WIDTH
+ #ifdef ULONG_MAX
+ #if (ULONG_MAX == 0xFFFF)
+ #define UNITY_LONG_WIDTH (16)
+ #elif (ULONG_MAX == 0xFFFFFFFF)
+ #define UNITY_LONG_WIDTH (32)
+ #elif (ULONG_MAX == 0xFFFFFFFFFFFFFFFF)
+ #define UNITY_LONG_WIDTH (64)
+ #else
+ #define UNITY_LONG_WIDTH (32)
+ #ifndef UNITY_SUPPORT_64
+ #define UNITY_SUPPORT_64
+ #endif
+ #endif
+ #else
+ #define UNITY_LONG_WIDTH (32)
+ #endif
+#endif
+
+// If the Pointer Width hasn't been specified,
+// We first try to guess based on INTPTR_MAX (if it exists)
+// Otherwise we fall back on assuming 32-bit
+#ifndef UNITY_POINTER_WIDTH
+ #ifdef UINTPTR_MAX
+ #if (UINTPTR_MAX <= 0xFFFF)
+ #define UNITY_POINTER_WIDTH (16)
+ #elif (UINTPTR_MAX <= 0xFFFFFFFF)
+ #define UNITY_POINTER_WIDTH (32)
+ #elif (UINTPTR_MAX <= 0xFFFFFFFFFFFFFFFF)
+ #define UNITY_POINTER_WIDTH (64)
+ #ifndef UNITY_SUPPORT_64
+ #define UNITY_SUPPORT_64
+ #endif
+ #endif
+ #endif
+#endif
+#ifndef UNITY_POINTER_WIDTH
+ #ifdef INTPTR_MAX
+ #if (INTPTR_MAX <= 0x7FFF)
+ #define UNITY_POINTER_WIDTH (16)
+ #elif (INTPTR_MAX <= 0x7FFFFFFF)
+ #define UNITY_POINTER_WIDTH (32)
+ #elif (INTPTR_MAX <= 0x7FFFFFFFFFFFFFFF)
+ #define UNITY_POINTER_WIDTH (64)
+ #ifndef UNITY_SUPPORT_64
+ #define UNITY_SUPPORT_64
+ #endif
+ #endif
+ #endif
+#endif
+#ifndef UNITY_POINTER_WIDTH
+ #define UNITY_POINTER_WIDTH (32)
+#endif
+
+//-------------------------------------------------------
+// Int Support
+//-------------------------------------------------------
+
+#if (UNITY_INT_WIDTH == 32)
+ typedef unsigned char _UU8;
+ typedef unsigned short _UU16;
+ typedef unsigned int _UU32;
+ typedef signed char _US8;
+ typedef signed short _US16;
+ typedef signed int _US32;
+#elif (UNITY_INT_WIDTH == 16)
+ typedef unsigned char _UU8;
+ typedef unsigned int _UU16;
+ typedef unsigned long _UU32;
+ typedef signed char _US8;
+ typedef signed int _US16;
+ typedef signed long _US32;
+#else
+ #error Invalid UNITY_INT_WIDTH specified! (16 or 32 are supported)
+#endif
+
+//-------------------------------------------------------
+// 64-bit Support
+//-------------------------------------------------------
+
+#ifndef UNITY_SUPPORT_64
+
+//No 64-bit Support
+typedef _UU32 _U_UINT;
+typedef _US32 _U_SINT;
+
+#else
+
+//64-bit Support
+#if (UNITY_LONG_WIDTH == 32)
+ typedef unsigned long long _UU64;
+ typedef signed long long _US64;
+#elif (UNITY_LONG_WIDTH == 64)
+ typedef unsigned long _UU64;
+ typedef signed long _US64;
+#else
+ #error Invalid UNITY_LONG_WIDTH specified! (32 or 64 are supported)
+#endif
+typedef _UU64 _U_UINT;
+typedef _US64 _U_SINT;
+
+#endif
+
+//-------------------------------------------------------
+// Pointer Support
+//-------------------------------------------------------
+
+#ifndef UNITY_POINTER_WIDTH
+#define UNITY_POINTER_WIDTH (32)
+#endif /* UNITY_POINTER_WIDTH */
+
+#if (UNITY_POINTER_WIDTH == 32)
+ typedef _UU32 _UP;
+#define UNITY_DISPLAY_STYLE_POINTER UNITY_DISPLAY_STYLE_HEX32
+#elif (UNITY_POINTER_WIDTH == 64)
+#ifndef UNITY_SUPPORT_64
+#error "You've Specified 64-bit pointers without enabling 64-bit Support. Define UNITY_SUPPORT_64"
+#endif
+ typedef _UU64 _UP;
+#define UNITY_DISPLAY_STYLE_POINTER UNITY_DISPLAY_STYLE_HEX64
+#elif (UNITY_POINTER_WIDTH == 16)
+ typedef _UU16 _UP;
+#define UNITY_DISPLAY_STYLE_POINTER UNITY_DISPLAY_STYLE_HEX16
+#else
+ #error Invalid UNITY_POINTER_WIDTH specified! (16, 32 or 64 are supported)
+#endif
+
+//-------------------------------------------------------
+// Float Support
+//-------------------------------------------------------
+
+#ifdef UNITY_EXCLUDE_FLOAT
+
+//No Floating Point Support
+#undef UNITY_FLOAT_PRECISION
+#undef UNITY_FLOAT_TYPE
+#undef UNITY_FLOAT_VERBOSE
+
+#else
+
+//Floating Point Support
+#ifndef UNITY_FLOAT_PRECISION
+#define UNITY_FLOAT_PRECISION (0.00001f)
+#endif
+#ifndef UNITY_FLOAT_TYPE
+#define UNITY_FLOAT_TYPE float
+#endif
+typedef UNITY_FLOAT_TYPE _UF;
+
+#endif
+
+//-------------------------------------------------------
+// Double Float Support
+//-------------------------------------------------------
+
+//unlike FLOAT, we DON'T include by default
+#ifndef UNITY_EXCLUDE_DOUBLE
+#ifndef UNITY_INCLUDE_DOUBLE
+#define UNITY_EXCLUDE_DOUBLE
+#endif
+#endif
+
+#ifdef UNITY_EXCLUDE_DOUBLE
+
+//No Floating Point Support
+#undef UNITY_DOUBLE_PRECISION
+#undef UNITY_DOUBLE_TYPE
+#undef UNITY_DOUBLE_VERBOSE
+
+#else
+
+//Floating Point Support
+#ifndef UNITY_DOUBLE_PRECISION
+#define UNITY_DOUBLE_PRECISION (1e-12f)
+#endif
+#ifndef UNITY_DOUBLE_TYPE
+#define UNITY_DOUBLE_TYPE double
+#endif
+typedef UNITY_DOUBLE_TYPE _UD;
+
+#endif
+
+//-------------------------------------------------------
+// Output Method
+//-------------------------------------------------------
+
+#ifndef UNITY_OUTPUT_CHAR
+//Default to using putchar, which is defined in stdio.h above
+#define UNITY_OUTPUT_CHAR(a) putchar(a)
+#else
+//If defined as something else, make sure we declare it here so it's ready for use
+extern int UNITY_OUTPUT_CHAR(int);
+#endif
+
+//-------------------------------------------------------
+// Footprint
+//-------------------------------------------------------
+
+#ifndef UNITY_LINE_TYPE
+#define UNITY_LINE_TYPE _U_UINT
+#endif
+
+#ifndef UNITY_COUNTER_TYPE
+#define UNITY_COUNTER_TYPE _U_UINT
+#endif
+
+//-------------------------------------------------------
+// Internal Structs Needed
+//-------------------------------------------------------
+
+typedef void (*UnityTestFunction)(void);
+
+#define UNITY_DISPLAY_RANGE_INT (0x10)
+#define UNITY_DISPLAY_RANGE_UINT (0x20)
+#define UNITY_DISPLAY_RANGE_HEX (0x40)
+#define UNITY_DISPLAY_RANGE_AUTO (0x80)
+
+typedef enum
+{
+#if (UNITY_INT_WIDTH == 16)
+ UNITY_DISPLAY_STYLE_INT = 2 + UNITY_DISPLAY_RANGE_INT + UNITY_DISPLAY_RANGE_AUTO,
+#elif (UNITY_INT_WIDTH == 32)
+ UNITY_DISPLAY_STYLE_INT = 4 + UNITY_DISPLAY_RANGE_INT + UNITY_DISPLAY_RANGE_AUTO,
+#elif (UNITY_INT_WIDTH == 64)
+ UNITY_DISPLAY_STYLE_INT = 8 + UNITY_DISPLAY_RANGE_INT + UNITY_DISPLAY_RANGE_AUTO,
+#endif
+ UNITY_DISPLAY_STYLE_INT8 = 1 + UNITY_DISPLAY_RANGE_INT,
+ UNITY_DISPLAY_STYLE_INT16 = 2 + UNITY_DISPLAY_RANGE_INT,
+ UNITY_DISPLAY_STYLE_INT32 = 4 + UNITY_DISPLAY_RANGE_INT,
+#ifdef UNITY_SUPPORT_64
+ UNITY_DISPLAY_STYLE_INT64 = 8 + UNITY_DISPLAY_RANGE_INT,
+#endif
+
+#if (UNITY_INT_WIDTH == 16)
+ UNITY_DISPLAY_STYLE_UINT = 2 + UNITY_DISPLAY_RANGE_UINT + UNITY_DISPLAY_RANGE_AUTO,
+#elif (UNITY_INT_WIDTH == 32)
+ UNITY_DISPLAY_STYLE_UINT = 4 + UNITY_DISPLAY_RANGE_UINT + UNITY_DISPLAY_RANGE_AUTO,
+#elif (UNITY_INT_WIDTH == 64)
+ UNITY_DISPLAY_STYLE_UINT = 8 + UNITY_DISPLAY_RANGE_UINT + UNITY_DISPLAY_RANGE_AUTO,
+#endif
+ UNITY_DISPLAY_STYLE_UINT8 = 1 + UNITY_DISPLAY_RANGE_UINT,
+ UNITY_DISPLAY_STYLE_UINT16 = 2 + UNITY_DISPLAY_RANGE_UINT,
+ UNITY_DISPLAY_STYLE_UINT32 = 4 + UNITY_DISPLAY_RANGE_UINT,
+#ifdef UNITY_SUPPORT_64
+ UNITY_DISPLAY_STYLE_UINT64 = 8 + UNITY_DISPLAY_RANGE_UINT,
+#endif
+ UNITY_DISPLAY_STYLE_HEX8 = 1 + UNITY_DISPLAY_RANGE_HEX,
+ UNITY_DISPLAY_STYLE_HEX16 = 2 + UNITY_DISPLAY_RANGE_HEX,
+ UNITY_DISPLAY_STYLE_HEX32 = 4 + UNITY_DISPLAY_RANGE_HEX,
+#ifdef UNITY_SUPPORT_64
+ UNITY_DISPLAY_STYLE_HEX64 = 8 + UNITY_DISPLAY_RANGE_HEX,
+#endif
+ UNITY_DISPLAY_STYLE_UNKNOWN
+} UNITY_DISPLAY_STYLE_T;
+
+struct _Unity
+{
+ const char* TestFile;
+ const char* CurrentTestName;
+ UNITY_LINE_TYPE CurrentTestLineNumber;
+ UNITY_COUNTER_TYPE NumberOfTests;
+ UNITY_COUNTER_TYPE TestFailures;
+ UNITY_COUNTER_TYPE TestIgnores;
+ UNITY_COUNTER_TYPE CurrentTestFailed;
+ UNITY_COUNTER_TYPE CurrentTestIgnored;
+ jmp_buf AbortFrame;
+};
+
+extern struct _Unity Unity;
+
+//-------------------------------------------------------
+// Test Suite Management
+//-------------------------------------------------------
+
+void UnityBegin(void);
+int UnityEnd(void);
+void UnityConcludeTest(void);
+void UnityDefaultTestRun(UnityTestFunction Func, const char* FuncName, const int FuncLineNum);
+
+//-------------------------------------------------------
+// Test Output
+//-------------------------------------------------------
+
+void UnityPrint(const char* string);
+void UnityPrintMask(const _U_UINT mask, const _U_UINT number);
+void UnityPrintNumberByStyle(const _U_SINT number, const UNITY_DISPLAY_STYLE_T style);
+void UnityPrintNumber(const _U_SINT number);
+void UnityPrintNumberUnsigned(const _U_UINT number);
+void UnityPrintNumberHex(const _U_UINT number, const char nibbles);
+
+#ifdef UNITY_FLOAT_VERBOSE
+void UnityPrintFloat(const _UF number);
+#endif
+
+//-------------------------------------------------------
+// Test Assertion Fuctions
+//-------------------------------------------------------
+// Use the macros below this section instead of calling
+// these directly. The macros have a consistent naming
+// convention and will pull in file and line information
+// for you.
+
+void UnityAssertEqualNumber(const _U_SINT expected,
+ const _U_SINT actual,
+ const char* msg,
+ const UNITY_LINE_TYPE lineNumber,
+ const UNITY_DISPLAY_STYLE_T style);
+
+void UnityAssertEqualIntArray(const _U_SINT* expected,
+ const _U_SINT* actual,
+ const _UU32 num_elements,
+ const char* msg,
+ const UNITY_LINE_TYPE lineNumber,
+ const UNITY_DISPLAY_STYLE_T style);
+
+void UnityAssertBits(const _U_SINT mask,
+ const _U_SINT expected,
+ const _U_SINT actual,
+ const char* msg,
+ const UNITY_LINE_TYPE lineNumber);
+
+void UnityAssertEqualString(const char* expected,
+ const char* actual,
+ const char* msg,
+ const UNITY_LINE_TYPE lineNumber);
+
+void UnityAssertEqualStringArray( const char** expected,
+ const char** actual,
+ const _UU32 num_elements,
+ const char* msg,
+ const UNITY_LINE_TYPE lineNumber);
+
+void UnityAssertEqualMemory( const void* expected,
+ const void* actual,
+ const _UU32 length,
+ const _UU32 num_elements,
+ const char* msg,
+ const UNITY_LINE_TYPE lineNumber);
+
+void UnityAssertNumbersWithin(const _U_SINT delta,
+ const _U_SINT expected,
+ const _U_SINT actual,
+ const char* msg,
+ const UNITY_LINE_TYPE lineNumber,
+ const UNITY_DISPLAY_STYLE_T style);
+
+void UnityFail(const char* message, const UNITY_LINE_TYPE line);
+
+void UnityIgnore(const char* message, const UNITY_LINE_TYPE line);
+
+#ifndef UNITY_EXCLUDE_FLOAT
+void UnityAssertFloatsWithin(const _UF delta,
+ const _UF expected,
+ const _UF actual,
+ const char* msg,
+ const UNITY_LINE_TYPE lineNumber);
+
+void UnityAssertEqualFloatArray(const _UF* expected,
+ const _UF* actual,
+ const _UU32 num_elements,
+ const char* msg,
+ const UNITY_LINE_TYPE lineNumber);
+#endif
+
+#ifndef UNITY_EXCLUDE_DOUBLE
+void UnityAssertDoublesWithin(const _UD delta,
+ const _UD expected,
+ const _UD actual,
+ const char* msg,
+ const UNITY_LINE_TYPE lineNumber);
+
+void UnityAssertEqualDoubleArray(const _UD* expected,
+ const _UD* actual,
+ const _UU32 num_elements,
+ const char* msg,
+ const UNITY_LINE_TYPE lineNumber);
+#endif
+
+//-------------------------------------------------------
+// Basic Fail and Ignore
+//-------------------------------------------------------
+
+#define UNITY_TEST_FAIL(line, message) UnityFail( (message), (UNITY_LINE_TYPE)line);
+#define UNITY_TEST_IGNORE(line, message) UnityIgnore( (message), (UNITY_LINE_TYPE)line);
+
+//-------------------------------------------------------
+// Test Asserts
+//-------------------------------------------------------
+
+#define UNITY_TEST_ASSERT(condition, line, message) if (condition) {} else {UNITY_TEST_FAIL((UNITY_LINE_TYPE)line, message);}
+#define UNITY_TEST_ASSERT_NULL(pointer, line, message) UNITY_TEST_ASSERT(((pointer) == NULL), (UNITY_LINE_TYPE)line, message)
+#define UNITY_TEST_ASSERT_NOT_NULL(pointer, line, message) UNITY_TEST_ASSERT(((pointer) != NULL), (UNITY_LINE_TYPE)line, message)
+
+#define UNITY_TEST_ASSERT_EQUAL_INT(expected, actual, line, message) UnityAssertEqualNumber((_U_SINT)(expected), (_U_SINT)(actual), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_INT)
+#define UNITY_TEST_ASSERT_EQUAL_INT8(expected, actual, line, message) UnityAssertEqualNumber((_U_SINT)(_US8 )(expected), (_U_SINT)(_US8 )(actual), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_INT)
+#define UNITY_TEST_ASSERT_EQUAL_INT16(expected, actual, line, message) UnityAssertEqualNumber((_U_SINT)(_US16)(expected), (_U_SINT)(_US16)(actual), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_INT)
+#define UNITY_TEST_ASSERT_EQUAL_INT32(expected, actual, line, message) UnityAssertEqualNumber((_U_SINT)(_US32)(expected), (_U_SINT)(_US32)(actual), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_INT)
+#define UNITY_TEST_ASSERT_EQUAL_UINT(expected, actual, line, message) UnityAssertEqualNumber((_U_SINT)(expected), (_U_SINT)(actual), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_UINT)
+#define UNITY_TEST_ASSERT_EQUAL_UINT8(expected, actual, line, message) UnityAssertEqualNumber((_U_SINT)(_US8 )(expected), (_U_SINT)(_US8 )(actual), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_UINT)
+#define UNITY_TEST_ASSERT_EQUAL_UINT16(expected, actual, line, message) UnityAssertEqualNumber((_U_SINT)(_US16)(expected), (_U_SINT)(_US16)(actual), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_UINT)
+#define UNITY_TEST_ASSERT_EQUAL_UINT32(expected, actual, line, message) UnityAssertEqualNumber((_U_SINT)(_US32)(expected), (_U_SINT)(_US32)(actual), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_UINT)
+#define UNITY_TEST_ASSERT_EQUAL_HEX8(expected, actual, line, message) UnityAssertEqualNumber((_U_SINT)(_US8 )(expected), (_U_SINT)(_US8 )(actual), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_HEX8)
+#define UNITY_TEST_ASSERT_EQUAL_HEX16(expected, actual, line, message) UnityAssertEqualNumber((_U_SINT)(_US16)(expected), (_U_SINT)(_US16)(actual), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_HEX16)
+#define UNITY_TEST_ASSERT_EQUAL_HEX32(expected, actual, line, message) UnityAssertEqualNumber((_U_SINT)(_US32)(expected), (_U_SINT)(_US32)(actual), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_HEX32)
+#define UNITY_TEST_ASSERT_BITS(mask, expected, actual, line, message) UnityAssertBits((_U_SINT)(mask), (_U_SINT)(expected), (_U_SINT)(actual), (message), (UNITY_LINE_TYPE)line)
+
+#define UNITY_TEST_ASSERT_INT_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((_U_SINT)(delta), (_U_SINT)(expected), (_U_SINT)(actual), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_INT)
+#define UNITY_TEST_ASSERT_UINT_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((_U_SINT)(delta), (_U_SINT)(expected), (_U_SINT)(actual), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_UINT)
+#define UNITY_TEST_ASSERT_HEX8_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((_U_SINT)(_U_UINT)(_UU8 )(delta), (_U_SINT)(_U_UINT)(_UU8 )(expected), (_U_SINT)(_U_UINT)(_UU8 )(actual), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_HEX8)
+#define UNITY_TEST_ASSERT_HEX16_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((_U_SINT)(_U_UINT)(_UU16)(delta), (_U_SINT)(_U_UINT)(_UU16)(expected), (_U_SINT)(_U_UINT)(_UU16)(actual), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_HEX16)
+#define UNITY_TEST_ASSERT_HEX32_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((_U_SINT)(_U_UINT)(_UU32)(delta), (_U_SINT)(_U_UINT)(_UU32)(expected), (_U_SINT)(_U_UINT)(_UU32)(actual), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_HEX32)
+
+#define UNITY_TEST_ASSERT_EQUAL_PTR(expected, actual, line, message) UnityAssertEqualNumber((_U_SINT)(_UP)(expected), (_U_SINT)(_UP)(actual), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_POINTER)
+#define UNITY_TEST_ASSERT_EQUAL_STRING(expected, actual, line, message) UnityAssertEqualString((const char*)(expected), (const char*)(actual), (message), (UNITY_LINE_TYPE)line)
+#define UNITY_TEST_ASSERT_EQUAL_MEMORY(expected, actual, len, line, message) UnityAssertEqualMemory((void*)(expected), (void*)(actual), (_UU32)(len), 1, (message), (UNITY_LINE_TYPE)line)
+
+#define UNITY_TEST_ASSERT_EQUAL_INT_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((const _U_SINT*)(expected), (const _U_SINT*)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_INT)
+#define UNITY_TEST_ASSERT_EQUAL_INT8_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((const _U_SINT*)(expected), (const _U_SINT*)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_INT8)
+#define UNITY_TEST_ASSERT_EQUAL_INT16_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((const _U_SINT*)(expected), (const _U_SINT*)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_INT16)
+#define UNITY_TEST_ASSERT_EQUAL_INT32_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((const _U_SINT*)(expected), (const _U_SINT*)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_INT32)
+#define UNITY_TEST_ASSERT_EQUAL_UINT_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((const _U_SINT*)(expected), (const _U_SINT*)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_UINT)
+#define UNITY_TEST_ASSERT_EQUAL_UINT8_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((const _U_SINT*)(expected), (const _U_SINT*)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_UINT8)
+#define UNITY_TEST_ASSERT_EQUAL_UINT16_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((const _U_SINT*)(expected), (const _U_SINT*)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_UINT16)
+#define UNITY_TEST_ASSERT_EQUAL_UINT32_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((const _U_SINT*)(expected), (const _U_SINT*)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_UINT32)
+#define UNITY_TEST_ASSERT_EQUAL_HEX8_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((const _U_SINT*)(expected), (const _U_SINT*)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_HEX8)
+#define UNITY_TEST_ASSERT_EQUAL_HEX16_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((const _U_SINT*)(expected), (const _U_SINT*)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_HEX16)
+#define UNITY_TEST_ASSERT_EQUAL_HEX32_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((const _U_SINT*)(expected), (const _U_SINT*)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_HEX32)
+#define UNITY_TEST_ASSERT_EQUAL_PTR_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((const _U_SINT*)(_UP*)(expected), (const _U_SINT*)(_UP*)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_POINTER)
+#define UNITY_TEST_ASSERT_EQUAL_STRING_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualStringArray((const char**)(expected), (const char**)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)line)
+#define UNITY_TEST_ASSERT_EQUAL_MEMORY_ARRAY(expected, actual, len, num_elements, line, message) UnityAssertEqualMemory((void*)(expected), (void*)(actual), (_UU32)(len), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)line)
+
+#ifdef UNITY_SUPPORT_64
+#define UNITY_TEST_ASSERT_EQUAL_INT64(expected, actual, line, message) UnityAssertEqualNumber((_U_SINT)(expected), (_U_SINT)(actual), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_INT64)
+#define UNITY_TEST_ASSERT_EQUAL_UINT64(expected, actual, line, message) UnityAssertEqualNumber((_U_SINT)(expected), (_U_SINT)(actual), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_UINT64)
+#define UNITY_TEST_ASSERT_EQUAL_HEX64(expected, actual, line, message) UnityAssertEqualNumber((_U_SINT)(expected), (_U_SINT)(actual), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_HEX64)
+#define UNITY_TEST_ASSERT_EQUAL_INT64_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((const _U_SINT*)(expected), (const _U_SINT*)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_INT64)
+#define UNITY_TEST_ASSERT_EQUAL_UINT64_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((const _U_SINT*)(expected), (const _U_SINT*)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_UINT64)
+#define UNITY_TEST_ASSERT_EQUAL_HEX64_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((const _U_SINT*)(expected), (const _U_SINT*)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_HEX64)
+#define UNITY_TEST_ASSERT_HEX64_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((_U_SINT)(delta), (_U_SINT)(expected), (_U_SINT)(actual), NULL, (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_HEX64)
+#endif
+
+#ifdef UNITY_EXCLUDE_FLOAT
+#define UNITY_TEST_ASSERT_FLOAT_WITHIN(delta, expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)line, "Unity Floating Point Disabled")
+#define UNITY_TEST_ASSERT_EQUAL_FLOAT(expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)line, "Unity Floating Point Disabled")
+#define UNITY_TEST_ASSERT_EQUAL_FLOAT_ARRAY(expected, actual, num_elements, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)line, "Unity Floating Point Disabled")
+#else
+#define UNITY_TEST_ASSERT_FLOAT_WITHIN(delta, expected, actual, line, message) UnityAssertFloatsWithin((_UF)(delta), (_UF)(expected), (_UF)(actual), (message), (UNITY_LINE_TYPE)line)
+#define UNITY_TEST_ASSERT_EQUAL_FLOAT(expected, actual, line, message) UNITY_TEST_ASSERT_FLOAT_WITHIN((_UF)(expected) * (_UF)UNITY_FLOAT_PRECISION, (_UF)expected, (_UF)actual, (UNITY_LINE_TYPE)line, message)
+#define UNITY_TEST_ASSERT_EQUAL_FLOAT_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualFloatArray((_UF*)(expected), (_UF*)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)line)
+#endif
+
+#ifdef UNITY_EXCLUDE_DOUBLE
+#define UNITY_TEST_ASSERT_DOUBLE_WITHIN(delta, expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)line, "Unity Double Precision Disabled")
+#define UNITY_TEST_ASSERT_EQUAL_DOUBLE(expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)line, "Unity Double Precision Disabled")
+#define UNITY_TEST_ASSERT_EQUAL_DOUBLE_ARRAY(expected, actual, num_elements, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)line, "Unity Double Precision Disabled")
+#else
+#define UNITY_TEST_ASSERT_DOUBLE_WITHIN(delta, expected, actual, line, message) UnityAssertDoublesWithin((_UD)(delta), (_UD)(expected), (_UD)(actual), (message), (UNITY_LINE_TYPE)line)
+#define UNITY_TEST_ASSERT_EQUAL_DOUBLE(expected, actual, line, message) UNITY_TEST_ASSERT_DOUBLE_WITHIN((_UF)(expected) * (_UD)UNITY_DOUBLE_PRECISION, (_UD)expected, (_UD)actual, (UNITY_LINE_TYPE)line, message)
+#define UNITY_TEST_ASSERT_EQUAL_DOUBLE_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualDoubleArray((_UD*)(expected), (_UD*)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)line)
+#endif
+
+#endif