mirror of
https://github.com/meekrosoft/fff
synced 2026-01-23 08:25:59 +01:00
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);
}
This commit is contained in:
committed by
Rubio Ribeiro Canario Terra
parent
a34e5a5a20
commit
fa15147055
28
fakegen.rb
28
fakegen.rb
@@ -8,6 +8,10 @@ $MAX_ARGS = 20
|
|||||||
$DEFAULT_ARG_HISTORY = 50
|
$DEFAULT_ARG_HISTORY = 50
|
||||||
$MAX_CALL_HISTORY = 50
|
$MAX_CALL_HISTORY = 50
|
||||||
|
|
||||||
|
def include_dependencies
|
||||||
|
putd "#include <stdarg.h>"
|
||||||
|
end
|
||||||
|
|
||||||
def output_constants
|
def output_constants
|
||||||
putd "#define FFF_MAX_ARGS (#{$MAX_ARGS}u)"
|
putd "#define FFF_MAX_ARGS (#{$MAX_ARGS}u)"
|
||||||
putd "#ifndef FFF_ARG_HISTORY_LEN"
|
putd "#ifndef FFF_ARG_HISTORY_LEN"
|
||||||
@@ -264,7 +268,8 @@ end
|
|||||||
# void (*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2);\
|
# void (*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2);\
|
||||||
def output_custom_function_signature(arg_count, has_varargs, is_value_function)
|
def output_custom_function_signature(arg_count, has_varargs, is_value_function)
|
||||||
return_type = is_value_function ? "RETURN_TYPE" : "void"
|
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
|
putd return_type + signature
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -286,8 +291,24 @@ def output_function_body(arg_count, has_varargs, is_value_function)
|
|||||||
putd "INCREMENT_CALL_COUNT(FUNCNAME); \\"
|
putd "INCREMENT_CALL_COUNT(FUNCNAME); \\"
|
||||||
putd "REGISTER_CALL(FUNCNAME); \\"
|
putd "REGISTER_CALL(FUNCNAME); \\"
|
||||||
|
|
||||||
return_type = is_value_function ? "return" : ""
|
if has_varargs
|
||||||
putd "if (FUNCNAME##_fake.custom_fake) #{return_type} FUNCNAME##_fake.custom_fake(#{arg_list(arg_count)}); \\"
|
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
|
putd "RETURN_FAKE_RESULT(FUNCNAME) \\" if is_value_function
|
||||||
end
|
end
|
||||||
@@ -400,6 +421,7 @@ end
|
|||||||
def output_c_and_cpp
|
def output_c_and_cpp
|
||||||
|
|
||||||
include_guard {
|
include_guard {
|
||||||
|
include_dependencies
|
||||||
output_constants
|
output_constants
|
||||||
output_internal_helper_macros
|
output_internal_helper_macros
|
||||||
yield
|
yield
|
||||||
|
|||||||
Reference in New Issue
Block a user