X-Git-Url: http://git.ozlabs.org/?p=ccan;a=blobdiff_plain;f=ccan%2Fopt%2Fopt.c;h=094b15c7e1b48c25aed1256aa741921ad8091f52;hp=f05d125fc828dda1e647a49788d5ccb1ac5b5d05;hb=c438ec17d7b2efe76e56e5fc5ab88bd4a02735e8;hpb=6a6f64f541e5d09162e0ba8814e04feb13ff5e8f diff --git a/ccan/opt/opt.c b/ccan/opt/opt.c index f05d125f..094b15c7 100644 --- a/ccan/opt/opt.c +++ b/ccan/opt/opt.c @@ -1,3 +1,4 @@ +/* Licensed under GPLv3+ - see LICENSE file for details */ #include #include #include @@ -106,7 +107,9 @@ static void check_opt(const struct opt_table *entry) const char *p; unsigned len; - if (entry->type != OPT_HASARG && entry->type != OPT_NOARG) + if (entry->type != OPT_HASARG && entry->type != OPT_NOARG + && entry->type != (OPT_EARLY|OPT_HASARG) + && entry->type != (OPT_EARLY|OPT_NOARG)) errx(1, "Option %s: unknown entry type %u", entry->names, entry->type); @@ -150,7 +153,7 @@ void _opt_register(const char *names, enum opt_type type, char *(*cb)(void *arg), char *(*cb_arg)(const char *optarg, void *arg), void (*show)(char buf[OPT_SHOW_LEN], const void *arg), - void *arg, const char *desc) + const void *arg, const char *desc) { struct opt_table opt; opt.names = names; @@ -158,7 +161,7 @@ void _opt_register(const char *names, enum opt_type type, opt.cb = cb; opt.cb_arg = cb_arg; opt.show = show; - opt.arg = arg; + opt.u.carg = arg; opt.desc = desc; check_opt(&opt); add_opt(&opt); @@ -183,7 +186,7 @@ void opt_register_table(const struct opt_table entry[], const char *desc) } /* We store the table length in arg ptr. */ if (desc) - opt_table[start].arg = (void *)(intptr_t)(opt_count - start); + opt_table[start].u.tlen = (opt_count - start); } /* Parse your arguments. */ @@ -195,7 +198,28 @@ bool opt_parse(int *argc, char *argv[], void (*errlog)(const char *fmt, ...)) /* This helps opt_usage. */ opt_argv0 = argv[0]; - while ((ret = parse_one(argc, argv, &offset, errlog)) == 1); + while ((ret = parse_one(argc, argv, 0, &offset, errlog)) == 1); + + /* parse_one returns 0 on finish, -1 on error */ + return (ret == 0); +} + +bool opt_early_parse(int argc, char *argv[], + void (*errlog)(const char *fmt, ...)) +{ + int ret; + unsigned off = 0; + char **tmpargv = malloc(sizeof(argv[0]) * (argc + 1)); + + /* We could avoid a copy and skip instead, but this is simple. */ + memcpy(tmpargv, argv, sizeof(argv[0]) * (argc + 1)); + + /* This helps opt_usage. */ + opt_argv0 = argv[0]; + + while ((ret = parse_one(&argc, tmpargv, OPT_EARLY, &off, errlog)) == 1); + + free(tmpargv); /* parse_one returns 0 on finish, -1 on error */ return (ret == 0); @@ -204,7 +228,8 @@ bool opt_parse(int *argc, char *argv[], void (*errlog)(const char *fmt, ...)) void opt_free_table(void) { free(opt_table); - opt_table=0; + opt_table = NULL; + opt_count = opt_num_short = opt_num_short_arg = opt_num_long = 0; } void opt_log_stderr(const char *fmt, ...)