我已经使用CMake argp_usage()
包裹了一个函数set_target_properties
,如下所示:
[project_root /测试/的CMakeLists.txt]
add_executable(test_args test_args.c)
target_link_libraries(test_args cmocka)
add_test(NAME test_args COMMAND test_args)
set_target_properties(test_args PROPERTIES LINK_FLAGS "-Wl,--wrap=argp_usage")
但是,我的生产代码仍然会调用真实的argp_usage()
。
问题是我的测试代码实际上并没有直接调用argp_usage,而是调用我的生产代码然后调用argp_usage,如下所示:
[project_root /测试/ test_args.c]
#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include <cmocka.h>
#include "../src/args.c"
#include "../src/args.h"
void __wrap_argp_usage(struct argp_state *state)
{
assert_non_null(state);
}
void parseArgs_inputIsValid_return0(void **state)
{
int rv, argc = 2;
char *argv[argc];
argv[0] = "eternity";
argv[1] = "--help";
rv = parse_args(argc, argv);
assert_int_equal(rv, 0);
}
int main(void)
{
const struct CMUnitTest tests[] =
{
cmocka_unit_test(parseArgs_inputIsValid_return0),
};
return cmocka_run_group_tests(tests, NULL, NULL);
}
注意调用rv = parse_args(argc, argv);
,即调用我的生产代码,函数定义如下:
[project_root / SRC / args.c]
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <argp.h>
#include <errno.h>
#include <config.h>
#include "args.h"
/* argp requires these to be global */
const char *argp_program_version = PACKAGE_VERSION;
const char *argp_program_bug_address = PACKAGE_BUGREPORT;
error_t parse_opt(int key, char *arg, struct argp_state *state)
{
struct args *args = state->input;
if (args->count > 128)
argp_usage(state);
switch (key)
{
case 'q': case 's':
args->silent = 1;
break;
case 'v':
args->verbose = 1;
break;
case 'o':
args->output_file = arg;
break;
case ARGP_KEY_ARG:
if (args->count-- < 0)
break;
break;
case ARGP_KEY_END:
if (state->arg_num < 1)
argp_usage(state);
break;
default:
return ARGP_ERR_UNKNOWN;
break;
}
return 0;
}
int parse_args(int argc, char **argv)
{
int rv;
const char* doc = "Eternity - your window to the good";
char args_doc[] = "file1.jpg file2.png file3.bmp ...";
struct argp_option options[] = {
{"verbose",'v', 0, 0, "Produce verbose output", 0},
{"quiet", 'q', 0, 0, "Don't produce any output", 0},
{"silent", 's', 0, OPTION_ALIAS, NULL, 0},
{"output", 'o', "FILE", 0, "Output to FILE instead of std output", 0},
{0}
};
struct argp argp = {options, parse_opt, args_doc, doc, NULL, 0, NULL};
struct args args;
args.count = argc;
args.silent = args.verbose = 0;
args.output_file = "-";
rv = argp_parse(&argp, argc, argv, 0, 0, &args);
if (rv != 0)
{
fprintf(stderr, strerror(rv));
return -1;
}
return 0;
}
现在,最后,实际调用argp_usage()
的函数(我试图包装的函数)是这个parse_opt()
函数,它是argp库使用的回调函数,但由我是用户。
如何包装argp_usage()
以便如果像这样间接调用它仍会调用包装函数__wrap_argp_usage()
?