tdb2: copy tdb1's changed expansion logic.
[ccan] / ccan / opt / opt.c
index 5aaa000b64a1cd31fd1078c021d62c4117c47146..094b15c7e1b48c25aed1256aa741921ad8091f52 100644 (file)
@@ -107,7 +107,9 @@ static void check_opt(const struct opt_table *entry)
        const char *p;
        unsigned len;
 
        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);
 
                errx(1, "Option %s: unknown entry type %u",
                     entry->names, entry->type);
 
@@ -196,7 +198,28 @@ bool opt_parse(int *argc, char *argv[], void (*errlog)(const char *fmt, ...))
        /* This helps opt_usage. */
        opt_argv0 = argv[0];
 
        /* 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);
 
        /* parse_one returns 0 on finish, -1 on error */
        return (ret == 0);
@@ -205,7 +228,8 @@ bool opt_parse(int *argc, char *argv[], void (*errlog)(const char *fmt, ...))
 void opt_free_table(void)
 {
        free(opt_table);
 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, ...)
 }
 
 void opt_log_stderr(const char *fmt, ...)