From: "René Scharfe" <l.s.r@web•de>
To: Git List <git@vger•kernel.org>
Cc: Patrick Steinhardt <ps@pks•im>
Subject: [PATCH v2 2/7] parse-options: add precision handling for PARSE_OPT_CMDMODE
Date: Wed, 9 Jul 2025 11:45:14 +0200 [thread overview]
Message-ID: <77b841ea-eab1-4e76-98ff-f7a16653fcb8@web.de> (raw)
In-Reply-To: <802eba72-c100-429a-80b7-7a0e8b6559ed@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.
Call the function that does the raw casting do_get_int_value() to
reserve the name get_int_value() for a more friendly wrapper we're
going to introduce in one of the next patches.
Signed-off-by: René Scharfe <l.s.r@web•de>
---
builtin/am.c | 1 +
parse-options.c | 41 ++++++++++++++++++++++++++++++-----
parse-options.h | 1 +
t/helper/test-parse-options.c | 13 ++++++++---
4 files changed, 48 insertions(+), 8 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 68ff494492..ddac008a5e 100644
--- a/parse-options.c
+++ b/parse-options.c
@@ -68,6 +68,26 @@ static char *fix_filename(const char *prefix, const char *file)
return prefix_filename_except_for_dash(prefix, file);
}
+static int do_get_int_value(const void *value, size_t precision, intmax_t *ret)
+{
+ switch (precision) {
+ case sizeof(int8_t):
+ *ret = *(int8_t *)value;
+ return 0;
+ case sizeof(int16_t):
+ *ret = *(int16_t *)value;
+ return 0;
+ case sizeof(int32_t):
+ *ret = *(int32_t *)value;
+ return 0;
+ case sizeof(int64_t):
+ *ret = *(int64_t *)value;
+ return 0;
+ default:
+ return -1;
+ }
+}
+
static enum parse_opt_result do_get_value(struct parse_opt_ctx_t *p,
const struct option *opt,
enum opt_parsed flags,
@@ -266,7 +286,9 @@ static enum parse_opt_result do_get_value(struct parse_opt_ctx_t *p,
}
struct parse_opt_cmdmode_list {
- int value, *value_ptr;
+ intmax_t value;
+ void *value_ptr;
+ size_t precision;
const struct option *opt;
const char *arg;
enum opt_parsed flags;
@@ -280,7 +302,7 @@ 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;
+ void *value_ptr = opts->value;
if (!(opts->flags & PARSE_OPT_CMDMODE) || !value_ptr)
continue;
@@ -292,10 +314,13 @@ static void build_cmdmode_list(struct parse_opt_ctx_t *ctx,
CALLOC_ARRAY(elem, 1);
elem->value_ptr = value_ptr;
- elem->value = *value_ptr;
+ elem->precision = opts->precision;
+ if (do_get_int_value(value_ptr, opts->precision, &elem->value))
+ optbug(opts, "has invalid precision");
elem->next = ctx->cmdmode_list;
ctx->cmdmode_list = elem;
}
+ BUG_if_bug("invalid 'struct option'");
}
static char *optnamearg(const struct option *opt, const char *arg,
@@ -317,7 +342,13 @@ 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;
+
+ if (do_get_int_value(elem->value_ptr, elem->precision,
+ &new_value))
+ BUG("impossible: invalid precision");
+
+ if (new_value == elem->value)
continue;
if (elem->opt &&
@@ -327,7 +358,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
next prev parent reply other threads:[~2025-07-09 9:45 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 ` [PATCH 1/6] parse-options: add precision handling for PARSE_OPT_CMDMODE René Scharfe
2025-07-01 10:55 ` 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 ` René Scharfe [this message]
2025-07-09 13:58 ` [PATCH v2 2/7] parse-options: add precision handling for PARSE_OPT_CMDMODE 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=77b841ea-eab1-4e76-98ff-f7a16653fcb8@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