Skip to content

Commit 8ff1a34

Browse files
pks-tgitster
authored andcommitted
parse-options: support unit factors in OPT_INTEGER()
There are two main differences between `OPT_INTEGER()` and `OPT_MAGNITUDE()`: - The former parses signed integers whereas the latter parses unsigned integers. - The latter parses unit factors like 'k', 'm' or 'g'. While the first difference makes obvious sense, there isn't really a good reason why signed integers shouldn't support unit factors, too. This inconsistency will also become a bit of a problem with subsequent commits, where we will fix a couple of callsites that pass an unsigned integer to `OPT_INTEGER()`. There are three options: - We could adapt those users to instead pass a signed integer, but this would needlessly extend the range of accepted integer values. - We could convert them to use `OPT_MAGNITUDE()`, as it only accepts unsigned integers. But now we have the inconsistency that we also start to accept unit factors. - We could introduce `OPT_UNSIGNED()` as equivalent to `OPT_INTEGER()` so that it knows to only accept unsigned integers without unit suffix. Introducing a whole new option type feels a bit excessive. There also isn't really a good reason why `OPT_INTEGER()` cannot be extended to also accept unit factors: all valid values passed to such options cannot have a unit factors right now, so there wouldn't be any ambiguity. Refactor `OPT_INTEGER()` to use `git_parse_int()`, which knows to interpret unit factors. This removes the inconsistency between the signed and unsigned options so that we can easily fix up callsites that pass the wrong integer type right now. Signed-off-by: Patrick Steinhardt <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent d012ceb commit 8ff1a34

File tree

3 files changed

+11
-7
lines changed

3 files changed

+11
-7
lines changed

Documentation/technical/api-parse-options.adoc

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -211,8 +211,10 @@ There are some macros to easily define options:
211211
Use of `--no-option` will clear the list of preceding values.
212212
213213
`OPT_INTEGER(short, long, &int_var, description)`::
214-
Introduce an option with integer argument.
215-
The integer is put into `int_var`.
214+
Introduce an option with integer argument. The argument must be a
215+
integer and may include a suffix of 'k', 'm' or 'g' to
216+
scale the provided value by 1024, 1024^2 or 1024^3 respectively.
217+
The scaled value is put into `int_var`.
216218
217219
`OPT_MAGNITUDE(short, long, &unsigned_long_var, description)`::
218220
Introduce an option with a size argument. The argument must be a

parse-options.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ static enum parse_opt_result do_get_value(struct parse_opt_ctx_t *p,
7373
enum opt_parsed flags,
7474
const char **argp)
7575
{
76-
const char *s, *arg;
76+
const char *arg;
7777
const int unset = flags & OPT_UNSET;
7878
int err;
7979

@@ -185,9 +185,9 @@ static enum parse_opt_result do_get_value(struct parse_opt_ctx_t *p,
185185
if (!*arg)
186186
return error(_("%s expects a numerical value"),
187187
optname(opt, flags));
188-
*(int *)opt->value = strtol(arg, (char **)&s, 10);
189-
if (*s)
190-
return error(_("%s expects a numerical value"),
188+
if (!git_parse_int(arg, opt->value))
189+
return error(_("%s expects an integer value"
190+
" with an optional k/m/g suffix"),
191191
optname(opt, flags));
192192
return 0;
193193

t/t0040-parse-options.sh

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,9 @@ test_expect_success 'OPT_BOOL() no negation #2' 'check_unknown_i18n --no-no-fear
111111

112112
test_expect_success 'OPT_BOOL() positivation' 'check boolean: 0 -D --doubt'
113113

114-
test_expect_success 'OPT_INT() negative' 'check integer: -2345 -i -2345'
114+
test_expect_success 'OPT_INTEGER() negative' 'check integer: -2345 -i -2345'
115+
test_expect_success 'OPT_INTEGER() kilo' 'check integer: 239616 -i 234k'
116+
test_expect_success 'OPT_INTEGER() negative kilo' 'check integer: -239616 -i -234k'
115117

116118
test_expect_success 'OPT_MAGNITUDE() simple' '
117119
check magnitude: 2345678 -m 2345678

0 commit comments

Comments
 (0)