diff options
Diffstat (limited to 'parse-options.c')
-rw-r--r-- | parse-options.c | 69 |
1 files changed, 45 insertions, 24 deletions
diff --git a/parse-options.c b/parse-options.c index 80106c06bc..e5ad34a2c3 100644 --- a/parse-options.c +++ b/parse-options.c @@ -5,10 +5,6 @@ #include "color.h" #include "utf8.h" -static int parse_options_usage(struct parse_opt_ctx_t *ctx, - const char * const *usagestr, - const struct option *opts, int err); - #define OPT_SHORT 1 #define OPT_UNSET 2 @@ -44,7 +40,7 @@ static void fix_filename(const char *prefix, const char **file) if (!file || !*file || !prefix || is_absolute_path(*file) || !strcmp("-", *file)) return; - *file = xstrdup(prefix_filename(prefix, strlen(prefix), *file)); + *file = prefix_filename(prefix, *file); } static int opt_command_mode_error(const struct option *opt, @@ -114,6 +110,8 @@ static int get_value(struct parse_opt_ctx_t *p, return 0; case OPTION_COUNTUP: + if (*(int *)opt->value < 0) + *(int *)opt->value = 0; *(int *)opt->value = unset ? 0 : *(int *)opt->value + 1; return 0; @@ -180,6 +178,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"); } @@ -397,7 +412,7 @@ void parse_options_start(struct parse_opt_ctx_t *ctx, const struct option *options, int flags) { memset(ctx, 0, sizeof(*ctx)); - ctx->argc = argc - 1; + ctx->argc = ctx->total = argc - 1; ctx->argv = argv + 1; ctx->out = argv; ctx->prefix = prefix; @@ -418,6 +433,7 @@ int parse_options_step(struct parse_opt_ctx_t *ctx, const char * const usagestr[]) { int internal_help = !(ctx->flags & PARSE_OPT_NO_INTERNAL_HELP); + int err = 0; /* we must reset ->opt, unknown short option leave it dangling */ ctx->opt = NULL; @@ -434,27 +450,32 @@ int parse_options_step(struct parse_opt_ctx_t *ctx, continue; } + /* lone -h asks for help */ + if (internal_help && ctx->total == 1 && !strcmp(arg + 1, "h")) + goto show_usage; + if (arg[1] != '-') { ctx->opt = arg + 1; - if (internal_help && *ctx->opt == 'h') - return parse_options_usage(ctx, usagestr, options, 0); switch (parse_short_opt(ctx, options)) { case -1: - return parse_options_usage(ctx, usagestr, options, 1); + goto show_usage_error; case -2: if (ctx->opt) check_typos(arg + 1, options); + if (internal_help && *ctx->opt == 'h') + goto show_usage; goto unknown; } if (ctx->opt) check_typos(arg + 1, options); while (ctx->opt) { - if (internal_help && *ctx->opt == 'h') - return parse_options_usage(ctx, usagestr, options, 0); switch (parse_short_opt(ctx, options)) { case -1: - return parse_options_usage(ctx, usagestr, options, 1); + goto show_usage_error; case -2: + if (internal_help && *ctx->opt == 'h') + goto show_usage; + /* fake a short option thing to hide the fact that we may have * started to parse aggregated stuff * @@ -479,10 +500,10 @@ int parse_options_step(struct parse_opt_ctx_t *ctx, if (internal_help && !strcmp(arg + 2, "help-all")) return usage_with_options_internal(ctx, usagestr, options, 1, 0); if (internal_help && !strcmp(arg + 2, "help")) - return parse_options_usage(ctx, usagestr, options, 0); + goto show_usage; switch (parse_long_opt(ctx, arg + 2, options)) { case -1: - return parse_options_usage(ctx, usagestr, options, 1); + goto show_usage_error; case -2: goto unknown; } @@ -494,6 +515,11 @@ unknown: ctx->opt = NULL; } return PARSE_OPT_DONE; + + show_usage_error: + err = 1; + show_usage: + return usage_with_options_internal(ctx, usagestr, options, 0, err); } int parse_options_end(struct parse_opt_ctx_t *ctx) @@ -563,8 +589,10 @@ static int usage_with_options_internal(struct parse_opt_ctx_t *ctx, fprintf_ln(outfile, _("usage: %s"), _(*usagestr++)); while (*usagestr && **usagestr) - /* TRANSLATORS: the colon here should align with the - one in "usage: %s" translation */ + /* + * TRANSLATORS: the colon here should align with the + * one in "usage: %s" translation. + */ fprintf_ln(outfile, _(" or: %s"), _(*usagestr++)); while (*usagestr) { if (**usagestr) @@ -635,17 +663,10 @@ void NORETURN usage_msg_opt(const char *msg, const char * const *usagestr, const struct option *options) { - fprintf(stderr, "%s\n\n", msg); + fprintf(stderr, "fatal: %s\n\n", msg); usage_with_options(usagestr, options); } -static int parse_options_usage(struct parse_opt_ctx_t *ctx, - const char * const *usagestr, - const struct option *opts, int err) -{ - return usage_with_options_internal(ctx, usagestr, opts, 0, err); -} - #undef opterror int opterror(const struct option *opt, const char *reason, int flags) { |