mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-03-03 10:46:58 +01:00
ccan: Update ccan modules to include incomplete option parsing
Signed-off-by: Christian Decker <@cdecker>
This commit is contained in:
parent
62e6a9ff54
commit
045f7ce7f7
8 changed files with 116 additions and 9 deletions
|
@ -1,3 +1,3 @@
|
|||
CCAN imported from http://ccodearchive.net.
|
||||
|
||||
CCAN version: init-2451-gfedf5151
|
||||
CCAN version: init-2454-gc656dceb
|
||||
|
|
|
@ -207,14 +207,15 @@ 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, 0, &offset, errlog)) == 1);
|
||||
while ((ret = parse_one(argc, argv, 0, &offset, errlog, false)) == 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, ...))
|
||||
static bool early_parse(int argc, char *argv[],
|
||||
void (*errlog)(const char *fmt, ...),
|
||||
bool ignore_unknown)
|
||||
{
|
||||
int ret;
|
||||
unsigned off = 0;
|
||||
|
@ -226,7 +227,7 @@ bool opt_early_parse(int argc, char *argv[],
|
|||
/* This helps opt_usage. */
|
||||
opt_argv0 = argv[0];
|
||||
|
||||
while ((ret = parse_one(&argc, tmpargv, OPT_EARLY, &off, errlog)) == 1);
|
||||
while ((ret = parse_one(&argc, tmpargv, OPT_EARLY, &off, errlog, ignore_unknown)) == 1);
|
||||
|
||||
opt_alloc.free(tmpargv);
|
||||
|
||||
|
@ -234,6 +235,18 @@ bool opt_early_parse(int argc, char *argv[],
|
|||
return (ret == 0);
|
||||
}
|
||||
|
||||
bool opt_early_parse(int argc, char *argv[],
|
||||
void (*errlog)(const char *fmt, ...))
|
||||
{
|
||||
return early_parse(argc, argv, errlog, false);
|
||||
}
|
||||
|
||||
bool opt_early_parse_incomplete(int argc, char *argv[],
|
||||
void (*errlog)(const char *fmt, ...))
|
||||
{
|
||||
return early_parse(argc, argv, errlog, true);
|
||||
}
|
||||
|
||||
void opt_free_table(void)
|
||||
{
|
||||
opt_alloc.free(opt_table);
|
||||
|
|
|
@ -286,6 +286,30 @@ bool opt_parse(int *argc, char *argv[], void (*errlog)(const char *fmt, ...));
|
|||
bool opt_early_parse(int argc, char *argv[],
|
||||
void (*errlog)(const char *fmt, ...));
|
||||
|
||||
/**
|
||||
* opt_early_parse_incomplete - parse early arguments, ignoring unknown ones.
|
||||
* @argc: argc
|
||||
* @argv: argv array.
|
||||
* @errlog: the function to print errors
|
||||
*
|
||||
* If you have plugins, you might need to do early parsing (eg. to find the
|
||||
* plugin directory) but you don't know what options the plugins will want.
|
||||
*
|
||||
* Thus, this function is just like opt_early_parse, but ignores unknown options.
|
||||
*
|
||||
* Example:
|
||||
* if (!opt_early_parse_incomplete(argc, argv, opt_log_stderr)) {
|
||||
* printf("You screwed up, aborting!\n");
|
||||
* exit(1);
|
||||
* }
|
||||
*
|
||||
* See Also:
|
||||
* opt_early_parse()
|
||||
*/
|
||||
bool opt_early_parse_incomplete(int argc, char *argv[],
|
||||
void (*errlog)(const char *fmt, ...));
|
||||
|
||||
|
||||
/**
|
||||
* opt_free_table - reset the opt library.
|
||||
*
|
||||
|
|
|
@ -30,7 +30,7 @@ static void consume_option(int *argc, char *argv[], unsigned optnum)
|
|||
|
||||
/* Returns 1 if argument consumed, 0 if all done, -1 on error. */
|
||||
int parse_one(int *argc, char *argv[], enum opt_type is_early, unsigned *offset,
|
||||
void (*errlog)(const char *fmt, ...))
|
||||
void (*errlog)(const char *fmt, ...), bool unknown_ok)
|
||||
{
|
||||
unsigned i, arg, len;
|
||||
const char *o, *optarg = NULL;
|
||||
|
@ -67,10 +67,13 @@ int parse_one(int *argc, char *argv[], enum opt_type is_early, unsigned *offset,
|
|||
continue;
|
||||
break;
|
||||
}
|
||||
if (!o)
|
||||
if (!o) {
|
||||
if (unknown_ok)
|
||||
goto ok;
|
||||
return parse_err(errlog, argv[0],
|
||||
argv[arg], strlen(argv[arg]),
|
||||
"unrecognized option");
|
||||
}
|
||||
/* For error messages, we include the leading '--' */
|
||||
o -= 2;
|
||||
len += 2;
|
||||
|
@ -82,10 +85,15 @@ int parse_one(int *argc, char *argv[], enum opt_type is_early, unsigned *offset,
|
|||
(*offset)++;
|
||||
break;
|
||||
}
|
||||
if (!o)
|
||||
if (!o) {
|
||||
if (unknown_ok) {
|
||||
(*offset)++;
|
||||
goto ok;
|
||||
}
|
||||
return parse_err(errlog, argv[0],
|
||||
argv[arg], strlen(argv[arg]),
|
||||
"unrecognized option");
|
||||
}
|
||||
/* For error messages, we include the leading '-' */
|
||||
o--;
|
||||
len = 2;
|
||||
|
@ -120,6 +128,7 @@ int parse_one(int *argc, char *argv[], enum opt_type is_early, unsigned *offset,
|
|||
return -1;
|
||||
}
|
||||
|
||||
ok:
|
||||
/* If no more letters in that short opt, reset offset. */
|
||||
if (*offset && !argv[arg][*offset + 1])
|
||||
*offset = 0;
|
||||
|
|
|
@ -22,6 +22,6 @@ struct opt_alloc {
|
|||
extern struct opt_alloc opt_alloc;
|
||||
|
||||
int parse_one(int *argc, char *argv[], enum opt_type is_early, unsigned *offset,
|
||||
void (*errlog)(const char *fmt, ...));
|
||||
void (*errlog)(const char *fmt, ...), bool unknown_ok);
|
||||
|
||||
#endif /* CCAN_OPT_PRIVATE_H */
|
||||
|
|
37
ccan/ccan/opt/test/run-early_incomplete.c
Normal file
37
ccan/ccan/opt/test/run-early_incomplete.c
Normal file
|
@ -0,0 +1,37 @@
|
|||
/* With errlog == NULL, we never get a "failure". */
|
||||
#include <ccan/tap/tap.h>
|
||||
#include <stdlib.h>
|
||||
#include <ccan/opt/opt.c>
|
||||
#include <ccan/opt/usage.c>
|
||||
#include <ccan/opt/helpers.c>
|
||||
#include <ccan/opt/parse.c>
|
||||
#include "utils.h"
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
plan_tests(8);
|
||||
|
||||
/* Simple short args.*/
|
||||
opt_register_noarg("-a", test_noarg, NULL, "All");
|
||||
opt_register_early_noarg("-b|--blong", test_noarg, NULL, "All");
|
||||
|
||||
/* This is OK. */
|
||||
ok1(parse_early_args_incomplete(&argc, &argv, "-c", NULL));
|
||||
ok1(test_cb_called == 0);
|
||||
|
||||
/* Skips letters correctly */
|
||||
ok1(parse_early_args_incomplete(&argc, &argv, "-ca", NULL));
|
||||
ok1(test_cb_called == 0); /* a is not an early arg! */
|
||||
|
||||
test_cb_called = 0;
|
||||
ok1(parse_early_args_incomplete(&argc, &argv, "-bca", NULL));
|
||||
ok1(test_cb_called == 1);
|
||||
|
||||
test_cb_called = 0;
|
||||
ok1(parse_early_args_incomplete(&argc, &argv, "--unknown", "--also-unknown", "--blong", NULL));
|
||||
ok1(test_cb_called == 1);
|
||||
|
||||
/* parse_args allocates argv */
|
||||
free(argv);
|
||||
return exit_status();
|
||||
}
|
|
@ -103,6 +103,29 @@ bool parse_early_args(int *argc, char ***argv, ...)
|
|||
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"),
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
bool parse_args(int *argc, char ***argv, ...);
|
||||
bool parse_early_args(int *argc, char ***argv, ...);
|
||||
bool parse_early_args_incomplete(int *argc, char ***argv, ...);
|
||||
extern char *err_output;
|
||||
void save_err_output(const char *fmt, ...);
|
||||
void reset_options(void);
|
||||
|
|
Loading…
Add table
Reference in a new issue