diff options
Diffstat (limited to 'parse-options.c')
-rw-r--r-- | parse-options.c | 47 |
1 files changed, 39 insertions, 8 deletions
diff --git a/parse-options.c b/parse-options.c index b536896f26..3eceba4463 100644 --- a/parse-options.c +++ b/parse-options.c @@ -14,8 +14,12 @@ static int parse_options_usage(struct parse_opt_ctx_t *ctx, int optbug(const struct option *opt, const char *reason) { - if (opt->long_name) + if (opt->long_name) { + if (opt->short_name) + return error("BUG: switch '%c' (--%s) %s", + opt->short_name, opt->long_name, reason); return error("BUG: option '%s' %s", opt->long_name, reason); + } return error("BUG: switch '%c' %s", opt->short_name, reason); } @@ -176,6 +180,23 @@ static int get_value(struct parse_opt_ctx_t *p, return opterror(opt, "expects a numerical value", flags); return 0; + case OPTION_MAGNITUDE: + if (unset) { + *(unsigned long *)opt->value = 0; + return 0; + } + if (opt->flags & PARSE_OPT_OPTARG && !p->opt) { + *(unsigned long *)opt->value = opt->defval; + return 0; + } + if (get_arg(p, opt, flags, &arg)) + return -1; + if (!git_parse_ulong(arg, opt->value)) + return opterror(opt, + "expects a non-negative integer value with an optional k/m/g suffix", + flags); + return 0; + default: die("should not happen, someone must be hit on the forehead"); } @@ -231,7 +252,8 @@ static int parse_long_opt(struct parse_opt_ctx_t *p, const char *arg, continue; again: - rest = skip_prefix(arg, long_name); + if (!skip_prefix(arg, long_name, &rest)) + rest = NULL; if (options->type == OPTION_ARGUMENT) { if (!rest) continue; @@ -280,12 +302,13 @@ is_abbreviated: continue; } flags |= OPT_UNSET; - rest = skip_prefix(arg + 3, long_name); - /* abbreviated and negated? */ - if (!rest && starts_with(long_name, arg + 3)) - goto is_abbreviated; - if (!rest) - continue; + if (!skip_prefix(arg + 3, long_name, &rest)) { + /* abbreviated and negated? */ + if (starts_with(long_name, arg + 3)) + goto is_abbreviated; + else + continue; + } } if (*rest) { if (*rest != '=') @@ -345,12 +368,20 @@ static void check_typos(const char *arg, const struct option *options) static void parse_options_check(const struct option *opts) { int err = 0; + char short_opts[128]; + memset(short_opts, '\0', sizeof(short_opts)); for (; opts->type != OPTION_END; opts++) { if ((opts->flags & PARSE_OPT_LASTARG_DEFAULT) && (opts->flags & PARSE_OPT_OPTARG)) err |= optbug(opts, "uses incompatible flags " "LASTARG_DEFAULT and OPTARG"); + if (opts->short_name) { + if (0x7F <= opts->short_name) + err |= optbug(opts, "invalid short name"); + else if (short_opts[opts->short_name]++) + err |= optbug(opts, "short name already used"); + } if (opts->flags & PARSE_OPT_NODASH && ((opts->flags & PARSE_OPT_OPTARG) || !(opts->flags & PARSE_OPT_NOARG) || |