Signed-off-by: Pierre Habouzit <madcoder@xxxxxxxxxx> --- parse-options.c | 22 +++++++++++++++------- parse-options.h | 7 +++++++ 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/parse-options.c b/parse-options.c index 8f70e5d..d716ccc 100644 --- a/parse-options.c +++ b/parse-options.c @@ -38,7 +38,10 @@ static int get_value(struct optparse_t *p, { const char *s, *arg; const int unset = flags & PARSE_OPT_UNSET; + int may_ign = 0, res; + if (!unset && !p->opt && (opt->flags & PARSE_OPT_OPTARG)) + may_ign = PARSE_OPT_MAY_IGN; if (unset && p->opt) return opterror(opt, "takes no value", flags); if (unset && (opt->flags & PARSE_OPT_NONEG)) @@ -86,7 +89,7 @@ static int get_value(struct optparse_t *p, *(const char **)opt->value = NULL; return 0; } - if (opt->flags & PARSE_OPT_OPTARG && (!arg || *arg == '-')) { + if (may_ign && (!arg || *arg == '-')) { *(const char **)opt->value = (const char *)opt->defval; return 0; } @@ -98,18 +101,23 @@ static int get_value(struct optparse_t *p, case OPTION_CALLBACK: if (unset || (opt->flags & PARSE_OPT_NOARG)) return (*opt->callback)(opt, NULL, flags); - if (opt->flags & PARSE_OPT_OPTARG && (!arg || *arg == '-')) - return (*opt->callback)(opt, NULL, flags); - if (!arg) + if (!may_ign && !arg) return opterror(opt, "requires a value", flags); - return (*opt->callback)(opt, get_arg(p), flags); + if (may_ign && arg && arg[0] == '-' && arg[1]) + return (*opt->callback)(opt, NULL, flags); + res = (*opt->callback)(opt, arg, flags); + if (!may_ign && res == PARSE_OPT_IGNORE) + die("should not happen: MAY_IGN unset, but arg was IGNOREd"); + if (res == PARSE_OPT_IGNORE) + get_arg(p); + return res; case OPTION_INTEGER: if (unset) { *(int *)opt->value = 0; return 0; } - if (opt->flags & PARSE_OPT_OPTARG && (!arg || !isdigit(*arg))) { + if (may_ign && (!arg || !isdigit(*arg))) { *(int *)opt->value = opt->defval; return 0; } @@ -251,7 +259,7 @@ int parse_options(int argc, const char **argv, const struct option *options, usage_with_options_internal(usagestr, options, 1); if (!strcmp(arg + 2, "help")) usage_with_options(usagestr, options); - if (parse_long_opt(&args, arg + 2, options)) + if (parse_long_opt(&args, arg + 2, options) < 0) usage_with_options(usagestr, options); } diff --git a/parse-options.h b/parse-options.h index ae6b3ca..eeb40a4 100644 --- a/parse-options.h +++ b/parse-options.h @@ -27,9 +27,16 @@ enum parse_opt_option_flags { PARSE_OPT_HIDDEN = 8, }; +enum parse_opt_cbres { + PARSE_OPT_ERR = -1, + PARSE_OPT_OK = 0, + PARSE_OPT_IGNORE = 1, +}; + enum parse_opt_cbflags { PARSE_OPT_SHORT = 1, PARSE_OPT_UNSET = 2, + PARSE_OPT_MAY_IGN = 4, }; struct option; -- 1.5.4.rc0.1148.ga3ab1-dirty - To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html