Git fork

parse-options: add precision handling for OPTION_COUNTUP

Similar to 09705696f7 (parse-options: introduce precision handling for
`OPTION_INTEGER`, 2025-04-17) support value variables of different sizes
for OPTION_COUNTUP. 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>

authored by

René Scharfe and committed by
Junio C Hamano
c1e616c3 1d918bf2

+21 -5
+17 -5
parse-options.c
··· 177 177 } 178 178 179 179 case OPTION_COUNTUP: 180 - if (*(int *)opt->value < 0) 181 - *(int *)opt->value = 0; 182 - *(int *)opt->value = unset ? 0 : *(int *)opt->value + 1; 183 - return 0; 180 + { 181 + size_t bits = CHAR_BIT * opt->precision; 182 + intmax_t upper_bound = INTMAX_MAX >> (bitsizeof(intmax_t) - bits); 183 + intmax_t value = get_int_value(opt, flags); 184 + 185 + if (value < 0) 186 + value = 0; 187 + if (unset) 188 + value = 0; 189 + else if (value < upper_bound) 190 + value++; 191 + else 192 + return error(_("value for %s exceeds %"PRIdMAX), 193 + optname(opt, flags), upper_bound); 194 + return set_int_value(opt, flags, value); 195 + } 184 196 185 197 case OPTION_SET_INT: 186 198 return set_int_value(opt, flags, unset ? 0 : opt->defval); ··· 651 663 case OPTION_BIT: 652 664 case OPTION_NEGBIT: 653 665 case OPTION_BITOP: 666 + case OPTION_COUNTUP: 654 667 if (!signed_int_fits(opts->defval, opts->precision)) 655 668 optbug(opts, "has invalid defval"); 656 669 /* fallthru */ 657 - case OPTION_COUNTUP: 658 670 case OPTION_NUMBER: 659 671 if ((opts->flags & PARSE_OPT_OPTARG) || 660 672 !(opts->flags & PARSE_OPT_NOARG))
+1
parse-options.h
··· 183 183 .short_name = (s), \ 184 184 .long_name = (l), \ 185 185 .value = (v), \ 186 + .precision = sizeof(*v), \ 186 187 .help = (h), \ 187 188 .flags = PARSE_OPT_NOARG|(f), \ 188 189 }
+3
t/helper/test-parse-options.c
··· 178 178 .type = OPTION_COUNTUP, 179 179 .short_name = '+', 180 180 .value = &boolean, 181 + .precision = sizeof(boolean), 181 182 .help = "same as -b", 182 183 .flags = PARSE_OPT_NOARG | PARSE_OPT_NONEG | PARSE_OPT_NODASH, 183 184 }, ··· 185 186 .type = OPTION_COUNTUP, 186 187 .long_name = "ambiguous", 187 188 .value = &ambiguous, 189 + .precision = sizeof(ambiguous), 188 190 .help = "positive ambiguity", 189 191 .flags = PARSE_OPT_NOARG | PARSE_OPT_NONEG, 190 192 }, ··· 192 194 .type = OPTION_COUNTUP, 193 195 .long_name = "no-ambiguous", 194 196 .value = &ambiguous, 197 + .precision = sizeof(ambiguous), 195 198 .help = "negative ambiguity", 196 199 .flags = PARSE_OPT_NOARG | PARSE_OPT_NONEG, 197 200 },