X-Git-Url: http://git.ozlabs.org/?p=ccan;a=blobdiff_plain;f=ccan%2Fopt%2Ftest%2Futils.c;h=2ff04884ebdc0efe6dc4d9dd8fe4ae6af4b9175b;hp=6870af741b188034a5a5337ae3de66c880189d71;hb=c656dceb3f04c2e3da7af40824c97eff5119a0b9;hpb=d89e5744f30b584ac4909ce1164af1289c41359b diff --git a/ccan/opt/test/utils.c b/ccan/opt/test/utils.c index 6870af74..2ff04884 100644 --- a/ccan/opt/test/utils.c +++ b/ccan/opt/test/utils.c @@ -1,15 +1,14 @@ -#define _GNU_SOURCE +#include "config.h" #include #include #include #include -#include #include #include #include "utils.h" unsigned int test_cb_called; -char *test_noarg(void *arg) +char *test_noarg(void *arg UNNEEDED) { test_cb_called++; return NULL; @@ -29,13 +28,15 @@ void show_arg(char buf[OPT_SHOW_LEN], const char *arg) char *err_output = NULL; -static void save_err_output(const char *fmt, ...) +void save_err_output(const char *fmt, ...) { va_list ap; char *p; va_start(ap, fmt); - vasprintf(&p, fmt, ap); + /* Check return, for fascist gcc */ + if (vasprintf(&p, fmt, ap) == -1) + p = NULL; va_end(ap); if (err_output) { @@ -47,7 +48,15 @@ static void save_err_output(const char *fmt, ...) err_output = p; } -/* FIXME: This leaks, BTW. */ +void reset_options(void) +{ + opt_free_table(); + free(err_output); + err_output = NULL; +} + +static bool allocated = false; + bool parse_args(int *argc, char ***argv, ...) { char **a; @@ -61,42 +70,89 @@ bool parse_args(int *argc, char ***argv, ...) (*argc)++; a = realloc(a, sizeof(*a) * (*argc + 1)); } + + if (allocated) + free(*argv); + *argv = a; - /* Re-set before parsing. */ - optind = 0; + allocated = true; return opt_parse(argc, *argv, save_err_output); } +bool parse_early_args(int *argc, char ***argv, ...) +{ + char **a; + va_list ap; + + va_start(ap, argv); + *argc = 1; + a = malloc(sizeof(*a) * (*argc + 1)); + a[0] = (*argv)[0]; + while ((a[*argc] = va_arg(ap, char *)) != NULL) { + (*argc)++; + a = realloc(a, sizeof(*a) * (*argc + 1)); + } + + if (allocated) + free(*argv); + + *argv = a; + allocated = true; + + return opt_early_parse(*argc, *argv, save_err_output); +} + +bool parse_early_args_incomplete(int *argc, char ***argv, ...) +{ + char **a; + va_list ap; + + va_start(ap, argv); + *argc = 1; + a = malloc(sizeof(*a) * (*argc + 1)); + a[0] = (*argv)[0]; + while ((a[*argc] = va_arg(ap, char *)) != NULL) { + (*argc)++; + a = realloc(a, sizeof(*a) * (*argc + 1)); + } + + if (allocated) + free(*argv); + + *argv = a; + allocated = true; + + return opt_early_parse_incomplete(*argc, *argv, save_err_output); +} + struct opt_table short_table[] = { /* Short opts, different args. */ - { OPT_WITHOUT_ARG("-a", test_noarg, "a"), "Description of a" }, - { OPT_WITH_ARG("-b", test_arg, show_arg, "b"), "Description of b" }, + OPT_WITHOUT_ARG("-a", test_noarg, "a", "Description of a"), + OPT_WITH_ARG("-b", test_arg, show_arg, "b", "Description of b"), OPT_ENDTABLE }; struct opt_table long_table[] = { /* Long opts, different args. */ - { OPT_WITHOUT_ARG("--ddd", test_noarg, "ddd"), "Description of ddd" }, - { OPT_WITH_ARG("--eee", test_arg, show_arg, "eee"), }, + OPT_WITHOUT_ARG("--ddd", test_noarg, "ddd", "Description of ddd"), + OPT_WITH_ARG("--eee ", test_arg, show_arg, "eee", ""), OPT_ENDTABLE }; struct opt_table long_and_short_table[] = { /* Short and long, different args. */ - { OPT_WITHOUT_ARG("--ggg/-g", test_noarg, "ggg"), - "Description of ggg" }, - { OPT_WITH_ARG("-h/--hhh", test_arg, NULL, "hhh"), - "Description of hhh"}, + OPT_WITHOUT_ARG("--ggg|-g", test_noarg, "ggg", "Description of ggg"), + OPT_WITH_ARG("-h|--hhh", test_arg, NULL, "hhh", "Description of hhh"), OPT_ENDTABLE }; /* Sub-table test. */ struct opt_table subtables[] = { /* Two short, and two long long, no description */ - { OPT_WITH_ARG("--jjj/-j/--lll/-l", test_arg, show_arg, "jjj") }, + OPT_WITH_ARG("--jjj|-j|--lll|-l", test_arg, show_arg, "jjj", ""), /* Hidden option */ - { OPT_WITH_ARG("--mmm/-m", test_arg, show_arg, "mmm"), opt_hidden }, + OPT_WITH_ARG("--mmm|-m", test_arg, show_arg, "mmm", opt_hidden), OPT_SUBTABLE(short_table, NULL), OPT_SUBTABLE(long_table, "long table options"), OPT_SUBTABLE(long_and_short_table, NULL),