]> git.ipfire.org Git - thirdparty/git.git/commitdiff
parse-options: add precision handling for OPTION_BIT
authorRené Scharfe <l.s.r@web.de>
Wed, 9 Jul 2025 09:45:33 +0000 (11:45 +0200)
committerJunio C Hamano <gitster@pobox.com>
Wed, 9 Jul 2025 15:39:28 +0000 (08:39 -0700)
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>
builtin/write-tree.c
parse-options.c
parse-options.h

index 5a8dc377ec07b0fc69a54e7062f594e48a29c476..cfec044710a56abe1e6f3eb58fcdc178365bb674 100644 (file)
@@ -35,6 +35,7 @@ int cmd_write_tree(int argc,
                        .type = OPTION_BIT,
                        .long_name = "ignore-cache-tree",
                        .value = &flags,
+                       .precision = sizeof(flags),
                        .help = N_("only useful for debugging"),
                        .flags = PARSE_OPT_HIDDEN | PARSE_OPT_NOARG,
                        .defval = WRITE_TREE_IGNORE_CACHE_TREE,
index 639f41b83b697bb73e726c550da329c28fd8965e..b5c877d5e1ea88a86a5c8ce5da3023a1d8e5abb6 100644 (file)
@@ -88,6 +88,14 @@ static int do_get_int_value(const void *value, size_t precision, intmax_t *ret)
        }
 }
 
+static intmax_t get_int_value(const struct option *opt, enum opt_parsed flags)
+{
+       intmax_t ret;
+       if (do_get_int_value(opt->value, opt->precision, &ret))
+               BUG("invalid precision for option %s", optname(opt, flags));
+       return ret;
+}
+
 static enum parse_opt_result set_int_value(const struct option *opt,
                                           enum opt_parsed flags,
                                           intmax_t value)
@@ -139,11 +147,14 @@ static enum parse_opt_result do_get_value(struct parse_opt_ctx_t *p,
                return opt->ll_callback(p, opt, NULL, unset);
 
        case OPTION_BIT:
+       {
+               intmax_t value = get_int_value(opt, flags);
                if (unset)
-                       *(int *)opt->value &= ~opt->defval;
+                       value &= ~opt->defval;
                else
-                       *(int *)opt->value |= opt->defval;
-               return 0;
+                       value |= opt->defval;
+               return set_int_value(opt, flags, value);
+       }
 
        case OPTION_NEGBIT:
                if (unset)
@@ -631,11 +642,11 @@ static void parse_options_check(const struct option *opts)
                        optbug(opts, "OPTION_SET_INT 0 should not be negatable");
                switch (opts->type) {
                case OPTION_SET_INT:
+               case OPTION_BIT:
                        if (!signed_int_fits(opts->defval, opts->precision))
                                optbug(opts, "has invalid defval");
                        /* fallthru */
                case OPTION_COUNTUP:
-               case OPTION_BIT:
                case OPTION_NEGBIT:
                case OPTION_NUMBER:
                case OPTION_BITOP:
index 71516e4b5b9fed29a9668bdf1897a36e19f137a1..6501ca3c2793c9efbe04e7604bb9acf1abfd47be 100644 (file)
@@ -172,6 +172,7 @@ struct option {
        .short_name = (s), \
        .long_name = (l), \
        .value = (v), \
+       .precision = sizeof(*v), \
        .help = (h), \
        .flags = PARSE_OPT_NOARG|(f), \
        .callback = NULL, \