Patchwork [05/14] monitor: Initial MonitorError usage

login
register
mail settings
Submitter Luiz Capitulino
Date Oct. 1, 2009, 3:50 p.m.
Message ID <1254412245-10452-6-git-send-email-lcapitulino@redhat.com>
Download mbox | patch
Permalink /patch/34739/
State Superseded
Headers show

Comments

Luiz Capitulino - Oct. 1, 2009, 3:50 p.m.
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(-)

Patch

diff --git a/monitor.c b/monitor.c
index 3f97926..2bfc592 100644
--- a/monitor.c
+++ b/monitor.c
@@ -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);