add tinyusb

This commit is contained in:
Joey Castillo
2021-08-28 12:50:18 -04:00
parent c9e00b83bb
commit 39a5c822a2
1054 changed files with 188322 additions and 0 deletions

View File

@@ -0,0 +1,46 @@
#include "CException.h"
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wmissing-field-initializers"
volatile CEXCEPTION_FRAME_T CExceptionFrames[CEXCEPTION_NUM_ID] = {{ 0 }};
#pragma GCC diagnostic pop
//------------------------------------------------------------------------------------------
// 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(ExceptionID);
}
//------------------------------------------------------------------------------------------
// 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
*/

View File

@@ -0,0 +1,115 @@
#ifndef _CEXCEPTION_H
#define _CEXCEPTION_H
#include <setjmp.h>
#ifdef __cplusplus
extern "C"
{
#endif
#define CEXCEPTION_VERSION_MAJOR 1
#define CEXCEPTION_VERSION_MINOR 3
#define CEXCEPTION_VERSION_BUILD 2
#define CEXCEPTION_VERSION ((CEXCEPTION_VERSION_MAJOR << 16) | (CEXCEPTION_VERSION_MINOR << 8) | CEXCEPTION_VERSION_BUILD)
//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
//These hooks allow you to inject custom code into places, particularly useful for saving and restoring additional state
#ifndef CEXCEPTION_HOOK_START_TRY
#define CEXCEPTION_HOOK_START_TRY
#endif
#ifndef CEXCEPTION_HOOK_HAPPY_TRY
#define CEXCEPTION_HOOK_HAPPY_TRY
#endif
#ifndef CEXCEPTION_HOOK_AFTER_TRY
#define CEXCEPTION_HOOK_AFTER_TRY
#endif
#ifndef CEXCEPTION_HOOK_START_CATCH
#define CEXCEPTION_HOOK_START_CATCH
#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[MY_ID].pFrame; \
CExceptionFrames[MY_ID].pFrame = (jmp_buf*)(&NewFrame); \
CExceptionFrames[MY_ID].Exception = CEXCEPTION_NONE; \
CEXCEPTION_HOOK_START_TRY; \
if (setjmp(NewFrame) == 0) { \
if (1)
//Catch (see C file for explanation)
#define Catch(e) \
else { } \
CExceptionFrames[MY_ID].Exception = CEXCEPTION_NONE; \
CEXCEPTION_HOOK_HAPPY_TRY; \
} \
else \
{ \
e = CExceptionFrames[MY_ID].Exception; \
(void)e; \
CEXCEPTION_HOOK_START_CATCH; \
} \
CExceptionFrames[MY_ID].pFrame = PrevFrame; \
CEXCEPTION_HOOK_AFTER_TRY; \
} \
if (CExceptionFrames[CEXCEPTION_GET_ID].Exception != CEXCEPTION_NONE)
//Throw an Error
void Throw(CEXCEPTION_T ExceptionID);
//Just exit the Try block and skip the Catch.
#define ExitTry() Throw(CEXCEPTION_NONE)
#ifdef __cplusplus
} // extern "C"
#endif
#endif // _CEXCEPTION_H

View File

@@ -0,0 +1,2 @@
18

View File

@@ -0,0 +1,2 @@
1.3.1

View File

@@ -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

View File

@@ -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

View File

@@ -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]
# ==========================================
[ "../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
def option_maker(options, key, val)
options = options || {}
options[key.to_sym] =
if val.chr == ":"
val[1..-1].to_sym
elsif val.include? ";"
val.split(';')
elsif val == 'true'
true
elsif val == 'false'
false
elsif val =~ /^\d+$/
val.to_i
else
val
end
options
end
# Command Line Support ###############################
if ($0 == __FILE__)
usage = "usage: ruby #{__FILE__} (-oOptionsFile) File(s)ToMock"
if (!ARGV[0])
puts usage
exit 1
end
options = {}
filelist = []
ARGV.each do |arg|
if (arg =~ /^-o\"?([a-zA-Z0-9._\\\/:\s]+)\"?/)
options.merge! CMockConfig.load_config_file_from_yaml( arg.gsub(/^-o/,'') )
elsif (arg =~ /^--([a-zA-Z0-9._\\\/:\s]+)=\"?([a-zA-Z0-9._\-\\\/:\s\;]+)\"?/)
options = option_maker(options, $1, $2)
else
filelist << arg
end
end
CMock.new(options).setup_mocks(filelist)
end

View File

@@ -0,0 +1,153 @@
# ==========================================
# 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',
:mock_suffix => '',
:weak => '',
:subdir => nil,
:plugins => [],
:strippables => ['(?:__attribute__\s*\(+.*?\)+)'],
:attributes => ['__ramfunc', '__irq', '__fiq', 'register', 'extern'],
:c_calling_conventions => ['__stdcall', '__cdecl', '__fastcall'],
:enforce_strict_ordering => false,
:fail_on_unexpected_calls => true,
:unity_helper_path => false,
:treat_as => {},
:treat_as_array => {},
: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
: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,
:orig_header_include_fmt => "#include \"%s\"",
:array_size_type => [],
:array_size_name => 'size|len',
}
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[:unity_helper_path] = [options[:unity_helper_path]] if options[:unity_helper_path].is_a? String
options[:includes_c_post_header] = ((options[:includes_c_post_header] || []) + (options[:unity_helper_path] || [])).uniq
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 do |key|
unless methods.include?(key)
eval("def #{key.to_s}() return @options[:#{key.to_s}] end")
end
end
end
def load_config_file_from_yaml yaml_filename
self.class.load_config_file_from_yaml yaml_filename
end
def self.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 nil unless (@options[:unity_helper_path])
return @options[:unity_helper_path].inject("") do |unity_helper, filename|
unity_helper + "\n" + File.new(filename).read
end
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*' => 'HEX8_ARRAY',
'void const*' => 'HEX8_ARRAY',
'const void*' => 'HEX8_ARRAY',
'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',
'char const*' => 'STRING',
'const char*' => 'STRING',
'pCHAR' => 'STRING',
'cstring' => 'STRING',
'CSTRING' => 'STRING',
'float' => 'FLOAT',
'double' => 'FLOAT'
}
end
end

View File

@@ -0,0 +1,44 @@
# ==========================================
# 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_subdir(subdir)
if !Dir.exists?("#{@config.mock_path}/")
require 'fileutils'
FileUtils.mkdir_p "#{@config.mock_path}/"
end
if subdir && !Dir.exists?("#{@config.mock_path}/#{subdir+'/' if subdir}")
require 'fileutils'
FileUtils.mkdir_p "#{@config.mock_path}/#{subdir+'/' if subdir}"
end
end
def create_file(filename, subdir)
raise "Where's the block of data to create?" unless block_given?
full_file_name_temp = "#{@config.mock_path}/#{subdir+'/' if subdir}#{filename}.new"
full_file_name_done = "#{@config.mock_path}/#{subdir+'/' if subdir}#{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

View File

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

View File

@@ -0,0 +1,63 @@
# ==========================================
# 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 do |m|
type = @utils.arg_type_with_const(m)
m[:ptr?] ? "#{type} #{m[:name]}, int #{m[:name]}_Depth" : "#{type} #{m[:name]}"
end.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 do |m|
type = @utils.arg_type_with_const(m)
m[:ptr?] ? "#{type} #{m[:name]}, int #{m[:name]}_Depth" : "#{type} #{m[:name]}"
end.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

View File

@@ -0,0 +1,88 @@
# ==========================================
# 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
end
def instance_structure(function)
func_name = function[:name]
" int #{func_name}_CallbackBool;\n" \
" CMOCK_#{func_name}_CALLBACK #{func_name}_CallbackFunctionPointer;\n" \
" int #{func_name}_CallbackCalls;\n"
end
def mock_function_declarations(function)
func_name = function[:name]
return_type = function[:return][:type]
action = @config.callback_after_arg_check ? 'AddCallback' : 'Stub'
style = (@include_count ? 1 : 0) | (function[:args].empty? ? 0 : 2)
styles = [ "void", "int cmock_num_calls", function[:args_string], "#{function[:args_string]}, int cmock_num_calls" ]
"typedef #{return_type} (* CMOCK_#{func_name}_CALLBACK)(#{styles[style]});\n" \
"void #{func_name}_AddCallback(CMOCK_#{func_name}_CALLBACK Callback);\n" \
"void #{func_name}_Stub(CMOCK_#{func_name}_CALLBACK Callback);\n" \
"#define #{func_name}_StubWithCallback #{func_name}_#{action}\n"
end
def generate_call(function)
args = function[:args].map { |m| m[:name] }
args << "Mock.#{function[:name]}_CallbackCalls++" if @include_count
"Mock.#{function[:name]}_CallbackFunctionPointer(#{args.join(', ')})"
end
def mock_implementation(function)
" if (Mock.#{function[:name]}_CallbackFunctionPointer != NULL)\n {\n" +
if function[:return][:void?]
" #{generate_call(function)};\n }\n"
else
" cmock_call_instance->ReturnVal = #{generate_call(function)};\n }\n"
end
end
def mock_implementation_precheck(function)
" if (!Mock.#{function[:name]}_CallbackBool &&\n" \
" Mock.#{function[:name]}_CallbackFunctionPointer != NULL)\n {\n" +
if function[:return][:void?]
" #{generate_call(function)};\n" \
" UNITY_CLR_DETAILS();\n" \
" return;\n }\n"
else
" #{function[:return][:type]} ret = #{generate_call(function)};\n" \
" UNITY_CLR_DETAILS();\n" \
" return ret;\n }\n"
end
end
def mock_interfaces(function)
func_name = function[:name]
has_ignore = @config.plugins.include? :ignore
lines = ""
lines << "void #{func_name}_AddCallback(CMOCK_#{func_name}_CALLBACK Callback)\n{\n"
lines << " Mock.#{func_name}_IgnoreBool = (int)0;\n" if has_ignore
lines << " Mock.#{func_name}_CallbackBool = (int)1;\n"
lines << " Mock.#{func_name}_CallbackFunctionPointer = Callback;\n}\n\n"
lines << "void #{func_name}_Stub(CMOCK_#{func_name}_CALLBACK Callback)\n{\n"
lines << " Mock.#{func_name}_IgnoreBool = (int)0;\n" if has_ignore
lines << " Mock.#{func_name}_CallbackBool = (int)0;\n"
lines << " Mock.#{func_name}_CallbackFunctionPointer = Callback;\n}\n\n"
end
def mock_verify(function)
func_name = function[:name]
" if (Mock.#{func_name}_CallbackFunctionPointer != NULL)\n call_instance = CMOCK_GUTS_NONE;\n"
end
end

View File

@@ -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" +
" UNITY_CLR_DETAILS();\n" +
" Throw(cmock_call_instance->ExceptionToThrow);\n }\n"
end
def mock_interfaces(function)
arg_insert = (function[:args_string] == "void") ? "" : "#{function[:args_string]}, "
[ "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

View File

@@ -0,0 +1,103 @@
# ==========================================
# 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
if (@config.plugins.include? :expect_any_args)
alias :mock_implementation :mock_implementation_might_check_args
else
alias :mock_implementation :mock_implementation_always_check_args
end
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_always_check_args(function)
lines = ""
function[:args].each do |arg|
lines << @utils.code_verify_an_arg_expectation(function, arg)
end
lines
end
def mock_implementation_might_check_args(function)
return "" if (function[:args].empty?)
lines = " if (!cmock_call_instance->ExpectAnyArgsBool)\n {\n"
function[:args].each do |arg|
lines << @utils.code_verify_an_arg_expectation(function, arg)
end
lines << " }\n"
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)
" UNITY_SET_DETAIL(CMockString_#{function[:name]});\n" +
" UNITY_TEST_ASSERT(CMOCK_GUTS_NONE == call_instance, cmock_line, CMockStringCalledLess);\n" +
" UNITY_CLR_DETAILS();\n"
end
end

View File

@@ -0,0 +1,53 @@
# ==========================================
# 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 CMockGeneratorPluginExpectAnyArgs
attr_reader :priority
attr_reader :config, :utils
def initialize(config, utils)
@config = config
@utils = utils
@priority = 3
end
def instance_typedefs(function)
" int ExpectAnyArgsBool;\n"
end
def mock_function_declarations(function)
unless (function[:args].empty?)
if (function[:return][:void?])
return "#define #{function[:name]}_ExpectAnyArgs() #{function[:name]}_CMockExpectAnyArgs(__LINE__)\n" +
"void #{function[:name]}_CMockExpectAnyArgs(UNITY_LINE_TYPE cmock_line);\n"
else
return "#define #{function[:name]}_ExpectAnyArgsAndReturn(cmock_retval) #{function[:name]}_CMockExpectAnyArgsAndReturn(__LINE__, cmock_retval)\n" +
"void #{function[:name]}_CMockExpectAnyArgsAndReturn(UNITY_LINE_TYPE cmock_line, #{function[:return][:str]});\n"
end
else
""
end
end
def mock_interfaces(function)
lines = ""
unless (function[:args].empty?)
if (function[:return][:void?])
lines << "void #{function[:name]}_CMockExpectAnyArgs(UNITY_LINE_TYPE cmock_line)\n{\n"
else
lines << "void #{function[:name]}_CMockExpectAnyArgsAndReturn(UNITY_LINE_TYPE cmock_line, #{function[:return][:str]})\n{\n"
end
lines << @utils.code_add_base_expectation(function[:name], true)
unless (function[:return][:void?])
lines << " cmock_call_instance->ReturnVal = cmock_to_return;\n"
end
lines << " cmock_call_instance->ExpectAnyArgsBool = (int)1;\n"
lines << "}\n\n"
end
return lines
end
end

View File

@@ -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 CMockGeneratorPluginIgnore
attr_reader :priority
attr_reader :config, :utils
def initialize(config, utils)
@config = config
@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?])
return "#define #{function[:name]}_Ignore() #{function[:name]}_CMockIgnore()\n" +
"void #{function[:name]}_CMockIgnore(void);\n"
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_precheck(function)
lines = " if (Mock.#{function[:name]}_IgnoreBool)\n {\n"
lines << " UNITY_CLR_DETAILS();\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 = ""
if (function[:return][:void?])
lines << "void #{function[:name]}_CMockIgnore(void)\n{\n"
else
lines << "void #{function[:name]}_CMockIgnoreAndReturn(UNITY_LINE_TYPE cmock_line, #{function[:return][:str]})\n{\n"
end
if (!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_ignore(function)
" Mock.#{function[:name]}_IgnoreBool = (int) 1;\n"
end
def mock_verify(function)
func_name = function[:name]
" if (Mock.#{func_name}_IgnoreBool)\n call_instance = CMOCK_GUTS_NONE;\n"
end
end

View File

@@ -0,0 +1,42 @@
class CMockGeneratorPluginIgnoreArg
attr_reader :priority
attr_accessor :utils
def initialize(config, utils)
@utils = utils
@priority = 10
end
def instance_typedefs(function)
lines = ""
function[:args].each do |arg|
lines << " int IgnoreArg_#{arg[:name]};\n"
end
lines
end
def mock_function_declarations(function)
lines = ""
function[:args].each do |arg|
lines << "#define #{function[:name]}_IgnoreArg_#{arg[:name]}()"
lines << " #{function[:name]}_CMockIgnoreArg_#{arg[:name]}(__LINE__)\n"
lines << "void #{function[:name]}_CMockIgnoreArg_#{arg[:name]}(UNITY_LINE_TYPE cmock_line);\n"
end
lines
end
def mock_interfaces(function)
lines = []
func_name = function[:name]
function[:args].each do |arg|
lines << "void #{func_name}_CMockIgnoreArg_#{arg[:name]}(UNITY_LINE_TYPE cmock_line)\n"
lines << "{\n"
lines << " CMOCK_#{func_name}_CALL_INSTANCE* cmock_call_instance = " +
"(CMOCK_#{func_name}_CALL_INSTANCE*)CMock_Guts_GetAddressFor(CMock_Guts_MemEndOfChain(Mock.#{func_name}_CallInstance));\n"
lines << " UNITY_TEST_ASSERT_NOT_NULL(cmock_call_instance, cmock_line, CMockStringIgnPreExp);\n"
lines << " cmock_call_instance->IgnoreArg_#{arg[:name]} = 1;\n"
lines << "}\n\n"
end
lines
end
end

View File

@@ -0,0 +1,79 @@
class CMockGeneratorPluginReturnThruPtr
attr_reader :priority
attr_accessor :utils
def initialize(config, utils)
@utils = utils
@priority = 9
end
def instance_typedefs(function)
lines = ""
function[:args].each do |arg|
if (@utils.ptr_or_str?(arg[:type]) and not arg[:const?])
lines << " int ReturnThruPtr_#{arg[:name]}_Used;\n"
lines << " #{arg[:type]} ReturnThruPtr_#{arg[:name]}_Val;\n"
lines << " int ReturnThruPtr_#{arg[:name]}_Size;\n"
end
end
lines
end
def mock_function_declarations(function)
lines = ""
function[:args].each do |arg|
if (@utils.ptr_or_str?(arg[:type]) and not arg[:const?])
lines << "#define #{function[:name]}_ReturnThruPtr_#{arg[:name]}(#{arg[:name]})"
# If the pointer type actually contains an asterisk, we can do sizeof the type (super safe), otherwise
# we need to do a sizeof the dereferenced pointer (which could be a problem if give the wrong size
if (arg[:type][-1] == '*')
lines << " #{function[:name]}_CMockReturnMemThruPtr_#{arg[:name]}(__LINE__, #{arg[:name]}, sizeof(#{arg[:type][0..-2]}))\n"
else
lines << " #{function[:name]}_CMockReturnMemThruPtr_#{arg[:name]}(__LINE__, #{arg[:name]}, sizeof(*#{arg[:name]}))\n"
end
lines << "#define #{function[:name]}_ReturnArrayThruPtr_#{arg[:name]}(#{arg[:name]}, cmock_len)"
lines << " #{function[:name]}_CMockReturnMemThruPtr_#{arg[:name]}(__LINE__, #{arg[:name]}, (int)(cmock_len * (int)sizeof(*#{arg[:name]})))\n"
lines << "#define #{function[:name]}_ReturnMemThruPtr_#{arg[:name]}(#{arg[:name]}, cmock_size)"
lines << " #{function[:name]}_CMockReturnMemThruPtr_#{arg[:name]}(__LINE__, #{arg[:name]}, cmock_size)\n"
lines << "void #{function[:name]}_CMockReturnMemThruPtr_#{arg[:name]}(UNITY_LINE_TYPE cmock_line, #{arg[:type]} #{arg[:name]}, int cmock_size);\n"
end
end
lines
end
def mock_interfaces(function)
lines = []
func_name = function[:name]
function[:args].each do |arg|
arg_name = arg[:name]
if (@utils.ptr_or_str?(arg[:type]) and not arg[:const?])
lines << "void #{func_name}_CMockReturnMemThruPtr_#{arg_name}(UNITY_LINE_TYPE cmock_line, #{arg[:type]} #{arg_name}, int cmock_size)\n"
lines << "{\n"
lines << " CMOCK_#{func_name}_CALL_INSTANCE* cmock_call_instance = " +
"(CMOCK_#{func_name}_CALL_INSTANCE*)CMock_Guts_GetAddressFor(CMock_Guts_MemEndOfChain(Mock.#{func_name}_CallInstance));\n"
lines << " UNITY_TEST_ASSERT_NOT_NULL(cmock_call_instance, cmock_line, CMockStringPtrPreExp);\n"
lines << " cmock_call_instance->ReturnThruPtr_#{arg_name}_Used = 1;\n"
lines << " cmock_call_instance->ReturnThruPtr_#{arg_name}_Val = #{arg_name};\n"
lines << " cmock_call_instance->ReturnThruPtr_#{arg_name}_Size = cmock_size;\n"
lines << "}\n\n"
end
end
lines
end
def mock_implementation(function)
lines = []
function[:args].each do |arg|
arg_name = arg[:name]
if (@utils.ptr_or_str?(arg[:type]) and not arg[:const?])
lines << " if (cmock_call_instance->ReturnThruPtr_#{arg_name}_Used)\n"
lines << " {\n"
lines << " UNITY_TEST_ASSERT_NOT_NULL(#{arg_name}, cmock_line, CMockStringPtrIsNULL);\n"
lines << " memcpy((void*)#{arg_name}, (void*)cmock_call_instance->ReturnThruPtr_#{arg_name}_Val,\n"
lines << " cmock_call_instance->ReturnThruPtr_#{arg_name}_Size);\n"
lines << " }\n"
end
end
lines
end
end

View File

@@ -0,0 +1,253 @@
# ==========================================
# 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
@expect_any = @config.plugins.include? :expect_any_args
@return_thru_ptr = @config.plugins.include? :return_thru_ptr
@ignore_arg = @config.plugins.include? :ignore_arg
@ignore = @config.plugins.include? :ignore
@treat_as = @config.treat_as
@helpers = helpers
end
def self.arg_type_with_const(arg)
# Restore any "const" that was removed in header parsing
if arg[:type].include?('*')
arg[:const_ptr?] ? "#{arg[:type]} const" : arg[:type]
else
arg[:const?] ? "const #{arg[:type]}" : arg[:type]
end
end
def arg_type_with_const(arg)
self.class.arg_type_with_const(arg)
end
def code_verify_an_arg_expectation(function, arg)
if (@arrays)
case(@ptr_handling)
when :smart then code_verify_an_arg_expectation_with_smart_arrays(function, arg)
when :compare_data then code_verify_an_arg_expectation_with_normal_arrays(function, arg)
when :compare_ptr then raise "ERROR: the array plugin doesn't enjoy working with :compare_ptr only. Disable one option."
end
else
code_verify_an_arg_expectation_with_no_arrays(function, arg)
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, CMockStringOutOfMemory);\n"
lines << " memset(cmock_call_instance, 0, sizeof(*cmock_call_instance));\n"
lines << " Mock.#{func_name}_CallInstance = CMock_Guts_MemChain(Mock.#{func_name}_CallInstance, cmock_guts_index);\n"
lines << " Mock.#{func_name}_IgnoreBool = (int)0;\n" if (@ignore)
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 << " cmock_call_instance->ExpectAnyArgsBool = (int)0;\n" if (@expect_any)
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 << " cmock_call_instance->IgnoreArg_#{arg[:name]} = 0;\n" if (@ignore_arg)
lines << " cmock_call_instance->ReturnThruPtr_#{arg[:name]}_Used = 0;\n" if (@return_thru_ptr and ptr_or_str?(arg[:type]) and not arg[:const?])
lines
end
def code_assign_argument_quickly(dest, arg)
if (arg[:ptr?] or @treat_as.include?(arg[:type]))
" #{dest} = #{arg[:name]};\n"
else
assert_expr = "sizeof(#{arg[:name]}) == sizeof(#{arg[:type]}) ? 1 : -1"
comment = "/* add #{arg[:type]} to :treat_as_array if this causes an error */"
" memcpy((void*)(&#{dest}), (void*)(&#{arg[:name]}),\n" +
" sizeof(#{arg[:type]}[#{assert_expr}])); #{comment}\n"
end
end
def code_add_argument_loader(function)
if (function[:args_string] != "void")
if (@arrays)
args_string = function[:args].map do |m|
type = arg_type_with_const(m)
m[:ptr?] ? "#{type} #{m[:name]}, int #{m[:name]}_Depth" : "#{type} #{m[:name]}"
end.join(', ')
"void CMockExpectParameters_#{function[:name]}(CMOCK_#{function[:name]}_CALL_INSTANCE* cmock_call_instance, #{args_string});\n" +
"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" +
"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|
if (@arrays and m[:ptr?] and not m[:array_data?])
"#{m[:name]}, 1"
elsif (@arrays and m[:array_size?])
"#{m[:name]}, #{m[:name]}"
else
m[:name]
end
end
" CMockExpectParameters_#{function[:name]}(cmock_call_instance, #{args.join(', ')});\n"
else
""
end
end
def ptr_or_str?(arg_type)
return (arg_type.include? '*' or
@treat_as.fetch(arg_type, "").include? '*')
end
#private ######################
def lookup_expect_type(function, arg)
c_type = arg[:type]
arg_name = arg[:name]
expected = "cmock_call_instance->Expected_#{arg_name}"
ignore = "cmock_call_instance->IgnoreArg_#{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
return c_type, arg_name, expected, ignore, unity_func[0], unity_func[1]
end
def code_verify_an_arg_expectation_with_no_arrays(function, arg)
c_type, arg_name, expected, ignore, unity_func, pre = lookup_expect_type(function, arg)
lines = ""
lines << " if (!#{ignore})\n" if @ignore_arg
lines << " {\n"
lines << " UNITY_SET_DETAILS(CMockString_#{function[:name]},CMockString_#{arg_name});\n"
case(unity_func)
when "UNITY_TEST_ASSERT_EQUAL_MEMORY"
c_type_local = c_type.gsub(/\*$/,'')
lines << " UNITY_TEST_ASSERT_EQUAL_MEMORY((void*)(#{pre}#{expected}), (void*)(#{pre}#{arg_name}), sizeof(#{c_type_local}), cmock_line, CMockStringMismatch);\n"
when "UNITY_TEST_ASSERT_EQUAL_MEMORY_ARRAY"
if (pre == '&')
lines << " UNITY_TEST_ASSERT_EQUAL_MEMORY((void*)(#{pre}#{expected}), (void*)(#{pre}#{arg_name}), sizeof(#{c_type.sub('*','')}), cmock_line, CMockStringMismatch);\n"
else
lines << " if (#{pre}#{expected} == NULL)\n"
lines << " { UNITY_TEST_ASSERT_NULL(#{pre}#{arg_name}, cmock_line, CMockStringExpNULL); }\n"
lines << " else\n"
lines << " { UNITY_TEST_ASSERT_EQUAL_MEMORY((void*)(#{pre}#{expected}), (void*)(#{pre}#{arg_name}), sizeof(#{c_type.sub('*','')}), cmock_line, CMockStringMismatch); }\n"
end
when /_ARRAY/
if (pre == '&')
lines << " #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, 1, cmock_line, CMockStringMismatch);\n"
else
lines << " if (#{pre}#{expected} == NULL)\n"
lines << " { UNITY_TEST_ASSERT_NULL(#{pre}#{arg_name}, cmock_line, CMockStringExpNULL); }\n"
lines << " else\n"
lines << " { #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, 1, cmock_line, CMockStringMismatch); }\n"
end
else
lines << " #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, cmock_line, CMockStringMismatch);\n"
end
lines << " }\n"
lines
end
def code_verify_an_arg_expectation_with_normal_arrays(function, arg)
c_type, arg_name, expected, ignore, unity_func, pre = lookup_expect_type(function, arg)
depth_name = (arg[:ptr?]) ? "cmock_call_instance->Expected_#{arg_name}_Depth" : 1
lines = ""
lines << " if (!#{ignore})\n" if @ignore_arg
lines << " {\n"
lines << " UNITY_SET_DETAILS(CMockString_#{function[:name]},CMockString_#{arg_name});\n"
lines << " if (#{pre}#{expected} != #{pre}#{arg_name}) {\n"
case(unity_func)
when "UNITY_TEST_ASSERT_EQUAL_MEMORY"
c_type_local = c_type.gsub(/\*$/,'')
lines << " UNITY_TEST_ASSERT_EQUAL_MEMORY((void*)(#{pre}#{expected}), (void*)(#{pre}#{arg_name}), sizeof(#{c_type_local}), cmock_line, CMockStringMismatch);\n"
when "UNITY_TEST_ASSERT_EQUAL_MEMORY_ARRAY"
if (pre == '&')
lines << " UNITY_TEST_ASSERT_EQUAL_MEMORY((void*)(#{pre}#{expected}), (void*)(#{pre}#{arg_name}), sizeof(#{c_type.sub('*','')}), cmock_line, CMockStringMismatch);\n"
else
lines << " if (#{pre}#{expected} == NULL)\n"
lines << " { UNITY_TEST_ASSERT_NULL(#{pre}#{arg_name}, cmock_line, CMockStringExpNULL); }\n"
lines << " else\n"
lines << " { UNITY_TEST_ASSERT_EQUAL_MEMORY_ARRAY((void*)(#{pre}#{expected}), (void*)(#{pre}#{arg_name}), sizeof(#{c_type.sub('*','')}), #{depth_name}, cmock_line, CMockStringMismatch); }\n"
end
when /_ARRAY/
if (pre == '&')
lines << " #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, #{depth_name}, cmock_line, CMockStringMismatch);\n"
else
lines << " if (#{pre}#{expected} == NULL)\n"
lines << " { UNITY_TEST_ASSERT_NULL(#{pre}#{arg_name}, cmock_line, CMockStringExpNULL); }\n"
lines << " else\n"
lines << " { #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, #{depth_name}, cmock_line, CMockStringMismatch); }\n"
end
else
lines << " #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, cmock_line, CMockStringMismatch);\n"
end
lines << " }\n }\n"
lines
end
def code_verify_an_arg_expectation_with_smart_arrays(function, arg)
c_type, arg_name, expected, ignore, unity_func, pre = lookup_expect_type(function, arg)
depth_name = (arg[:ptr?]) ? "cmock_call_instance->Expected_#{arg_name}_Depth" : 1
lines = ""
lines << " if (!#{ignore})\n" if @ignore_arg
lines << " {\n"
lines << " UNITY_SET_DETAILS(CMockString_#{function[:name]},CMockString_#{arg_name});\n"
lines << " if (#{pre}#{expected} != #{pre}#{arg_name}) {\n"
case(unity_func)
when "UNITY_TEST_ASSERT_EQUAL_MEMORY"
c_type_local = c_type.gsub(/\*$/,'')
lines << " UNITY_TEST_ASSERT_EQUAL_MEMORY((void*)(#{pre}#{expected}), (void*)(#{pre}#{arg_name}), sizeof(#{c_type_local}), cmock_line, CMockStringMismatch);\n"
when "UNITY_TEST_ASSERT_EQUAL_MEMORY_ARRAY"
if (pre == '&')
lines << " UNITY_TEST_ASSERT_EQUAL_MEMORY_ARRAY((void*)(#{pre}#{expected}), (void*)(#{pre}#{arg_name}), sizeof(#{c_type.sub('*','')}), #{depth_name}, cmock_line, CMockStringMismatch);\n"
else
lines << " if (#{pre}#{expected} == NULL)\n"
lines << " { UNITY_TEST_ASSERT_NULL(#{arg_name}, cmock_line, CMockStringExpNULL); }\n"
lines << ((depth_name != 1) ? " else if (#{depth_name} == 0)\n { UNITY_TEST_ASSERT_EQUAL_PTR(#{pre}#{expected}, #{pre}#{arg_name}, cmock_line, CMockStringMismatch); }\n" : "")
lines << " else\n"
lines << " { UNITY_TEST_ASSERT_EQUAL_MEMORY_ARRAY((void*)(#{pre}#{expected}), (void*)(#{pre}#{arg_name}), sizeof(#{c_type.sub('*','')}), #{depth_name}, cmock_line, CMockStringMismatch); }\n"
end
when /_ARRAY/
if (pre == '&')
lines << " #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, #{depth_name}, cmock_line, CMockStringMismatch);\n"
else
lines << " if (#{pre}#{expected} == NULL)\n"
lines << " { UNITY_TEST_ASSERT_NULL(#{pre}#{arg_name}, cmock_line, CMockStringExpNULL); }\n"
lines << ((depth_name != 1) ? " else if (#{depth_name} == 0)\n { UNITY_TEST_ASSERT_EQUAL_PTR(#{pre}#{expected}, #{pre}#{arg_name}, cmock_line, CMockStringMismatch); }\n" : "")
lines << " else\n"
lines << " { #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, #{depth_name}, cmock_line, CMockStringMismatch); }\n"
end
else
lines << " #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, cmock_line, CMockStringMismatch);\n"
end
lines << " }\n }\n"
lines
end
end

View File

@@ -0,0 +1,364 @@
# ==========================================
# 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_attr_noconst, :c_attributes, :treat_as_void, :treat_externs
def initialize(cfg)
@funcs = []
@c_strippables = cfg.strippables
@c_attr_noconst = cfg.attributes.uniq - ['const']
@c_attributes = ['const'] + c_attr_noconst
@c_calling_conventions = cfg.c_calling_conventions.uniq
@treat_as_array = cfg.treat_as_array
@treat_as_void = (['void'] + cfg.treat_as_void).uniq
@declaration_parse_matcher = /([\w\s\*\(\),\[\]]+??)\(([\w\s\*\(\),\.\[\]+-]*)\)$/m
@standards = (['int','short','char','long','unsigned','signed'] + cfg.treat_as.keys).uniq
@array_size_name = cfg.array_size_name
@array_size_type = (['int', 'size_t'] + cfg.array_size_type).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)
# let's clean up the encoding in case they've done anything weird with the characters we might find
source = source.force_encoding("ISO-8859-1").encode("utf-8", :replace => nil)
# 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]+)\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!(/__attribute(?:__)?\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|typedef)[\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[^;]*/m, '') # remove typedef statements
source.gsub!(/\)(\w)/, ') \1') # add space between parenthese and alphanumeric
source.gsub!(/(^|\W+)(?:#{@c_strippables.join('|')})(?=$|\W+)/,'\1') unless @c_strippables.empty? # remove known attributes slated to be stripped
#scan standalone function pointers and remove them, because they can just be ignored
source.gsub!(/\w+\s*\(\s*\*\s*\w+\s*\)\s*\([^)]*\)\s*;/,';')
#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
# remove nested pairs of braces because no function declarations will be inside of them (leave outer pair for function definition detection)
if (RUBY_VERSION.split('.')[0].to_i > 1)
#we assign a string first because (no joke) if Ruby 1.9.3 sees this line as a regex, it will crash.
r = "\\{([^\\{\\}]*|\\g<0>)*\\}"
source.gsub!(/#{r}/m, '{ }')
else
while source.gsub!(/\{[^\{\}]*\{[^\{\}]*\}[^\{\}]*\}/m, '{ }')
end
end
# remove function definitions by stripping off the arguments right now
source.gsub!(/\([^\)]*\)\s*\{[^\}]*\}/m, ";")
#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*/).uniq
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
src_lines.delete_if {|line| line.empty? } #drop empty lines
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_type_and_name(arg)
# Split up words and remove known attributes. For pointer types, make sure
# to remove 'const' only when it applies to the pointer itself, not when it
# applies to the type pointed to. For non-pointer types, remove any
# occurrence of 'const'.
arg.gsub!(/(\w)\*/,'\1 *') # pull asterisks away from preceding word
arg.gsub!(/\*(\w)/,'* \1') # pull asterisks away from following word
arg_array = arg.split
arg_info = divine_ptr_and_const(arg)
arg_info[:name] = arg_array[-1]
attributes = arg.include?('*') ? @c_attr_noconst : @c_attributes
attr_array = []
type_array = []
arg_array[0..-2].each do |word|
if attributes.include?(word)
attr_array << word
elsif @c_calling_conventions.include?(word)
arg_info[:c_calling_convention] = word
else
type_array << word
end
end
if arg_info[:const_ptr?]
attr_array << 'const'
type_array.delete_at(type_array.rindex('const'))
end
arg_info[:modifier] = attr_array.join(' ')
arg_info[:type] = type_array.join(' ').gsub(/\s+\*/,'*') # remove space before asterisks
return arg_info
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_info = parse_type_and_name(arg)
arg_info.delete(:modifier) # don't care about this
arg_info.delete(:c_calling_convention) # don't care about this
# in C, array arguments implicitly degrade to pointers
# make the translation explicit here to simplify later logic
if @treat_as_array[arg_info[:type]] and not arg_info[:ptr?] then
arg_info[:type] = "#{@treat_as_array[arg_info[:type]]}*"
arg_info[:type] = "const #{arg_info[:type]}" if arg_info[:const?]
arg_info[:ptr?] = true
end
args << arg_info
end
# Try to find array pair in parameters following this pattern : <type> * <name>, <@array_size_type> <@array_size_name>
args.each_with_index {|val, index|
next_index = index + 1
if (args.length > next_index)
if (val[:ptr?] == true and args[next_index][:name].match(@array_size_name) and @array_size_type.include?(args[next_index][:type]))
val[:array_data?] = true
args[next_index][:array_size?] = true
end
end
}
return args
end
def divine_ptr(arg)
return false unless arg.include? '*'
# treat "const char *" and similar as a string, not a pointer
return false if /(^|\s)(const\s+)?char(\s+const)?\s*\*(?!.*\*)/ =~ arg
return true
end
def divine_const(arg)
# a non-pointer arg containing "const" is a constant
# an arg containing "const" before the last * is a pointer to a constant
return ( arg.include?('*') ? (/(^|\s|\*)const(\s(\w|\s)*)?\*(?!.*\*)/ =~ arg)
: (/(^|\s)const(\s|$)/ =~ arg) ) ? true : false
end
def divine_ptr_and_const(arg)
divination = {}
divination[:ptr?] = divine_ptr(arg)
divination[:const?] = divine_const(arg)
# an arg containing "const" after the last * is a constant pointer
divination[:const_ptr?] = (/\*(?!.*\*)\s*const(\s|$)/ =~ arg) ? true : false
return divination
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*\(*[\s\w+-]*\)*\s*\])+/,'*\1') # magically turn brackets into asterisks, also match for parentheses that come from macros
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
parsed = parse_type_and_name(regex_match[1])
decl[:name] = parsed[:name]
decl[:modifier] = parsed[:modifier]
unless parsed[:c_calling_convention].nil?
decl[:c_calling_convention] = parsed[:c_calling_convention]
end
rettype = parsed[:type]
rettype = 'void' if (@local_as_void.include?(rettype.strip))
decl[:return] = { :type => rettype,
:name => 'cmock_to_return',
:str => "#{rettype} cmock_to_return",
:void? => (rettype == 'void'),
:ptr? => parsed[:ptr?],
:const? => parsed[:const?],
:const_ptr? => parsed[:const_ptr?]
}
#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

View File

@@ -0,0 +1,55 @@
# ==========================================
# 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]
# ==========================================
require 'thread'
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)
self.class.plugin_require_mutex.synchronize { load_plugin(plugin_name, object_name, config, utils) }
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
private
def self.plugin_require_mutex
@mutex ||= Mutex.new
end
def load_plugin(plugin_name, object_name, config, utils)
begin
unless (Object.const_defined? object_name)
file_name = "#{File.expand_path(File.dirname(__FILE__))}/cmock_generator_plugin_#{plugin_name.downcase}.rb"
require file_name
end
class_name = Object.const_get(object_name)
@plugins << class_name.new(config, utils)
rescue
file_name = "#{File.expand_path(File.dirname(__FILE__))}/cmock_generator_plugin_#{plugin_name.downcase}.rb"
raise "ERROR: CMock unable to load plugin '#{plugin_name}' '#{object_name}' #{file_name}"
end
end
end

View File

@@ -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

View File

@@ -0,0 +1,2 @@
217

View File

@@ -0,0 +1,2 @@
2.4.6

View File

@@ -0,0 +1,216 @@
/* ==========================================
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 "cmock.h"
//public constants to be used by mocks
const char* CMockStringOutOfMemory = "CMock has run out of memory. Please allocate more.";
const char* CMockStringCalledMore = "Called more times than expected.";
const char* CMockStringCalledLess = "Called fewer times than expected.";
const char* CMockStringCalledEarly = "Called earlier than expected.";
const char* CMockStringCalledLate = "Called later than expected.";
const char* CMockStringCallOrder = "Called out of order.";
const char* CMockStringIgnPreExp = "IgnoreArg called before Expect.";
const char* CMockStringPtrPreExp = "ReturnThruPtr called before Expect.";
const char* CMockStringPtrIsNULL = "Pointer is NULL.";
const char* CMockStringExpNULL = "Expected NULL.";
const char* CMockStringMismatch = "Function called with unexpected argument value.";
//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 = CMOCK_MEM_ALIGN_SIZE;
#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 = CMOCK_MEM_ALIGN_SIZE;
#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)
{
#ifndef CMOCK_MEM_DYNAMIC
return CMOCK_GUTS_NONE; // nothing we can do; our static buffer is out of memory
#else
// our dynamic buffer does not have enough room; request more via realloc()
CMOCK_MEM_INDEX_TYPE new_buffersize = CMock_Guts_BufferSize + CMOCK_MEM_SIZE + size;
unsigned char* new_buffer = realloc(CMock_Guts_Buffer, (size_t)new_buffersize);
if (new_buffer == NULL)
return CMOCK_GUTS_NONE; // realloc() failed; out of memory
CMock_Guts_Buffer = new_buffer;
CMock_Guts_BufferSize = new_buffersize;
#endif
}
//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_INDEX_TYPE)((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_Guts_MemEndOfChain
//-------------------------------------------------------
CMOCK_MEM_INDEX_TYPE CMock_Guts_MemEndOfChain(CMOCK_MEM_INDEX_TYPE root_index)
{
CMOCK_MEM_INDEX_TYPE index = root_index;
CMOCK_MEM_INDEX_TYPE next_index;
for (next_index = root_index;
next_index != CMOCK_GUTS_NONE;
next_index = CMock_Guts_MemNext(index))
{
index = next_index;
}
return index;
}
//-------------------------------------------------------
// 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_MemBytesCapacity
//-------------------------------------------------------
CMOCK_MEM_INDEX_TYPE CMock_Guts_MemBytesCapacity(void)
{
return (sizeof(CMock_Guts_Buffer) - CMOCK_MEM_ALIGN_SIZE);
}
//-------------------------------------------------------
// 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
}
//-------------------------------------------------------
// CMock_Guts_MemFreeFinal
//-------------------------------------------------------
void CMock_Guts_MemFreeFinal(void)
{
CMock_Guts_FreePtr = CMOCK_MEM_ALIGN_SIZE;
#ifdef CMOCK_MEM_DYNAMIC
if (CMock_Guts_Buffer)
{
free(CMock_Guts_Buffer);
CMock_Guts_Buffer = NULL;
}
#endif
}

View File

@@ -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]
========================================== */
#ifndef CMOCK_FRAMEWORK_H
#define CMOCK_FRAMEWORK_H
#include "cmock_internals.h"
#define CMOCK_VERSION_MAJOR 2
#define CMOCK_VERSION_MINOR 5
#define CMOCK_VERSION_BUILD 0
#define CMOCK_VERSION ((CMOCK_VERSION_MAJOR << 16) | (CMOCK_VERSION_MINOR << 8) | CMOCK_VERSION_BUILD)
//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);
CMOCK_MEM_INDEX_TYPE CMock_Guts_MemEndOfChain(CMOCK_MEM_INDEX_TYPE root_index);
void* CMock_Guts_GetAddressFor(CMOCK_MEM_INDEX_TYPE index);
CMOCK_MEM_INDEX_TYPE CMock_Guts_MemBytesCapacity(void);
CMOCK_MEM_INDEX_TYPE CMock_Guts_MemBytesFree(void);
CMOCK_MEM_INDEX_TYPE CMock_Guts_MemBytesUsed(void);
void CMock_Guts_MemFreeAll(void);
void CMock_Guts_MemFreeFinal(void);
#endif //CMOCK_FRAMEWORK

View File

@@ -0,0 +1,91 @@
/* ==========================================
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_INTERNALS_H
#define CMOCK_FRAMEWORK_INTERNALS_H
#include "unity.h"
//These are constants that the generated mocks have access to
extern const char* CMockStringOutOfMemory;
extern const char* CMockStringCalledMore;
extern const char* CMockStringCalledLess;
extern const char* CMockStringCalledEarly;
extern const char* CMockStringCalledLate;
extern const char* CMockStringCallOrder;
extern const char* CMockStringIgnPreExp;
extern const char* CMockStringPtrPreExp;
extern const char* CMockStringPtrIsNULL;
extern const char* CMockStringExpNULL;
extern const char* CMockStringMismatch;
//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 <stdlib.h>
#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
#ifdef UNITY_POINTER_WIDTH
#ifdef UNITY_INT_WIDTH
#if UNITY_POINTER_WIDTH == UNITY_INT_WIDTH
#define CMOCK_MEM_PTR_AS_INT unsigned int
#endif
#endif
#endif
#endif
#ifndef CMOCK_MEM_PTR_AS_INT
#ifdef UNITY_POINTER_WIDTH
#ifdef UNITY_LONG_WIDTH
#if UNITY_POINTER_WIDTH == UNITY_LONG_WIDTH
#define CMOCK_MEM_PTR_AS_INT unsigned long
#endif
#if UNITY_POINTER_WIDTH > UNITY_LONG_WIDTH
#define CMOCK_MEM_PTR_AS_INT unsigned long long
#endif
#endif
#endif
#endif
#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
#ifdef UNITY_LONG_WIDTH
#if (UNITY_LONG_WIDTH == 16)
#define CMOCK_MEM_ALIGN (1)
#elif (UNITY_LONG_WIDTH == 32)
#define CMOCK_MEM_ALIGN (2)
#elif (UNITY_LONG_WIDTH == 64)
#define CMOCK_MEM_ALIGN (3)
#else
#define CMOCK_MEM_ALIGN (2)
#endif
#else
#define CMOCK_MEM_ALIGN (2)
#endif
#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 (CMOCK_MEM_INDEX_TYPE)(1u << CMOCK_MEM_ALIGN)
#define CMOCK_MEM_ALIGN_MASK (CMOCK_MEM_INDEX_TYPE)(CMOCK_MEM_ALIGN_SIZE - 1)
#define CMOCK_MEM_INDEX_SIZE (CMOCK_MEM_INDEX_TYPE)(CMOCK_MEM_PTR_AS_INT)((sizeof(CMOCK_MEM_INDEX_TYPE) > CMOCK_MEM_ALIGN_SIZE) ? sizeof(CMOCK_MEM_INDEX_TYPE) : CMOCK_MEM_ALIGN_SIZE)
#endif //CMOCK_FRAMEWORK_INTERNALS

View File

@@ -0,0 +1,17 @@
###################################################################################
# #
# NAME: meson.build #
# #
# AUTHOR: Mike Karlesky, Mark VanderVoord, Greg Williams. #
# WRITTEN BY: Michael Brockus. #
# #
# License: MIT #
# #
###################################################################################
cmock_dir = include_directories('.')
cmock_lib = static_library(meson.project_name(),
sources: ['cmock.c'],
dependencies: [unity_dep],
include_directories: cmock_dir)

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -0,0 +1,119 @@
# ==========================================
# 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
return unless RUBY_PLATFORM =~ /(win|w)32$/
get_std_handle = Win32API.new('kernel32', 'GetStdHandle', ['L'], 'L')
@set_console_txt_attrb =
Win32API.new('kernel32', 'SetConsoleTextAttribute', %w[L N], 'I')
@hout = get_std_handle.call(-11)
end
def change_to(new_colour)
if RUBY_PLATFORM =~ /(win|w)32$/
@set_console_txt_attrb.call(@hout, 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)
# ANSI Escape Codes - Foreground colors
# | Code | Color |
# | 39 | Default foreground color |
# | 30 | Black |
# | 31 | Red |
# | 32 | Green |
# | 33 | Yellow |
# | 34 | Blue |
# | 35 | Magenta |
# | 36 | Cyan |
# | 37 | Light gray |
# | 90 | Dark gray |
# | 91 | Light red |
# | 92 | Light green |
# | 93 | Light yellow |
# | 94 | Light blue |
# | 95 | Light magenta |
# | 96 | Light cyan |
# | 97 | White |
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 then 37
when :default then 39
else
39
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
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

View File

@@ -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_relative 'colour_prompt'
$colour_output = true
def report(message)
if !$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
Regexp.last_match(1).to_i.zero? ? :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

View File

@@ -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
//-------------------------------------------

View File

@@ -0,0 +1,309 @@
# ==========================================
# 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'
require 'pathname'
# TEMPLATE_TST
TEMPLATE_TST ||= '#include "unity.h"
%2$s#include "%1$s.h"
void setUp(void)
{
}
void tearDown(void)
{
}
void test_%1$s_NeedToImplement(void)
{
TEST_IGNORE_MESSAGE("Need to Implement %1$s");
}
'.freeze
# TEMPLATE_SRC
TEMPLATE_SRC ||= '%2$s#include "%1$s.h"
'.freeze
# TEMPLATE_INC
TEMPLATE_INC ||= '#ifndef %3$s_H
#define %3$s_H
%2$s
#endif // %3$s_H
'.freeze
class UnityModuleGenerator
############################
def initialize(options = nil)
@options = UnityModuleGenerator.default_options
case options
when NilClass then @options
when String then @options.merge!(UnityModuleGenerator.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
# Create default file paths if none were provided
@options[:path_src] = "#{__dir__}/../src/" if @options[:path_src].nil?
@options[:path_inc] = @options[:path_src] if @options[:path_inc].nil?
@options[:path_tst] = "#{__dir__}/../test/" if @options[:path_tst].nil?
@options[:path_src] += '/' unless @options[:path_src][-1] == 47
@options[:path_inc] += '/' unless @options[:path_inc][-1] == 47
@options[:path_tst] += '/' unless @options[:path_tst][-1] == 47
# Built in patterns
@patterns = {
'src' => {
'' => { inc: [] }
},
'test' => {
'' => { inc: [] }
},
'dh' => {
'Driver' => { inc: [create_filename('%1$s', 'Hardware.h')] },
'Hardware' => { inc: [] }
},
'dih' => {
'Driver' => { inc: [create_filename('%1$s', 'Hardware.h'), create_filename('%1$s', 'Interrupt.h')] },
'Interrupt' => { inc: [create_filename('%1$s', 'Hardware.h')] },
'Hardware' => { inc: [] }
},
'mch' => {
'Model' => { inc: [] },
'Conductor' => { inc: [create_filename('%1$s', 'Model.h'), create_filename('%1$s', 'Hardware.h')] },
'Hardware' => { inc: [] }
},
'mvp' => {
'Model' => { inc: [] },
'Presenter' => { inc: [create_filename('%1$s', 'Model.h'), create_filename('%1$s', 'View.h')] },
'View' => { inc: [] }
}
}
end
############################
def self.default_options
{
pattern: 'src',
includes: {
src: [],
inc: [],
tst: []
},
update_svn: false,
boilerplates: {},
test_prefix: 'Test',
mock_prefix: 'Mock'
}
end
############################
def self.grab_config(config_file)
options = default_options
unless config_file.nil? || config_file.empty?
require 'yaml'
yaml_guts = YAML.load_file(config_file)
options.merge!(yaml_guts[:unity] || yaml_guts[:cmock])
raise "No :unity or :cmock section found in #{config_file}" unless options
end
options
end
############################
def files_to_operate_on(module_name, pattern = nil)
# strip any leading path information from the module name and save for later
subfolder = File.dirname(module_name)
module_name = File.basename(module_name)
# create triad definition
prefix = @options[:test_prefix] || 'Test'
triad = [{ ext: '.c', path: @options[:path_src], prefix: '', template: TEMPLATE_SRC, inc: :src, boilerplate: @options[:boilerplates][:src] },
{ ext: '.h', path: @options[:path_inc], prefix: '', template: TEMPLATE_INC, inc: :inc, boilerplate: @options[:boilerplates][:inc] },
{ ext: '.c', path: @options[:path_tst], prefix: prefix, template: TEMPLATE_TST, inc: :tst, boilerplate: @options[:boilerplates][:tst] }]
# prepare the pattern for use
pattern = (pattern || @options[:pattern] || 'src').downcase
patterns = @patterns[pattern]
raise "ERROR: The design pattern '#{pattern}' specified isn't one that I recognize!" if patterns.nil?
# single file patterns (currently just 'test') can reject the other parts of the triad
triad.select! { |v| v[:inc] == :tst } if pattern == 'test'
# Assemble the path/names of the files we need to work with.
files = []
triad.each do |cfg|
patterns.each_pair do |pattern_file, pattern_traits|
submodule_name = create_filename(module_name, pattern_file)
filename = cfg[:prefix] + submodule_name + cfg[:ext]
files << {
path: (Pathname.new("#{cfg[:path]}#{subfolder}") + filename).cleanpath,
name: submodule_name,
template: cfg[:template],
boilerplate: cfg[:boilerplate],
includes: case (cfg[:inc])
when :src then (@options[:includes][:src] || []) | (pattern_traits[:inc].map { |f| format(f, module_name) })
when :inc then (@options[:includes][:inc] || [])
when :tst then (@options[:includes][:tst] || []) | (pattern_traits[:inc].map { |f| format("#{@options[:mock_prefix]}#{f}", module_name) })
end
}
end
end
files
end
############################
def create_filename(part1, part2 = '')
if part2.empty?
case (@options[:naming])
when 'bumpy' then part1
when 'camel' then part1
when 'snake' then part1.downcase
when 'caps' then part1.upcase
else part1
end
else
case (@options[:naming])
when 'bumpy' then part1 + part2
when 'camel' then part1 + part2
when 'snake' then part1.downcase + '_' + part2.downcase
when 'caps' then part1.upcase + '_' + part2.upcase
else part1 + '_' + part2
end
end
end
############################
def generate(module_name, pattern = nil)
files = files_to_operate_on(module_name, pattern)
# Abort if all of the module files already exist
all_files_exist = true
files.each do |file|
all_files_exist = false unless File.exist?(file[:path])
end
raise "ERROR: File #{files[0][:name]} already exists. Exiting." if all_files_exist
# Create Source Modules
files.each_with_index do |file, _i|
# If this file already exists, don't overwrite it.
if File.exist?(file[:path])
puts "File #{file[:path]} already exists!"
next
end
# Create the path first if necessary.
FileUtils.mkdir_p(File.dirname(file[:path]), verbose: false)
File.open(file[:path], 'w') do |f|
f.write("#{file[:boilerplate]}\n" % [file[:name]]) unless file[:boilerplate].nil?
f.write(file[:template] % [file[:name],
file[:includes].map { |ff| "#include \"#{ff}\"\n" }.join,
file[:name].upcase])
end
if @options[:update_svn]
`svn add \"#{file[:path]}\"`
if $!.exitstatus.zero?
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'
end
############################
def destroy(module_name, pattern = nil)
files_to_operate_on(module_name, pattern).each do |filespec|
file = filespec[:path]
if File.exist?(file)
if @options[: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'
end
end
############################
# Handle As Command Line If Called That Way
if $0 == __FILE__
destroy = false
options = {}
module_name = nil
# Parse the command line parameters.
ARGV.each do |arg|
case arg
when /^-d/ then destroy = true
when /^-u/ then options[:update_svn] = true
when /^-p\"?(\w+)\"?/ then options[:pattern] = Regexp.last_match(1)
when /^-s\"?(.+)\"?/ then options[:path_src] = Regexp.last_match(1)
when /^-i\"?(.+)\"?/ then options[:path_inc] = Regexp.last_match(1)
when /^-t\"?(.+)\"?/ then options[:path_tst] = Regexp.last_match(1)
when /^-n\"?(.+)\"?/ then options[:naming] = Regexp.last_match(1)
when /^-y\"?(.+)\"?/ then options = UnityModuleGenerator.grab_config(Regexp.last_match(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)/
ARGV = [].freeze
else
raise "ERROR: Unknown option specified '#{arg}'"
end
end
unless ARGV[0]
puts ["\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 source module, header and test. (DEFAULT)',
' test - just a test file.',
' -d destroy module instead of creating it.',
' -n"camel" sets the file naming convention.',
' bumpy - BumpyCaseFilenames.',
' camel - camelCaseFilenames.',
' snake - snake_case_filenames.',
' caps - CAPS_CASE_FILENAMES.',
' -u update subversion too (requires subversion command line)',
' -y"my.yml" selects a different yaml config file for module generation',
''].join("\n")
exit
end
raise 'ERROR: You must have a Module name specified! (use option -h for help)' if module_name.nil?
if destroy
UnityModuleGenerator.new(options).destroy(module_name)
else
UnityModuleGenerator.new(options).generate(module_name)
end
end

View File

@@ -0,0 +1,495 @@
# ==========================================
# 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]
# ==========================================
class UnityTestRunnerGenerator
def initialize(options = nil)
@options = UnityTestRunnerGenerator.default_options
case options
when NilClass
@options
when String
@options.merge!(UnityTestRunnerGenerator.grab_config(options))
when Hash
# Check if some of these have been specified
@options[:has_setup] = !options[:setup_name].nil?
@options[:has_teardown] = !options[:teardown_name].nil?
@options[:has_suite_setup] = !options[:suite_setup].nil?
@options[:has_suite_teardown] = !options[:suite_teardown].nil?
@options.merge!(options)
else
raise 'If you specify arguments, it should be a filename or a hash of options'
end
require_relative 'type_sanitizer'
end
def self.default_options
{
includes: [],
defines: [],
plugins: [],
framework: :unity,
test_prefix: 'test|spec|should',
mock_prefix: 'Mock',
mock_suffix: '',
setup_name: 'setUp',
teardown_name: 'tearDown',
test_reset_name: 'resetTest',
test_verify_name: 'verifyTest',
main_name: 'main', # set to :auto to automatically generate each time
main_export_decl: '',
cmdline_args: false,
omit_begin_end: false,
use_param_tests: false
}
end
def self.grab_config(config_file)
options = default_options
unless config_file.nil? || config_file.empty?
require 'yaml'
yaml_guts = YAML.load_file(config_file)
options.merge!(yaml_guts[:unity] || yaml_guts[:cmock])
raise "No :unity or :cmock section found in #{config_file}" unless options
end
options
end
def run(input_file, output_file, options = nil)
@options.merge!(options) unless options.nil?
# pull required data from source file
source = File.read(input_file)
source = source.force_encoding('ISO-8859-1').encode('utf-8', replace: nil)
tests = find_tests(source)
headers = find_includes(source)
testfile_includes = (headers[:local] + headers[:system])
used_mocks = find_mocks(testfile_includes)
testfile_includes = (testfile_includes - used_mocks)
testfile_includes.delete_if { |inc| inc =~ /(unity|cmock)/ }
find_setup_and_teardown(source)
# build runner file
generate(input_file, output_file, tests, used_mocks, testfile_includes)
# 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?
all_files_used += headers[:linkonly] unless headers[:linkonly].empty?
all_files_used.uniq
end
def generate(input_file, output_file, tests, used_mocks, testfile_includes)
File.open(output_file, 'w') do |output|
create_header(output, used_mocks, testfile_includes)
create_externs(output, tests, used_mocks)
create_mock_management(output, used_mocks)
create_setup(output)
create_teardown(output)
create_suite_setup(output)
create_suite_teardown(output)
create_reset(output)
create_run_test(output)
create_args_wrappers(output, tests)
create_main(output, input_file, tests, used_mocks)
end
return unless @options[:header_file] && !@options[:header_file].empty?
File.open(@options[:header_file], 'w') do |output|
create_h_file(output, @options[:header_file], tests, testfile_includes, used_mocks)
end
end
def find_tests(source)
tests_and_line_numbers = []
# contains characters which will be substituted from within strings, doing
# this prevents these characters from interferring with scrubbers
# @ is not a valid C character, so there should be no clashes with files genuinely containing these markers
substring_subs = { '{' => '@co@', '}' => '@cc@', ';' => '@ss@', '/' => '@fs@' }
substring_re = Regexp.union(substring_subs.keys)
substring_unsubs = substring_subs.invert # the inverse map will be used to fix the strings afterwords
substring_unsubs['@quote@'] = '\\"'
substring_unsubs['@apos@'] = '\\\''
substring_unre = Regexp.union(substring_unsubs.keys)
source_scrubbed = source.clone
source_scrubbed = source_scrubbed.gsub(/\\"/, '@quote@') # hide escaped quotes to allow capture of the full string/char
source_scrubbed = source_scrubbed.gsub(/\\'/, '@apos@') # hide escaped apostrophes to allow capture of the full string/char
source_scrubbed = source_scrubbed.gsub(/("[^"\n]*")|('[^'\n]*')/) { |s| s.gsub(substring_re, substring_subs) } # temporarily hide problematic characters within strings
source_scrubbed = source_scrubbed.gsub(/\/\/(?:.+\/\*|\*(?:$|[^\/])).*$/, '') # remove line comments that comment out the start of blocks
source_scrubbed = source_scrubbed.gsub(/\/\*.*?\*\//m, '') # remove block comments
source_scrubbed = source_scrubbed.gsub(/\/\/.*$/, '') # remove line comments (all that remain)
lines = source_scrubbed.split(/(^\s*\#.*$) | (;|\{|\}) /x) # Treat preprocessor directives as a logical line. Match ;, {, and } as end of lines
.map { |line| line.gsub(substring_unre, substring_unsubs) } # unhide the problematic characters previously removed
lines.each_with_index do |line, _index|
# find tests
next unless line =~ /^((?:\s*TEST_CASE\s*\(.*?\)\s*)*)\s*void\s+((?:#{@options[:test_prefix]}).*)\s*\(\s*(.*)\s*\)/m
arguments = Regexp.last_match(1)
name = Regexp.last_match(2)
call = Regexp.last_match(3)
params = Regexp.last_match(4)
args = nil
if @options[:use_param_tests] && !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, params: params, line_number: 0 }
end
tests_and_line_numbers.uniq! { |v| v[:test] }
# determine line numbers and create tests to run
source_lines = source.split("\n")
source_index = 0
tests_and_line_numbers.size.times do |i|
source_lines[source_index..-1].each_with_index do |line, index|
next unless line =~ /\s+#{tests_and_line_numbers[i][:test]}(?:\s|\()/
source_index += index
tests_and_line_numbers[i][:line_number] = source_index + 1
break
end
end
tests_and_line_numbers
end
def find_includes(source)
# 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
includes = {
local: source.scan(/^\s*#include\s+\"\s*(.+)\.[hH]\s*\"/).flatten,
system: source.scan(/^\s*#include\s+<\s*(.+)\s*>/).flatten.map { |inc| "<#{inc}>" },
linkonly: source.scan(/^TEST_FILE\(\s*\"\s*(.+)\.[cC]\w*\s*\"/).flatten
}
includes
end
def find_mocks(includes)
mock_headers = []
includes.each do |include_path|
include_file = File.basename(include_path)
mock_headers << include_path if include_file =~ /^#{@options[:mock_prefix]}.*#{@options[:mock_suffix]}$/i
end
mock_headers
end
def find_setup_and_teardown(source)
@options[:has_setup] = source =~ /void\s+#{@options[:setup_name]}\s*\(/
@options[:has_teardown] = source =~ /void\s+#{@options[:teardown_name]}\s*\(/
@options[:has_suite_setup] ||= (source =~ /void\s+suiteSetUp\s*\(/)
@options[:has_suite_teardown] ||= (source =~ /void\s+suiteTearDown\s*\(/)
end
def create_header(output, mocks, testfile_includes = [])
output.puts('/* AUTOGENERATED FILE. DO NOT EDIT. */')
output.puts("\n/*=======Automagically Detected Files To Include=====*/")
output.puts("#include \"#{@options[:framework]}.h\"")
output.puts('#include "cmock.h"') unless mocks.empty?
if @options[:defines] && !@options[:defines].empty?
@options[:defines].each { |d| output.puts("#ifndef #{d}\n#define #{d}\n#endif /* #{d} */") }
end
if @options[:header_file] && !@options[:header_file].empty?
output.puts("#include \"#{File.basename(@options[:header_file])}\"")
else
@options[:includes].flatten.uniq.compact.each do |inc|
output.puts("#include #{inc.include?('<') ? inc : "\"#{inc.gsub('.h', '')}.h\""}")
end
testfile_includes.each do |inc|
output.puts("#include #{inc.include?('<') ? inc : "\"#{inc.gsub('.h', '')}.h\""}")
end
end
mocks.each do |mock|
output.puts("#include \"#{mock.gsub('.h', '')}.h\"")
end
output.puts('#include "CException.h"') if @options[:plugins].include?(:cexception)
return unless @options[:enforce_strict_ordering]
output.puts('')
output.puts('int GlobalExpectCount;')
output.puts('int GlobalVerifyOrder;')
output.puts('char* GlobalOrderError;')
end
def create_externs(output, tests, _mocks)
output.puts("\n/*=======External Functions This Runner Calls=====*/")
output.puts("extern void #{@options[:setup_name]}(void);")
output.puts("extern void #{@options[:teardown_name]}(void);")
output.puts("\n#ifdef __cplusplus\nextern \"C\"\n{\n#endif") if @options[:externc]
tests.each do |test|
output.puts("extern void #{test[:test]}(#{test[:call] || 'void'});")
end
output.puts("#ifdef __cplusplus\n}\n#endif") if @options[:externc]
output.puts('')
end
def create_mock_management(output, mock_headers)
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 = mock_headers.map { |mock| File.basename(mock) }
mocks.each do |mock|
mock_clean = TypeSanitizer.sanitize_c_identifier(mock)
output.puts(" #{mock_clean}_Init();")
end
output.puts("}\n")
output.puts('static void CMock_Verify(void)')
output.puts('{')
mocks.each do |mock|
mock_clean = TypeSanitizer.sanitize_c_identifier(mock)
output.puts(" #{mock_clean}_Verify();")
end
output.puts("}\n")
output.puts('static void CMock_Destroy(void)')
output.puts('{')
mocks.each do |mock|
mock_clean = TypeSanitizer.sanitize_c_identifier(mock)
output.puts(" #{mock_clean}_Destroy();")
end
output.puts("}\n")
end
def create_setup(output)
return if @options[:has_setup]
output.puts("\n/*=======Setup (stub)=====*/")
output.puts("void #{@options[:setup_name]}(void) {}")
end
def create_teardown(output)
return if @options[:has_teardown]
output.puts("\n/*=======Teardown (stub)=====*/")
output.puts("void #{@options[:teardown_name]}(void) {}")
end
def create_suite_setup(output)
return if @options[:suite_setup].nil?
output.puts("\n/*=======Suite Setup=====*/")
output.puts('void suiteSetUp(void)')
output.puts('{')
output.puts(@options[:suite_setup])
output.puts('}')
end
def create_suite_teardown(output)
return if @options[:suite_teardown].nil?
output.puts("\n/*=======Suite Teardown=====*/")
output.puts('int suiteTearDown(int num_failures)')
output.puts('{')
output.puts(@options[:suite_teardown])
output.puts('}')
end
def create_reset(output)
output.puts("\n/*=======Test Reset Options=====*/")
output.puts("void #{@options[:test_reset_name]}(void);")
output.puts("void #{@options[:test_reset_name]}(void)")
output.puts('{')
output.puts(" #{@options[:teardown_name]}();")
output.puts(' CMock_Verify();')
output.puts(' CMock_Destroy();')
output.puts(' CMock_Init();')
output.puts(" #{@options[:setup_name]}();")
output.puts('}')
output.puts("void #{@options[:test_verify_name]}(void);")
output.puts("void #{@options[:test_verify_name]}(void)")
output.puts('{')
output.puts(' CMock_Verify();')
output.puts('}')
end
def create_run_test(output)
require 'erb'
template = ERB.new(File.read(File.join(__dir__, 'run_test.erb')))
output.puts(template.result(binding))
end
def create_args_wrappers(output, tests)
return unless @options[:use_param_tests]
output.puts("\n/*=======Parameterized Test Wrappers=====*/")
tests.each do |test|
next if test[:args].nil? || test[:args].empty?
test[:args].each.with_index(1) do |args, idx|
output.puts("static void runner_args#{idx}_#{test[:test]}(void)")
output.puts('{')
output.puts(" #{test[:test]}(#{args});")
output.puts("}\n")
end
end
end
def create_main(output, filename, tests, used_mocks)
output.puts("\n\n/*=======MAIN=====*/")
main_name = @options[:main_name].to_sym == :auto ? "main_#{filename.gsub('.c', '')}" : (@options[:main_name]).to_s
if @options[:cmdline_args]
if main_name != 'main'
output.puts("#{@options[:main_export_decl]} int #{main_name}(int argc, char** argv);")
end
output.puts("#{@options[:main_export_decl]} int #{main_name}(int argc, char** argv)")
output.puts('{')
output.puts(' int parse_status = UnityParseOptions(argc, argv);')
output.puts(' if (parse_status != 0)')
output.puts(' {')
output.puts(' if (parse_status < 0)')
output.puts(' {')
output.puts(" UnityPrint(\"#{filename.gsub('.c', '')}.\");")
output.puts(' UNITY_PRINT_EOL();')
tests.each do |test|
if (!@options[:use_param_tests]) || test[:args].nil? || test[:args].empty?
output.puts(" UnityPrint(\" #{test[:test]}\");")
output.puts(' UNITY_PRINT_EOL();')
else
test[:args].each do |args|
output.puts(" UnityPrint(\" #{test[:test]}(#{args})\");")
output.puts(' UNITY_PRINT_EOL();')
end
end
end
output.puts(' return 0;')
output.puts(' }')
output.puts(' return parse_status;')
output.puts(' }')
else
main_return = @options[:omit_begin_end] ? 'void' : 'int'
if main_name != 'main'
output.puts("#{@options[:main_export_decl]} #{main_return} #{main_name}(void);")
end
output.puts("#{main_return} #{main_name}(void)")
output.puts('{')
end
output.puts(' suiteSetUp();') if @options[:has_suite_setup]
if @options[:omit_begin_end]
output.puts(" UnitySetTestFile(\"#{filename.gsub(/\\/, '\\\\\\')}\");")
else
output.puts(" UnityBegin(\"#{filename.gsub(/\\/, '\\\\\\')}\");")
end
tests.each do |test|
if (!@options[:use_param_tests]) || test[:args].nil? || test[:args].empty?
output.puts(" run_test(#{test[:test]}, \"#{test[:test]}\", #{test[:line_number]});")
else
test[:args].each.with_index(1) do |args, idx|
wrapper = "runner_args#{idx}_#{test[:test]}"
testname = "#{test[:test]}(#{args})".dump
output.puts(" run_test(#{wrapper}, #{testname}, #{test[:line_number]});")
end
end
end
output.puts
output.puts(' CMock_Guts_MemFreeFinal();') unless used_mocks.empty?
if @options[:has_suite_teardown]
if @options[:omit_begin_end]
output.puts(' (void) suite_teardown(0);')
else
output.puts(' return suiteTearDown(UnityEnd());')
end
else
output.puts(' return UnityEnd();') if not @options[:omit_begin_end]
end
output.puts('}')
end
def create_h_file(output, filename, tests, testfile_includes, used_mocks)
filename = File.basename(filename).gsub(/[-\/\\\.\,\s]/, '_').upcase
output.puts('/* AUTOGENERATED FILE. DO NOT EDIT. */')
output.puts("#ifndef _#{filename}")
output.puts("#define _#{filename}\n\n")
output.puts("#include \"#{@options[:framework]}.h\"")
output.puts('#include "cmock.h"') unless used_mocks.empty?
@options[:includes].flatten.uniq.compact.each do |inc|
output.puts("#include #{inc.include?('<') ? inc : "\"#{inc.gsub('.h', '')}.h\""}")
end
testfile_includes.each do |inc|
output.puts("#include #{inc.include?('<') ? inc : "\"#{inc.gsub('.h', '')}.h\""}")
end
output.puts "\n"
tests.each do |test|
if test[:params].nil? || test[:params].empty?
output.puts("void #{test[:test]}(void);")
else
output.puts("void #{test[:test]}(#{test[:params]});")
end
end
output.puts("#endif\n\n")
end
end
if $0 == __FILE__
options = { includes: [] }
# parse out all the options first (these will all be removed as we go)
ARGV.reject! do |arg|
case arg
when '-cexception'
options[:plugins] = [:cexception]
true
when /\.*\.ya?ml/
options = UnityTestRunnerGenerator.grab_config(arg)
true
when /--(\w+)=\"?(.*)\"?/
options[Regexp.last_match(1).to_sym] = Regexp.last_match(2)
true
when /\.*\.h/
options[:includes] << arg
true
else false
end
end
# make sure there is at least one parameter left (the input file)
unless ARGV[0]
puts ["\nusage: ruby #{__FILE__} (files) (options) input_test_file (output)",
"\n input_test_file - this is the C file you want to create a runner for",
' output - this is the name of the runner file to generate',
' defaults to (input_test_file)_Runner',
' files:',
' *.yml / *.yaml - loads configuration from here in :unity or :cmock',
' *.h - header files are added as #includes in runner',
' options:',
' -cexception - include cexception support',
' -externc - add extern "C" for cpp support',
' --setup_name="" - redefine setUp func name to something else',
' --teardown_name="" - redefine tearDown func name to something else',
' --main_name="" - redefine main func name to something else',
' --test_prefix="" - redefine test prefix from default test|spec|should',
' --test_reset_name="" - redefine resetTest func name to something else',
' --test_verify_name="" - redefine verifyTest func name to something else',
' --suite_setup="" - code to execute for setup of entire suite',
' --suite_teardown="" - code to execute for teardown of entire suite',
' --use_param_tests=1 - enable parameterized tests (disabled by default)',
' --omit_begin_end=1 - omit calls to UnityBegin and UnityEnd (disabled by default)',
' --header_file="" - path/name of test header file to generate too'].join("\n")
exit 1
end
# create the default test runner name if not specified
ARGV[1] = ARGV[0].gsub('.c', '_Runner.c') unless ARGV[1]
UnityTestRunnerGenerator.new(options).run(ARGV[0], ARGV[1])
end

View File

@@ -0,0 +1,322 @@
#============================================================
# Author: John Theofanopoulos
# A simple parser. Takes the output files generated during the
# build process and extracts information relating to the tests.
#
# Notes:
# To capture an output file under VS builds use the following:
# devenv [build instructions] > Output.txt & type Output.txt
#
# To capture an output file under Linux builds use the following:
# make | tee Output.txt
#
# This script can handle the following output formats:
# - normal output (raw unity)
# - fixture output (unity_fixture.h/.c)
# - fixture output with verbose flag set ("-v")
#
# To use this parser use the following command
# ruby parseOutput.rb [options] [file]
# options: -xml : produce a JUnit compatible XML file
# file: file to scan for results
#============================================================
# Parser class for handling the input file
class ParseOutput
def initialize
# internal data
@class_name_idx = 0
@path_delim = nil
# xml output related
@xml_out = false
@array_list = false
# current suite name and statistics
@test_suite = nil
@total_tests = 0
@test_passed = 0
@test_failed = 0
@test_ignored = 0
end
# Set the flag to indicate if there will be an XML output file or not
def set_xml_output
@xml_out = true
end
# If write our output to XML
def write_xml_output
output = File.open('report.xml', 'w')
output << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
@array_list.each do |item|
output << item << "\n"
end
end
# Pushes the suite info as xml to the array list, which will be written later
def push_xml_output_suite_info
# Insert opening tag at front
heading = '<testsuite name="Unity" tests="' + @total_tests.to_s + '" failures="' + @test_failed.to_s + '"' + ' skips="' + @test_ignored.to_s + '">'
@array_list.insert(0, heading)
# Push back the closing tag
@array_list.push '</testsuite>'
end
# Pushes xml output data to the array list, which will be written later
def push_xml_output_passed(test_name)
@array_list.push ' <testcase classname="' + @test_suite + '" name="' + test_name + '"/>'
end
# Pushes xml output data to the array list, which will be written later
def push_xml_output_failed(test_name, reason)
@array_list.push ' <testcase classname="' + @test_suite + '" name="' + test_name + '">'
@array_list.push ' <failure type="ASSERT FAILED">' + reason + '</failure>'
@array_list.push ' </testcase>'
end
# Pushes xml output data to the array list, which will be written later
def push_xml_output_ignored(test_name, reason)
@array_list.push ' <testcase classname="' + @test_suite + '" name="' + test_name + '">'
@array_list.push ' <skipped type="TEST IGNORED">' + reason + '</skipped>'
@array_list.push ' </testcase>'
end
# This function will try and determine when the suite is changed. This is
# is the name that gets added to the classname parameter.
def test_suite_verify(test_suite_name)
# Split the path name
test_name = test_suite_name.split(@path_delim)
# Remove the extension and extract the base_name
base_name = test_name[test_name.size - 1].split('.')[0]
# Return if the test suite hasn't changed
return unless base_name.to_s != @test_suite.to_s
@test_suite = base_name
printf "New Test: %s\n", @test_suite
end
# Prepares the line for verbose fixture output ("-v")
def prepare_fixture_line(line)
line = line.sub('IGNORE_TEST(', '')
line = line.sub('TEST(', '')
line = line.sub(')', ',')
line = line.chomp
array = line.split(',')
array.map { |x| x.to_s.lstrip.chomp }
end
# Test was flagged as having passed so format the output.
# This is using the Unity fixture output and not the original Unity output.
def test_passed_unity_fixture(array)
class_name = array[0]
test_name = array[1]
test_suite_verify(class_name)
printf "%-40s PASS\n", test_name
push_xml_output_passed(test_name) if @xml_out
end
# Test was flagged as having failed so format the output.
# This is using the Unity fixture output and not the original Unity output.
def test_failed_unity_fixture(array)
class_name = array[0]
test_name = array[1]
test_suite_verify(class_name)
reason_array = array[2].split(':')
reason = reason_array[-1].lstrip.chomp + ' at line: ' + reason_array[-4]
printf "%-40s FAILED\n", test_name
push_xml_output_failed(test_name, reason) if @xml_out
end
# Test was flagged as being ignored so format the output.
# This is using the Unity fixture output and not the original Unity output.
def test_ignored_unity_fixture(array)
class_name = array[0]
test_name = array[1]
reason = 'No reason given'
if array.size > 2
reason_array = array[2].split(':')
tmp_reason = reason_array[-1].lstrip.chomp
reason = tmp_reason == 'IGNORE' ? 'No reason given' : tmp_reason
end
test_suite_verify(class_name)
printf "%-40s IGNORED\n", test_name
push_xml_output_ignored(test_name, reason) if @xml_out
end
# Test was flagged as having passed so format the output
def test_passed(array)
last_item = array.length - 1
test_name = array[last_item - 1]
test_suite_verify(array[@class_name_idx])
printf "%-40s PASS\n", test_name
return unless @xml_out
push_xml_output_passed(test_name) if @xml_out
end
# Test was flagged as having failed so format the line
def test_failed(array)
last_item = array.length - 1
test_name = array[last_item - 2]
reason = array[last_item].chomp.lstrip + ' at line: ' + array[last_item - 3]
class_name = array[@class_name_idx]
if test_name.start_with? 'TEST('
array2 = test_name.split(' ')
test_suite = array2[0].sub('TEST(', '')
test_suite = test_suite.sub(',', '')
class_name = test_suite
test_name = array2[1].sub(')', '')
end
test_suite_verify(class_name)
printf "%-40s FAILED\n", test_name
push_xml_output_failed(test_name, reason) if @xml_out
end
# Test was flagged as being ignored so format the output
def test_ignored(array)
last_item = array.length - 1
test_name = array[last_item - 2]
reason = array[last_item].chomp.lstrip
class_name = array[@class_name_idx]
if test_name.start_with? 'TEST('
array2 = test_name.split(' ')
test_suite = array2[0].sub('TEST(', '')
test_suite = test_suite.sub(',', '')
class_name = test_suite
test_name = array2[1].sub(')', '')
end
test_suite_verify(class_name)
printf "%-40s IGNORED\n", test_name
push_xml_output_ignored(test_name, reason) if @xml_out
end
# Adjusts the os specific members according to the current path style
# (Windows or Unix based)
def detect_os_specifics(line)
if line.include? '\\'
# Windows X:\Y\Z
@class_name_idx = 1
@path_delim = '\\'
else
# Unix Based /X/Y/Z
@class_name_idx = 0
@path_delim = '/'
end
end
# Main function used to parse the file that was captured.
def process(file_name)
@array_list = []
puts 'Parsing file: ' + file_name
@test_passed = 0
@test_failed = 0
@test_ignored = 0
puts ''
puts '=================== RESULTS ====================='
puts ''
File.open(file_name).each do |line|
# Typical test lines look like these:
# ----------------------------------------------------
# 1. normal output:
# <path>/<test_file>.c:36:test_tc1000_opsys:FAIL: Expected 1 Was 0
# <path>/<test_file>.c:112:test_tc5004_initCanChannel:IGNORE: Not Yet Implemented
# <path>/<test_file>.c:115:test_tc5100_initCanVoidPtrs:PASS
#
# 2. fixture output
# <path>/<test_file>.c:63:TEST(<test_group>, <test_function>):FAIL: Expected 0x00001234 Was 0x00005A5A
# <path>/<test_file>.c:36:TEST(<test_group>, <test_function>):IGNORE
# Note: "PASS" information won't be generated in this mode
#
# 3. fixture output with verbose information ("-v")
# TEST(<test_group, <test_file>)<path>/<test_file>:168::FAIL: Expected 0x8D Was 0x8C
# TEST(<test_group>, <test_file>)<path>/<test_file>:22::IGNORE: This Test Was Ignored On Purpose
# IGNORE_TEST(<test_group, <test_file>)
# TEST(<test_group, <test_file>) PASS
#
# Note: Where path is different on Unix vs Windows devices (Windows leads with a drive letter)!
detect_os_specifics(line)
line_array = line.split(':')
# If we were able to split the line then we can look to see if any of our target words
# were found. Case is important.
next unless (line_array.size >= 4) || (line.start_with? 'TEST(') || (line.start_with? 'IGNORE_TEST(')
# check if the output is fixture output (with verbose flag "-v")
if (line.start_with? 'TEST(') || (line.start_with? 'IGNORE_TEST(')
line_array = prepare_fixture_line(line)
if line.include? ' PASS'
test_passed_unity_fixture(line_array)
@test_passed += 1
elsif line.include? 'FAIL'
test_failed_unity_fixture(line_array)
@test_failed += 1
elsif line.include? 'IGNORE'
test_ignored_unity_fixture(line_array)
@test_ignored += 1
end
# normal output / fixture output (without verbose "-v")
elsif line.include? ':PASS'
test_passed(line_array)
@test_passed += 1
elsif line.include? ':FAIL'
test_failed(line_array)
@test_failed += 1
elsif line.include? ':IGNORE:'
test_ignored(line_array)
@test_ignored += 1
elsif line.include? ':IGNORE'
line_array.push('No reason given')
test_ignored(line_array)
@test_ignored += 1
end
@total_tests = @test_passed + @test_failed + @test_ignored
end
puts ''
puts '=================== SUMMARY ====================='
puts ''
puts 'Tests Passed : ' + @test_passed.to_s
puts 'Tests Failed : ' + @test_failed.to_s
puts 'Tests Ignored : ' + @test_ignored.to_s
return unless @xml_out
# push information about the suite
push_xml_output_suite_info
# write xml output file
write_xml_output
end
end
# If the command line has no values in, used a default value of Output.txt
parse_my_file = ParseOutput.new
if ARGV.size >= 1
ARGV.each do |arg|
if arg == '-xml'
parse_my_file.set_xml_output
else
parse_my_file.process(arg)
break
end
end
end

View File

@@ -0,0 +1,36 @@
/*=======Test Runner Used To Run Each Test=====*/
static void run_test(UnityTestFunction func, const char* name, int line_num)
{
Unity.CurrentTestName = name;
Unity.CurrentTestLineNumber = line_num;
#ifdef UNITY_USE_COMMAND_LINE_ARGS
if (!UnityTestMatches())
return;
#endif
Unity.NumberOfTests++;
UNITY_CLR_DETAILS();
UNITY_EXEC_TIME_START();
CMock_Init();
if (TEST_PROTECT())
{
<% if @options[:plugins].include?(:cexception) %>
CEXCEPTION_T e;
Try {
<% end %>
<%= @options[:setup_name] %>();
func();
<% if @options[:plugins].include?(:cexception) %>
} Catch(e) {
TEST_ASSERT_EQUAL_HEX32_MESSAGE(CEXCEPTION_NONE, e, "Unhandled Exception!");
}
<% end %>
}
if (TEST_PROTECT())
{
<%= @options[:teardown_name] %>();
CMock_Verify();
}
CMock_Destroy();
UNITY_EXEC_TIME_STOP();
UnityConcludeTest();
}

View File

@@ -0,0 +1,251 @@
#!/usr/bin/ruby
#
# unity_to_junit.rb
#
require 'fileutils'
require 'optparse'
require 'ostruct'
require 'set'
require 'pp'
VERSION = 1.0
class ArgvParser
#
# Return a structure describing the options.
#
def self.parse(args)
# The options specified on the command line will be collected in *options*.
# We set default values here.
options = OpenStruct.new
options.results_dir = '.'
options.root_path = '.'
options.out_file = 'results.xml'
opts = OptionParser.new do |o|
o.banner = 'Usage: unity_to_junit.rb [options]'
o.separator ''
o.separator 'Specific options:'
o.on('-r', '--results <dir>', 'Look for Unity Results files here.') do |results|
# puts "results #{results}"
options.results_dir = results
end
o.on('-p', '--root_path <path>', 'Prepend this path to files in results.') do |root_path|
options.root_path = root_path
end
o.on('-o', '--output <filename>', 'XML file to generate.') do |out_file|
# puts "out_file: #{out_file}"
options.out_file = out_file
end
o.separator ''
o.separator 'Common options:'
# No argument, shows at tail. This will print an options summary.
o.on_tail('-h', '--help', 'Show this message') do
puts o
exit
end
# Another typical switch to print the version.
o.on_tail('--version', 'Show version') do
puts "unity_to_junit.rb version #{VERSION}"
exit
end
end
opts.parse!(args)
options
end
end
class UnityToJUnit
include FileUtils::Verbose
attr_reader :report, :total_tests, :failures, :ignored
attr_writer :targets, :root, :out_file
def initialize
@report = ''
@unit_name = ''
end
def run
# Clean up result file names
results = @targets.map { |target| target.tr('\\', '/') }
# puts "Output File: #{@out_file}"
f = File.new(@out_file, 'w')
write_xml_header(f)
write_suites_header(f)
results.each do |result_file|
lines = File.readlines(result_file).map(&:chomp)
raise "Empty test result file: #{result_file}" if lines.empty?
result_output = get_details(result_file, lines)
tests, failures, ignored = parse_test_summary(lines)
result_output[:counts][:total] = tests
result_output[:counts][:failed] = failures
result_output[:counts][:ignored] = ignored
result_output[:counts][:passed] = (result_output[:counts][:total] - result_output[:counts][:failed] - result_output[:counts][:ignored])
# use line[0] from the test output to get the test_file path and name
test_file_str = lines[0].tr('\\', '/')
test_file_str = test_file_str.split(':')
test_file = if test_file_str.length < 2
result_file
else
test_file_str[0] + ':' + test_file_str[1]
end
result_output[:source][:path] = File.dirname(test_file)
result_output[:source][:file] = File.basename(test_file)
# save result_output
@unit_name = File.basename(test_file, '.*')
write_suite_header(result_output[:counts], f)
write_failures(result_output, f)
write_tests(result_output, f)
write_ignored(result_output, f)
write_suite_footer(f)
end
write_suites_footer(f)
f.close
end
def usage(err_msg = nil)
puts "\nERROR: "
puts err_msg if err_msg
puts 'Usage: unity_to_junit.rb [options]'
puts ''
puts 'Specific options:'
puts ' -r, --results <dir> Look for Unity Results files here.'
puts ' -p, --root_path <path> Prepend this path to files in results.'
puts ' -o, --output <filename> XML file to generate.'
puts ''
puts 'Common options:'
puts ' -h, --help Show this message'
puts ' --version Show version'
exit 1
end
protected
def get_details(_result_file, lines)
results = results_structure
lines.each do |line|
line = line.tr('\\', '/')
_src_file, src_line, test_name, status, msg = line.split(/:/)
case status
when 'IGNORE' then results[:ignores] << { test: test_name, line: src_line, message: msg }
when 'FAIL' then results[:failures] << { test: test_name, line: src_line, message: msg }
when 'PASS' then results[:successes] << { test: test_name, line: src_line, message: msg }
end
end
results
end
def parse_test_summary(summary)
raise "Couldn't parse test results: #{summary}" unless summary.find { |v| v =~ /(\d+) Tests (\d+) Failures (\d+) Ignored/ }
[Regexp.last_match(1).to_i, Regexp.last_match(2).to_i, Regexp.last_match(3).to_i]
end
private
def results_structure
{
source: { path: '', file: '' },
successes: [],
failures: [],
ignores: [],
counts: { total: 0, passed: 0, failed: 0, ignored: 0 },
stdout: []
}
end
def write_xml_header(stream)
stream.puts "<?xml version='1.0' encoding='utf-8' ?>"
end
def write_suites_header(stream)
stream.puts '<testsuites>'
end
def write_suite_header(counts, stream)
stream.puts "\t<testsuite errors=\"0\" skipped=\"#{counts[:ignored]}\" failures=\"#{counts[:failed]}\" tests=\"#{counts[:total]}\" name=\"unity\">"
end
def write_failures(results, stream)
result = results[:failures]
result.each do |item|
filename = File.join(results[:source][:path], File.basename(results[:source][:file], '.*'))
stream.puts "\t\t<testcase classname=\"#{@unit_name}\" name=\"#{item[:test]}\" time=\"0\">"
stream.puts "\t\t\t<failure message=\"#{item[:message]}\" type=\"Assertion\"/>"
stream.puts "\t\t\t<system-err>&#xD;[File] #{filename}&#xD;[Line] #{item[:line]}&#xD;</system-err>"
stream.puts "\t\t</testcase>"
end
end
def write_tests(results, stream)
result = results[:successes]
result.each do |item|
stream.puts "\t\t<testcase classname=\"#{@unit_name}\" name=\"#{item[:test]}\" time=\"0\" />"
end
end
def write_ignored(results, stream)
result = results[:ignores]
result.each do |item|
filename = File.join(results[:source][:path], File.basename(results[:source][:file], '.*'))
puts "Writing ignored tests for test harness: #{filename}"
stream.puts "\t\t<testcase classname=\"#{@unit_name}\" name=\"#{item[:test]}\" time=\"0\">"
stream.puts "\t\t\t<skipped message=\"#{item[:message]}\" type=\"Assertion\"/>"
stream.puts "\t\t\t<system-err>&#xD;[File] #{filename}&#xD;[Line] #{item[:line]}&#xD;</system-err>"
stream.puts "\t\t</testcase>"
end
end
def write_suite_footer(stream)
stream.puts "\t</testsuite>"
end
def write_suites_footer(stream)
stream.puts '</testsuites>'
end
end
if $0 == __FILE__
# parse out the command options
options = ArgvParser.parse(ARGV)
# create an instance to work with
utj = UnityToJUnit.new
begin
# look in the specified or current directory for result files
targets = "#{options.results_dir.tr('\\', '/')}**/*.test*"
results = Dir[targets]
raise "No *.testpass, *.testfail, or *.testresults files found in '#{targets}'" if results.empty?
utj.targets = results
# set the root path
utj.root = options.root_path
# set the output XML file name
# puts "Output File from options: #{options.out_file}"
utj.out_file = options.out_file
# run the summarizer
puts utj.run
rescue StandardError => e
utj.usage e.message
end
end

View File

@@ -0,0 +1,25 @@
# ==========================================
# 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
return unless @all_files
return unless File.exist?('test_file_filter.yml')
filters = YAML.load_file('test_file_filter.yml')
@all_files = filters[:all_files]
@only_files = filters[:only_files]
@exclude_files = filters[:exclude_files]
end
attr_accessor :all_files, :only_files, :exclude_files
end
end

View File

@@ -0,0 +1,6 @@
module TypeSanitizer
def self.sanitize_c_identifier(unsanitized)
# convert filename to valid C identifier by replacing invalid chars with '_'
unsanitized.gsub(/[-\/\\\.\,\s]/, '_')
end
end

View File

@@ -0,0 +1,139 @@
#! python3
# ==========================================
# Unity Project - A Test Framework for C
# Copyright (c) 2015 Alexander Mueller / XelaRellum@web.de
# [Released under MIT License. Please refer to license.txt for details]
# Based on the ruby script by Mike Karlesky, Mark VanderVoord, Greg Williams
# ==========================================
import sys
import os
import re
from glob import glob
class UnityTestSummary:
def __init__(self):
self.report = ''
self.total_tests = 0
self.failures = 0
self.ignored = 0
def run(self):
# Clean up result file names
results = []
for target in self.targets:
results.append(target.replace('\\', '/'))
# Dig through each result file, looking for details on pass/fail:
failure_output = []
ignore_output = []
for result_file in results:
lines = list(map(lambda line: line.rstrip(), open(result_file, "r").read().split('\n')))
if len(lines) == 0:
raise Exception("Empty test result file: %s" % result_file)
details = self.get_details(result_file, lines)
failures = details['failures']
ignores = details['ignores']
if len(failures) > 0: failure_output.append('\n'.join(failures))
if len(ignores) > 0: ignore_output.append('n'.join(ignores))
tests,failures,ignored = self.parse_test_summary('\n'.join(lines))
self.total_tests += tests
self.failures += failures
self.ignored += ignored
if self.ignored > 0:
self.report += "\n"
self.report += "--------------------------\n"
self.report += "UNITY IGNORED TEST SUMMARY\n"
self.report += "--------------------------\n"
self.report += "\n".join(ignore_output)
if self.failures > 0:
self.report += "\n"
self.report += "--------------------------\n"
self.report += "UNITY FAILED TEST SUMMARY\n"
self.report += "--------------------------\n"
self.report += '\n'.join(failure_output)
self.report += "\n"
self.report += "--------------------------\n"
self.report += "OVERALL UNITY TEST SUMMARY\n"
self.report += "--------------------------\n"
self.report += "{total_tests} TOTAL TESTS {failures} TOTAL FAILURES {ignored} IGNORED\n".format(total_tests = self.total_tests, failures=self.failures, ignored=self.ignored)
self.report += "\n"
return self.report
def set_targets(self, target_array):
self.targets = target_array
def set_root_path(self, path):
self.root = path
def usage(self, err_msg=None):
print("\nERROR: ")
if err_msg:
print(err_msg)
print("\nUsage: unity_test_summary.py result_file_directory/ root_path/")
print(" result_file_directory - The location of your results files.")
print(" Defaults to current directory if not specified.")
print(" Should end in / if specified.")
print(" root_path - Helpful for producing more verbose output if using relative paths.")
sys.exit(1)
def get_details(self, result_file, lines):
results = { 'failures': [], 'ignores': [], 'successes': [] }
for line in lines:
parts = line.split(':')
if len(parts) == 5:
src_file,src_line,test_name,status,msg = parts
elif len(parts) == 4:
src_file,src_line,test_name,status = parts
msg = ''
else:
continue
if len(self.root) > 0:
line_out = "%s%s" % (self.root, line)
else:
line_out = line
if status == 'IGNORE':
results['ignores'].append(line_out)
elif status == 'FAIL':
results['failures'].append(line_out)
elif status == 'PASS':
results['successes'].append(line_out)
return results
def parse_test_summary(self, summary):
m = re.search(r"([0-9]+) Tests ([0-9]+) Failures ([0-9]+) Ignored", summary)
if not m:
raise Exception("Couldn't parse test results: %s" % summary)
return int(m.group(1)), int(m.group(2)), int(m.group(3))
if __name__ == '__main__':
uts = UnityTestSummary()
try:
#look in the specified or current directory for result files
if len(sys.argv) > 1:
targets_dir = sys.argv[1]
else:
targets_dir = './'
targets = list(map(lambda x: x.replace('\\', '/'), glob(targets_dir + '**/*.test*', recursive=True)))
if len(targets) == 0:
raise Exception("No *.testpass or *.testfail files found in '%s'" % targets_dir)
uts.set_targets(targets)
#set the root path
if len(sys.argv) > 2:
root_path = sys.argv[2]
else:
root_path = os.path.split(__file__)[0]
uts.set_root_path(root_path)
#run the summarizer
print(uts.run())
except Exception as e:
uts.usage(e)

View File

@@ -0,0 +1,135 @@
# ==========================================
# 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
attr_writer :targets, :root
def initialize(_opts = {})
@report = ''
@total_tests = 0
@failures = 0
@ignored = 0
end
def run
# Clean up result file names
results = @targets.map { |target| target.tr('\\', '/') }
# 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(&:chomp)
raise "Empty test result file: #{result_file}" if lines.empty?
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
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 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 && (@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
results
end
def parse_test_summary(summary)
raise "Couldn't parse test results: #{summary}" unless summary.find { |v| v =~ /(\d+) Tests (\d+) Failures (\d+) Ignored/ }
[Regexp.last_match(1).to_i, Regexp.last_match(2).to_i, Regexp.last_match(3).to_i]
end
end
if $0 == __FILE__
# parse out the command options
opts, args = ARGV.partition { |v| v =~ /^--\w+/ }
opts.map! { |v| v[2..-1].to_sym }
# create an instance to work with
uts = UnityTestSummary.new(opts)
begin
# look in the specified or current directory for result files
args[0] ||= './'
targets = "#{ARGV[0].tr('\\', '/')}**/*.test*"
results = Dir[targets]
raise "No *.testpass, *.testfail, or *.testresults files found in '#{targets}'" if results.empty?
uts.targets = results
# set the root path
args[1] ||= Dir.pwd + '/'
uts.root = ARGV[1]
# run the summarizer
puts uts.run
rescue StandardError => e
uts.usage e.message
end
end

View File

@@ -0,0 +1,146 @@
import sys
import os
from glob import glob
from pyparsing import *
from junit_xml import TestSuite, TestCase
class UnityTestSummary:
def __init__(self):
self.report = ''
self.total_tests = 0
self.failures = 0
self.ignored = 0
self.targets = 0
self.root = None
self.test_suites = dict()
def run(self):
# Clean up result file names
results = []
for target in self.targets:
results.append(target.replace('\\', '/'))
# Dig through each result file, looking for details on pass/fail:
for result_file in results:
lines = list(map(lambda line: line.rstrip(), open(result_file, "r").read().split('\n')))
if len(lines) == 0:
raise Exception("Empty test result file: %s" % result_file)
# define an expression for your file reference
entry_one = Combine(
oneOf(list(alphas)) + ':/' +
Word(alphanums + '_-./'))
entry_two = Word(printables + ' ', excludeChars=':')
entry = entry_one | entry_two
delimiter = Literal(':').suppress()
tc_result_line = Group(entry.setResultsName('tc_file_name') + delimiter + entry.setResultsName(
'tc_line_nr') + delimiter + entry.setResultsName('tc_name') + delimiter + entry.setResultsName(
'tc_status') + Optional(
delimiter + entry.setResultsName('tc_msg'))).setResultsName("tc_line")
eol = LineEnd().suppress()
sol = LineStart().suppress()
blank_line = sol + eol
tc_summary_line = Group(Word(nums).setResultsName("num_of_tests") + "Tests" + Word(nums).setResultsName(
"num_of_fail") + "Failures" + Word(nums).setResultsName("num_of_ignore") + "Ignored").setResultsName(
"tc_summary")
tc_end_line = Or(Literal("FAIL"), Literal('Ok')).setResultsName("tc_result")
# run it and see...
pp1 = tc_result_line | Optional(tc_summary_line | tc_end_line)
pp1.ignore(blank_line | OneOrMore("-"))
result = list()
for l in lines:
result.append((pp1.parseString(l)).asDict())
# delete empty results
result = filter(None, result)
tc_list = list()
for r in result:
if 'tc_line' in r:
tmp_tc_line = r['tc_line']
# get only the file name which will be used as the classname
file_name = tmp_tc_line['tc_file_name'].split('\\').pop().split('/').pop().rsplit('.', 1)[0]
tmp_tc = TestCase(name=tmp_tc_line['tc_name'], classname=file_name)
if 'tc_status' in tmp_tc_line:
if str(tmp_tc_line['tc_status']) == 'IGNORE':
if 'tc_msg' in tmp_tc_line:
tmp_tc.add_skipped_info(message=tmp_tc_line['tc_msg'],
output=r'[File]={0}, [Line]={1}'.format(
tmp_tc_line['tc_file_name'], tmp_tc_line['tc_line_nr']))
else:
tmp_tc.add_skipped_info(message=" ")
elif str(tmp_tc_line['tc_status']) == 'FAIL':
if 'tc_msg' in tmp_tc_line:
tmp_tc.add_failure_info(message=tmp_tc_line['tc_msg'],
output=r'[File]={0}, [Line]={1}'.format(
tmp_tc_line['tc_file_name'], tmp_tc_line['tc_line_nr']))
else:
tmp_tc.add_failure_info(message=" ")
tc_list.append((str(result_file), tmp_tc))
for k, v in tc_list:
try:
self.test_suites[k].append(v)
except KeyError:
self.test_suites[k] = [v]
ts = []
for suite_name in self.test_suites:
ts.append(TestSuite(suite_name, self.test_suites[suite_name]))
with open('result.xml', 'w') as f:
TestSuite.to_file(f, ts, prettyprint='True', encoding='utf-8')
return self.report
def set_targets(self, target_array):
self.targets = target_array
def set_root_path(self, path):
self.root = path
@staticmethod
def usage(err_msg=None):
print("\nERROR: ")
if err_msg:
print(err_msg)
print("\nUsage: unity_test_summary.py result_file_directory/ root_path/")
print(" result_file_directory - The location of your results files.")
print(" Defaults to current directory if not specified.")
print(" Should end in / if specified.")
print(" root_path - Helpful for producing more verbose output if using relative paths.")
sys.exit(1)
if __name__ == '__main__':
uts = UnityTestSummary()
try:
# look in the specified or current directory for result files
if len(sys.argv) > 1:
targets_dir = sys.argv[1]
else:
targets_dir = './'
targets = list(map(lambda x: x.replace('\\', '/'), glob(targets_dir + '*.test*')))
if len(targets) == 0:
raise Exception("No *.testpass or *.testfail files found in '%s'" % targets_dir)
uts.set_targets(targets)
# set the root path
if len(sys.argv) > 2:
root_path = sys.argv[2]
else:
root_path = os.path.split(__file__)[0]
uts.set_root_path(root_path)
# run the summarizer
print(uts.run())
except Exception as e:
UnityTestSummary.usage(e)

View File

@@ -0,0 +1,2 @@
122

View File

@@ -0,0 +1,2 @@
2.4.3

View File

@@ -0,0 +1,22 @@
###################################################################################
# #
# NAME: CMakeLists.txt #
# #
# AUTHOR: Mike Karlesky, Mark VanderVoord, Greg Williams. #
# WRITTEN BY: Michael Brockus. #
# #
# License: MIT #
# #
###################################################################################
cmake_minimum_required(VERSION 3.0 FATAL_ERROR)
add_library(unity STATIC "unity.c")
install(TARGETS unity EXPORT unityConfig
ARCHIVE DESTINATION "${CMAKE_CURRENT_SOURCE_DIR}/${CMAKE_INSTALL_LIBDIR}"
LIBRARY DESTINATION "${CMAKE_CURRENT_SOURCE_DIR}/${CMAKE_INSTALL_LIBDIR}"
RUNTIME DESTINATION "${CMAKE_CURRENT_SOURCE_DIR}/${CMAKE_INSTALL_BINDIR}"
INCLUDES DESTINATION "${CMAKE_INSTALL_LIBDIR}")

View File

@@ -0,0 +1,16 @@
###################################################################################
# #
# NAME: meson.build #
# #
# AUTHOR: Mike Karlesky, Mark VanderVoord, Greg Williams. #
# WRITTEN BY: Michael Brockus. #
# #
# License: MIT #
# #
###################################################################################
unity_dir = include_directories('.')
unity_lib = static_library(meson.project_name(),
sources: ['unity.c'],
include_directories: unity_dir)

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,617 @@
/* ==========================================
Unity Project - A Test Framework for C
Copyright (c) 2007-19 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
#define UNITY_VERSION_MAJOR 2
#define UNITY_VERSION_MINOR 5
#define UNITY_VERSION_BUILD 0
#define UNITY_VERSION ((UNITY_VERSION_MAJOR << 16) | (UNITY_VERSION_MINOR << 8) | UNITY_VERSION_BUILD)
#ifdef __cplusplus
extern "C"
{
#endif
#include "unity_internals.h"
/*-------------------------------------------------------
* Test Setup / Teardown
*-------------------------------------------------------*/
/* These functions are intended to be called before and after each test.
* If using unity directly, these will need to be provided for each test
* executable built. If you are using the test runner generator and/or
* Ceedling, these are optional. */
void setUp(void);
void tearDown(void);
/* These functions are intended to be called at the beginning and end of an
* entire test suite. suiteTearDown() is passed the number of tests that
* failed, and its return value becomes the exit code of main(). If using
* Unity directly, you're in charge of calling these if they are desired.
* If using Ceedling or the test runner generator, these will be called
* automatically if they exist. */
void suiteSetUp(void);
int suiteTearDown(int num_failures);
/*-------------------------------------------------------
* Test Reset and Verify
*-------------------------------------------------------*/
/* These functions are intended to be called before during tests in order
* to support complex test loops, etc. Both are NOT built into Unity. Instead
* the test runner generator will create them. resetTest will run teardown and
* setup again, verifying any end-of-test needs between. verifyTest will only
* run the verification. */
void resetTest(void);
void verifyTest(void);
/*-------------------------------------------------------
* Configuration Options
*-------------------------------------------------------
* All options described below should be passed as a compiler flag to all files using Unity. If you must add #defines, place them BEFORE the #include above.
* Integers/longs/pointers
* - Unity attempts to automatically discover your integer sizes
* - define UNITY_EXCLUDE_STDINT_H to stop attempting to look in <stdint.h>
* - define UNITY_EXCLUDE_LIMITS_H to stop attempting to look in <limits.h>
* - If you cannot use the automatic methods above, you can force Unity by using these options:
* - define UNITY_SUPPORT_64
* - set UNITY_INT_WIDTH
* - set UNITY_LONG_WIDTH
* - set UNITY_POINTER_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_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_EXCLUDE_FLOAT_PRINT to trim binary size, won't print floating point values in errors
* Output
* - by default, Unity prints to standard out with putchar. define UNITY_OUTPUT_CHAR(a) with a different function if desired
* - define UNITY_DIFFERENTIATE_FINAL_FAIL to print FAILED (vs. FAIL) at test end summary - for automated search for failure
* 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
* Tests with Arguments
* - you'll want to define UNITY_USE_COMMAND_LINE_ARGS if you have the test runner passing arguments to Unity
*-------------------------------------------------------
* 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_MESSAGE(message) UnityMessage((message), __LINE__)
#define TEST_ONLY()
/* It is not necessary for you to call PASS. A PASS condition is assumed if nothing fails.
* This method allows you to abort a test immediately with a PASS state, ignoring the remainder of the test. */
#define TEST_PASS() TEST_ABORT()
#define TEST_PASS_MESSAGE(message) do { UnityMessage((message), __LINE__); TEST_ABORT(); } while(0)
/* This macro does nothing, but it is useful for build tools (like Ceedling) to make use of this to figure out
* which files should be linked to in order to perform a test. Use it like TEST_FILE("sandwiches.c") */
#define TEST_FILE(a)
/*-------------------------------------------------------
* 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_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_size_t(expected, actual) UNITY_TEST_ASSERT_EQUAL_UINT((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_EQUAL_CHAR(expected, actual) UNITY_TEST_ASSERT_EQUAL_CHAR((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), (UNITY_UINT32)(-1), (actual), __LINE__, NULL)
#define TEST_ASSERT_BITS_LOW(mask, actual) UNITY_TEST_ASSERT_BITS((mask), (UNITY_UINT32)(0), (actual), __LINE__, NULL)
#define TEST_ASSERT_BIT_HIGH(bit, actual) UNITY_TEST_ASSERT_BITS(((UNITY_UINT32)1 << (bit)), (UNITY_UINT32)(-1), (actual), __LINE__, NULL)
#define TEST_ASSERT_BIT_LOW(bit, actual) UNITY_TEST_ASSERT_BITS(((UNITY_UINT32)1 << (bit)), (UNITY_UINT32)(0), (actual), __LINE__, NULL)
/* Integer Greater Than/ Less Than (of all sizes) */
#define TEST_ASSERT_GREATER_THAN(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_INT((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_THAN_INT(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_INT((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_THAN_INT8(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_INT8((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_THAN_INT16(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_INT16((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_THAN_INT32(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_INT32((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_THAN_INT64(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_INT64((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_THAN_UINT(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_UINT((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_THAN_UINT8(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_UINT8((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_THAN_UINT16(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_UINT16((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_THAN_UINT32(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_UINT32((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_THAN_UINT64(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_UINT64((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_THAN_size_t(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_UINT((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_THAN_HEX8(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_HEX8((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_THAN_HEX16(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_HEX16((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_THAN_HEX32(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_HEX32((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_THAN_HEX64(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_HEX64((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_THAN_CHAR(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_CHAR((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_THAN(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_INT((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_THAN_INT(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_INT((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_THAN_INT8(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_INT8((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_THAN_INT16(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_INT16((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_THAN_INT32(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_INT32((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_THAN_INT64(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_INT64((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_THAN_UINT(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_UINT((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_THAN_UINT8(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_UINT8((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_THAN_UINT16(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_UINT16((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_THAN_UINT32(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_UINT32((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_THAN_UINT64(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_UINT64((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_THAN_size_t(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_UINT((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_THAN_HEX8(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_HEX8((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_THAN_HEX16(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_HEX16((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_THAN_HEX32(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_HEX32((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_THAN_HEX64(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_HEX64((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_THAN_CHAR(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_CHAR((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_OR_EQUAL(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_OR_EQUAL_INT(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_OR_EQUAL_INT8(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT8((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_OR_EQUAL_INT16(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT16((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_OR_EQUAL_INT32(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT32((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_OR_EQUAL_INT64(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT64((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_OR_EQUAL_UINT(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_OR_EQUAL_UINT8(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT8((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_OR_EQUAL_UINT16(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT16((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_OR_EQUAL_UINT32(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT32((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_OR_EQUAL_UINT64(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT64((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_OR_EQUAL_size_t(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_OR_EQUAL_HEX8(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_HEX8((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_OR_EQUAL_HEX16(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_HEX16((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_OR_EQUAL_HEX32(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_HEX32((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_OR_EQUAL_HEX64(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_HEX64((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_OR_EQUAL_CHAR(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_CHAR((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_OR_EQUAL(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_OR_EQUAL_INT(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_OR_EQUAL_INT8(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT8((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_OR_EQUAL_INT16(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT16((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_OR_EQUAL_INT32(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT32((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_OR_EQUAL_INT64(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT64((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_OR_EQUAL_UINT(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_OR_EQUAL_UINT8(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT8((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_OR_EQUAL_UINT16(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT16((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_OR_EQUAL_UINT32(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT32((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_OR_EQUAL_UINT64(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT64((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_OR_EQUAL_size_t(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_OR_EQUAL_HEX8(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_HEX8((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_OR_EQUAL_HEX16(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_HEX16((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_OR_EQUAL_HEX32(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_HEX32((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_OR_EQUAL_HEX64(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_HEX64((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_OR_EQUAL_CHAR(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_CHAR((threshold), (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_INT8_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_INT8_WITHIN((delta), (expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_INT16_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_INT16_WITHIN((delta), (expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_INT32_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_INT32_WITHIN((delta), (expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_INT64_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_INT64_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_UINT8_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_UINT8_WITHIN((delta), (expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_UINT16_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_UINT16_WITHIN((delta), (expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_UINT32_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_UINT32_WITHIN((delta), (expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_UINT64_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_UINT64_WITHIN((delta), (expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_size_t_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)
#define TEST_ASSERT_CHAR_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_CHAR_WITHIN((delta), (expected), (actual), __LINE__, NULL)
/* Integer Array Ranges (of all sizes) */
#define TEST_ASSERT_INT_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_INT_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL)
#define TEST_ASSERT_INT8_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_INT8_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL)
#define TEST_ASSERT_INT16_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_INT16_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL)
#define TEST_ASSERT_INT32_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_INT32_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL)
#define TEST_ASSERT_INT64_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_INT64_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL)
#define TEST_ASSERT_UINT_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_UINT_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL)
#define TEST_ASSERT_UINT8_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_UINT8_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL)
#define TEST_ASSERT_UINT16_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_UINT16_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL)
#define TEST_ASSERT_UINT32_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_UINT32_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL)
#define TEST_ASSERT_UINT64_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_UINT64_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL)
#define TEST_ASSERT_size_t_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_UINT_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL)
#define TEST_ASSERT_HEX_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_HEX32_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL)
#define TEST_ASSERT_HEX8_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_HEX8_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL)
#define TEST_ASSERT_HEX16_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_HEX16_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL)
#define TEST_ASSERT_HEX32_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_HEX32_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL)
#define TEST_ASSERT_HEX64_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_HEX64_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL)
#define TEST_ASSERT_CHAR_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_CHAR_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __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_STRING_LEN(expected, actual, len) UNITY_TEST_ASSERT_EQUAL_STRING_LEN((expected), (actual), (len), __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_size_t_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_UINT_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)
#define TEST_ASSERT_EQUAL_CHAR_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_CHAR_ARRAY((expected), (actual), (num_elements), __LINE__, NULL)
/* Arrays Compared To Single Value */
#define TEST_ASSERT_EACH_EQUAL_INT(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_INT((expected), (actual), (num_elements), __LINE__, NULL)
#define TEST_ASSERT_EACH_EQUAL_INT8(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_INT8((expected), (actual), (num_elements), __LINE__, NULL)
#define TEST_ASSERT_EACH_EQUAL_INT16(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_INT16((expected), (actual), (num_elements), __LINE__, NULL)
#define TEST_ASSERT_EACH_EQUAL_INT32(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_INT32((expected), (actual), (num_elements), __LINE__, NULL)
#define TEST_ASSERT_EACH_EQUAL_INT64(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_INT64((expected), (actual), (num_elements), __LINE__, NULL)
#define TEST_ASSERT_EACH_EQUAL_UINT(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_UINT((expected), (actual), (num_elements), __LINE__, NULL)
#define TEST_ASSERT_EACH_EQUAL_UINT8(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_UINT8((expected), (actual), (num_elements), __LINE__, NULL)
#define TEST_ASSERT_EACH_EQUAL_UINT16(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_UINT16((expected), (actual), (num_elements), __LINE__, NULL)
#define TEST_ASSERT_EACH_EQUAL_UINT32(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_UINT32((expected), (actual), (num_elements), __LINE__, NULL)
#define TEST_ASSERT_EACH_EQUAL_UINT64(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_UINT64((expected), (actual), (num_elements), __LINE__, NULL)
#define TEST_ASSERT_EACH_EQUAL_size_t(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_UINT((expected), (actual), (num_elements), __LINE__, NULL)
#define TEST_ASSERT_EACH_EQUAL_HEX(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_HEX32((expected), (actual), (num_elements), __LINE__, NULL)
#define TEST_ASSERT_EACH_EQUAL_HEX8(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_HEX8((expected), (actual), (num_elements), __LINE__, NULL)
#define TEST_ASSERT_EACH_EQUAL_HEX16(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_HEX16((expected), (actual), (num_elements), __LINE__, NULL)
#define TEST_ASSERT_EACH_EQUAL_HEX32(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_HEX32((expected), (actual), (num_elements), __LINE__, NULL)
#define TEST_ASSERT_EACH_EQUAL_HEX64(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_HEX64((expected), (actual), (num_elements), __LINE__, NULL)
#define TEST_ASSERT_EACH_EQUAL_PTR(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_PTR((expected), (actual), (num_elements), __LINE__, NULL)
#define TEST_ASSERT_EACH_EQUAL_STRING(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_STRING((expected), (actual), (num_elements), __LINE__, NULL)
#define TEST_ASSERT_EACH_EQUAL_MEMORY(expected, actual, len, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_MEMORY((expected), (actual), (len), (num_elements), __LINE__, NULL)
#define TEST_ASSERT_EACH_EQUAL_CHAR(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_CHAR((expected), (actual), (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)
#define TEST_ASSERT_EACH_EQUAL_FLOAT(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_FLOAT((expected), (actual), (num_elements), __LINE__, NULL)
#define TEST_ASSERT_FLOAT_IS_INF(actual) UNITY_TEST_ASSERT_FLOAT_IS_INF((actual), __LINE__, NULL)
#define TEST_ASSERT_FLOAT_IS_NEG_INF(actual) UNITY_TEST_ASSERT_FLOAT_IS_NEG_INF((actual), __LINE__, NULL)
#define TEST_ASSERT_FLOAT_IS_NAN(actual) UNITY_TEST_ASSERT_FLOAT_IS_NAN((actual), __LINE__, NULL)
#define TEST_ASSERT_FLOAT_IS_DETERMINATE(actual) UNITY_TEST_ASSERT_FLOAT_IS_DETERMINATE((actual), __LINE__, NULL)
#define TEST_ASSERT_FLOAT_IS_NOT_INF(actual) UNITY_TEST_ASSERT_FLOAT_IS_NOT_INF((actual), __LINE__, NULL)
#define TEST_ASSERT_FLOAT_IS_NOT_NEG_INF(actual) UNITY_TEST_ASSERT_FLOAT_IS_NOT_NEG_INF((actual), __LINE__, NULL)
#define TEST_ASSERT_FLOAT_IS_NOT_NAN(actual) UNITY_TEST_ASSERT_FLOAT_IS_NOT_NAN((actual), __LINE__, NULL)
#define TEST_ASSERT_FLOAT_IS_NOT_DETERMINATE(actual) UNITY_TEST_ASSERT_FLOAT_IS_NOT_DETERMINATE((actual), __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)
#define TEST_ASSERT_EACH_EQUAL_DOUBLE(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_DOUBLE((expected), (actual), (num_elements), __LINE__, NULL)
#define TEST_ASSERT_DOUBLE_IS_INF(actual) UNITY_TEST_ASSERT_DOUBLE_IS_INF((actual), __LINE__, NULL)
#define TEST_ASSERT_DOUBLE_IS_NEG_INF(actual) UNITY_TEST_ASSERT_DOUBLE_IS_NEG_INF((actual), __LINE__, NULL)
#define TEST_ASSERT_DOUBLE_IS_NAN(actual) UNITY_TEST_ASSERT_DOUBLE_IS_NAN((actual), __LINE__, NULL)
#define TEST_ASSERT_DOUBLE_IS_DETERMINATE(actual) UNITY_TEST_ASSERT_DOUBLE_IS_DETERMINATE((actual), __LINE__, NULL)
#define TEST_ASSERT_DOUBLE_IS_NOT_INF(actual) UNITY_TEST_ASSERT_DOUBLE_IS_NOT_INF((actual), __LINE__, NULL)
#define TEST_ASSERT_DOUBLE_IS_NOT_NEG_INF(actual) UNITY_TEST_ASSERT_DOUBLE_IS_NOT_NEG_INF((actual), __LINE__, NULL)
#define TEST_ASSERT_DOUBLE_IS_NOT_NAN(actual) UNITY_TEST_ASSERT_DOUBLE_IS_NOT_NAN((actual), __LINE__, NULL)
#define TEST_ASSERT_DOUBLE_IS_NOT_DETERMINATE(actual) UNITY_TEST_ASSERT_DOUBLE_IS_NOT_DETERMINATE((actual), __LINE__, NULL)
/* Shorthand */
#ifdef UNITY_SHORTHAND_AS_OLD
#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")
#endif
#ifdef UNITY_SHORTHAND_AS_INT
#define TEST_ASSERT_EQUAL(expected, actual) UNITY_TEST_ASSERT_EQUAL_INT((expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_NOT_EQUAL(expected, actual) UNITY_TEST_FAIL(__LINE__, UnityStrErrShorthand)
#endif
#ifdef UNITY_SHORTHAND_AS_MEM
#define TEST_ASSERT_EQUAL(expected, actual) UNITY_TEST_ASSERT_EQUAL_MEMORY((&expected), (&actual), sizeof(expected), __LINE__, NULL)
#define TEST_ASSERT_NOT_EQUAL(expected, actual) UNITY_TEST_FAIL(__LINE__, UnityStrErrShorthand)
#endif
#ifdef UNITY_SHORTHAND_AS_RAW
#define TEST_ASSERT_EQUAL(expected, actual) UNITY_TEST_ASSERT(((expected) == (actual)), __LINE__, " Expected Equal")
#define TEST_ASSERT_NOT_EQUAL(expected, actual) UNITY_TEST_ASSERT(((expected) != (actual)), __LINE__, " Expected Not-Equal")
#endif
#ifdef UNITY_SHORTHAND_AS_NONE
#define TEST_ASSERT_EQUAL(expected, actual) UNITY_TEST_FAIL(__LINE__, UnityStrErrShorthand)
#define TEST_ASSERT_NOT_EQUAL(expected, actual) UNITY_TEST_FAIL(__LINE__, UnityStrErrShorthand)
#endif
/*-------------------------------------------------------
* 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_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_size_t_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_UINT( (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), (UNITY_UINT32)(-1), (actual), __LINE__, (message))
#define TEST_ASSERT_BITS_LOW_MESSAGE(mask, actual, message) UNITY_TEST_ASSERT_BITS((mask), (UNITY_UINT32)(0), (actual), __LINE__, (message))
#define TEST_ASSERT_BIT_HIGH_MESSAGE(bit, actual, message) UNITY_TEST_ASSERT_BITS(((UNITY_UINT32)1 << (bit)), (UNITY_UINT32)(-1), (actual), __LINE__, (message))
#define TEST_ASSERT_BIT_LOW_MESSAGE(bit, actual, message) UNITY_TEST_ASSERT_BITS(((UNITY_UINT32)1 << (bit)), (UNITY_UINT32)(0), (actual), __LINE__, (message))
#define TEST_ASSERT_EQUAL_CHAR_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_CHAR((expected), (actual), __LINE__, (message))
/* Integer Greater Than/ Less Than (of all sizes) */
#define TEST_ASSERT_GREATER_THAN_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_INT((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_THAN_INT_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_INT((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_THAN_INT8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_INT8((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_THAN_INT16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_INT16((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_THAN_INT32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_INT32((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_THAN_INT64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_INT64((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_THAN_UINT_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_UINT((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_THAN_UINT8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_UINT8((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_THAN_UINT16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_UINT16((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_THAN_UINT32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_UINT32((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_THAN_UINT64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_UINT64((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_THAN_size_t_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_UINT((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_THAN_HEX8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_HEX8((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_THAN_HEX16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_HEX16((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_THAN_HEX32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_HEX32((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_THAN_HEX64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_HEX64((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_THAN_CHAR_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_CHAR((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_THAN_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_INT((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_THAN_INT_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_INT((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_THAN_INT8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_INT8((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_THAN_INT16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_INT16((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_THAN_INT32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_INT32((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_THAN_INT64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_INT64((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_THAN_UINT_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_UINT((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_THAN_UINT8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_UINT8((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_THAN_UINT16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_UINT16((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_THAN_UINT32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_UINT32((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_THAN_UINT64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_UINT64((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_THAN_size_t_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_UINT((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_THAN_HEX8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_HEX8((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_THAN_HEX16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_HEX16((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_THAN_HEX32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_HEX32((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_THAN_HEX64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_HEX64((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_THAN_CHAR_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_CHAR((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_OR_EQUAL_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_OR_EQUAL_INT_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_OR_EQUAL_INT8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT8((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_OR_EQUAL_INT16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT16((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_OR_EQUAL_INT32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT32((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_OR_EQUAL_INT64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT64((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_OR_EQUAL_UINT_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_OR_EQUAL_UINT8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT8((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_OR_EQUAL_UINT16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT16((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_OR_EQUAL_UINT32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT32((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_OR_EQUAL_UINT64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT64((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_OR_EQUAL_size_t_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_OR_EQUAL_HEX8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_HEX8((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_OR_EQUAL_HEX16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_HEX16((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_OR_EQUAL_HEX32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_HEX32((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_OR_EQUAL_HEX64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_HEX64((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_OR_EQUAL_CHAR_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_CHAR((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_OR_EQUAL_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_OR_EQUAL_INT_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_OR_EQUAL_INT8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT8((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_OR_EQUAL_INT16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT16((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_OR_EQUAL_INT32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT32((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_OR_EQUAL_INT64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT64((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_OR_EQUAL_UINT_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_OR_EQUAL_UINT8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT8((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_OR_EQUAL_UINT16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT16((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_OR_EQUAL_UINT32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT32((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_OR_EQUAL_UINT64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT64((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_OR_EQUAL_size_t_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_OR_EQUAL_HEX8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_HEX8((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_OR_EQUAL_HEX16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_HEX16((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_OR_EQUAL_HEX32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_HEX32((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_OR_EQUAL_HEX64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_HEX64((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_OR_EQUAL_CHAR_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_CHAR((threshold), (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_INT8_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_INT8_WITHIN((delta), (expected), (actual), __LINE__, (message))
#define TEST_ASSERT_INT16_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_INT16_WITHIN((delta), (expected), (actual), __LINE__, (message))
#define TEST_ASSERT_INT32_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_INT32_WITHIN((delta), (expected), (actual), __LINE__, (message))
#define TEST_ASSERT_INT64_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_INT64_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_UINT8_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_UINT8_WITHIN((delta), (expected), (actual), __LINE__, (message))
#define TEST_ASSERT_UINT16_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_UINT16_WITHIN((delta), (expected), (actual), __LINE__, (message))
#define TEST_ASSERT_UINT32_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_UINT32_WITHIN((delta), (expected), (actual), __LINE__, (message))
#define TEST_ASSERT_UINT64_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_UINT64_WITHIN((delta), (expected), (actual), __LINE__, (message))
#define TEST_ASSERT_size_t_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))
#define TEST_ASSERT_CHAR_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_CHAR_WITHIN((delta), (expected), (actual), __LINE__, (message))
/* Integer Array Ranges (of all sizes) */
#define TEST_ASSERT_INT_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_INT_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message))
#define TEST_ASSERT_INT8_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_INT8_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message))
#define TEST_ASSERT_INT16_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_INT16_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message))
#define TEST_ASSERT_INT32_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_INT32_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message))
#define TEST_ASSERT_INT64_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_INT64_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message))
#define TEST_ASSERT_UINT_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_UINT_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message))
#define TEST_ASSERT_UINT8_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_UINT8_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message))
#define TEST_ASSERT_UINT16_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_UINT16_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message))
#define TEST_ASSERT_UINT32_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_UINT32_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message))
#define TEST_ASSERT_UINT64_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_UINT64_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message))
#define TEST_ASSERT_size_t_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_UINT_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message))
#define TEST_ASSERT_HEX_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_HEX32_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message))
#define TEST_ASSERT_HEX8_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_HEX8_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message))
#define TEST_ASSERT_HEX16_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_HEX16_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message))
#define TEST_ASSERT_HEX32_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_HEX32_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message))
#define TEST_ASSERT_HEX64_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_HEX64_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message))
#define TEST_ASSERT_CHAR_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_CHAR_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __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_STRING_LEN_MESSAGE(expected, actual, len, message) UNITY_TEST_ASSERT_EQUAL_STRING_LEN((expected), (actual), (len), __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_size_t_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_UINT_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))
#define TEST_ASSERT_EQUAL_CHAR_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_CHAR_ARRAY((expected), (actual), (num_elements), __LINE__, (message))
/* Arrays Compared To Single Value*/
#define TEST_ASSERT_EACH_EQUAL_INT_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_INT((expected), (actual), (num_elements), __LINE__, (message))
#define TEST_ASSERT_EACH_EQUAL_INT8_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_INT8((expected), (actual), (num_elements), __LINE__, (message))
#define TEST_ASSERT_EACH_EQUAL_INT16_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_INT16((expected), (actual), (num_elements), __LINE__, (message))
#define TEST_ASSERT_EACH_EQUAL_INT32_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_INT32((expected), (actual), (num_elements), __LINE__, (message))
#define TEST_ASSERT_EACH_EQUAL_INT64_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_INT64((expected), (actual), (num_elements), __LINE__, (message))
#define TEST_ASSERT_EACH_EQUAL_UINT_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_UINT((expected), (actual), (num_elements), __LINE__, (message))
#define TEST_ASSERT_EACH_EQUAL_UINT8_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_UINT8((expected), (actual), (num_elements), __LINE__, (message))
#define TEST_ASSERT_EACH_EQUAL_UINT16_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_UINT16((expected), (actual), (num_elements), __LINE__, (message))
#define TEST_ASSERT_EACH_EQUAL_UINT32_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_UINT32((expected), (actual), (num_elements), __LINE__, (message))
#define TEST_ASSERT_EACH_EQUAL_UINT64_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_UINT64((expected), (actual), (num_elements), __LINE__, (message))
#define TEST_ASSERT_EACH_EQUAL_size_t_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_UINT((expected), (actual), (num_elements), __LINE__, (message))
#define TEST_ASSERT_EACH_EQUAL_HEX_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_HEX32((expected), (actual), (num_elements), __LINE__, (message))
#define TEST_ASSERT_EACH_EQUAL_HEX8_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_HEX8((expected), (actual), (num_elements), __LINE__, (message))
#define TEST_ASSERT_EACH_EQUAL_HEX16_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_HEX16((expected), (actual), (num_elements), __LINE__, (message))
#define TEST_ASSERT_EACH_EQUAL_HEX32_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_HEX32((expected), (actual), (num_elements), __LINE__, (message))
#define TEST_ASSERT_EACH_EQUAL_HEX64_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_HEX64((expected), (actual), (num_elements), __LINE__, (message))
#define TEST_ASSERT_EACH_EQUAL_PTR_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_PTR((expected), (actual), (num_elements), __LINE__, (message))
#define TEST_ASSERT_EACH_EQUAL_STRING_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_STRING((expected), (actual), (num_elements), __LINE__, (message))
#define TEST_ASSERT_EACH_EQUAL_MEMORY_MESSAGE(expected, actual, len, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_MEMORY((expected), (actual), (len), (num_elements), __LINE__, (message))
#define TEST_ASSERT_EACH_EQUAL_CHAR_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_CHAR((expected), (actual), (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))
#define TEST_ASSERT_EACH_EQUAL_FLOAT_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_FLOAT((expected), (actual), (num_elements), __LINE__, (message))
#define TEST_ASSERT_FLOAT_IS_INF_MESSAGE(actual, message) UNITY_TEST_ASSERT_FLOAT_IS_INF((actual), __LINE__, (message))
#define TEST_ASSERT_FLOAT_IS_NEG_INF_MESSAGE(actual, message) UNITY_TEST_ASSERT_FLOAT_IS_NEG_INF((actual), __LINE__, (message))
#define TEST_ASSERT_FLOAT_IS_NAN_MESSAGE(actual, message) UNITY_TEST_ASSERT_FLOAT_IS_NAN((actual), __LINE__, (message))
#define TEST_ASSERT_FLOAT_IS_DETERMINATE_MESSAGE(actual, message) UNITY_TEST_ASSERT_FLOAT_IS_DETERMINATE((actual), __LINE__, (message))
#define TEST_ASSERT_FLOAT_IS_NOT_INF_MESSAGE(actual, message) UNITY_TEST_ASSERT_FLOAT_IS_NOT_INF((actual), __LINE__, (message))
#define TEST_ASSERT_FLOAT_IS_NOT_NEG_INF_MESSAGE(actual, message) UNITY_TEST_ASSERT_FLOAT_IS_NOT_NEG_INF((actual), __LINE__, (message))
#define TEST_ASSERT_FLOAT_IS_NOT_NAN_MESSAGE(actual, message) UNITY_TEST_ASSERT_FLOAT_IS_NOT_NAN((actual), __LINE__, (message))
#define TEST_ASSERT_FLOAT_IS_NOT_DETERMINATE_MESSAGE(actual, message) UNITY_TEST_ASSERT_FLOAT_IS_NOT_DETERMINATE((actual), __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))
#define TEST_ASSERT_EACH_EQUAL_DOUBLE_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_DOUBLE((expected), (actual), (num_elements), __LINE__, (message))
#define TEST_ASSERT_DOUBLE_IS_INF_MESSAGE(actual, message) UNITY_TEST_ASSERT_DOUBLE_IS_INF((actual), __LINE__, (message))
#define TEST_ASSERT_DOUBLE_IS_NEG_INF_MESSAGE(actual, message) UNITY_TEST_ASSERT_DOUBLE_IS_NEG_INF((actual), __LINE__, (message))
#define TEST_ASSERT_DOUBLE_IS_NAN_MESSAGE(actual, message) UNITY_TEST_ASSERT_DOUBLE_IS_NAN((actual), __LINE__, (message))
#define TEST_ASSERT_DOUBLE_IS_DETERMINATE_MESSAGE(actual, message) UNITY_TEST_ASSERT_DOUBLE_IS_DETERMINATE((actual), __LINE__, (message))
#define TEST_ASSERT_DOUBLE_IS_NOT_INF_MESSAGE(actual, message) UNITY_TEST_ASSERT_DOUBLE_IS_NOT_INF((actual), __LINE__, (message))
#define TEST_ASSERT_DOUBLE_IS_NOT_NEG_INF_MESSAGE(actual, message) UNITY_TEST_ASSERT_DOUBLE_IS_NOT_NEG_INF((actual), __LINE__, (message))
#define TEST_ASSERT_DOUBLE_IS_NOT_NAN_MESSAGE(actual, message) UNITY_TEST_ASSERT_DOUBLE_IS_NOT_NAN((actual), __LINE__, (message))
#define TEST_ASSERT_DOUBLE_IS_NOT_DETERMINATE_MESSAGE(actual, message) UNITY_TEST_ASSERT_DOUBLE_IS_NOT_DETERMINATE((actual), __LINE__, (message))
/* Shorthand */
#ifdef UNITY_SHORTHAND_AS_OLD
#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))
#endif
#ifdef UNITY_SHORTHAND_AS_INT
#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_FAIL(__LINE__, UnityStrErrShorthand)
#endif
#ifdef UNITY_SHORTHAND_AS_MEM
#define TEST_ASSERT_EQUAL_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_MEMORY((&expected), (&actual), sizeof(expected), __LINE__, message)
#define TEST_ASSERT_NOT_EQUAL_MESSAGE(expected, actual, message) UNITY_TEST_FAIL(__LINE__, UnityStrErrShorthand)
#endif
#ifdef UNITY_SHORTHAND_AS_RAW
#define TEST_ASSERT_EQUAL_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT(((expected) == (actual)), __LINE__, message)
#define TEST_ASSERT_NOT_EQUAL_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT(((expected) != (actual)), __LINE__, message)
#endif
#ifdef UNITY_SHORTHAND_AS_NONE
#define TEST_ASSERT_EQUAL_MESSAGE(expected, actual, message) UNITY_TEST_FAIL(__LINE__, UnityStrErrShorthand)
#define TEST_ASSERT_NOT_EQUAL_MESSAGE(expected, actual, message) UNITY_TEST_FAIL(__LINE__, UnityStrErrShorthand)
#endif
/* end of UNITY_FRAMEWORK_H */
#ifdef __cplusplus
}
#endif
#endif

File diff suppressed because it is too large Load Diff