From: Junio C Hamano <gitster@pobox.com>
To: Jiamu Sun <39@barroit.sh>
Cc: git@vger.kernel.org
Subject: Re: [PATCH 1/5] parseopt: extract subcommand handling from parse_options_step()
Date: Sun, 08 Mar 2026 16:40:44 -0700 [thread overview]
Message-ID: <xmqq1phtao03.fsf@gitster.g> (raw)
In-Reply-To: <SY0P300MB0801422323C4C4185B9617A1CE78A@SY0P300MB0801.AUSP300.PROD.OUTLOOK.COM> (Jiamu Sun's message of "Sun, 8 Mar 2026 21:17:21 +0900")
Jiamu Sun <39@barroit.sh> writes:
> -static enum parse_opt_result parse_subcommand(const char *arg,
> - const struct option *options)
So, this function used to return either PARSE_OPT_SUBCOMMAND or
PARSE_OPT_UNKNOWN, and the caller (in an "switch ()" statement in
the parse_options_step() we see below) expected only these two. We
now instead ...
> +static int parse_subcommand(const char *arg, const struct option *options)
... make it return either 0 (success - we found a subcommand) or -1
(failure - we did not). The updated caller does use the return
value in "if ()" condition to return early when we found a
subcommand successfully, which is a lot more straight-forward than
the original "switch()". The original is even worse in that it
enumerates other PARSE_OPT_* values that are possible at the time of
writing it, instead of catching everything else with "default:",
which makes the switch() statement a maintenance burden. Getting
rid of that switch and clarifying that there are only two possible
outcome from this function alone is a good enough justification to
have this clean-up patch. Very well done.
Editing the hunk to show only the postimage reveals that the new
implementation has CodingGuidelines violation ...
> {
> + for (; options->type != OPTION_END; options++) {
> + if (options->type != OPTION_SUBCOMMAND ||
> + strcmp(options->long_name, arg))
> + continue;
>
> + parse_opt_subcommand_fn **opt_val = options->value;
... here. Move the variable definition up in the block introduced
by the for(;;) statement, perhaps?
> + *opt_val = options->subcommand_fn;
> +
> + return 0;
> + }
> +
> + return -1;
> +}
> +
And the part of the caller of parse_subcommand() that used to be the
switch() statement in the parse_options_step() is now extracted into
yet another helper function here.
> +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.
> + */
Thanks to being a small helper function, we lost two levels of
indentation which made this comment a lot more readable with
reflowing the lines ;-)
> + if (ctx->flags & PARSE_OPT_SUBCOMMAND_OPTIONAL)
> + return PARSE_OPT_DONE;
> +
> + error(_("unknown subcommand: `%s'"), arg);
> + usage_with_options(usagestr, options);
> }
It is clear that there is no unintended behaviour change around this
helper function and parse_subcommand(). Very nice.
> @@ -990,37 +1016,16 @@ 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;
> +
> + } else {
> + return handle_subcommand(ctx, arg,
> + options, usagestr);
> }
> }
Editing the hunk to only show the postimage shows us that the blank
line at the end of the "if ()" block is funny. Drop it. Or even
better, as the block either returns or continues anyway, lose the
"else" block, perhaps? Which will make the above read like so:
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;
}
return has_subcommands(ctx, arg, options, usagestr);
or swapping the logic the other way around, i.e.,
if (ctx->has_subcommands)
return has_subcommands(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;
may make the result even easier to read, perhaps?
next prev parent reply other threads:[~2026-03-08 23:40 UTC|newest]
Thread overview: 67+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-03-08 12:17 [PATCH 0/5] parseopt: add subcommand autocorrection Jiamu Sun
2026-03-08 12:17 ` [PATCH 1/5] parseopt: extract subcommand handling from parse_options_step() Jiamu Sun
2026-03-08 23:40 ` Junio C Hamano [this message]
2026-03-09 1:56 ` Jiamu Sun
2026-03-08 12:17 ` [PATCH 2/5] help: refactor command autocorrection handling Jiamu Sun
2026-03-08 23:52 ` Junio C Hamano
2026-03-09 2:06 ` Jiamu Sun
2026-03-08 12:17 ` [PATCH 3/5] parseopt: autocorrect mistyped subcommands Jiamu Sun
2026-03-09 0:04 ` Junio C Hamano
2026-03-09 2:11 ` Jiamu Sun
2026-03-08 12:17 ` [PATCH 4/5] parseopt: enable subcommand autocorrect for remote and notes Jiamu Sun
2026-03-08 12:17 ` [PATCH 5/5] help: add tests for subcommand autocorrection Jiamu Sun
2026-03-11 17:01 ` Aaron Plattner
2026-03-11 22:45 ` Jiamu Sun
2026-03-12 13:35 ` Junio C Hamano
2026-03-08 20:11 ` [PATCH 0/5] parseopt: add " Junio C Hamano
2026-03-08 22:07 ` Jiamu Sun
2026-03-08 23:16 ` [PATCH v2 " Jiamu Sun
2026-03-08 23:16 ` [PATCH v2 1/5] parseopt: extract subcommand handling from parse_options_step() Jiamu Sun
2026-03-08 23:16 ` [PATCH v2 2/5] help: refactor command autocorrection handling Jiamu Sun
2026-03-08 23:16 ` [PATCH v2 3/5] parseopt: autocorrect mistyped subcommands Jiamu Sun
2026-03-08 23:16 ` [PATCH v2 4/5] parseopt: enable subcommand autocorrect for remote and notes Jiamu Sun
2026-03-08 23:16 ` [PATCH v2 5/5] help: add tests for subcommand autocorrection Jiamu Sun
2026-03-10 11:40 ` [PATCH v3 0/8] parseopt: add " Jiamu Sun
2026-03-10 11:41 ` [PATCH v3 1/8] parseopt: extract subcommand handling from parse_options_step() Jiamu Sun
2026-03-10 12:46 ` Karthik Nayak
2026-03-11 1:49 ` Jiamu Sun
2026-03-11 4:20 ` Junio C Hamano
2026-03-11 4:20 ` Junio C Hamano
2026-03-11 6:12 ` Jiamu Sun
2026-03-10 11:41 ` [PATCH v3 2/8] help: make autocorrect handling reusable Jiamu Sun
2026-03-10 12:52 ` Karthik Nayak
2026-03-10 20:10 ` Junio C Hamano
2026-03-11 2:05 ` Jiamu Sun
2026-03-11 1:58 ` Jiamu Sun
2026-03-10 11:41 ` [PATCH v3 3/8] help: move tty check for autocorrection to autocorrect.c Jiamu Sun
2026-03-10 14:06 ` Karthik Nayak
2026-03-11 2:16 ` Jiamu Sun
2026-03-12 0:10 ` Jiamu Sun
2026-03-10 11:41 ` [PATCH v3 4/8] autocorrect: rename AUTOCORRECT_SHOW to AUTOCORRECT_HINTONLY Jiamu Sun
2026-03-10 14:08 ` Karthik Nayak
2026-03-11 2:46 ` Jiamu Sun
2026-03-10 11:41 ` [PATCH v3 5/8] autocorrect: provide config resolution API Jiamu Sun
2026-03-10 14:15 ` Karthik Nayak
2026-03-10 11:41 ` [PATCH v3 6/8] parseopt: autocorrect mistyped subcommands Jiamu Sun
2026-03-10 20:16 ` Junio C Hamano
2026-03-11 2:48 ` Jiamu Sun
2026-03-11 23:26 ` Jiamu Sun
2026-03-12 2:38 ` Junio C Hamano
2026-03-12 4:53 ` Jiamu Sun
2026-03-10 11:41 ` [PATCH v3 7/8] parseopt: enable subcommand autocorrection for git-remote and git-notes Jiamu Sun
2026-03-10 11:41 ` [PATCH v3 8/8] help: add tests for subcommand autocorrection Jiamu Sun
2026-03-11 4:23 ` Junio C Hamano
2026-03-11 6:10 ` Jiamu Sun
2026-03-16 15:36 ` [PATCH v4 00/10] parseopt: add " Jiamu Sun
2026-03-16 15:36 ` [PATCH v4 01/10] parseopt: extract subcommand handling from parse_options_step() Jiamu Sun
2026-03-16 15:36 ` [PATCH v4 02/10] help: make autocorrect handling reusable Jiamu Sun
2026-03-16 15:36 ` [PATCH v4 03/10] help: move tty check for autocorrection to autocorrect.c Jiamu Sun
2026-03-16 15:36 ` [PATCH v4 04/10] autocorrect: use mode and delay instead of magic numbers Jiamu Sun
2026-03-16 15:36 ` [PATCH v4 05/10] autocorrect: rename AUTOCORRECT_SHOW to AUTOCORRECT_HINT Jiamu Sun
2026-03-16 15:36 ` [PATCH v4 06/10] autocorrect: provide config resolution API Jiamu Sun
2026-03-16 15:36 ` [PATCH v4 07/10] parseopt: autocorrect mistyped subcommands Jiamu Sun
2026-03-16 19:41 ` Junio C Hamano
2026-03-17 3:21 ` Jiamu Sun
2026-03-16 15:36 ` [PATCH v4 08/10] parseopt: enable subcommand autocorrection for git-remote and git-notes Jiamu Sun
2026-03-16 15:36 ` [PATCH v4 09/10] parseopt: add tests for subcommand autocorrection Jiamu Sun
2026-03-16 15:36 ` [PATCH v4 10/10] doc: document autocorrect API Jiamu Sun
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=xmqq1phtao03.fsf@gitster.g \
--to=gitster@pobox.com \
--cc=39@barroit.sh \
--cc=git@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox