Am 15.04.25 um 14:14 schrieb Patrick Steinhardt: > We have two generic ways to parse integers in the "parse-options" > subsytem: "subsystem" > - `OPTION_INTEGER` parses a signed integer. > > - `OPTION_MAGNITUDE` parses an unsigned integer, but it also > interprets suffixes like "k" or "g". > > Notably missing is a middle ground that parses unsigned integers without > interpreting suffixes. Introduce a new `OPTION_UNSIGNED` option type to > plug this gap. This option type will be used in subsequent commits. > > Signed-off-by: Patrick Steinhardt <ps@xxxxxx> > --- > parse-options.c | 43 +++++++++++++++++++++++++++++++++++++++++++ > parse-options.h | 12 ++++++++++++ > t/helper/test-parse-options.c | 4 +++- > t/t0040-parse-options.sh | 18 +++++++++++++++++- > 4 files changed, 75 insertions(+), 2 deletions(-) > > diff --git a/parse-options.c b/parse-options.c > index ae836c384c7..9670e46a679 100644 > --- a/parse-options.c > +++ b/parse-options.c > @@ -216,6 +216,49 @@ static enum parse_opt_result do_get_value(struct parse_opt_ctx_t *p, > optname(opt, flags)); > } > } > + case OPTION_UNSIGNED: > + { > + uintmax_t upper_bound = UINTMAX_MAX >> (bitsizeof(uintmax_t) - CHAR_BIT * opt->precision); > + uintmax_t value; > + > + if (unset) { > + value = 0; > + } else if (opt->flags & PARSE_OPT_OPTARG && !p->opt) { > + value = opt->defval; > + } else if (get_arg(p, opt, flags, &arg)) { > + return -1; > + } else if (!*arg) { > + return error(_("%s expects a numerical value"), > + optname(opt, flags)); > + } else { > + value = strtoumax(arg, (char **)&s, 10); > + if (*s) > + return error(_("%s expects a numerical value"), > + optname(opt, flags)); > + } > + > + if (value > upper_bound) > + return error(_("value %"PRIuMAX" for %s exceeds %"PRIuMAX), > + value, optname(opt, flags), upper_bound); > + > + switch (opt->precision) { > + case 1: > + *(int8_t *)opt->value = value; uint8_t, surely. Similarly for the other casts below. > + return 0; > + case 2: > + *(int16_t *)opt->value = value; > + return 0; > + case 4: > + *(int32_t *)opt->value = value; > + return 0; > + case 8: > + *(int64_t *)opt->value = value; > + return 0; > + default: > + BUG("invalid precision for option %s", > + optname(opt, flags)); > + } > + } > case OPTION_MAGNITUDE: > { > uintmax_t upper_bound = UINTMAX_MAX >> (bitsizeof(uintmax_t) - CHAR_BIT * opt->precision);