parse-options: introduce precision handling for OPTION_UNSIGNED

This commit is the equivalent to the preceding commit, but instead of
introducing precision handling for `OPTION_INTEGER` we introduce it for
`OPTION_UNSIGNED`.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Patrick Steinhardt
2025-04-17 12:49:41 +02:00
committed by Junio C Hamano
parent 09705696f7
commit bc288c5929
6 changed files with 60 additions and 13 deletions

View File

@@ -197,7 +197,7 @@ static enum parse_opt_result do_get_value(struct parse_opt_ctx_t *p,
if (value < lower_bound)
return error(_("value %s for %s not in range [%"PRIdMAX",%"PRIdMAX"]"),
arg, optname(opt, flags), lower_bound, upper_bound);
arg, optname(opt, flags), (intmax_t)lower_bound, (intmax_t)upper_bound);
switch (opt->precision) {
case 1:
@@ -218,21 +218,47 @@ static enum parse_opt_result do_get_value(struct parse_opt_ctx_t *p,
}
}
case OPTION_UNSIGNED:
{
uintmax_t upper_bound = UINTMAX_MAX >> (bitsizeof(uintmax_t) - CHAR_BIT * opt->precision);
uintmax_t value;
if (unset) {
*(unsigned long *)opt->value = 0;
return 0;
}
if (opt->flags & PARSE_OPT_OPTARG && !p->opt) {
*(unsigned long *)opt->value = opt->defval;
return 0;
}
if (get_arg(p, opt, flags, &arg))
value = 0;
} else if (opt->flags & PARSE_OPT_OPTARG && !p->opt) {
value = opt->defval;
} else if (get_arg(p, opt, flags, &arg)) {
return -1;
if (!git_parse_ulong(arg, opt->value))
} else if (!*arg) {
return error(_("%s expects a numerical value"),
optname(opt, flags));
} else if (!git_parse_unsigned(arg, &value, upper_bound)) {
if (errno == ERANGE)
return error(_("value %s for %s not in range [%"PRIdMAX",%"PRIdMAX"]"),
arg, optname(opt, flags), (uintmax_t) 0, upper_bound);
return error(_("%s expects a non-negative integer value"
" with an optional k/m/g suffix"),
optname(opt, flags));
return 0;
}
switch (opt->precision) {
case 1:
*(uint8_t *)opt->value = value;
return 0;
case 2:
*(uint16_t *)opt->value = value;
return 0;
case 4:
*(uint32_t *)opt->value = value;
return 0;
case 8:
*(uint64_t *)opt->value = value;
return 0;
default:
BUG("invalid precision for option %s",
optname(opt, flags));
}
}
default:
BUG("opt->type %d should not happen", opt->type);