@@ -217,6 +217,32 @@ static int monitor_handler_ported(const mon_cmd_t *cmd)
return cmd->user_print != NULL;
}
+static void monitor_print_parsing_err(Monitor *mon, MonitorError *error)
+{
+ QDict *qdict;
+
+ if (!monitor_has_error(error))
+ return;
+
+ assert(qobject_type(error->data) == QTYPE_QDICT);
+ qdict = qobject_to_qdict(error->data);
+
+ /* Handle exceptions first */
+ if (qint_get_int(error->code) == MON_ERR_UNCMD) {
+ monitor_printf(mon, "%s: '%s'\n", qstring_get_str(error->desc),
+ qdict_get_str(qdict, "name"));
+ return;
+ }
+
+ /* standard format */
+ monitor_printf(mon, "%s: ", qdict_get_str(qdict, "name"));
+ monitor_printf(mon, "%s", qstring_get_str(error->desc));
+ if (qdict_haskey(qdict, "extra"))
+ monitor_printf(mon, " '%c'", (int) qdict_get_int(qdict, "extra"));
+
+ monitor_puts(mon, "\n");
+}
+
static int compare_cmd(const char *name, const char *list)
{
const char *p, *pstart;
@@ -2834,6 +2860,19 @@ static char *key_get_info(const char *type, char **key)
return ++p;
}
+static void monitor_parse_error(MonitorError *error, int code,
+ const char *cmdname, int extra)
+{
+ QDict *qdict;
+
+ qdict = qdict_new();
+ qdict_put(qdict, "name", qstring_from_str(cmdname));
+ if (extra != -1)
+ qdict_put(qdict, "extra", qint_from_int(extra));
+
+ monitor_error_set(error, code, QOBJECT(qdict), NULL);
+}
+
static int default_fmt_format = 'x';
static int default_fmt_size = 4;
@@ -2841,7 +2880,8 @@ static int default_fmt_size = 4;
static const mon_cmd_t *monitor_parse_command(Monitor *mon,
const char *cmdline,
- QDict *qdict)
+ QDict *qdict,
+ MonitorError *error)
{
const char *p, *typestr;
int c;
@@ -2866,7 +2906,7 @@ static const mon_cmd_t *monitor_parse_command(Monitor *mon,
}
if (cmd->name == NULL) {
- monitor_printf(mon, "unknown command: '%s'\n", cmdname);
+ monitor_parse_error(error, MON_ERR_UNCMD, cmdname, -1);
return NULL;
}
@@ -2883,7 +2923,7 @@ static const mon_cmd_t *monitor_parse_command(Monitor *mon,
case 'B':
case 's':
{
- int ret;
+ int err;
while (qemu_isspace(*p))
p++;
@@ -2894,21 +2934,20 @@ static const mon_cmd_t *monitor_parse_command(Monitor *mon,
break;
}
}
- ret = get_str(buf, sizeof(buf), &p);
- if (ret < 0) {
+ err = get_str(buf, sizeof(buf), &p);
+ if (err < 0) {
switch(c) {
case 'F':
- monitor_printf(mon, "%s: filename expected\n",
- cmdname);
+ err = MON_ERR_EXPFILE;
break;
case 'B':
- monitor_printf(mon, "%s: block device name expected\n",
- cmdname);
+ err = MON_ERR_EXPBLK;
break;
default:
- monitor_printf(mon, "%s: string expected\n", cmdname);
+ err = MON_ERR_EXPSTR;
break;
}
+ monitor_parse_error(error, err, cmdname, -1);
goto fail;
}
qdict_put(qdict, key, qstring_from_str(buf));
@@ -2966,8 +3005,7 @@ static const mon_cmd_t *monitor_parse_command(Monitor *mon,
}
next:
if (*p != '\0' && !qemu_isspace(*p)) {
- monitor_printf(mon, "invalid char in format: '%c'\n",
- *p);
+ monitor_parse_error(error, MON_ERR_INVCHAR, cmdname,*p);
goto fail;
}
if (format < 0)
@@ -3022,8 +3060,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, "integer is for 32-bit values\n");
+ monitor_parse_error(error, MON_ERR_INVINT, cmdname, -1);
goto fail;
}
qdict_put(qdict, key, qint_from_int(val));
@@ -3043,8 +3080,7 @@ static const mon_cmd_t *monitor_parse_command(Monitor *mon,
if (*p == '-') {
p++;
if (*p != c) {
- monitor_printf(mon, "%s: unsupported option -%c\n",
- cmdname, *p);
+ monitor_parse_error(error, MON_ERR_UNSOPT, cmdname, *p);
goto fail;
}
p++;
@@ -3055,7 +3091,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_parse_error(error, MON_ERR_UNTYPE, cmdname, c);
goto fail;
}
qemu_free(key);
@@ -3065,8 +3101,7 @@ static const mon_cmd_t *monitor_parse_command(Monitor *mon,
while (qemu_isspace(*p))
p++;
if (*p != '\0') {
- monitor_printf(mon, "%s: extraneous characters at the end of line\n",
- cmdname);
+ monitor_parse_error(error, MON_ERR_EXTCHAR, cmdname, -1);
goto fail;
}
@@ -3086,9 +3121,11 @@ static void monitor_handle_command(Monitor *mon, const char *cmdline)
qdict = qdict_new();
error = monitor_error_new();
- cmd = monitor_parse_command(mon, cmdline, qdict);
- if (!cmd)
+ cmd = monitor_parse_command(mon, cmdline, qdict, error);
+ if (!cmd) {
+ monitor_print_parsing_err(mon, error);
goto out;
+ }
qemu_errors_to_mon(mon);
This commit converts errors generated by monitor_parse_command() to use the new MonitorError style. The MonitorError used is setup by the newly introduced monitor_parse_error(). It allocates a QDict to store the command name which trigged the error and any 'extra information'. The error is printed by monitor_print_parsing_err(), it knows how to format the error message properly. As a result of this change errors are always returned and printed in only one place. Also, parsing error messages will the following standard format: <command-name>: <error-description> <extra-info> This is good, because current code does not have a defined "standard". There is a side effect though: some error messages will change. NOTE: Not all errors have been converted. Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com> --- monitor.c | 79 ++++++++++++++++++++++++++++++++++++++++++++---------------- 1 files changed, 58 insertions(+), 21 deletions(-)