C调用 - 间接包装函数

时间:2017-08-05 06:09:45

标签: c cmake

我已经使用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()

0 个答案:

没有答案