git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
From: Jeff King <peff@peff.net>
To: Johannes Schindelin <johannes.schindelin@gmx.de>
Cc: git@vger.kernel.org, Junio C Hamano <gitster@pobox.com>
Subject: Re: [PATCH] revert: clarify seemingly bogus OPT_END repetition
Date: Tue, 5 Jul 2016 16:44:47 -0400	[thread overview]
Message-ID: <20160705204447.GB14496@sigill.intra.peff.net> (raw)
In-Reply-To: <20160705202820.GA14496@sigill.intra.peff.net>

On Tue, Jul 05, 2016 at 04:28:20PM -0400, Jeff King wrote:

> I wonder if parse_options_concat should simply allocate a new list
> (after computing the total required size). I guess this is the only
> caller, though, so perhaps it's not the end of the world. In the
> meantime, your patch is certainly an improvement.

Something like the patch below.

I admit this isn't buggy _now_, so this is potentially just churn. It
does make further patches look nicer, though (they don't have to add
apparently meaningless OPT_END() slots).

-- >8 --
Subject: [PATCH] parse_options: allocate a new array when concatenating

In exactly one callers (builtin/revert.c), we build up the
options list dynamically from multiple arrays. We do so by
manually inserting "filler" entries into one array, and then
copying the other array into the allocated space.

This is tedious and error-prone, as you have to adjust the
filler any time the second array is modified (although we do
at least check and die() when the counts do not match up).

Instead, let's just allocate a new array.

Signed-off-by: Jeff King <peff@peff.net>
---
 builtin/revert.c   | 13 ++++---------
 parse-options-cb.c | 29 +++++++++++++++++------------
 parse-options.h    |  2 +-
 3 files changed, 22 insertions(+), 22 deletions(-)

diff --git a/builtin/revert.c b/builtin/revert.c
index 56a2c36..4e69380 100644
--- a/builtin/revert.c
+++ b/builtin/revert.c
@@ -76,7 +76,7 @@ static void parse_args(int argc, const char **argv, struct replay_opts *opts)
 	const char * const * usage_str = revert_or_cherry_pick_usage(opts);
 	const char *me = action_name(opts);
 	int cmd = 0;
-	struct option options[] = {
+	struct option base_options[] = {
 		OPT_CMDMODE(0, "quit", &cmd, N_("end revert or cherry-pick sequence"), 'q'),
 		OPT_CMDMODE(0, "continue", &cmd, N_("resume revert or cherry-pick sequence"), 'c'),
 		OPT_CMDMODE(0, "abort", &cmd, N_("cancel revert or cherry-pick sequence"), 'a'),
@@ -91,13 +91,9 @@ static void parse_args(int argc, const char **argv, struct replay_opts *opts)
 			N_("option for merge strategy"), option_parse_x),
 		{ OPTION_STRING, 'S', "gpg-sign", &opts->gpg_sign, N_("key-id"),
 		  N_("GPG sign commit"), PARSE_OPT_OPTARG, NULL, (intptr_t) "" },
-		OPT_END(),
-		OPT_END(),
-		OPT_END(),
-		OPT_END(),
-		OPT_END(),
-		OPT_END(),
+		OPT_END()
 	};
+	struct option *options = base_options;
 
 	if (opts->action == REPLAY_PICK) {
 		struct option cp_extra[] = {
@@ -108,8 +104,7 @@ static void parse_args(int argc, const char **argv, struct replay_opts *opts)
 			OPT_BOOL(0, "keep-redundant-commits", &opts->keep_redundant_commits, N_("keep redundant, empty commits")),
 			OPT_END(),
 		};
-		if (parse_options_concat(options, ARRAY_SIZE(options), cp_extra))
-			die(_("program error"));
+		options = parse_options_concat(options, cp_extra);
 	}
 
 	argc = parse_options(argc, argv, NULL, options, usage_str,
diff --git a/parse-options-cb.c b/parse-options-cb.c
index 239898d..2d87520 100644
--- a/parse-options-cb.c
+++ b/parse-options-cb.c
@@ -117,19 +117,24 @@ int parse_opt_tertiary(const struct option *opt, const char *arg, int unset)
 	return 0;
 }
 
-int parse_options_concat(struct option *dst, size_t dst_size, struct option *src)
+struct option *parse_options_concat(struct option *a, struct option *b)
 {
-	int i, j;
-
-	for (i = 0; i < dst_size; i++)
-		if (dst[i].type == OPTION_END)
-			break;
-	for (j = 0; i < dst_size; i++, j++) {
-		dst[i] = src[j];
-		if (src[j].type == OPTION_END)
-			return 0;
-	}
-	return -1;
+	struct option *ret;
+	size_t i, a_len = 0, b_len = 0;
+
+	for (i = 0; a[i].type != OPTION_END; i++)
+		a_len++;
+	for (i = 0; b[i].type != OPTION_END; i++)
+		b_len++;
+
+	ALLOC_ARRAY(ret, st_add3(a_len, b_len, 1));
+	for (i = 0; i < a_len; i++)
+		ret[i] = a[i];
+	for (i = 0; i < b_len; i++)
+		ret[a_len + i] = b[i];
+	ret[a_len + b_len] = b[b_len]; /* final OPTION_END */
+
+	return ret;
 }
 
 int parse_opt_string_list(const struct option *opt, const char *arg, int unset)
diff --git a/parse-options.h b/parse-options.h
index ea4af92..78f8384 100644
--- a/parse-options.h
+++ b/parse-options.h
@@ -215,7 +215,7 @@ extern int parse_options_step(struct parse_opt_ctx_t *ctx,
 
 extern int parse_options_end(struct parse_opt_ctx_t *ctx);
 
-extern int parse_options_concat(struct option *dst, size_t, struct option *src);
+extern struct option *parse_options_concat(struct option *a, struct option *b);
 
 /*----- some often used options -----*/
 extern int parse_opt_abbrev_cb(const struct option *, const char *, int);
-- 
2.9.0.320.gd3e6182


  reply	other threads:[~2016-07-05 20:44 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-07-05 11:58 [PATCH] revert: clarify seemingly bogus OPT_END repetition Johannes Schindelin
2016-07-05 20:28 ` Jeff King
2016-07-05 20:44   ` Jeff King [this message]
2016-07-05 21:15     ` Jacob Keller
2016-07-06  7:01       ` Johannes Schindelin
2016-07-06 11:09         ` Michael J Gruber
2016-07-06 13:16           ` Over-/underquoting, was " Johannes Schindelin
2016-07-06 20:15             ` Jacob Keller
2016-07-09 15:34               ` Michael J Gruber
2016-07-09 23:35                 ` Eric Wong
2016-07-06  7:28     ` Johannes Schindelin
2016-07-06  7:03   ` Johannes Schindelin
2016-07-06 10:48     ` Jeff King

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=20160705204447.GB14496@sigill.intra.peff.net \
    --to=peff@peff.net \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=johannes.schindelin@gmx.de \
    /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).