mirror of
https://github.com/git/git.git
synced 2026-03-11 09:29:49 +01:00
parseopt: extract subcommand handling from parse_options_step()
Move the subcommand branch out of parse_options_step() into a new handle_subcommand() helper. Also, make parse_subcommand() return a simple success/failure status. This removes the switch over impossible parse_opt_result values and makes the non-option path easier to follow and maintain. Signed-off-by: Jiamu Sun <39@barroit.sh> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
committed by
Junio C Hamano
parent
d181b9354c
commit
38ed9faa1d
@@ -605,17 +605,44 @@ static enum parse_opt_result parse_nodash_opt(struct parse_opt_ctx_t *p,
|
||||
return PARSE_OPT_ERROR;
|
||||
}
|
||||
|
||||
static enum parse_opt_result parse_subcommand(const char *arg,
|
||||
const struct option *options)
|
||||
static int parse_subcommand(const char *arg, const struct option *options)
|
||||
{
|
||||
for (; options->type != OPTION_END; options++)
|
||||
if (options->type == OPTION_SUBCOMMAND &&
|
||||
!strcmp(options->long_name, arg)) {
|
||||
*(parse_opt_subcommand_fn **)options->value = options->subcommand_fn;
|
||||
return PARSE_OPT_SUBCOMMAND;
|
||||
}
|
||||
for (; options->type != OPTION_END; options++) {
|
||||
parse_opt_subcommand_fn **opt_val;
|
||||
|
||||
return PARSE_OPT_UNKNOWN;
|
||||
if (options->type != OPTION_SUBCOMMAND ||
|
||||
strcmp(options->long_name, arg))
|
||||
continue;
|
||||
|
||||
opt_val = options->value;
|
||||
*opt_val = options->subcommand_fn;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static enum parse_opt_result handle_subcommand(struct parse_opt_ctx_t *ctx,
|
||||
const char *arg,
|
||||
const struct option *options,
|
||||
const char * const usagestr[])
|
||||
{
|
||||
int err = parse_subcommand(arg, options);
|
||||
|
||||
if (!err)
|
||||
return PARSE_OPT_SUBCOMMAND;
|
||||
|
||||
/*
|
||||
* arg is neither a short or long option nor a subcommand. Since this
|
||||
* command has a default operation mode, we have to treat this arg and
|
||||
* all remaining args as args meant to that default operation mode.
|
||||
* So we are done parsing.
|
||||
*/
|
||||
if (ctx->flags & PARSE_OPT_SUBCOMMAND_OPTIONAL)
|
||||
return PARSE_OPT_DONE;
|
||||
|
||||
error(_("unknown subcommand: `%s'"), arg);
|
||||
usage_with_options(usagestr, options);
|
||||
}
|
||||
|
||||
static void check_typos(const char *arg, const struct option *options)
|
||||
@@ -990,38 +1017,17 @@ enum parse_opt_result parse_options_step(struct parse_opt_ctx_t *ctx,
|
||||
if (*arg != '-' || !arg[1]) {
|
||||
if (parse_nodash_opt(ctx, arg, options) == 0)
|
||||
continue;
|
||||
if (!ctx->has_subcommands) {
|
||||
if (ctx->flags & PARSE_OPT_STOP_AT_NON_OPTION)
|
||||
return PARSE_OPT_NON_OPTION;
|
||||
ctx->out[ctx->cpidx++] = ctx->argv[0];
|
||||
continue;
|
||||
}
|
||||
switch (parse_subcommand(arg, options)) {
|
||||
case PARSE_OPT_SUBCOMMAND:
|
||||
return PARSE_OPT_SUBCOMMAND;
|
||||
case PARSE_OPT_UNKNOWN:
|
||||
if (ctx->flags & PARSE_OPT_SUBCOMMAND_OPTIONAL)
|
||||
/*
|
||||
* arg is neither a short or long
|
||||
* option nor a subcommand. Since
|
||||
* this command has a default
|
||||
* operation mode, we have to treat
|
||||
* this arg and all remaining args
|
||||
* as args meant to that default
|
||||
* operation mode.
|
||||
* So we are done parsing.
|
||||
*/
|
||||
return PARSE_OPT_DONE;
|
||||
error(_("unknown subcommand: `%s'"), arg);
|
||||
usage_with_options(usagestr, options);
|
||||
case PARSE_OPT_COMPLETE:
|
||||
case PARSE_OPT_HELP:
|
||||
case PARSE_OPT_ERROR:
|
||||
case PARSE_OPT_DONE:
|
||||
case PARSE_OPT_NON_OPTION:
|
||||
/* Impossible. */
|
||||
BUG("parse_subcommand() cannot return these");
|
||||
|
||||
if (ctx->has_subcommands) {
|
||||
return handle_subcommand(ctx, arg, options,
|
||||
usagestr);
|
||||
}
|
||||
|
||||
if (ctx->flags & PARSE_OPT_STOP_AT_NON_OPTION)
|
||||
return PARSE_OPT_NON_OPTION;
|
||||
|
||||
ctx->out[ctx->cpidx++] = ctx->argv[0];
|
||||
continue;
|
||||
}
|
||||
|
||||
/* lone -h asks for help */
|
||||
|
||||
Reference in New Issue
Block a user