public inbox for git@vger.kernel.org 
 help / color / mirror / Atom feed
From: "René Scharfe" <l.s.r@web•de>
To: Git List <git@vger•kernel.org>
Cc: Patrick Steinhardt <ps@pks•im>
Subject: [PATCH 1/6] parse-options: add precision handling for PARSE_OPT_CMDMODE
Date: Sun, 29 Jun 2025 13:50:31 +0200	[thread overview]
Message-ID: <d92697a6-5367-4412-88db-164ba4dd6230@web.de> (raw)
In-Reply-To: <cf5cd57d-733f-4239-80f8-23bdc1523ab2@web.de>

Build on 09705696f7 (parse-options: introduce precision handling for
`OPTION_INTEGER`, 2025-04-17) to support value variables of different
sizes for PARSE_OPT_CMDMODE options.  Do that by requiring their
"precision" to be set and casting their "value" pointer accordingly.

get_value() needs to access all PARSE_OPT_CMDMODE values in addition to
the actual value it is supposed to get to detect conflicting changes.
Give it an example struct option pointer in cmdmode_list instead of just
the "value" pointer to allow it to use the proper "precision".

Use optbug() in get_int_value() to report options with unsupported
"precision" values without requiring enum opt_parsed flags, as we don't
have them in build_cmdmode_list().  Use BUG right afterwards to abort
for uses outside of build_cmdmode_list() by aborting immediately.

Signed-off-by: René Scharfe <l.s.r@web•de>
---
 builtin/am.c                  |  1 +
 parse-options.c               | 36 ++++++++++++++++++++++++++---------
 parse-options.h               |  1 +
 t/helper/test-parse-options.c | 13 ++++++++++---
 4 files changed, 39 insertions(+), 12 deletions(-)

diff --git a/builtin/am.c b/builtin/am.c
index a800003340..c9d925f7b9 100644
--- a/builtin/am.c
+++ b/builtin/am.c
@@ -2406,6 +2406,7 @@ int cmd_am(int argc,
 			.type = OPTION_CALLBACK,
 			.long_name = "show-current-patch",
 			.value = &resume_mode,
+			.precision = sizeof(resume_mode),
 			.argh = "(diff|raw)",
 			.help = N_("show the patch being applied"),
 			.flags = PARSE_OPT_CMDMODE | PARSE_OPT_OPTARG | PARSE_OPT_NONEG | PARSE_OPT_LITERAL_ARGHELP,
diff --git a/parse-options.c b/parse-options.c
index a9a39ecaef..da07a000a3 100644
--- a/parse-options.c
+++ b/parse-options.c
@@ -68,6 +68,23 @@ static char *fix_filename(const char *prefix, const char *file)
 		return prefix_filename_except_for_dash(prefix, file);
 }
 
+static intmax_t get_int_value(const struct option *opt)
+{
+	switch (opt->precision) {
+	case sizeof(int8_t):
+		return *(int8_t *)opt->value;
+	case sizeof(int16_t):
+		return *(int16_t *)opt->value;
+	case sizeof(int32_t):
+		return *(int32_t *)opt->value;
+	case sizeof(int64_t):
+		return *(int64_t *)opt->value;
+	default:
+		optbug(opt, "has invalid precision");
+		BUG("invalid 'struct option'");
+	}
+}
+
 static enum parse_opt_result do_get_value(struct parse_opt_ctx_t *p,
 					  const struct option *opt,
 					  enum opt_parsed flags,
@@ -266,8 +283,8 @@ static enum parse_opt_result do_get_value(struct parse_opt_ctx_t *p,
 }
 
 struct parse_opt_cmdmode_list {
-	int value, *value_ptr;
-	const struct option *opt;
+	intmax_t value;
+	const struct option *opt, *reference_opt;
 	const char *arg;
 	enum opt_parsed flags;
 	struct parse_opt_cmdmode_list *next;
@@ -280,19 +297,18 @@ static void build_cmdmode_list(struct parse_opt_ctx_t *ctx,
 
 	for (; opts->type != OPTION_END; opts++) {
 		struct parse_opt_cmdmode_list *elem = ctx->cmdmode_list;
-		int *value_ptr = opts->value;
 
-		if (!(opts->flags & PARSE_OPT_CMDMODE) || !value_ptr)
+		if (!(opts->flags & PARSE_OPT_CMDMODE) || !opts->value)
 			continue;
 
-		while (elem && elem->value_ptr != value_ptr)
+		while (elem && elem->reference_opt->value != opts->value)
 			elem = elem->next;
 		if (elem)
 			continue;
 
 		CALLOC_ARRAY(elem, 1);
-		elem->value_ptr = value_ptr;
-		elem->value = *value_ptr;
+		elem->reference_opt = opts;
+		elem->value = get_int_value(opts);
 		elem->next = ctx->cmdmode_list;
 		ctx->cmdmode_list = elem;
 	}
@@ -317,7 +333,9 @@ static enum parse_opt_result get_value(struct parse_opt_ctx_t *p,
 	char *opt_name, *other_opt_name;
 
 	for (; elem; elem = elem->next) {
-		if (*elem->value_ptr == elem->value)
+		intmax_t new_value = get_int_value(elem->reference_opt);
+
+		if (new_value == elem->value)
 			continue;
 
 		if (elem->opt &&
@@ -327,7 +345,7 @@ static enum parse_opt_result get_value(struct parse_opt_ctx_t *p,
 		elem->opt = opt;
 		elem->arg = arg;
 		elem->flags = flags;
-		elem->value = *elem->value_ptr;
+		elem->value = new_value;
 	}
 
 	if (result || !elem)
diff --git a/parse-options.h b/parse-options.h
index 91c3e3c29b..c75a473c9e 100644
--- a/parse-options.h
+++ b/parse-options.h
@@ -269,6 +269,7 @@ struct option {
 	.short_name = (s), \
 	.long_name = (l), \
 	.value = (v), \
+	.precision = sizeof(*v), \
 	.help = (h), \
 	.flags = PARSE_OPT_CMDMODE|PARSE_OPT_NOARG|PARSE_OPT_NONEG | (f), \
 	.defval = (i), \
diff --git a/t/helper/test-parse-options.c b/t/helper/test-parse-options.c
index f2663dd0c0..1e03ff88f6 100644
--- a/t/helper/test-parse-options.c
+++ b/t/helper/test-parse-options.c
@@ -148,9 +148,16 @@ int cmd__parse_options(int argc, const char **argv)
 		OPT_SET_INT(0, "set23", &integer, "set integer to 23", 23),
 		OPT_CMDMODE(0, "mode1", &integer, "set integer to 1 (cmdmode option)", 1),
 		OPT_CMDMODE(0, "mode2", &integer, "set integer to 2 (cmdmode option)", 2),
-		OPT_CALLBACK_F(0, "mode34", &integer, "(3|4)",
-			"set integer to 3 or 4 (cmdmode option)",
-			PARSE_OPT_CMDMODE, mode34_callback),
+		{
+			.type = OPTION_CALLBACK,
+			.long_name = "mode34",
+			.value = &integer,
+			.precision = sizeof(integer),
+			.argh = "(3|4)",
+			.help = "set integer to 3 or 4 (cmdmode option)",
+			.flags = PARSE_OPT_CMDMODE,
+			.callback = mode34_callback,
+		},
 		OPT_CALLBACK('L', "length", &integer, "str",
 			"get length of <str>", length_callback),
 		OPT_FILENAME('F', "file", &file, "set file to <file>"),
-- 
2.50.0

  reply	other threads:[~2025-06-29 11:50 UTC|newest]

Thread overview: 31+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-06-29 11:43 [PATCH 0/6] parse-options: add more precision handling René Scharfe
2025-06-29 11:50 ` René Scharfe [this message]
2025-07-01 10:55   ` [PATCH 1/6] parse-options: add precision handling for PARSE_OPT_CMDMODE Patrick Steinhardt
2025-07-01 15:15     ` René Scharfe
2025-06-29 11:50 ` [PATCH 2/6] parse-options: add precision handling for OPTION_SET_INT René Scharfe
2025-07-01 10:55   ` Patrick Steinhardt
2025-07-01 15:54     ` René Scharfe
2025-07-02  2:31       ` Patrick Steinhardt
2025-06-29 11:50 ` [PATCH 3/6] parse-options: add precision handling for OPTION_BIT René Scharfe
2025-06-29 11:51 ` [PATCH 4/6] parse-options: add precision handling for OPTION_NEGBIT René Scharfe
2025-06-29 11:51 ` [PATCH 5/6] parse-options: add precision handling for OPTION_BITOP René Scharfe
2025-07-01 10:55   ` Patrick Steinhardt
2025-07-01 15:21     ` René Scharfe
2025-07-02  2:33       ` Patrick Steinhardt
2025-06-29 11:51 ` [PATCH 6/6] parse-options: add precision handling for OPTION_COUNTUP René Scharfe
2025-07-01 10:55   ` Patrick Steinhardt
2025-07-01 16:01     ` René Scharfe
2025-07-02  2:29       ` Patrick Steinhardt
2025-07-09  9:26 ` [PATCH v2 0/7] parse-options: add more precision handling René Scharfe
2025-07-09  9:44   ` [PATCH v2 1/7] parse-options: require PARSE_OPT_NOARG for OPTION_BITOP René Scharfe
2025-07-09 13:59     ` Patrick Steinhardt
2025-07-09  9:45   ` [PATCH v2 2/7] parse-options: add precision handling for PARSE_OPT_CMDMODE René Scharfe
2025-07-09 13:58     ` Patrick Steinhardt
2025-07-09 15:05       ` René Scharfe
2025-07-09 15:58         ` Patrick Steinhardt
2025-07-09 15:56       ` Junio C Hamano
2025-07-09  9:45   ` [PATCH v2 3/7] parse-options: add precision handling for OPTION_SET_INT René Scharfe
2025-07-09  9:45   ` [PATCH v2 4/7] parse-options: add precision handling for OPTION_BIT René Scharfe
2025-07-09  9:45   ` [PATCH v2 5/7] parse-options: add precision handling for OPTION_NEGBIT René Scharfe
2025-07-09  9:46   ` [PATCH v2 6/7] parse-options: add precision handling for OPTION_BITOP René Scharfe
2025-07-09  9:46   ` [PATCH v2 7/7] parse-options: add precision handling for OPTION_COUNTUP René Scharfe

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=d92697a6-5367-4412-88db-164ba4dd6230@web.de \
    --to=l.s.r@web$(echo .)de \
    --cc=git@vger$(echo .)kernel.org \
    --cc=ps@pks$(echo .)im \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html
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