X-Git-Url: http://git.ozlabs.org/?a=blobdiff_plain;f=ccan%2Fopt%2Fparse.c;h=d227f7bca2ab679033dd920fe426983dc0ea9314;hb=2b3517d40f2d8ac728785a21da19db6e1230d010;hp=b92bcb14871eed40e4873e8473ac1c359e46d5e7;hpb=74257cee33ae3033f961d5f22a0313b8cb1b18d4;p=ccan diff --git a/ccan/opt/parse.c b/ccan/opt/parse.c index b92bcb14..d227f7bc 100644 --- a/ccan/opt/parse.c +++ b/ccan/opt/parse.c @@ -1,4 +1,4 @@ -/* Licensed under GPLv3+ - see LICENSE file for details */ +/* Licensed under GPLv2+ - see LICENSE file for details */ /* Actual code to parse commandline. */ #include #include @@ -29,12 +29,12 @@ 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[], unsigned *offset, - void (*errlog)(const char *fmt, ...)) +int parse_one(int *argc, char *argv[], enum opt_type is_early, unsigned *offset, + void (*errlog)(const char *fmt, ...), bool unknown_ok) { unsigned i, arg, len; const char *o, *optarg = NULL; - char *problem; + char *problem = NULL; if (getenv("POSIXLY_CORRECT")) { /* Don't find options after non-options. */ @@ -67,10 +67,13 @@ int parse_one(int *argc, char *argv[], 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,20 +85,26 @@ int parse_one(int *argc, char *argv[], 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; } - if (opt_table[i].type == OPT_NOARG) { + if ((opt_table[i].type & ~OPT_EARLY) == OPT_NOARG) { if (optarg) return parse_err(errlog, argv[0], o, len, "doesn't allow an argument"); - problem = opt_table[i].cb(opt_table[i].u.arg); + if ((opt_table[i].type & OPT_EARLY) == is_early) + problem = opt_table[i].cb(opt_table[i].u.arg); } else { if (!optarg) { /* Swallow any short options as optarg, eg -afile */ @@ -108,15 +117,18 @@ int parse_one(int *argc, char *argv[], unsigned *offset, if (!optarg) return parse_err(errlog, argv[0], o, len, "requires an argument"); - problem = opt_table[i].cb_arg(optarg, opt_table[i].u.arg); + if ((opt_table[i].type & OPT_EARLY) == is_early) + problem = opt_table[i].cb_arg(optarg, + opt_table[i].u.arg); } if (problem) { parse_err(errlog, argv[0], o, len, problem); - free(problem); + opt_alloc.free(problem); return -1; } +ok: /* If no more letters in that short opt, reset offset. */ if (*offset && !argv[arg][*offset + 1]) *offset = 0;