Skip to content

Commit c1e616c

Browse files
rscharfegitster
authored andcommitted
parse-options: add precision handling for OPTION_COUNTUP
Similar to 0970569 (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 <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 1d918bf commit c1e616c

File tree

3 files changed

+21
-5
lines changed

3 files changed

+21
-5
lines changed

parse-options.c

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -177,10 +177,22 @@ static enum parse_opt_result do_get_value(struct parse_opt_ctx_t *p,
177177
}
178178

179179
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+
}
184196

185197
case OPTION_SET_INT:
186198
return set_int_value(opt, flags, unset ? 0 : opt->defval);
@@ -651,10 +663,10 @@ static void parse_options_check(const struct option *opts)
651663
case OPTION_BIT:
652664
case OPTION_NEGBIT:
653665
case OPTION_BITOP:
666+
case OPTION_COUNTUP:
654667
if (!signed_int_fits(opts->defval, opts->precision))
655668
optbug(opts, "has invalid defval");
656669
/* fallthru */
657-
case OPTION_COUNTUP:
658670
case OPTION_NUMBER:
659671
if ((opts->flags & PARSE_OPT_OPTARG) ||
660672
!(opts->flags & PARSE_OPT_NOARG))

parse-options.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,7 @@ struct option {
183183
.short_name = (s), \
184184
.long_name = (l), \
185185
.value = (v), \
186+
.precision = sizeof(*v), \
186187
.help = (h), \
187188
.flags = PARSE_OPT_NOARG|(f), \
188189
}

t/helper/test-parse-options.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,20 +178,23 @@ int cmd__parse_options(int argc, const char **argv)
178178
.type = OPTION_COUNTUP,
179179
.short_name = '+',
180180
.value = &boolean,
181+
.precision = sizeof(boolean),
181182
.help = "same as -b",
182183
.flags = PARSE_OPT_NOARG | PARSE_OPT_NONEG | PARSE_OPT_NODASH,
183184
},
184185
{
185186
.type = OPTION_COUNTUP,
186187
.long_name = "ambiguous",
187188
.value = &ambiguous,
189+
.precision = sizeof(ambiguous),
188190
.help = "positive ambiguity",
189191
.flags = PARSE_OPT_NOARG | PARSE_OPT_NONEG,
190192
},
191193
{
192194
.type = OPTION_COUNTUP,
193195
.long_name = "no-ambiguous",
194196
.value = &ambiguous,
197+
.precision = sizeof(ambiguous),
195198
.help = "negative ambiguity",
196199
.flags = PARSE_OPT_NOARG | PARSE_OPT_NONEG,
197200
},

0 commit comments

Comments
 (0)