Added the return_thru_ptr and ignore_arg plugins

This commit is contained in:
Dennis Lambe Jr
2012-12-19 19:06:10 -05:00
parent 0647e5a9e2
commit 932785fd71
5 changed files with 210 additions and 42 deletions
+47
View File
@@ -0,0 +1,47 @@
class CMockGeneratorPluginIgnoreArg
attr_reader :priority
attr_accessor :config, :utils, :unity_helper, :ordered
def initialize(config, utils)
@config = config
@ordered = @config.enforce_strict_ordering
@utils = utils
@unity_helper = @utils.helpers[:unity_helper]
@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|
arg_name = arg[:name]
arg_type = arg[:type]
lines << "void #{function[:name]}_CMockIgnoreArg_#{arg[:name]}(UNITY_LINE_TYPE cmock_line)\n"
lines << "{\n"
lines << " CMOCK_#{func_name}_CALL_INSTANCE* cmock_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, \"#{arg_name} IgnoreArg called before Expect on '#{func_name}'.\");\n"
lines << " cmock_call_instance->IgnoreArg_#{arg_name} = 1;\n"
lines << "}\n\n"
end
lines
end
end
@@ -0,0 +1,77 @@
class CMockGeneratorPluginReturnThruPtr
attr_reader :priority
attr_accessor :config, :utils, :unity_helper, :ordered
def initialize(config, utils)
@config = config
@ordered = @config.enforce_strict_ordering
@utils = utils
@unity_helper = @utils.helpers[:unity_helper]
@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]})"
lines << " #{function[:name]}_CMockReturnMemThruPtr_#{arg[:name]}(__LINE__, #{arg[:name]}, sizeof(*#{arg[:name]}))\n"
lines << "#define #{function[:name]}_ReturnArrayThruPtr_#{arg[:name]}(#{arg[:name]}, cmock_len)"
lines << " #{function[:name]}_CMockReturnMemThruPtr_#{arg[:name]}(__LINE__, #{arg[:name]}, cmock_len * 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]
arg_type = arg[:type]
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_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, \"#{arg_name} ReturnThruPtr called before Expect on '#{func_name}'.\");\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]
arg_type = arg[:type]
if (@utils.ptr_or_str?(arg[:type]) and not arg[:const?])
lines << " if (cmock_call_instance->ReturnThruPtr_#{arg_name}_Used)\n"
lines << " {\n"
lines << " memcpy(#{arg_name}, cmock_call_instance->ReturnThruPtr_#{arg_name}_Val,\n"
lines << " cmock_call_instance->ReturnThruPtr_#{arg_name}_Size);\n"
lines << " }\n"
end
end
lines
end
end
+67 -42
View File
@@ -14,6 +14,8 @@ class CMockGeneratorUtils
@ordered = @config.enforce_strict_ordering
@arrays = @config.plugins.include? :array
@cexception = @config.plugins.include? :cexception
@return_thru_ptr = @config.plugins.include? :return_thru_ptr
@ignore_arg = @config.plugins.include? :ignore_arg
@treat_as = @config.treat_as
@helpers = helpers
@@ -28,7 +30,7 @@ class CMockGeneratorUtils
end
end
def code_add_base_expectation(func_name, global_ordering_supported=true)
def code_add_base_expectation(func_name, global_ordering_supported=true)
lines = " CMOCK_MEM_INDEX_TYPE cmock_guts_index = CMock_Guts_MemNew(sizeof(CMOCK_#{func_name}_CALL_INSTANCE));\n"
lines << " CMOCK_#{func_name}_CALL_INSTANCE* cmock_call_instance = (CMOCK_#{func_name}_CALL_INSTANCE*)CMock_Guts_GetAddressFor(cmock_guts_index);\n"
lines << " UNITY_TEST_ASSERT_NOT_NULL(cmock_call_instance, cmock_line, \"CMock has run out of memory. Please allocate more.\");\n"
@@ -42,6 +44,8 @@ class CMockGeneratorUtils
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
@@ -84,94 +88,115 @@ class CMockGeneratorUtils
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}"
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
unity_msg = "Function '#{function[:name]}' called with unexpected value for argument '#{arg_name}'."
return c_type, arg_name, expected, unity_func[0], unity_func[1], unity_msg
return c_type, arg_name, expected, ignore, unity_func[0], unity_func[1], unity_msg
end
def code_verify_an_arg_expectation_with_no_arrays(function, arg)
c_type, arg_name, expected, unity_func, pre, unity_msg = lookup_expect_type(function, arg)
c_type, arg_name, expected, ignore, unity_func, pre, unity_msg = lookup_expect_type(function, arg)
lines = ""
lines << " if (!#{ignore})\n" if @ignore_arg
lines << " {\n"
case(unity_func)
when "UNITY_TEST_ASSERT_EQUAL_MEMORY"
c_type_local = c_type.gsub(/\*$/,'')
return " UNITY_TEST_ASSERT_EQUAL_MEMORY((void*)(#{pre}#{expected}), (void*)(#{pre}#{arg_name}), sizeof(#{c_type_local}), cmock_line, \"#{unity_msg}\");\n"
lines << " UNITY_TEST_ASSERT_EQUAL_MEMORY((void*)(#{pre}#{expected}), (void*)(#{pre}#{arg_name}), sizeof(#{c_type_local}), cmock_line, \"#{unity_msg}\");\n"
when "UNITY_TEST_ASSERT_EQUAL_MEMORY"
[ " if (#{pre}#{expected} == NULL)",
" { UNITY_TEST_ASSERT_NULL(#{pre}#{arg_name}, cmock_line, \"Expected NULL. #{unity_msg}\"); }",
" else",
" { UNITY_TEST_ASSERT_EQUAL_MEMORY((void*)(#{pre}#{expected}), (void*)(#{pre}#{arg_name}), sizeof(#{c_type.sub('*','')}), cmock_line, \"#{unity_msg}\"); }\n"].join("\n")
lines << " if (#{pre}#{expected} == NULL)\n"
lines << " { UNITY_TEST_ASSERT_NULL(#{pre}#{arg_name}, cmock_line, \"Expected NULL. #{unity_msg}\"); }\n"
lines << " else\n"
lines << " { UNITY_TEST_ASSERT_EQUAL_MEMORY((void*)(#{pre}#{expected}), (void*)(#{pre}#{arg_name}), sizeof(#{c_type.sub('*','')}), cmock_line, \"#{unity_msg}\"); }\n"
when /_ARRAY/
[ " if (#{pre}#{expected} == NULL)",
" { UNITY_TEST_ASSERT_NULL(#{pre}#{arg_name}, cmock_line, \"Expected NULL. #{unity_msg}\"); }",
" else",
" { #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, 1, cmock_line, \"#{unity_msg}\"); }\n"].join("\n")
lines << " if (#{pre}#{expected} == NULL)\n"
lines << " { UNITY_TEST_ASSERT_NULL(#{pre}#{arg_name}, cmock_line, \"Expected NULL. #{unity_msg}\"); }\n"
lines << " else\n"
lines << " { #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, 1, cmock_line, \"#{unity_msg}\"); }\n"
else
return " #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, cmock_line, \"#{unity_msg}\");\n"
end
lines << " #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, cmock_line, \"#{unity_msg}\");\n"
end
lines << " }\n"
lines
end
def code_verify_an_arg_expectation_with_normal_arrays(function, arg)
c_type, arg_name, expected, unity_func, pre, unity_msg = lookup_expect_type(function, arg)
c_type, arg_name, expected, ignore, unity_func, pre, unity_msg = 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"
case(unity_func)
when "UNITY_TEST_ASSERT_EQUAL_MEMORY"
c_type_local = c_type.gsub(/\*$/,'')
return " UNITY_TEST_ASSERT_EQUAL_MEMORY((void*)(#{pre}#{expected}), (void*)(#{pre}#{arg_name}), sizeof(#{c_type_local}), cmock_line, \"#{unity_msg}\");\n"
lines << " UNITY_TEST_ASSERT_EQUAL_MEMORY((void*)(#{pre}#{expected}), (void*)(#{pre}#{arg_name}), sizeof(#{c_type_local}), cmock_line, \"#{unity_msg}\");\n"
when "UNITY_TEST_ASSERT_EQUAL_MEMORY_ARRAY"
[ " if (#{pre}#{expected} == NULL)",
" { UNITY_TEST_ASSERT_NULL(#{pre}#{arg_name}, cmock_line, \"Expected NULL. #{unity_msg}\"); }",
" else",
" { UNITY_TEST_ASSERT_EQUAL_MEMORY_ARRAY((void*)(#{pre}#{expected}), (void*)(#{pre}#{arg_name}), sizeof(#{c_type.sub('*','')}), #{depth_name}, cmock_line, \"#{unity_msg}\"); }\n"].compact.join("\n")
lines << " if (#{pre}#{expected} == NULL)\n"
lines << " { UNITY_TEST_ASSERT_NULL(#{pre}#{arg_name}, cmock_line, \"Expected NULL. #{unity_msg}\"); }\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, \"#{unity_msg}\"); }\n"
when /_ARRAY/
if (pre == '&')
" #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, #{depth_name}, cmock_line, \"#{unity_msg}\");\n"
lines << " #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, #{depth_name}, cmock_line, \"#{unity_msg}\");\n"
else
[ " if (#{pre}#{expected} == NULL)",
" { UNITY_TEST_ASSERT_NULL(#{pre}#{arg_name}, cmock_line, \"Expected NULL. #{unity_msg}\"); }",
" else",
" { #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, #{depth_name}, cmock_line, \"#{unity_msg}\"); }\n"].compact.join("\n")
lines << " if (#{pre}#{expected} == NULL)\n"
lines << " { UNITY_TEST_ASSERT_NULL(#{pre}#{arg_name}, cmock_line, \"Expected NULL. #{unity_msg}\"); }\n"
lines << " else\n"
lines << " { #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, #{depth_name}, cmock_line, \"#{unity_msg}\"); }\n"
end
else
return " #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, cmock_line, \"#{unity_msg}\");\n"
lines << " #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, cmock_line, \"#{unity_msg}\");\n"
end
lines << " }\n"
lines
end
def code_verify_an_arg_expectation_with_smart_arrays(function, arg)
c_type, arg_name, expected, unity_func, pre, unity_msg = lookup_expect_type(function, arg)
c_type, arg_name, expected, ignore, unity_func, pre, unity_msg = 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"
case(unity_func)
when "UNITY_TEST_ASSERT_EQUAL_MEMORY"
c_type_local = c_type.gsub(/\*$/,'')
return " UNITY_TEST_ASSERT_EQUAL_MEMORY((void*)(#{pre}#{expected}), (void*)(#{pre}#{arg_name}), sizeof(#{c_type_local}), cmock_line, \"#{unity_msg}\");\n"
lines << " UNITY_TEST_ASSERT_EQUAL_MEMORY((void*)(#{pre}#{expected}), (void*)(#{pre}#{arg_name}), sizeof(#{c_type_local}), cmock_line, \"#{unity_msg}\");\n"
when "UNITY_TEST_ASSERT_EQUAL_MEMORY_ARRAY"
[ " if (#{pre}#{expected} == NULL)",
" { UNITY_TEST_ASSERT_NULL(#{arg_name}, cmock_line, \"Expected NULL. #{unity_msg}\"); }",
((depth_name != 1) ? " else if (#{depth_name} == 0)\n { UNITY_TEST_ASSERT_EQUAL_PTR(#{pre}#{expected}, #{pre}#{arg_name}, cmock_line, \"#{unity_msg}\"); }" : nil),
" else",
" { UNITY_TEST_ASSERT_EQUAL_MEMORY_ARRAY((void*)(#{pre}#{expected}), (void*)(#{pre}#{arg_name}), sizeof(#{c_type.sub('*','')}), #{depth_name}, cmock_line, \"#{unity_msg}\"); }\n"].compact.join("\n")
lines << " if (#{pre}#{expected} == NULL)\n"
lines << " { UNITY_TEST_ASSERT_NULL(#{arg_name}, cmock_line, \"Expected NULL. #{unity_msg}\"); }\n"
lines << ((depth_name != 1) ? " else if (#{depth_name} == 0)\n { UNITY_TEST_ASSERT_EQUAL_PTR(#{pre}#{expected}, #{pre}#{arg_name}, cmock_line, \"#{unity_msg}\"); }\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, \"#{unity_msg}\"); }\n"
when /_ARRAY/
if (pre == '&')
" #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, #{depth_name}, cmock_line, \"#{unity_msg}\");\n"
lines << " #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, #{depth_name}, cmock_line, \"#{unity_msg}\");\n"
else
[ " if (#{pre}#{expected} == NULL)",
" { UNITY_TEST_ASSERT_NULL(#{pre}#{arg_name}, cmock_line, \"Expected NULL. #{unity_msg}\"); }",
((depth_name != 1) ? " else if (#{depth_name} == 0)\n { UNITY_TEST_ASSERT_EQUAL_PTR(#{pre}#{expected}, #{pre}#{arg_name}, cmock_line, \"#{unity_msg}\"); }" : nil),
" else",
" { #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, #{depth_name}, cmock_line, \"#{unity_msg}\"); }\n"].compact.join("\n")
lines << " if (#{pre}#{expected} == NULL)\n"
lines << " { UNITY_TEST_ASSERT_NULL(#{pre}#{arg_name}, cmock_line, \"Expected NULL. #{unity_msg}\"); }\n"
lines << ((depth_name != 1) ? " else if (#{depth_name} == 0)\n { UNITY_TEST_ASSERT_EQUAL_PTR(#{pre}#{expected}, #{pre}#{arg_name}, cmock_line, \"#{unity_msg}\"); }\n" : "")
lines << " else\n"
lines << " { #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, #{depth_name}, cmock_line, \"#{unity_msg}\"); }\n"
end
else
return " #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, cmock_line, \"#{unity_msg}\");\n"
lines << " #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, cmock_line, \"#{unity_msg}\");\n"
end
lines << " }\n"
lines
end
end
end
+18
View File
@@ -146,6 +146,24 @@ CMOCK_MEM_INDEX_TYPE CMock_Guts_MemNext(CMOCK_MEM_INDEX_TYPE previous_item_index
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
//-------------------------------------------------------
+1
View File
@@ -20,6 +20,7 @@
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);