mirror of
https://github.com/torvalds/linux.git
synced 2026-07-27 01:32:21 +02:00
tools subcmd: allow parsing distinct --opt and --no-opt
libsubcmd automatically generates for every option --opt an equivalent negated option, --no-opt, to unset the option. Vice versa, for every option declared as --no-opt, a shorthand --opt is declared for convenience. Add a flag, PARSE_OPT_NOAUTONEG, to disable this behavior. This new flag behaves similarly to the already existing PARSE_OPT_NONEG, only it does not reject the --no-opt variant, but leaves it undefined. That is useful when there is a conflicting distinct --no-opt option in the syntax of the tool. PARSE_OPT_NOAUTONEG is enabled per-option, allowing to unset other options that do not have this conflict. Link: https://lore.kernel.org/r/20260528103254.2990068-4-tglozar@redhat.com Signed-off-by: Tomas Glozar <tglozar@redhat.com>
This commit is contained in:
parent
534d9a93db
commit
da62fc3458
|
|
@ -427,7 +427,8 @@ static int parse_long_opt(struct parse_opt_ctx_t *p, const char *arg,
|
|||
return 0;
|
||||
}
|
||||
if (!rest) {
|
||||
if (strstarts(options->long_name, "no-")) {
|
||||
if (strstarts(options->long_name, "no-") &&
|
||||
!(options->flags & PARSE_OPT_NOAUTONEG)) {
|
||||
/*
|
||||
* The long name itself starts with "no-", so
|
||||
* accept the option without "no-" so that users
|
||||
|
|
@ -465,12 +466,12 @@ static int parse_long_opt(struct parse_opt_ctx_t *p, const char *arg,
|
|||
continue;
|
||||
}
|
||||
/* negated and abbreviated very much? */
|
||||
if (strstarts("no-", arg)) {
|
||||
if (strstarts("no-", arg) && !(options->flags & PARSE_OPT_NOAUTONEG)) {
|
||||
flags |= OPT_UNSET;
|
||||
goto is_abbreviated;
|
||||
}
|
||||
/* negated? */
|
||||
if (strncmp(arg, "no-", 3))
|
||||
if (strncmp(arg, "no-", 3) || (options->flags & PARSE_OPT_NOAUTONEG))
|
||||
continue;
|
||||
flags |= OPT_UNSET;
|
||||
rest = skip_prefix(arg + 3, options->long_name);
|
||||
|
|
@ -1019,7 +1020,8 @@ int parse_options_usage(const char * const *usagestr,
|
|||
if (strstarts(opts->long_name, optstr))
|
||||
print_option_help(opts, 0);
|
||||
if (strstarts("no-", optstr) &&
|
||||
strstarts(opts->long_name, optstr + 3))
|
||||
strstarts(opts->long_name, optstr + 3) &&
|
||||
!(opts->flags & PARSE_OPT_NOAUTONEG))
|
||||
print_option_help(opts, 0);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@ enum parse_opt_option_flags {
|
|||
PARSE_OPT_NOEMPTY = 128,
|
||||
PARSE_OPT_NOBUILD = 256,
|
||||
PARSE_OPT_CANSKIP = 512,
|
||||
PARSE_OPT_NOAUTONEG = 1024,
|
||||
};
|
||||
|
||||
struct option;
|
||||
|
|
@ -149,6 +150,8 @@ struct option {
|
|||
{ .type = OPTION_CALLBACK, .short_name = (s), .long_name = (l), .value = (v), .argh = "time", .help = (h), .callback = parse_opt_approxidate_cb }
|
||||
#define OPT_CALLBACK(s, l, v, a, h, f) \
|
||||
{ .type = OPTION_CALLBACK, .short_name = (s), .long_name = (l), .value = (v), .argh = (a), .help = (h), .callback = (f) }
|
||||
#define OPT_CALLBACK_FLAG(s, l, v, a, h, f, fl) \
|
||||
{ .type = OPTION_CALLBACK, .short_name = (s), .long_name = (l), .value = (v), .argh = (a), .help = (h), .callback = (f), .flags = (fl) }
|
||||
#define OPT_CALLBACK_SET(s, l, v, os, a, h, f) \
|
||||
{ .type = OPTION_CALLBACK, .short_name = (s), .long_name = (l), .value = (v), .argh = (a), .help = (h), .callback = (f), .set = check_vtype(os, bool *)}
|
||||
#define OPT_CALLBACK_NOOPT(s, l, v, a, h, f) \
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user