From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:36923) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Yxkby-0000Zj-3Y for qemu-devel@nongnu.org; Wed, 27 May 2015 19:19:47 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Yxkbw-0007cS-R9 for qemu-devel@nongnu.org; Wed, 27 May 2015 19:19:46 -0400 Received: from mx1.redhat.com ([209.132.183.28]:58803) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Yxkbw-0007cO-Hj for qemu-devel@nongnu.org; Wed, 27 May 2015 19:19:44 -0400 Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) by mx1.redhat.com (Postfix) with ESMTPS id 4225F19F25D for ; Wed, 27 May 2015 23:19:44 +0000 (UTC) From: Bandan Das Date: Wed, 27 May 2015 19:19:13 -0400 Message-Id: <1432768754-28523-2-git-send-email-bsd@redhat.com> In-Reply-To: <1432768754-28523-1-git-send-email-bsd@redhat.com> References: <1432768754-28523-1-git-send-email-bsd@redhat.com> Subject: [Qemu-devel] [PATCH v3 1/2] monitor: cleanup parsing of cmd name and cmd arguments List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: armbru@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 Signed-off-by: Bandan Das --- monitor.c | 90 +++++++++++++++++++++++++++++++++++++-------------------------- 1 file changed, 53 insertions(+), 37 deletions(-) diff --git a/monitor.c b/monitor.c index b2561e1..521258d 100644 --- a/monitor.c +++ b/monitor.c @@ -3683,11 +3683,10 @@ 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 + * Parse cmdline anchored at @endp according to command table @table. + * If @*endp is blank, return NULL. + * If @*endp is invalid, report to @mon and return NULL. + * If a sub-command table exists, and if @*endp 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. @@ -3695,31 +3694,26 @@ static const mon_cmd_t *qmp_find_cmd(const char *cmdname) * when the command is a sub-command. */ static const mon_cmd_t *monitor_parse_command(Monitor *mon, - const char *cmdline, - int start, - mon_cmd_t *table, - QDict *qdict) + const char **endp, + 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; #ifdef DEBUG - monitor_printf(mon, "command='%s', start='%d'\n", cmdline, start); + monitor_printf(mon, "command='%s', start='%d'\n", cmdline, *start); #endif /* extract the command name */ - p = get_command_name(cmdline + start, cmdname, sizeof(cmdname)); + p = get_command_name(*endp, 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 - *endp), *endp); return NULL; } @@ -3727,16 +3721,33 @@ static const mon_cmd_t *monitor_parse_command(Monitor *mon, while (qemu_isspace(*p)) { p++; } + + *endp = 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, endp, cmd->sub_table); } + return cmd; +} + +/* + * Parse arguments for @cmd anchored at @endp + * If it can't be parsed, report to @mon, and return NULL. + * Else, insert command arguments into @qdict, and return it. + */ + +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(;;) { @@ -3766,14 +3777,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; @@ -3915,7 +3926,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') { @@ -4023,7 +4034,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; @@ -4057,7 +4068,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)); @@ -4066,7 +4077,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); @@ -4077,13 +4088,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; } @@ -4115,11 +4127,15 @@ static void handle_user_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) - goto out; + qdict = monitor_parse_arguments(mon, &cmdline, cmd); + if (!qdict) { + return; + } if (handler_is_async(cmd)) { user_async_cmd_handler(mon, cmd, qdict); @@ -4137,7 +4153,7 @@ static void handle_user_command(Monitor *mon, const char *cmdline) cmd->mhandler.cmd(mon, qdict); } -out: + /* Drop reference taken in monitor_parse_arguments */ QDECREF(qdict); } -- 2.1.0