mirror of https://github.com/xqemu/xqemu.git
monitor: cleanup parsing of cmd name and cmd arguments
There's too much going on in monitor_parse_command(). Split up the arguments parsing bits into a separate function monitor_parse_arguments(). Let the original function check for command validity and sub-commands if any and return data (*cmd) that the newly introduced function can process and return a QDict. Also, pass a pointer to the cmdline to track current parser location. Suggested-by: Markus Armbruster <armbru@redhat.com> Signed-off-by: Bandan Das <bsd@redhat.com> Acked-by: Luiz Capitulino <lcapitulino@redhat.com> Signed-off-by: Markus Armbruster <armbru@redhat.com>
This commit is contained in:
parent
19f2db5c84
commit
ae50212ff7
98
monitor.c
98
monitor.c
|
@ -3634,39 +3634,32 @@ static const mon_cmd_t *qmp_find_cmd(const char *cmdname)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Parse @cmdline according to command table @table.
|
* Parse command name from @cmdp according to command table @table.
|
||||||
* If @cmdline is blank, return NULL.
|
* If blank, return NULL.
|
||||||
* If it can't be parsed, report to @mon, and return NULL.
|
* Else, if no valid command can be found, report to @mon, and return
|
||||||
* Else, insert command arguments into @qdict, and return the command.
|
* NULL.
|
||||||
* If a sub-command table exists, and if @cmdline contains an additional string
|
* Else, change @cmdp to point right behind the name, and return its
|
||||||
* for a sub-command, this function will try to search the sub-command table.
|
* command table entry.
|
||||||
* If no additional string for a sub-command is present, this function will
|
* Do not assume the return value points into @table! It doesn't when
|
||||||
* return the command found in @table.
|
* the command is found in a sub-command table.
|
||||||
* Do not assume the returned command points into @table! It doesn't
|
|
||||||
* when the command is a sub-command.
|
|
||||||
*/
|
*/
|
||||||
static const mon_cmd_t *monitor_parse_command(Monitor *mon,
|
static const mon_cmd_t *monitor_parse_command(Monitor *mon,
|
||||||
const char *cmdline,
|
const char **cmdp,
|
||||||
int start,
|
mon_cmd_t *table)
|
||||||
mon_cmd_t *table,
|
|
||||||
QDict *qdict)
|
|
||||||
{
|
{
|
||||||
const char *p, *typestr;
|
const char *p;
|
||||||
int c;
|
|
||||||
const mon_cmd_t *cmd;
|
const mon_cmd_t *cmd;
|
||||||
char cmdname[256];
|
char cmdname[256];
|
||||||
char buf[1024];
|
|
||||||
char *key;
|
|
||||||
|
|
||||||
/* extract the command name */
|
/* extract the command name */
|
||||||
p = get_command_name(cmdline + start, cmdname, sizeof(cmdname));
|
p = get_command_name(*cmdp, cmdname, sizeof(cmdname));
|
||||||
if (!p)
|
if (!p)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
cmd = search_dispatch_table(table, cmdname);
|
cmd = search_dispatch_table(table, cmdname);
|
||||||
if (!cmd) {
|
if (!cmd) {
|
||||||
monitor_printf(mon, "unknown command: '%.*s'\n",
|
monitor_printf(mon, "unknown command: '%.*s'\n",
|
||||||
(int)(p - cmdline), cmdline);
|
(int)(p - *cmdp), *cmdp);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3674,15 +3667,33 @@ static const mon_cmd_t *monitor_parse_command(Monitor *mon,
|
||||||
while (qemu_isspace(*p)) {
|
while (qemu_isspace(*p)) {
|
||||||
p++;
|
p++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
*cmdp = p;
|
||||||
/* search sub command */
|
/* search sub command */
|
||||||
if (cmd->sub_table != NULL) {
|
if (cmd->sub_table != NULL && *p != '\0') {
|
||||||
/* check if user set additional command */
|
return monitor_parse_command(mon, cmdp, cmd->sub_table);
|
||||||
if (*p == '\0') {
|
}
|
||||||
|
|
||||||
return cmd;
|
return cmd;
|
||||||
}
|
}
|
||||||
return monitor_parse_command(mon, cmdline, p - cmdline,
|
|
||||||
cmd->sub_table, qdict);
|
/*
|
||||||
}
|
* Parse arguments for @cmd.
|
||||||
|
* If it can't be parsed, report to @mon, and return NULL.
|
||||||
|
* Else, insert command arguments into a QDict, and return it.
|
||||||
|
* Note: On success, caller has to free the QDict structure.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static QDict *monitor_parse_arguments(Monitor *mon,
|
||||||
|
const char **endp,
|
||||||
|
const mon_cmd_t *cmd)
|
||||||
|
{
|
||||||
|
const char *typestr;
|
||||||
|
char *key;
|
||||||
|
int c;
|
||||||
|
const char *p = *endp;
|
||||||
|
char buf[1024];
|
||||||
|
QDict *qdict = qdict_new();
|
||||||
|
|
||||||
/* parse the parameters */
|
/* parse the parameters */
|
||||||
typestr = cmd->args_type;
|
typestr = cmd->args_type;
|
||||||
|
@ -3713,14 +3724,14 @@ static const mon_cmd_t *monitor_parse_command(Monitor *mon,
|
||||||
switch(c) {
|
switch(c) {
|
||||||
case 'F':
|
case 'F':
|
||||||
monitor_printf(mon, "%s: filename expected\n",
|
monitor_printf(mon, "%s: filename expected\n",
|
||||||
cmdname);
|
cmd->name);
|
||||||
break;
|
break;
|
||||||
case 'B':
|
case 'B':
|
||||||
monitor_printf(mon, "%s: block device name expected\n",
|
monitor_printf(mon, "%s: block device name expected\n",
|
||||||
cmdname);
|
cmd->name);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
monitor_printf(mon, "%s: string expected\n", cmdname);
|
monitor_printf(mon, "%s: string expected\n", cmd->name);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
goto fail;
|
goto fail;
|
||||||
|
@ -3862,7 +3873,7 @@ static const mon_cmd_t *monitor_parse_command(Monitor *mon,
|
||||||
goto fail;
|
goto fail;
|
||||||
/* Check if 'i' is greater than 32-bit */
|
/* Check if 'i' is greater than 32-bit */
|
||||||
if ((c == 'i') && ((val >> 32) & 0xffffffff)) {
|
if ((c == 'i') && ((val >> 32) & 0xffffffff)) {
|
||||||
monitor_printf(mon, "\'%s\' has failed: ", cmdname);
|
monitor_printf(mon, "\'%s\' has failed: ", cmd->name);
|
||||||
monitor_printf(mon, "integer is for 32-bit values\n");
|
monitor_printf(mon, "integer is for 32-bit values\n");
|
||||||
goto fail;
|
goto fail;
|
||||||
} else if (c == 'M') {
|
} else if (c == 'M') {
|
||||||
|
@ -3970,7 +3981,7 @@ static const mon_cmd_t *monitor_parse_command(Monitor *mon,
|
||||||
if(!is_valid_option(p, typestr)) {
|
if(!is_valid_option(p, typestr)) {
|
||||||
|
|
||||||
monitor_printf(mon, "%s: unsupported option -%c\n",
|
monitor_printf(mon, "%s: unsupported option -%c\n",
|
||||||
cmdname, *p);
|
cmd->name, *p);
|
||||||
goto fail;
|
goto fail;
|
||||||
} else {
|
} else {
|
||||||
skip_key = 1;
|
skip_key = 1;
|
||||||
|
@ -4004,7 +4015,7 @@ static const mon_cmd_t *monitor_parse_command(Monitor *mon,
|
||||||
len = strlen(p);
|
len = strlen(p);
|
||||||
if (len <= 0) {
|
if (len <= 0) {
|
||||||
monitor_printf(mon, "%s: string expected\n",
|
monitor_printf(mon, "%s: string expected\n",
|
||||||
cmdname);
|
cmd->name);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
qdict_put(qdict, key, qstring_from_str(p));
|
qdict_put(qdict, key, qstring_from_str(p));
|
||||||
|
@ -4013,7 +4024,7 @@ static const mon_cmd_t *monitor_parse_command(Monitor *mon,
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
bad_type:
|
bad_type:
|
||||||
monitor_printf(mon, "%s: unknown type '%c'\n", cmdname, c);
|
monitor_printf(mon, "%s: unknown type '%c'\n", cmd->name, c);
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
g_free(key);
|
g_free(key);
|
||||||
|
@ -4024,13 +4035,14 @@ static const mon_cmd_t *monitor_parse_command(Monitor *mon,
|
||||||
p++;
|
p++;
|
||||||
if (*p != '\0') {
|
if (*p != '\0') {
|
||||||
monitor_printf(mon, "%s: extraneous characters at the end of line\n",
|
monitor_printf(mon, "%s: extraneous characters at the end of line\n",
|
||||||
cmdname);
|
cmd->name);
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
return cmd;
|
return qdict;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
|
QDECREF(qdict);
|
||||||
g_free(key);
|
g_free(key);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -4050,13 +4062,17 @@ static void handle_hmp_command(Monitor *mon, const char *cmdline)
|
||||||
QDict *qdict;
|
QDict *qdict;
|
||||||
const mon_cmd_t *cmd;
|
const mon_cmd_t *cmd;
|
||||||
|
|
||||||
qdict = qdict_new();
|
cmd = monitor_parse_command(mon, &cmdline, mon->cmd_table);
|
||||||
|
if (!cmd) {
|
||||||
cmd = monitor_parse_command(mon, cmdline, 0, mon->cmd_table, qdict);
|
return;
|
||||||
if (cmd) {
|
|
||||||
cmd->mhandler.cmd(mon, qdict);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
qdict = monitor_parse_arguments(mon, &cmdline, cmd);
|
||||||
|
if (!qdict) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd->mhandler.cmd(mon, qdict);
|
||||||
QDECREF(qdict);
|
QDECREF(qdict);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue