+/* Licensed under GPLv3+ - see LICENSE file for details */
#include <ccan/opt/opt.h>
#include <string.h>
#include <errno.h>
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);
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;
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);
}
/* 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. */
/* 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);
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, ...)