From b9d8cadeaa4516444fff34f5bd6cea2f7572c289 Mon Sep 17 00:00:00 2001 From: Erik Skultety Date: Wed, 7 Sep 2016 17:30:48 +0200 Subject: [PATCH] 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 --- tools/virsh-nodedev.c | 6 ++---- tools/vsh.c | 24 +++++++++++++++++++----- tools/vsh.h | 4 +++- 3 files changed, 24 insertions(+), 10 deletions(-) diff --git a/tools/virsh-nodedev.c b/tools/virsh-nodedev.c index 321f15cb70..9446664e38 100644 --- a/tools/virsh-nodedev.c +++ b/tools/virsh-nodedev.c @@ -986,10 +986,8 @@ const vshCmdDef nodedevCmds[] = { .flags = 0 }, {.name = "nodedev-dettach", - .handler = cmdNodeDeviceDetach, - .opts = opts_node_device_detach, - .info = info_node_device_detach, - .flags = VSH_CMD_FLAG_ALIAS + .flags = VSH_CMD_FLAG_ALIAS, + .alias = "nodedev-detach" }, {.name = "nodedev-dumpxml", .handler = cmdNodeDeviceDumpXML, diff --git a/tools/vsh.c b/tools/vsh.c index 008d890443..041113f2b4 100644 --- a/tools/vsh.c +++ b/tools/vsh.c @@ -330,6 +330,13 @@ vshCmddefCheckInternals(const vshCmdDef *cmd) size_t i; 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. */ if (!(help = vshCmddefGetInfo(cmd, "help")) || !*help) return -1; @@ -1407,6 +1414,13 @@ vshCommandParse(vshControl *ctl, vshCommandParser *parser) vshError(ctl, _("unknown command: '%s'"), tkdata); 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, &opts_required) < 0) { vshError(ctl, @@ -2568,7 +2582,8 @@ vshReadlineCommandGenerator(const char *text, int state) if (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)) return vshStrdup(NULL, name); @@ -2706,8 +2721,10 @@ vshReadlineParse(const char *text, int state) if (!cmd) { if (!(cmd = vshCmddefSearch(tkdata))) 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, &const_opts_required) < 0) goto error; @@ -3351,9 +3368,6 @@ cmdSelfTest(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED) for (grp = cmdGroups; grp->name; grp++) { for (def = grp->commands; def->name; def++) { - if (def->flags & VSH_CMD_FLAG_ALIAS) - continue; - if (vshCmddefCheckInternals(def) < 0) return false; } diff --git a/tools/vsh.h b/tools/vsh.h index 7f0819118b..8f5d1a69f7 100644 --- a/tools/vsh.h +++ b/tools/vsh.h @@ -179,6 +179,7 @@ struct _vshCmdDef { const vshCmdOptDef *opts; /* definition of command options */ const vshCmdInfo *info; /* details about command */ 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, \ .opts = NULL, \ .info = info_selftest, \ - .flags = VSH_CMD_FLAG_NOCONNECT | VSH_CMD_FLAG_ALIAS \ + .flags = VSH_CMD_FLAG_NOCONNECT | VSH_CMD_FLAG_ALIAS, \ + .alias = "self-test" \ } -- GitLab