git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
From: "SZEDER Gábor" <szeder.dev@gmail.com>
To: "Ævar Arnfjörð Bjarmason" <avarab@gmail.com>
Cc: git@vger.kernel.org
Subject: Re: [PATCH 09/20] parse-options: add support for parsing subcommands
Date: Mon, 25 Jul 2022 21:29:47 +0200	[thread overview]
Message-ID: <20220725192947.GB2543@szeder.dev> (raw)
In-Reply-To: <220725.86a68xp7az.gmgdl@evledraar.gmail.com>

On Mon, Jul 25, 2022 at 04:43:30PM +0200, Ævar Arnfjörð Bjarmason wrote:
> > diff --git a/builtin/blame.c b/builtin/blame.c
> > index 02e39420b6..a9fe8cf7a6 100644
> > --- a/builtin/blame.c
> > +++ b/builtin/blame.c
> > @@ -920,6 +920,7 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
> >  			break;
> >  		case PARSE_OPT_HELP:
> >  		case PARSE_OPT_ERROR:
> > +		case PARSE_OPT_SUBCOMMAND:
> >  			exit(129);
> >  		case PARSE_OPT_COMPLETE:
> >  			exit(0);
> > diff --git a/builtin/shortlog.c b/builtin/shortlog.c
> > index 086dfee45a..7a1e1fe7c0 100644
> > --- a/builtin/shortlog.c
> > +++ b/builtin/shortlog.c
> > @@ -381,6 +381,7 @@ int cmd_shortlog(int argc, const char **argv, const char *prefix)
> >  			break;
> >  		case PARSE_OPT_HELP:
> >  		case PARSE_OPT_ERROR:
> > +		case PARSE_OPT_SUBCOMMAND:
> >  			exit(129);
> >  		case PARSE_OPT_COMPLETE:
> >  			exit(0);
> 
> This feels a bit like carrying forward an API wart, i.e. shouldn't we
> instead BUG() if we are returning a PARSE_OPT_SUBCOMMAND from
> parse_options_step() for options lists that don't have
> PARSE_OPT_SUBCOMMAND in them?
> 
> I.e. is this even reachable, or just something to suppress the compiler
> complaining about missing enum labels?

I think it's as good as unreachable, because neither of these two
commands have subcommands.  However, without these hunks the compiler
invoked with '-Wswitch' (implied by '-Wall') does indeed complain.
 
> ...but why not...
> 
> >  static void parse_options_start_1(struct parse_opt_ctx_t *ctx,
> >  				  int argc, const char **argv, const char *prefix,
> >  				  const struct option *options,
> > @@ -515,6 +547,19 @@ static void parse_options_start_1(struct parse_opt_ctx_t *ctx,
> >  	ctx->prefix = prefix;
> >  	ctx->cpidx = ((flags & PARSE_OPT_KEEP_ARGV0) != 0);
> >  	ctx->flags = flags;
> > +	ctx->has_subcommands = has_subcommands(options);
> > +	if (!ctx->has_subcommands && (flags & PARSE_OPT_SUBCOMMAND_OPTIONAL))
> > +		BUG("Using PARSE_OPT_SUBCOMMAND_OPTIONAL without subcommands");
> > +	if (ctx->has_subcommands) {
> > +		if (flags & PARSE_OPT_STOP_AT_NON_OPTION)
> > +			BUG("subcommands are incompatible with PARSE_OPT_STOP_AT_NON_OPTION");
> > +		if (!(flags & PARSE_OPT_SUBCOMMAND_OPTIONAL)) {
> > +			if (flags & PARSE_OPT_KEEP_UNKNOWN_OPT)
> > +				BUG("subcommands are incompatible with PARSE_OPT_KEEP_UNKNOWN unless in combination with PARSE_OPT_SUBCOMMAND_OPTIONAL");
> > +			if (flags & PARSE_OPT_KEEP_DASHDASH)
> > +				BUG("subcommands are incompatible with PARSE_OPT_KEEP_DASHDASH unless in combination with PARSE_OPT_SUBCOMMAND_OPTIONAL");
> > +		}
> > +	}
> 
> ...move this into parse_options_check()? I.e. we'd need to loop over the
> list once, but it seems like this should belong there.
> 
> We have an existing bug in-tree due to usage_with_options() not doing a
> parse_options_check() (I have a local fix...), checking this sort of
> thing there instead of in parse_options_start() is therefore the right
> thing to do, i.e. we shoudl have a one-stop "does this options variable
> look sane?".

The checks added in this hunk (and the existing checks in the hunk's
after-context) are not about the elements of the 'struct option'
array, like the checks in parse_options_check(), but rather about the
sensibility of parse_options()'s 'parse_opt_flags' parameter.
usage_with_options() doesn't have (and doesn't at all need) such a
parameter.

> > +				error(_("unknown subcommand: %s"), arg);
> 
> s/%s/'%s'/ while we're at it, perhaps?

Indeed, though it should be `%s', because that's what surrounds
unknown switches and options in the corresponding error messages.

> > +				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:
> > +				BUG("parse_subcommand() cannot return these");
> 
> nit: BUG("got bad %d", v) or whatever, i.e. say what we got?

All these are impossible, so I don't think it matters.  This is
another case of the compiler with '-Wswitch' complaining, and follows
suit of similar switch statements after the calls to parse_short_opt()
and parse_long_opt() functions.

> > @@ -206,6 +217,11 @@ struct option {
> >  #define OPT_ALIAS(s, l, source_long_name) \
> >  	{ OPTION_ALIAS, (s), (l), (source_long_name) }
> >  
> > +#define OPT_SUBCOMMAND(l, v, fn)      { OPTION_SUBCOMMAND, 0, (l), (v), NULL, \
> > +					NULL, 0, NULL, 0, NULL, 0, (fn) }
> > +#define OPT_SUBCOMMAND_F(l, v, fn, f) { OPTION_SUBCOMMAND, 0, (l), (v), NULL, \
> > +					NULL, (f), NULL, 0, NULL, 0, (fn) }
> 
> Nit, I know you're carrying forward existing patterns, but since that
> all pre-dated designated init perhaps we could just (untested):
> 	
> 	#define OPT_SUBCOMMAND_F(l, v, fn, f) { \
> 		.type = OPTION_SUBCOMMAND, \
> 		.long_name = (l), \
> 		.value = (v), \
> 		.ll_callback = (fn), \
> 	}
> 	#define OPT_SUBCOMMAND(l, v, fn) OPT_SUBCOMMAND_F((l), (v), (fn), 0)
> 
> Which IMO is much nicer. I have some patches somewhere to convert these
> to saner patterns (I think not designated init, but the X() can be
> defined in terms of X_F() like that, but since this is new we can use
> designated init all the way...

Oh, I love this idea!  But are we there yet?  I remember the weather
balloon about designated initializers, but I'm not sure whether we've
already made the decision to allow them.  If we do, then I'm inclined
to volunteer to clean up all those OPT_* macros in 'parse-options.h'
with designated initializers, 

> > +{
> > +	int i;
> 
> Nit: missing \n (usual style of variable decl);

Hm, speaking of newer C features, what about 'for (int i = 0; ...)'?

> > +		error("'cmd' is mandatory");
> > +		usage_with_options(usage, test_flag_options);
> 
> nit: I think you want usage_msg_optf() or usage_msg_opt().

Maybe... but I don't know what they do ;)  Though I remember removing
a couple of similar error() and usage_with_options() pairs from the
builtin commands.


  reply	other threads:[~2022-07-25 19:29 UTC|newest]

Thread overview: 97+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-07-25 12:38 [PATCH 00/20] parse-options: handle subcommands SZEDER Gábor
2022-07-25 12:38 ` [PATCH 01/20] git.c: update NO_PARSEOPT markings SZEDER Gábor
2022-07-25 14:31   ` Ævar Arnfjörð Bjarmason
2022-08-02 17:37     ` SZEDER Gábor
2022-08-02 21:00       ` Junio C Hamano
2022-08-03 13:11         ` Ævar Arnfjörð Bjarmason
2022-08-03 21:34         ` SZEDER Gábor
2022-08-04  7:47           ` Ævar Arnfjörð Bjarmason
2022-08-11 21:35           ` Junio C Hamano
2022-08-12 15:28             ` SZEDER Gábor
2022-08-12 16:46               ` Junio C Hamano
2022-07-26 19:55   ` SZEDER Gábor
2022-07-25 12:38 ` [PATCH 02/20] t3301-notes.sh: check that default operation mode doesn't take arguments SZEDER Gábor
2022-07-25 12:38 ` [PATCH 03/20] t5505-remote.sh: check the behavior without a subcommand SZEDER Gábor
2022-07-25 14:37   ` Ævar Arnfjörð Bjarmason
2022-07-25 12:38 ` [PATCH 04/20] t0040-parse-options: test parse_options() with various 'parse_opt_flags' SZEDER Gábor
2022-07-25 14:38   ` Ævar Arnfjörð Bjarmason
2022-08-12 15:04     ` SZEDER Gábor
2022-07-25 12:38 ` [PATCH 05/20] api-parse-options.txt: fix description of OPT_CMDMODE SZEDER Gábor
2022-07-25 12:38 ` [PATCH 06/20] parse-options: PARSE_OPT_KEEP_UNKNOWN only applies to --options SZEDER Gábor
2022-07-25 12:38 ` [PATCH 07/20] parse-options: clarify the limitations of PARSE_OPT_NODASH SZEDER Gábor
2022-07-25 12:38 ` [PATCH 08/20] parse-options: drop leading space from '--git-completion-helper' output SZEDER Gábor
2022-07-25 12:38 ` [PATCH 09/20] parse-options: add support for parsing subcommands SZEDER Gábor
2022-07-25 14:43   ` Ævar Arnfjörð Bjarmason
2022-07-25 19:29     ` SZEDER Gábor [this message]
2022-07-25 19:41       ` Ævar Arnfjörð Bjarmason
2022-07-25 21:02         ` SZEDER Gábor
2022-08-12 15:15         ` SZEDER Gábor
2022-07-25 17:37   ` Junio C Hamano
2022-07-25 12:38 ` [PATCH 10/20] builtin/bundle.c: let parse-options parse subcommands SZEDER Gábor
2022-07-25 12:38 ` [PATCH 11/20] builtin/commit-graph.c: " SZEDER Gábor
2022-07-25 12:38 ` [PATCH 12/20] builtin/gc.c: let parse-options parse 'git maintenance's subcommands SZEDER Gábor
2022-07-25 12:38 ` [PATCH 13/20] builtin/hook.c: let parse-option parse subcommands SZEDER Gábor
2022-07-25 12:38 ` [PATCH 14/20] builtin/multi-pack-index.c: let parse-options " SZEDER Gábor
2022-07-25 12:38 ` [PATCH 15/20] builtin/notes.c: " SZEDER Gábor
2022-07-25 16:49   ` Junio C Hamano
2022-07-25 12:38 ` [PATCH 16/20] builtin/reflog.c: " SZEDER Gábor
2022-07-25 12:38 ` [PATCH 17/20] builtin/remote.c: " SZEDER Gábor
2022-07-25 12:38 ` [PATCH 18/20] builtin/sparse-checkout.c: " SZEDER Gábor
2022-07-25 12:38 ` [PATCH 19/20] builtin/stash.c: " SZEDER Gábor
2022-07-25 12:38 ` [PATCH 20/20] builtin/worktree.c: " SZEDER Gábor
2022-07-25 13:15 ` [PATCH 00/20] parse-options: handle subcommands Derrick Stolee
2022-07-25 16:00   ` SZEDER Gábor
2022-07-25 16:08     ` Derrick Stolee
2022-07-25 17:13 ` Ævar Arnfjörð Bjarmason
2022-07-25 17:56 ` Junio C Hamano
2022-07-26 15:42   ` Johannes Schindelin
2022-07-26 18:02     ` Ævar Arnfjörð Bjarmason
2022-08-19 16:03 ` [PATCH v2 " SZEDER Gábor
2022-08-19 16:03   ` [PATCH v2 01/20] git.c: update NO_PARSEOPT markings SZEDER Gábor
2022-08-19 16:03   ` [PATCH v2 02/20] t3301-notes.sh: check that default operation mode doesn't take arguments SZEDER Gábor
2022-08-19 16:03   ` [PATCH v2 03/20] t5505-remote.sh: check the behavior without a subcommand SZEDER Gábor
2022-08-19 16:03   ` [PATCH v2 04/20] t0040-parse-options: test parse_options() with various 'parse_opt_flags' SZEDER Gábor
2022-08-19 17:23     ` Ævar Arnfjörð Bjarmason
2022-08-20 11:14       ` SZEDER Gábor
2022-08-19 18:18     ` Junio C Hamano
2022-08-20 10:31       ` SZEDER Gábor
2022-08-20 21:27         ` Junio C Hamano
2022-08-19 16:03   ` [PATCH v2 05/20] api-parse-options.txt: fix description of OPT_CMDMODE SZEDER Gábor
2022-08-19 16:03   ` [PATCH v2 06/20] parse-options: PARSE_OPT_KEEP_UNKNOWN only applies to --options SZEDER Gábor
2022-08-19 16:03   ` [PATCH v2 07/20] parse-options: clarify the limitations of PARSE_OPT_NODASH SZEDER Gábor
2022-08-19 16:03   ` [PATCH v2 08/20] parse-options: drop leading space from '--git-completion-helper' output SZEDER Gábor
2022-08-19 17:30     ` Ævar Arnfjörð Bjarmason
2022-08-19 18:35       ` SZEDER Gábor
2022-08-19 16:04   ` [PATCH v2 09/20] parse-options: add support for parsing subcommands SZEDER Gábor
2022-08-19 17:33     ` Ævar Arnfjörð Bjarmason
2022-08-19 19:03     ` Ævar Arnfjörð Bjarmason
2022-08-19 16:04   ` [PATCH v2 10/20] builtin/bundle.c: let parse-options parse subcommands SZEDER Gábor
2022-08-19 17:50     ` Ævar Arnfjörð Bjarmason
2022-08-19 16:04   ` [PATCH v2 11/20] builtin/commit-graph.c: " SZEDER Gábor
2022-08-19 17:53     ` Ævar Arnfjörð Bjarmason
2022-08-19 17:56       ` Ævar Arnfjörð Bjarmason
2022-08-19 18:22       ` SZEDER Gábor
2022-08-19 16:04   ` [PATCH v2 12/20] builtin/gc.c: let parse-options parse 'git maintenance's subcommands SZEDER Gábor
2022-08-19 20:59     ` Junio C Hamano
2022-08-19 16:04   ` [PATCH v2 13/20] builtin/hook.c: let parse-options parse subcommands SZEDER Gábor
2022-08-19 16:04   ` [PATCH v2 14/20] builtin/multi-pack-index.c: " SZEDER Gábor
2022-08-19 17:57     ` Ævar Arnfjörð Bjarmason
2022-08-19 16:04   ` [PATCH v2 15/20] builtin/notes.c: " SZEDER Gábor
2022-08-19 18:01     ` Ævar Arnfjörð Bjarmason
2022-08-21 17:56       ` SZEDER Gábor
2022-08-19 16:04   ` [PATCH v2 16/20] builtin/reflog.c: " SZEDER Gábor
2022-08-19 18:08     ` Ævar Arnfjörð Bjarmason
2022-08-19 16:04   ` [PATCH v2 17/20] builtin/remote.c: " SZEDER Gábor
2022-08-19 16:04   ` [PATCH v2 18/20] builtin/sparse-checkout.c: " SZEDER Gábor
2022-08-19 16:04   ` [PATCH v2 19/20] builtin/stash.c: " SZEDER Gábor
2022-08-19 19:06     ` Ævar Arnfjörð Bjarmason
2022-08-20 10:27       ` SZEDER Gábor
2022-08-19 16:04   ` [PATCH v2 20/20] builtin/worktree.c: " SZEDER Gábor
2022-09-05 18:50   ` [PATCH 0/5] parse-options: minor cleanups for handling subcommands SZEDER Gábor
2022-09-05 18:50     ` [PATCH 1/5] t0040-parse-options: remove leftover debugging SZEDER Gábor
2022-09-05 18:50     ` [PATCH 2/5] test-parse-options.c: don't use for loop initial declaration SZEDER Gábor
2022-09-05 18:50     ` [PATCH 3/5] test-parse-options.c: fix style of comparison with zero SZEDER Gábor
2022-09-05 18:50     ` [PATCH 4/5] notes: simplify default operation mode arguments check SZEDER Gábor
2022-09-05 18:50     ` [PATCH 5/5] notes, remote: show unknown subcommands between `' SZEDER Gábor
2022-09-07 19:12     ` [PATCH 0/5] parse-options: minor cleanups for handling subcommands Junio C Hamano
2022-09-07 21:22       ` SZEDER Gábor

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

  List information: http://vger.kernel.org/majordomo-info.html

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220725192947.GB2543@szeder.dev \
    --to=szeder.dev@gmail.com \
    --cc=avarab@gmail.com \
    --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.
Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).