Skip to content

Commit b1ce2b6

Browse files
rscharfegitster
authored andcommitted
parse-options: normalize arg and long_name before comparison
Strip "no-" from arg and long_name before comparing them. This way we no longer have to repeat the comparison with an offset of 3 for negated arguments. Note that we must not modify the "flags" value, which tracks whether arg is negated, inside the loop. When registering "--n", "--no" or "--no-" as abbreviation for any negative option, we used to OR it with OPT_UNSET and end the loop. We can simply hard-code OPT_UNSET and leave flags unchanged instead. Signed-off-by: René Scharfe <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 0d8a309 commit b1ce2b6

File tree

1 file changed

+22
-22
lines changed

1 file changed

+22
-22
lines changed

parse-options.c

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -382,28 +382,42 @@ static enum parse_opt_result parse_long_opt(
382382
const struct option *options)
383383
{
384384
const char *arg_end = strchrnul(arg, '=');
385+
const char *arg_start = arg;
386+
enum opt_parsed flags = OPT_LONG;
387+
int arg_starts_with_no_no = 0;
385388
struct parsed_option abbrev = { .option = NULL, .flags = OPT_LONG };
386389
struct parsed_option ambiguous = { .option = NULL, .flags = OPT_LONG };
387390

391+
if (skip_prefix(arg_start, "no-", &arg_start)) {
392+
if (skip_prefix(arg_start, "no-", &arg_start))
393+
arg_starts_with_no_no = 1;
394+
else
395+
flags |= OPT_UNSET;
396+
}
397+
388398
for (; options->type != OPTION_END; options++) {
389399
const char *rest, *long_name = options->long_name;
390-
enum opt_parsed flags = OPT_LONG, opt_flags = OPT_LONG;
400+
enum opt_parsed opt_flags = OPT_LONG;
401+
int allow_unset = !(options->flags & PARSE_OPT_NONEG);
391402

392403
if (options->type == OPTION_SUBCOMMAND)
393404
continue;
394405
if (!long_name)
395406
continue;
396407

397-
if (!starts_with(arg, "no-") &&
398-
!(options->flags & PARSE_OPT_NONEG) &&
399-
skip_prefix(long_name, "no-", &long_name))
408+
if (skip_prefix(long_name, "no-", &long_name))
400409
opt_flags |= OPT_UNSET;
410+
else if (arg_starts_with_no_no)
411+
continue;
412+
413+
if (((flags ^ opt_flags) & OPT_UNSET) && !allow_unset)
414+
continue;
401415

402-
if (!skip_prefix(arg, long_name, &rest))
416+
if (!skip_prefix(arg_start, long_name, &rest))
403417
rest = NULL;
404418
if (!rest) {
405419
/* abbreviated? */
406-
if (!strncmp(long_name, arg, arg_end - arg)) {
420+
if (!strncmp(long_name, arg_start, arg_end - arg_start)) {
407421
register_abbrev(p, options, flags ^ opt_flags,
408422
&abbrev, &ambiguous);
409423
}
@@ -412,24 +426,10 @@ static enum parse_opt_result parse_long_opt(
412426
continue;
413427
/* negated and abbreviated very much? */
414428
if (starts_with("no-", arg)) {
415-
flags |= OPT_UNSET;
416-
register_abbrev(p, options, flags ^ opt_flags,
429+
register_abbrev(p, options, OPT_UNSET ^ opt_flags,
417430
&abbrev, &ambiguous);
418-
continue;
419-
}
420-
/* negated? */
421-
if (!starts_with(arg, "no-"))
422-
continue;
423-
flags |= OPT_UNSET;
424-
if (!skip_prefix(arg + 3, long_name, &rest)) {
425-
/* abbreviated and negated? */
426-
if (!strncmp(long_name, arg + 3,
427-
arg_end - arg - 3))
428-
register_abbrev(p, options,
429-
flags ^ opt_flags,
430-
&abbrev, &ambiguous);
431-
continue;
432431
}
432+
continue;
433433
}
434434
if (*rest) {
435435
if (*rest != '=')

0 commit comments

Comments
 (0)