parse-options: add precision handling for OPTION_BIT
Similar to 09705696f7 (parse-options: introduce precision handling for `OPTION_INTEGER`, 2025-04-17) support value variables of different sizes for OPTION_BIT. Do that by requiring their "precision" to be set, casting their "value" pointer accordingly and checking whether the value fits. Signed-off-by: René Scharfe <l.s.r@web.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
René Scharfe committed
Jul 9, 2025 at 11:45 UTC
5228211c4b92052c0a38f2ab67cd0b87a7baec30
3 files changed
+17
-4
builtin/write-tree.c
+1
@@ -35,6 +35,7 @@ int cmd_write_tree(int argc,
35
.type = OPTION_BIT,
36
.long_name = "ignore-cache-tree",
37
.value = &flags,
38
+ .precision = sizeof(flags),
39
.help = N_("only useful for debugging"),
40
.flags = PARSE_OPT_HIDDEN | PARSE_OPT_NOARG,
41
.defval = WRITE_TREE_IGNORE_CACHE_TREE,
parse-options.c
+15
-4
@@ -88,6 +88,14 @@ static int do_get_int_value(const void *value, size_t precision, intmax_t *ret)
88
}
89
}
90
91
+static intmax_t get_int_value(const struct option *opt, enum opt_parsed flags)
92
+{
93
+ intmax_t ret;
94
+ if (do_get_int_value(opt->value, opt->precision, &ret))
95
+ BUG("invalid precision for option %s", optname(opt, flags));
96
+ return ret;
97
+}
98
+
99
static enum parse_opt_result set_int_value(const struct option *opt,
100
enum opt_parsed flags,
101
intmax_t value)
@@ -139,11 +147,14 @@ static enum parse_opt_result do_get_value(struct parse_opt_ctx_t *p,
147
return opt->ll_callback(p, opt, NULL, unset);
148
149
case OPTION_BIT:
150
+ {
151
+ intmax_t value = get_int_value(opt, flags);
152
if (unset)
143
- *(int *)opt->value &= ~opt->defval;
153
+ value &= ~opt->defval;
154
else
145
- *(int *)opt->value |= opt->defval;
146
- return 0;
155
+ value |= opt->defval;
156
+ return set_int_value(opt, flags, value);
157
+ }
158
159
case OPTION_NEGBIT:
160
if (unset)
@@ -631,11 +642,11 @@ static void parse_options_check(const struct option *opts)
642
optbug(opts, "OPTION_SET_INT 0 should not be negatable");
643
switch (opts->type) {
644
case OPTION_SET_INT:
645
+ case OPTION_BIT:
646
if (!signed_int_fits(opts->defval, opts->precision))
647
optbug(opts, "has invalid defval");
648
/* fallthru */
649
case OPTION_COUNTUP:
638
- case OPTION_BIT:
650
case OPTION_NEGBIT:
651
case OPTION_NUMBER:
652
case OPTION_BITOP:
parse-options.h
+1
@@ -172,6 +172,7 @@ struct option {
172
.short_name = (s), \
173
.long_name = (l), \
174
.value = (v), \
175
+ .precision = sizeof(*v), \
176
.help = (h), \
177
.flags = PARSE_OPT_NOARG|(f), \
178
.callback = NULL, \