From: Markus Armbruster <armbru@redhat.com>
To: qemu-devel@nongnu.org
Cc: Bandan Das <bsd@redhat.com>
Subject: [Qemu-devel] [PULL 04/24] monitor: cleanup parsing of cmd name and cmd arguments
Date: Mon, 22 Jun 2015 21:04:29 +0200 [thread overview]
Message-ID: <1434999889-849-5-git-send-email-armbru@redhat.com> (raw)
In-Reply-To: <1434999889-849-1-git-send-email-armbru@redhat.com>
From: Bandan Das <bsd@redhat.com>
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>
---
monitor.c | 96 +++++++++++++++++++++++++++++++++++++--------------------------
1 file changed, 56 insertions(+), 40 deletions(-)
diff --git a/monitor.c b/monitor.c
index 04e94e0..e29ac74 100644
--- a/monitor.c
+++ b/monitor.c
@@ -3634,39 +3634,32 @@ static const mon_cmd_t *qmp_find_cmd(const char *cmdname)
}
/*
- * Parse @cmdline according to command table @table.
- * If @cmdline is blank, return NULL.
- * If it can't be parsed, report to @mon, and return NULL.
- * Else, insert command arguments into @qdict, and return the command.
- * If a sub-command table exists, and if @cmdline contains an additional string
- * for a sub-command, this function will try to search the sub-command table.
- * If no additional string for a sub-command is present, this function will
- * return the command found in @table.
- * Do not assume the returned command points into @table! It doesn't
- * when the command is a sub-command.
+ * Parse command name from @cmdp according to command table @table.
+ * If blank, return NULL.
+ * Else, if no valid command can be found, report to @mon, and return
+ * NULL.
+ * Else, change @cmdp to point right behind the name, and return its
+ * command table entry.
+ * Do not assume the return value points into @table! It doesn't when
+ * the command is found in a sub-command table.
*/
static const mon_cmd_t *monitor_parse_command(Monitor *mon,
- const char *cmdline,
- int start,
- mon_cmd_t *table,
- QDict *qdict)
+ const char **cmdp,
+ mon_cmd_t *table)
{
- const char *p, *typestr;
- int c;
+ const char *p;
const mon_cmd_t *cmd;
char cmdname[256];
- char buf[1024];
- char *key;
/* extract the command name */
- p = get_command_name(cmdline + start, cmdname, sizeof(cmdname));
+ p = get_command_name(*cmdp, cmdname, sizeof(cmdname));
if (!p)
return NULL;
cmd = search_dispatch_table(table, cmdname);
if (!cmd) {
monitor_printf(mon, "unknown command: '%.*s'\n",
- (int)(p - cmdline), cmdline);
+ (int)(p - *cmdp), *cmdp);
return NULL;
}
@@ -3674,16 +3667,34 @@ static const mon_cmd_t *monitor_parse_command(Monitor *mon,
while (qemu_isspace(*p)) {
p++;
}
+
+ *cmdp = p;
/* search sub command */
- if (cmd->sub_table != NULL) {
- /* check if user set additional command */
- if (*p == '\0') {
- return cmd;
- }
- return monitor_parse_command(mon, cmdline, p - cmdline,
- cmd->sub_table, qdict);
+ if (cmd->sub_table != NULL && *p != '\0') {
+ return monitor_parse_command(mon, cmdp, cmd->sub_table);
}
+ return cmd;
+}
+
+/*
+ * 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 */
typestr = cmd->args_type;
for(;;) {
@@ -3713,14 +3724,14 @@ static const mon_cmd_t *monitor_parse_command(Monitor *mon,
switch(c) {
case 'F':
monitor_printf(mon, "%s: filename expected\n",
- cmdname);
+ cmd->name);
break;
case 'B':
monitor_printf(mon, "%s: block device name expected\n",
- cmdname);
+ cmd->name);
break;
default:
- monitor_printf(mon, "%s: string expected\n", cmdname);
+ monitor_printf(mon, "%s: string expected\n", cmd->name);
break;
}
goto fail;
@@ -3862,7 +3873,7 @@ static const mon_cmd_t *monitor_parse_command(Monitor *mon,
goto fail;
/* Check if 'i' is greater than 32-bit */
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");
goto fail;
} else if (c == 'M') {
@@ -3970,7 +3981,7 @@ static const mon_cmd_t *monitor_parse_command(Monitor *mon,
if(!is_valid_option(p, typestr)) {
monitor_printf(mon, "%s: unsupported option -%c\n",
- cmdname, *p);
+ cmd->name, *p);
goto fail;
} else {
skip_key = 1;
@@ -4004,7 +4015,7 @@ static const mon_cmd_t *monitor_parse_command(Monitor *mon,
len = strlen(p);
if (len <= 0) {
monitor_printf(mon, "%s: string expected\n",
- cmdname);
+ cmd->name);
break;
}
qdict_put(qdict, key, qstring_from_str(p));
@@ -4013,7 +4024,7 @@ static const mon_cmd_t *monitor_parse_command(Monitor *mon,
break;
default:
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;
}
g_free(key);
@@ -4024,13 +4035,14 @@ static const mon_cmd_t *monitor_parse_command(Monitor *mon,
p++;
if (*p != '\0') {
monitor_printf(mon, "%s: extraneous characters at the end of line\n",
- cmdname);
+ cmd->name);
goto fail;
}
- return cmd;
+ return qdict;
fail:
+ QDECREF(qdict);
g_free(key);
return NULL;
}
@@ -4050,13 +4062,17 @@ static void handle_hmp_command(Monitor *mon, const char *cmdline)
QDict *qdict;
const mon_cmd_t *cmd;
- qdict = qdict_new();
+ cmd = monitor_parse_command(mon, &cmdline, mon->cmd_table);
+ if (!cmd) {
+ return;
+ }
- cmd = monitor_parse_command(mon, cmdline, 0, mon->cmd_table, qdict);
- if (cmd) {
- cmd->mhandler.cmd(mon, qdict);
+ qdict = monitor_parse_arguments(mon, &cmdline, cmd);
+ if (!qdict) {
+ return;
}
+ cmd->mhandler.cmd(mon, qdict);
QDECREF(qdict);
}
--
1.9.3
next prev parent reply other threads:[~2015-06-22 19:05 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-06-22 19:04 [Qemu-devel] [PULL 00/24] Monitor patches Markus Armbruster
2015-06-22 19:04 ` [Qemu-devel] [PULL 01/24] qobject: Use 'bool' for qbool Markus Armbruster
2015-06-22 19:04 ` [Qemu-devel] [PULL 02/24] qobject: Use 'bool' inside qdict Markus Armbruster
2015-06-22 19:04 ` [Qemu-devel] [PULL 03/24] monitor: remove debug prints Markus Armbruster
2015-06-22 19:04 ` Markus Armbruster [this message]
2015-06-22 19:04 ` [Qemu-devel] [PULL 05/24] monitor: Point to "help" command on syntax error Markus Armbruster
2015-06-22 19:04 ` [Qemu-devel] [PULL 06/24] monitor: Fix failure path for "S" argument Markus Armbruster
2015-06-22 19:04 ` [Qemu-devel] [PULL 07/24] monitor: Split mon_get_cpu fn to remove ENV_GET_CPU Markus Armbruster
2015-06-22 19:04 ` [Qemu-devel] [PULL 08/24] disas: Remove uses of CPU env Markus Armbruster
2015-06-22 19:04 ` [Qemu-devel] [PULL 09/24] qdev-monitor: Stop error avalanche in qbus_find_recursive() Markus Armbruster
2015-06-22 19:04 ` [Qemu-devel] [PULL 10/24] qdev-monitor: Fix check for full bus Markus Armbruster
2015-06-22 19:04 ` [Qemu-devel] [PULL 11/24] qdev-monitor: Convert qbus_find() to Error Markus Armbruster
2015-06-22 19:04 ` [Qemu-devel] [PULL 12/24] qdev-monitor: Propagate errors through set_property() Markus Armbruster
2015-06-22 19:04 ` [Qemu-devel] [PULL 13/24] qdev-monitor: Propagate errors through qdev_device_add() Markus Armbruster
2015-06-22 19:04 ` [Qemu-devel] [PULL 14/24] QemuOpts: Wean off qerror_report_err() Markus Armbruster
2015-06-22 19:04 ` [Qemu-devel] [PULL 15/24] vl: Avoid qerror_report() outside QMP command handlers Markus Armbruster
2015-06-22 19:04 ` [Qemu-devel] [PULL 16/24] vl: Use error_report() for --display errors Markus Armbruster
2015-06-22 19:04 ` [Qemu-devel] [PULL 17/24] qerror: Eliminate QERR_DEVICE_NOT_FOUND Markus Armbruster
2015-06-22 19:04 ` [Qemu-devel] [PULL 18/24] qerror: Clean up QERR_ macros to expand into a single string Markus Armbruster
2015-06-22 19:04 ` [Qemu-devel] [PULL 19/24] tpm: Avoid qerror_report() outside QMP command handlers Markus Armbruster
2015-06-22 19:04 ` [Qemu-devel] [PULL 20/24] qmp: Wean off qerror_report() Markus Armbruster
2015-06-22 19:04 ` [Qemu-devel] [PULL 21/24] qerror: Finally unused, clean up Markus Armbruster
2015-06-22 19:04 ` [Qemu-devel] [PULL 22/24] qerror: Move #include out of qerror.h Markus Armbruster
2015-06-22 19:04 ` [Qemu-devel] [PULL 23/24] Include qapi/qmp/qerror.h exactly where needed Markus Armbruster
2015-06-22 19:04 ` [Qemu-devel] [PULL 24/24] Include monitor/monitor.h " Markus Armbruster
2015-06-23 12:32 ` [Qemu-devel] [PULL 00/24] Monitor patches Peter Maydell
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1434999889-849-5-git-send-email-armbru@redhat.com \
--to=armbru@redhat.com \
--cc=bsd@redhat.com \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).