parse-options: add a separate case for help output on error

When we parse a command line option such as -h or --help, we currently
exit 129, since that is the exit code when help output is printed. In a
future commit, we'll change this to exit 0 instead, since we're doing
what the user wanted successfully.

However, there are some cases where we print help output because the
user has provided ambiguous or invalid input, such as an ambiguous
option, and we'll want to exit unsuccessfully there.  Make this easier
by defining a new return code, PARSE_OPT_HELP_ERROR, that can be used in
this case, while reserving PARSE_OPT_HELP for those cases where the user
has requested help directly.

Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
brian m. carlson
2026-07-08 00:15:55 +00:00
committed by Junio C Hamano
parent 5df632cd05
commit 154aee0bd2
5 changed files with 13 additions and 4 deletions

View File

@@ -1013,6 +1013,7 @@ int cmd_blame(int argc,
case PARSE_OPT_UNKNOWN:
break;
case PARSE_OPT_HELP:
case PARSE_OPT_HELP_ERROR:
case PARSE_OPT_ERROR:
case PARSE_OPT_SUBCOMMAND:
exit(129);

View File

@@ -433,6 +433,7 @@ int cmd_shortlog(int argc,
case PARSE_OPT_UNKNOWN:
break;
case PARSE_OPT_HELP:
case PARSE_OPT_HELP_ERROR:
case PARSE_OPT_ERROR:
case PARSE_OPT_SUBCOMMAND:
exit(129);

View File

@@ -1133,6 +1133,7 @@ int cmd_update_index(int argc,
break;
switch (parseopt_state) {
case PARSE_OPT_HELP:
case PARSE_OPT_HELP_ERROR:
case PARSE_OPT_ERROR:
exit(129);
case PARSE_OPT_COMPLETE:

View File

@@ -583,7 +583,7 @@ static enum parse_opt_result parse_long_opt(
ambiguous.option->long_name,
(abbrev.flags & OPT_UNSET) ? "no-" : "",
abbrev.option->long_name);
return PARSE_OPT_HELP;
return PARSE_OPT_HELP_ERROR;
}
if (abbrev.option) {
if (*arg_end)
@@ -1037,6 +1037,7 @@ enum parse_opt_result parse_options_step(struct parse_opt_ctx_t *ctx,
usage_with_options(usagestr, options);
case PARSE_OPT_COMPLETE:
case PARSE_OPT_HELP:
case PARSE_OPT_HELP_ERROR:
case PARSE_OPT_ERROR:
case PARSE_OPT_DONE:
case PARSE_OPT_NON_OPTION:
@@ -1072,6 +1073,7 @@ enum parse_opt_result parse_options_step(struct parse_opt_ctx_t *ctx,
case PARSE_OPT_NON_OPTION:
case PARSE_OPT_SUBCOMMAND:
case PARSE_OPT_HELP:
case PARSE_OPT_HELP_ERROR:
case PARSE_OPT_COMPLETE:
BUG("parse_short_opt() cannot return these");
case PARSE_OPT_DONE:
@@ -1099,6 +1101,7 @@ enum parse_opt_result parse_options_step(struct parse_opt_ctx_t *ctx,
case PARSE_OPT_SUBCOMMAND:
case PARSE_OPT_COMPLETE:
case PARSE_OPT_HELP:
case PARSE_OPT_HELP_ERROR:
BUG("parse_short_opt() cannot return these");
case PARSE_OPT_DONE:
break;
@@ -1132,6 +1135,7 @@ enum parse_opt_result parse_options_step(struct parse_opt_ctx_t *ctx,
case PARSE_OPT_UNKNOWN:
goto unknown;
case PARSE_OPT_HELP:
case PARSE_OPT_HELP_ERROR:
goto show_usage;
case PARSE_OPT_NON_OPTION:
case PARSE_OPT_SUBCOMMAND:
@@ -1197,6 +1201,7 @@ int parse_options(int argc, const char **argv,
parse_options_start_1(&ctx, argc, argv, prefix, options, flags);
switch (parse_options_step(&ctx, options, usagestr)) {
case PARSE_OPT_HELP:
case PARSE_OPT_HELP_ERROR:
case PARSE_OPT_ERROR:
exit(129);
case PARSE_OPT_COMPLETE:
@@ -1363,7 +1368,7 @@ static enum parse_opt_result usage_with_options_internal(struct parse_opt_ctx_t
parse_options_check_harder(opts);
if (!usagestr)
return PARSE_OPT_HELP;
return err ? PARSE_OPT_HELP_ERROR : PARSE_OPT_HELP;
if (!err && ctx && ctx->flags & PARSE_OPT_SHELL_EVAL)
fprintf(outfile, "cat <<\\EOF\n");
@@ -1476,7 +1481,7 @@ static enum parse_opt_result usage_with_options_internal(struct parse_opt_ctx_t
if (!err && ctx && ctx->flags & PARSE_OPT_SHELL_EVAL)
fputs("EOF\n", outfile);
return PARSE_OPT_HELP;
return err ? PARSE_OPT_HELP_ERROR : PARSE_OPT_HELP;
}
void NORETURN usage_with_options(const char * const *usagestr,

View File

@@ -57,7 +57,8 @@ enum parse_opt_option_flags {
};
enum parse_opt_result {
PARSE_OPT_COMPLETE = -3,
PARSE_OPT_COMPLETE = -4,
PARSE_OPT_HELP_ERROR = -3,
PARSE_OPT_HELP = -2,
PARSE_OPT_ERROR = -1, /* must be the same as error() */
PARSE_OPT_DONE = 0, /* fixed so that "return 0" works */