diff options
Diffstat (limited to 'parse-options.c')
-rw-r--r-- | parse-options.c | 42 |
1 files changed, 22 insertions, 20 deletions
diff --git a/parse-options.c b/parse-options.c index 3eceba4463..312a85dbde 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 @@ -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; @@ -414,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; @@ -435,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; @@ -451,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 * @@ -496,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; } @@ -511,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) @@ -656,13 +665,6 @@ void NORETURN usage_msg_opt(const char *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) { |