mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-02-08 04:31:33 +00:00
virsh: add option aliases
In the past, we have created some virsh options with less-than-stellar names. For back-compat reasons, those names must continue to parse, but we don't want to document them in help output. This introduces a new option type, an alias, which points to a canonical option name later in the option list. I'm actually quite impressed that our code has already been factored to do all option parsing through common entry points, such that I got this added in relatively few lines of code! * tools/virsh.c (VSH_OT_ALIAS): New option type. (opts_echo): Hook up an alias, for easy testing. (vshCmddefOptParse, vshCmddefHelp, vshCmddefGetOption): Allow for aliases. * tools/virsh.pod (NOTES): Document promise of back-compat. * tests/virshtest.c (mymain): Test new feature.
This commit is contained in:
parent
2e22f23bde
commit
1c56b9fe53
@ -386,6 +386,12 @@ mymain(void)
|
|||||||
DO_TEST(30, "--shell a\n",
|
DO_TEST(30, "--shell a\n",
|
||||||
"echo \t '-'\"-\" \t --shell \t a");
|
"echo \t '-'\"-\" \t --shell \t a");
|
||||||
|
|
||||||
|
/* Tests of alias handling. */
|
||||||
|
DO_TEST(31, "hello\n", "echo", "--string", "hello");
|
||||||
|
DO_TEST(32, "hello\n", "echo --string hello");
|
||||||
|
DO_TEST(33, "hello\n", "echo", "--str", "hello");
|
||||||
|
DO_TEST(34, "hello\n", "echo --str hello");
|
||||||
|
|
||||||
# undef DO_TEST
|
# undef DO_TEST
|
||||||
|
|
||||||
VIR_FREE(custom_uri);
|
VIR_FREE(custom_uri);
|
||||||
|
@ -138,7 +138,8 @@ typedef enum {
|
|||||||
VSH_OT_STRING, /* optional string option */
|
VSH_OT_STRING, /* optional string option */
|
||||||
VSH_OT_INT, /* optional or mandatory int option */
|
VSH_OT_INT, /* optional or mandatory int option */
|
||||||
VSH_OT_DATA, /* string data (as non-option) */
|
VSH_OT_DATA, /* string data (as non-option) */
|
||||||
VSH_OT_ARGV /* remaining arguments */
|
VSH_OT_ARGV, /* remaining arguments */
|
||||||
|
VSH_OT_ALIAS, /* alternate spelling for a later argument */
|
||||||
} vshCmdOptType;
|
} vshCmdOptType;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -190,7 +191,8 @@ typedef struct {
|
|||||||
const char *name; /* the name of option, or NULL for list end */
|
const char *name; /* the name of option, or NULL for list end */
|
||||||
vshCmdOptType type; /* option type */
|
vshCmdOptType type; /* option type */
|
||||||
unsigned int flags; /* flags */
|
unsigned int flags; /* flags */
|
||||||
const char *help; /* non-NULL help string */
|
const char *help; /* non-NULL help string; or for VSH_OT_ALIAS
|
||||||
|
* the name of a later public option */
|
||||||
} vshCmdOptDef;
|
} vshCmdOptDef;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -15363,6 +15365,7 @@ static const vshCmdInfo info_echo[] = {
|
|||||||
static const vshCmdOptDef opts_echo[] = {
|
static const vshCmdOptDef opts_echo[] = {
|
||||||
{"shell", VSH_OT_BOOL, 0, N_("escape for shell use")},
|
{"shell", VSH_OT_BOOL, 0, N_("escape for shell use")},
|
||||||
{"xml", VSH_OT_BOOL, 0, N_("escape for XML use")},
|
{"xml", VSH_OT_BOOL, 0, N_("escape for XML use")},
|
||||||
|
{"str", VSH_OT_ALIAS, 0, "string"},
|
||||||
{"string", VSH_OT_ARGV, 0, N_("arguments to echo")},
|
{"string", VSH_OT_ARGV, 0, N_("arguments to echo")},
|
||||||
{NULL, 0, 0, NULL}
|
{NULL, 0, 0, NULL}
|
||||||
};
|
};
|
||||||
@ -17411,6 +17414,18 @@ vshCmddefOptParse(const vshCmdDef *cmd, uint32_t *opts_need_arg,
|
|||||||
return -1; /* bool options can't be mandatory */
|
return -1; /* bool options can't be mandatory */
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (opt->type == VSH_OT_ALIAS) {
|
||||||
|
int j;
|
||||||
|
if (opt->flags || !opt->help)
|
||||||
|
return -1; /* alias options are tracked by the original name */
|
||||||
|
for (j = i + 1; cmd->opts[j].name; j++) {
|
||||||
|
if (STREQ(opt->help, cmd->opts[j].name))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!cmd->opts[j].name)
|
||||||
|
return -1; /* alias option must map to a later option name */
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (opt->flags & VSH_OFLAG_REQ_OPT) {
|
if (opt->flags & VSH_OFLAG_REQ_OPT) {
|
||||||
if (opt->flags & VSH_OFLAG_REQ)
|
if (opt->flags & VSH_OFLAG_REQ)
|
||||||
*opts_required |= 1 << i;
|
*opts_required |= 1 << i;
|
||||||
@ -17442,6 +17457,10 @@ vshCmddefGetOption(vshControl *ctl, const vshCmdDef *cmd, const char *name,
|
|||||||
const vshCmdOptDef *opt = &cmd->opts[i];
|
const vshCmdOptDef *opt = &cmd->opts[i];
|
||||||
|
|
||||||
if (STREQ(opt->name, name)) {
|
if (STREQ(opt->name, name)) {
|
||||||
|
if (opt->type == VSH_OT_ALIAS) {
|
||||||
|
name = opt->help;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if ((*opts_seen & (1 << i)) && opt->type != VSH_OT_ARGV) {
|
if ((*opts_seen & (1 << i)) && opt->type != VSH_OT_ARGV) {
|
||||||
vshError(ctl, _("option --%s already seen"), name);
|
vshError(ctl, _("option --%s already seen"), name);
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -17620,6 +17639,9 @@ vshCmddefHelp(vshControl *ctl, const char *cmdname)
|
|||||||
: _("[<%s>]...");
|
: _("[<%s>]...");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case VSH_OT_ALIAS:
|
||||||
|
/* aliases are intentionally undocumented */
|
||||||
|
continue;
|
||||||
default:
|
default:
|
||||||
assert(0);
|
assert(0);
|
||||||
}
|
}
|
||||||
@ -17661,6 +17683,8 @@ vshCmddefHelp(vshControl *ctl, const char *cmdname)
|
|||||||
shortopt ? _("[--%s] <string>") : _("<%s>"),
|
shortopt ? _("[--%s] <string>") : _("<%s>"),
|
||||||
opt->name);
|
opt->name);
|
||||||
break;
|
break;
|
||||||
|
case VSH_OT_ALIAS:
|
||||||
|
continue;
|
||||||
default:
|
default:
|
||||||
assert(0);
|
assert(0);
|
||||||
}
|
}
|
||||||
|
@ -115,6 +115,12 @@ program returned, may not mean the action is complete and you
|
|||||||
must poll periodically to detect that the guest completed the
|
must poll periodically to detect that the guest completed the
|
||||||
operation.
|
operation.
|
||||||
|
|
||||||
|
B<virsh> strives for backward compatibility. Although the B<help>
|
||||||
|
command only lists the preferred usage of a command, if an older
|
||||||
|
version of B<virsh> supported an alternate spelling of a command or
|
||||||
|
option (such as I<--tunnelled> instead of I<--tunneled>), then
|
||||||
|
scripts using that older spelling will continue to work.
|
||||||
|
|
||||||
=head1 GENERIC COMMANDS
|
=head1 GENERIC COMMANDS
|
||||||
|
|
||||||
The following commands are generic i.e. not specific to a domain.
|
The following commands are generic i.e. not specific to a domain.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user