From fa1514705559a16d057742f133df2adc000550b0 Mon Sep 17 00:00:00 2001 From: "Rubio R. C. Terra" Date: Tue, 7 Jun 2016 09:42:35 -0300 Subject: [PATCH] Added custom fake support for variadic functions Custom fake support for variadic functions was limited. The variable parameters were not passed to the custom fake. Now a va_list is passed to the custom fake, so it is possible to access all the arguments. For instance, a custom fake for fprintf() could call the real fprintf() like this: int fprintf_custom(FILE *stream, const char *format, va_list ap) { if (fprintf0_fake.return_val < 0) // should we fail? return fprintf0_fake.return_val; return vfprintf(stream, format, ap); } --- fakegen.rb | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/fakegen.rb b/fakegen.rb index 96a02ea..d908fb7 100644 --- a/fakegen.rb +++ b/fakegen.rb @@ -8,6 +8,10 @@ $MAX_ARGS = 20 $DEFAULT_ARG_HISTORY = 50 $MAX_CALL_HISTORY = 50 +def include_dependencies + putd "#include " +end + def output_constants putd "#define FFF_MAX_ARGS (#{$MAX_ARGS}u)" putd "#ifndef FFF_ARG_HISTORY_LEN" @@ -264,7 +268,8 @@ end # void (*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2);\ def output_custom_function_signature(arg_count, has_varargs, is_value_function) return_type = is_value_function ? "RETURN_TYPE" : "void" - signature = "(*custom_fake)(#{arg_val_list(arg_count)}); \\" + ap_list = has_varargs ? ", va_list ap" : "" + signature = "(*custom_fake)(#{arg_val_list(arg_count)}#{ap_list}); \\" putd return_type + signature end @@ -285,10 +290,26 @@ def output_function_body(arg_count, has_varargs, is_value_function) putd "}\\" putd "INCREMENT_CALL_COUNT(FUNCNAME); \\" putd "REGISTER_CALL(FUNCNAME); \\" - - return_type = is_value_function ? "return" : "" - putd "if (FUNCNAME##_fake.custom_fake) #{return_type} FUNCNAME##_fake.custom_fake(#{arg_list(arg_count)}); \\" - + + if has_varargs + putd "if(FUNCNAME##_fake.custom_fake){\\" + putd " RETURN_TYPE ret;\\" if is_value_function + putd " va_list ap;\\" + putd " va_start(ap, arg#{arg_count-1});\\" + custom_fake_call = "FUNCNAME##_fake.custom_fake(#{arg_list(arg_count)}, ap);" + if is_value_function + putd " ret = #{custom_fake_call}\\" + else + putd " #{custom_fake_call}\\" + end + putd " va_end(ap);\\" + putd " return ret;\\" if is_value_function + putd "}\\" + else + return_type = is_value_function ? "return " : "" + putd "if (FUNCNAME##_fake.custom_fake) #{return_type}FUNCNAME##_fake.custom_fake(#{arg_list(arg_count)}); \\" + end + putd "RETURN_FAKE_RESULT(FUNCNAME) \\" if is_value_function end @@ -400,6 +421,7 @@ end def output_c_and_cpp include_guard { + include_dependencies output_constants output_internal_helper_macros yield