mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-21 20:15:17 +00:00
virsh: better handling the boolean option
in old code the following commands are equivalent: virsh # dumpxml --update-cpu=vm1 virsh # dumpxml --update-cpu vm1 because the old code split the option argument into 2 parts: --update-cpu=vm1 is split into update-cpu and vm1, and update-cpu is a boolean option, so the parser takes vm1 as another argument, very strange. after this patch applied, the first one will become illegal. To achieve this, we don't parse/check options when parsing command sting, but check options when parsing a command argument. And the argument is not split when parsing command sting. Signed-off-by: Lai Jiangshan <laijs@cn.fujitsu.com>
This commit is contained in:
parent
cdfe543fc8
commit
4417f08de4
@ -10327,14 +10327,12 @@ vshCommandRun(vshControl *ctl, const vshCmd *cmd)
|
||||
*/
|
||||
#define VSH_TK_ERROR -1
|
||||
#define VSH_TK_NONE 0
|
||||
#define VSH_TK_OPTION 1
|
||||
#define VSH_TK_DATA 2
|
||||
#define VSH_TK_END 3
|
||||
#define VSH_TK_DATA 1
|
||||
#define VSH_TK_END 2
|
||||
|
||||
static int ATTRIBUTE_NONNULL(3) ATTRIBUTE_NONNULL(4)
|
||||
vshCommandGetToken(vshControl *ctl, char *str, char **end, char **res)
|
||||
{
|
||||
int tk = VSH_TK_NONE;
|
||||
bool double_quote = false;
|
||||
int sz = 0;
|
||||
char *p = str;
|
||||
@ -10358,22 +10356,6 @@ vshCommandGetToken(vshControl *ctl, char *str, char **end, char **res)
|
||||
if (!double_quote && (*p == ' ' || *p == '\t' || *p == ';'))
|
||||
break;
|
||||
|
||||
/* end of option name could be '=' */
|
||||
if (tk == VSH_TK_OPTION && *p == '=') {
|
||||
p++; /* skip '=' */
|
||||
break;
|
||||
}
|
||||
|
||||
if (tk == VSH_TK_NONE) {
|
||||
if (*p == '-' && *(p + 1) == '-' && *(p + 2)
|
||||
&& c_isalnum(*(p + 2))) {
|
||||
tk = VSH_TK_OPTION;
|
||||
p += 2;
|
||||
} else {
|
||||
tk = VSH_TK_DATA;
|
||||
}
|
||||
}
|
||||
|
||||
if (*p == '"') {
|
||||
double_quote = !double_quote;
|
||||
p++;
|
||||
@ -10390,7 +10372,7 @@ vshCommandGetToken(vshControl *ctl, char *str, char **end, char **res)
|
||||
|
||||
*q = '\0';
|
||||
*end = p;
|
||||
return tk;
|
||||
return VSH_TK_DATA;
|
||||
}
|
||||
|
||||
static int
|
||||
@ -10449,18 +10431,28 @@ vshCommandParse(vshControl *ctl, char *cmdstr)
|
||||
goto syntaxError; /* ... or ignore this command only? */
|
||||
}
|
||||
VIR_FREE(tkdata);
|
||||
} else if (tk == VSH_TK_OPTION) {
|
||||
if (!(opt = vshCmddefGetOption(cmd, tkdata))) {
|
||||
} else if (*tkdata == '-' && *(tkdata + 1) == '-' && *(tkdata + 2)
|
||||
&& c_isalnum(*(tkdata + 2))) {
|
||||
char *optstr = strchr(tkdata + 2, '=');
|
||||
if (optstr) {
|
||||
*optstr = '\0'; /* convert the '=' to '\0' */
|
||||
optstr = vshStrdup(ctl, optstr + 1);
|
||||
}
|
||||
if (!(opt = vshCmddefGetOption(cmd, tkdata + 2))) {
|
||||
vshError(ctl,
|
||||
_("command '%s' doesn't support option --%s"),
|
||||
cmd->name, tkdata);
|
||||
cmd->name, tkdata + 2);
|
||||
VIR_FREE(optstr);
|
||||
goto syntaxError;
|
||||
}
|
||||
VIR_FREE(tkdata); /* option name */
|
||||
VIR_FREE(tkdata);
|
||||
|
||||
if (opt->type != VSH_OT_BOOL) {
|
||||
/* option data */
|
||||
tk = vshCommandGetToken(ctl, str, &end, &tkdata);
|
||||
if (optstr)
|
||||
tkdata = optstr;
|
||||
else
|
||||
tk = vshCommandGetToken(ctl, str, &end, &tkdata);
|
||||
str = end;
|
||||
if (tk == VSH_TK_ERROR)
|
||||
goto syntaxError;
|
||||
@ -10472,6 +10464,14 @@ vshCommandParse(vshControl *ctl, char *cmdstr)
|
||||
VSH_OT_INT ? _("number") : _("string"));
|
||||
goto syntaxError;
|
||||
}
|
||||
} else {
|
||||
tkdata = NULL;
|
||||
if (optstr) {
|
||||
vshError(ctl, _("invalid '=' after option --%s"),
|
||||
opt->name);
|
||||
VIR_FREE(optstr);
|
||||
goto syntaxError;
|
||||
}
|
||||
}
|
||||
} else if (tk == VSH_TK_DATA) {
|
||||
if (!(opt = vshCmddefGetData(cmd, data_ct++))) {
|
||||
@ -10497,8 +10497,8 @@ vshCommandParse(vshControl *ctl, char *cmdstr)
|
||||
vshDebug(ctl, 4, "%s: %s(%s): %s\n",
|
||||
cmd->name,
|
||||
opt->name,
|
||||
tk == VSH_TK_OPTION ? _("OPTION") : _("DATA"),
|
||||
arg->data);
|
||||
opt->type != VSH_OT_BOOL ? _("optdata") : _("bool"),
|
||||
opt->type != VSH_OT_BOOL ? arg->data : _("(none)"));
|
||||
}
|
||||
if (!str)
|
||||
break;
|
||||
|
Loading…
x
Reference in New Issue
Block a user