virt-admin: Tweak command parsing logic so that aliases point to new commands

Change the logic in a way, so that VSH_CMD_FLAG_ALIAS behaves similarly to
how VSH_OT_ALIAS for command options, i.e. there is no need for code duplication
for the alias and the aliased command structures. Along with that change,
switch any existing VSH_CMD_FLAG_ALIAS occurrences to this new format. Also,
since this patch introduces a new command structure element, adjust the
virsh-self-test test to make sure we won't ever miss to specify the '.alias'
member for an aliased command because doing that would lead to an internal
error.

Signed-off-by: Erik Skultety <eskultet@redhat.com>
This commit is contained in:
Erik Skultety 2016-09-07 17:30:48 +02:00
parent 73a2510feb
commit b9d8cadeaa
3 changed files with 24 additions and 10 deletions

View File

@ -986,10 +986,8 @@ const vshCmdDef nodedevCmds[] = {
.flags = 0 .flags = 0
}, },
{.name = "nodedev-dettach", {.name = "nodedev-dettach",
.handler = cmdNodeDeviceDetach, .flags = VSH_CMD_FLAG_ALIAS,
.opts = opts_node_device_detach, .alias = "nodedev-detach"
.info = info_node_device_detach,
.flags = VSH_CMD_FLAG_ALIAS
}, },
{.name = "nodedev-dumpxml", {.name = "nodedev-dumpxml",
.handler = cmdNodeDeviceDumpXML, .handler = cmdNodeDeviceDumpXML,

View File

@ -330,6 +330,13 @@ vshCmddefCheckInternals(const vshCmdDef *cmd)
size_t i; size_t i;
const char *help = NULL; const char *help = NULL;
/* in order to perform the validation resolve the alias first */
if (cmd->flags & VSH_CMD_FLAG_ALIAS) {
if (!cmd->alias)
return -1;
cmd = vshCmddefSearch(cmd->alias);
}
/* Each command has to provide a non-empty help string. */ /* Each command has to provide a non-empty help string. */
if (!(help = vshCmddefGetInfo(cmd, "help")) || !*help) if (!(help = vshCmddefGetInfo(cmd, "help")) || !*help)
return -1; return -1;
@ -1407,6 +1414,13 @@ vshCommandParse(vshControl *ctl, vshCommandParser *parser)
vshError(ctl, _("unknown command: '%s'"), tkdata); vshError(ctl, _("unknown command: '%s'"), tkdata);
goto syntaxError; /* ... or ignore this command only? */ goto syntaxError; /* ... or ignore this command only? */
} }
/* aliases need to be resolved to the actual commands */
if (cmd->flags & VSH_CMD_FLAG_ALIAS) {
VIR_FREE(tkdata);
tkdata = vshStrdup(ctl, cmd->alias);
cmd = vshCmddefSearch(tkdata);
}
if (vshCmddefOptParse(cmd, &opts_need_arg, if (vshCmddefOptParse(cmd, &opts_need_arg,
&opts_required) < 0) { &opts_required) < 0) {
vshError(ctl, vshError(ctl,
@ -2568,7 +2582,8 @@ vshReadlineCommandGenerator(const char *text, int state)
if (cmds[cmd_list_index].name) { if (cmds[cmd_list_index].name) {
while ((name = cmds[cmd_list_index].name)) { while ((name = cmds[cmd_list_index].name)) {
cmd_list_index++; if (cmds[cmd_list_index++].flags & VSH_CMD_FLAG_ALIAS)
continue;
if (STREQLEN(name, text, len)) if (STREQLEN(name, text, len))
return vshStrdup(NULL, name); return vshStrdup(NULL, name);
@ -2706,8 +2721,10 @@ vshReadlineParse(const char *text, int state)
if (!cmd) { if (!cmd) {
if (!(cmd = vshCmddefSearch(tkdata))) if (!(cmd = vshCmddefSearch(tkdata)))
goto error; goto error;
cmd_exists = true; if (cmd->flags & VSH_CMD_FLAG_ALIAS)
cmd = vshCmddefSearch(cmd->alias);
cmd_exists = true;
if (vshCmddefOptParse(cmd, &const_opts_need_arg, if (vshCmddefOptParse(cmd, &const_opts_need_arg,
&const_opts_required) < 0) &const_opts_required) < 0)
goto error; goto error;
@ -3351,9 +3368,6 @@ cmdSelfTest(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED)
for (grp = cmdGroups; grp->name; grp++) { for (grp = cmdGroups; grp->name; grp++) {
for (def = grp->commands; def->name; def++) { for (def = grp->commands; def->name; def++) {
if (def->flags & VSH_CMD_FLAG_ALIAS)
continue;
if (vshCmddefCheckInternals(def) < 0) if (vshCmddefCheckInternals(def) < 0)
return false; return false;
} }

View File

@ -179,6 +179,7 @@ struct _vshCmdDef {
const vshCmdOptDef *opts; /* definition of command options */ const vshCmdOptDef *opts; /* definition of command options */
const vshCmdInfo *info; /* details about command */ const vshCmdInfo *info; /* details about command */
unsigned int flags; /* bitwise OR of VSH_CMD_FLAG */ unsigned int flags; /* bitwise OR of VSH_CMD_FLAG */
const char *alias; /* name of the aliased command */
}; };
/* /*
@ -445,7 +446,8 @@ bool cmdSelfTest(vshControl *ctl, const vshCmd *cmd);
.handler = cmdSelfTest, \ .handler = cmdSelfTest, \
.opts = NULL, \ .opts = NULL, \
.info = info_selftest, \ .info = info_selftest, \
.flags = VSH_CMD_FLAG_NOCONNECT | VSH_CMD_FLAG_ALIAS \ .flags = VSH_CMD_FLAG_NOCONNECT | VSH_CMD_FLAG_ALIAS, \
.alias = "self-test" \
} }