qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Luiz Capitulino <lcapitulino@redhat.com>
To: qemu-devel@nongnu.org
Cc: aliguori@us.ibm.com, kraxel@redhat.com
Subject: [Qemu-devel] [PATCH 4/9] Introduce QError
Date: Tue, 13 Oct 2009 13:57:01 -0300	[thread overview]
Message-ID: <1255453026-18637-5-git-send-email-lcapitulino@redhat.com> (raw)
In-Reply-To: <1255453026-18637-1-git-send-email-lcapitulino@redhat.com>

QError is a high-level data type that can be used to store error
information.

Before using it functions usually have to register a new error type,
this is done by adding a new entry in the qerror_type[] table with
the following error information:

1. Code, which should be added to enum QErrorCode first
2. Description, the general error cause
3. Prefix, usually subsystem's name
4. A print function

The prefix and print function are optional. If no print function is
specified the default one will be used, which prints the prefix
before printing the error description.

Note that the default function is very simple and a deep level of
data structure nesting has not been tested.

QError exports the following functions:

- qerror_new(): Create a new 'empty' QError
- qerror_from_va(): Create a new QError from the specified va_list
- qerror_print(): Print the specified QError

Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
---
 Makefile  |    2 +-
 qerror.c  |  189 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 qerror.h  |   47 +++++++++++++++
 qobject.h |    1 +
 4 files changed, 238 insertions(+), 1 deletions(-)
 create mode 100644 qerror.c
 create mode 100644 qerror.h

diff --git a/Makefile b/Makefile
index e60eb4b..1c1ee86 100644
--- a/Makefile
+++ b/Makefile
@@ -125,7 +125,7 @@ obj-y += buffered_file.o migration.o migration-tcp.o net.o qemu-sockets.o
 obj-y += qemu-char.o aio.o net-checksum.o savevm.o
 obj-y += msmouse.o ps2.o
 obj-y += qdev.o qdev-properties.o
-obj-y += qint.o qstring.o qdict.o qlist.o qmisc.o qemu-config.o
+obj-y += qint.o qstring.o qdict.o qlist.o qmisc.o qerror.o qemu-config.o
 
 obj-$(CONFIG_BRLAPI) += baum.o
 obj-$(CONFIG_WIN32) += tap-win32.o
diff --git a/qerror.c b/qerror.c
new file mode 100644
index 0000000..bbea770
--- /dev/null
+++ b/qerror.c
@@ -0,0 +1,189 @@
+/*
+ * QError: QEMU Error data-type.
+ *
+ * Copyright (C) 2009 Red Hat Inc.
+ *
+ * Authors:
+ *  Luiz Capitulino <lcapitulino@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.  See
+ * the COPYING file in the top-level directory.
+ */
+#include "sysemu.h"
+#include "qint.h"
+#include "qmisc.h"
+#include "qlist.h"
+#include "qerror.h"
+#include "qstring.h"
+#include "qemu-common.h"
+
+static void qerror_destroy_obj(QObject *obj);
+
+static const QType qerror_type = {
+    .code = QTYPE_QERROR,
+    .destroy = qerror_destroy_obj,
+};
+
+static QErrorTable qerror_table[] = {
+    {
+        .code   = QERR_UNKNOWN,
+        .desc   = "unknown error",
+    },
+};
+
+/**
+ * qerror_new(): Create a new QError
+ *
+ * Return strong reference.
+ */
+QError *qerror_new(void)
+{
+    QError *qerr;
+
+    qerr = qemu_mallocz(sizeof(*qerr));
+    QOBJECT_INIT(qerr, &qerror_type);
+
+    return qerr;
+}
+
+/*
+ * qerror_from_va(): Create a new QError from a va_list
+ *
+ * The specified format and va_list are used to build the specific
+ * error data object, which is stored in the 'data' member of QError.
+ *
+ * Return strong reference.
+ */
+QError *qerror_from_va(QErrorCode code, const char *fmt, va_list va)
+{
+    QError *qerr;
+
+    assert((code > 0) && (code < QERR_MAX));
+
+    qerr = qerror_new();
+    qerr->entry = &qerror_table[code];
+    if (fmt) {
+        qerr->data = qobject_from_va(fmt, va);
+        if (!qerr->data) {
+            qemu_free(qerr);
+            return NULL;
+        }
+    }
+
+    return qerr;
+}
+
+static int show_dict_sep;
+static int show_list_sep;
+static void qerror_qobject_print(const QObject *obj);
+
+static void print_qdict(const char *key, QObject *obj, void *opaque)
+{
+    if (show_dict_sep)
+        qemu_error(",");
+
+    qemu_error("%s=", key);
+    qerror_qobject_print(obj);
+
+    show_dict_sep = 1;
+}
+
+static void print_qlist(QObject *obj, void *opaque)
+{
+    if (show_list_sep)
+        qemu_error(",");
+
+    qerror_qobject_print(obj);
+
+    show_list_sep = 1;
+}
+
+static void qerror_qobject_print(const QObject *obj)
+{
+    if (!obj)
+        return;
+
+    switch (qobject_type(obj)) {
+        case QTYPE_QINT:
+            qemu_error("%" PRId64, qint_get_int(qobject_to_qint(obj)));
+            break;
+        case QTYPE_QSTRING:
+            qemu_error("%s", qstring_get_str(qobject_to_qstring(obj)));
+            break;
+        case QTYPE_QDICT:
+            show_dict_sep = 0;
+            qdict_iter(qobject_to_qdict(obj), print_qdict, NULL);
+            break;
+        case QTYPE_QLIST:
+            show_list_sep = 0;
+            qlist_iter(qobject_to_qlist(obj), print_qlist, NULL);
+            break;
+        default:
+            abort();
+            break;
+    }
+}
+
+/**
+ * qerror_default_print(): Standard function to print QError data
+ */
+static void qerror_default_print(const QError *qerror)
+{
+    const QErrorTable *entry = qerror->entry;
+
+    if (entry->prefix)
+        qemu_error("%s: ", entry->prefix);
+
+    qemu_error("%s", entry->desc);
+    if (qerror->data) {
+        qemu_error(": ");
+        qerror_qobject_print(qerror->data);
+    }
+
+    qemu_error("\n");
+}
+
+/**
+ * qerror_print(): Print QError data
+ *
+ * This function calls the user_print() callback associated
+ * with the error to print QError data in human readable
+ * format.
+ *
+ * If the error does not define a user_print() callback, the
+ * standard one will be called.
+ */
+void qerror_print(const QError *qerror)
+{
+    if (qerror->entry->user_print) {
+        qerror->entry->user_print(qerror);
+    } else {
+        qerror_default_print(qerror);
+    }
+}
+
+/**
+ * qobject_to_qerror(): Convert a QObject into a QError
+ */
+QError *qobject_to_qerror(const QObject *obj)
+{
+    if (qobject_type(obj) != QTYPE_QERROR) {
+        return NULL;
+    }
+
+    return container_of(obj, QError, base);
+}
+
+/**
+ * qerror_destroy_obj(): Free all memory allocated by a QError
+ */
+static void qerror_destroy_obj(QObject *obj)
+{
+    QError *qerr;
+
+    assert(obj != NULL);
+    qerr = qobject_to_qerror(obj);
+
+    qobject_decref(qerr->data);
+    qemu_free(qerr);
+}
diff --git a/qerror.h b/qerror.h
new file mode 100644
index 0000000..ed25ef1
--- /dev/null
+++ b/qerror.h
@@ -0,0 +1,47 @@
+/*
+ * QError header file.
+ *
+ * Copyright (C) 2009 Red Hat Inc.
+ *
+ * Authors:
+ *  Luiz Capitulino <lcapitulino@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.  See
+ * the COPYING file in the top-level directory.
+ */
+#ifndef QERROR_H
+#define QERROR_H
+
+#include <stdarg.h>
+#include "qobject.h"
+
+/*
+ * IMPORTANT: errors numbers must not change after they have been
+ * added here.
+ */
+typedef enum QErrorCode {
+    QERR_UNKNOWN,
+    QERR_MAX,
+} QErrorCode;
+
+struct QError;
+
+typedef struct QErrorTable {
+    QErrorCode code;
+    const char *prefix;
+    const char *desc;
+    void (*user_print)(const struct QError *qerror);
+} QErrorTable;
+
+typedef struct QError {
+    QObject_HEAD;
+    QObject *data; /* error specific data */
+    const QErrorTable *entry;
+} QError;
+
+QError *qerror_new(void);
+QError *qerror_from_va(QErrorCode code, const char *fmt, va_list va);
+QError *qobject_to_qerror(const QObject *obj);
+void qerror_print(const QError *qerror);
+
+#endif /* QERROR_H */
diff --git a/qobject.h b/qobject.h
index 4cc9287..484d4dd 100644
--- a/qobject.h
+++ b/qobject.h
@@ -41,6 +41,7 @@ typedef enum {
     QTYPE_QSTRING,
     QTYPE_QDICT,
     QTYPE_QLIST,
+    QTYPE_QERROR,
 } qtype_code;
 
 struct QObject;
-- 
1.6.5.rc3.8.g8ba5e

  parent reply	other threads:[~2009-10-13 16:57 UTC|newest]

Thread overview: 63+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-10-13 16:56 [Qemu-devel] [PATCH v0 0/9] QError Luiz Capitulino
2009-10-13 16:56 ` [Qemu-devel] [PATCH 1/9] QDict: Introduce qdict_iter() Luiz Capitulino
2009-10-13 16:56 ` [Qemu-devel] [PATCH 2/9] check-qdict: Add test for qdict_iter() Luiz Capitulino
2009-10-13 16:57 ` [Qemu-devel] [PATCH 3/9] qmisc: Introduce qobject_from_va() Luiz Capitulino
2009-10-13 21:52   ` Markus Armbruster
2009-10-14 13:40     ` Luiz Capitulino
2009-10-14 14:27       ` [Qemu-devel] " Paolo Bonzini
2009-10-13 16:57 ` Luiz Capitulino [this message]
2009-10-13 16:57 ` [Qemu-devel] [PATCH 5/9] monitor: QError support Luiz Capitulino
2009-10-13 21:59   ` Markus Armbruster
2009-10-14 13:14     ` [Qemu-devel] " Paolo Bonzini
2009-10-14 14:07       ` Markus Armbruster
2009-10-13 16:57 ` [Qemu-devel] [PATCH 6/9] QError: Add qdev not found error Luiz Capitulino
2009-10-14 23:02   ` Hollis Blanchard
2009-10-15 13:34     ` Luiz Capitulino
2009-10-15 17:16       ` Hollis Blanchard
2009-10-15 17:52         ` Luiz Capitulino
2009-10-15 18:13           ` Hollis Blanchard
2009-10-15 19:08             ` Luiz Capitulino
2009-10-15 20:13               ` Hollis Blanchard
2009-10-15 20:57                 ` Anthony Liguori
2009-10-15 21:18                   ` Hollis Blanchard
2009-10-15 21:27                     ` Anthony Liguori
2009-10-15 22:44                       ` Hollis Blanchard
2009-10-16  8:06                         ` [Qemu-devel] " Paolo Bonzini
2009-10-16 13:05                           ` Luiz Capitulino
2009-10-19 10:25                             ` Daniel P. Berrange
2009-10-19 12:28                               ` Luiz Capitulino
2009-10-19 12:42                                 ` Daniel P. Berrange
2009-10-16 13:39                           ` Anthony Liguori
2009-10-18  4:25                       ` [Qemu-devel] " Jamie Lokier
2009-10-18 12:17                         ` [Qemu-devel] " Paolo Bonzini
2009-10-19 16:50                           ` Hollis Blanchard
2009-10-19 21:16                             ` Paolo Bonzini
2009-10-16  7:30               ` [Qemu-devel] " Gerd Hoffmann
2009-10-16 12:39                 ` Luiz Capitulino
2009-10-16 13:34                   ` [Qemu-devel] " Paolo Bonzini
2009-10-16 13:37                 ` [Qemu-devel] " Anthony Liguori
2009-10-16 14:17                   ` Luiz Capitulino
2009-10-16 17:28                     ` [Qemu-devel] " Paolo Bonzini
2009-10-16 17:47                       ` Anthony Liguori
2009-10-16  8:02               ` Paolo Bonzini
2009-10-18  4:28                 ` Jamie Lokier
2009-10-18  4:34                   ` Jamie Lokier
2009-10-13 16:57 ` [Qemu-devel] [PATCH 7/9] qdev: Use QError for " Luiz Capitulino
2009-10-13 22:34   ` Markus Armbruster
2009-10-14 13:29     ` [Qemu-devel] " Paolo Bonzini
2009-10-14 16:42       ` Luiz Capitulino
2009-10-14 14:51     ` [Qemu-devel] " Luiz Capitulino
2009-10-19 10:12     ` Daniel P. Berrange
2009-10-19 10:40       ` Gerd Hoffmann
2009-10-19 10:47         ` Daniel P. Berrange
2009-10-19 11:22         ` [Qemu-devel] " Paolo Bonzini
2009-10-19 14:00       ` [Qemu-devel] " Anthony Liguori
2009-10-19 15:21         ` Daniel P. Berrange
2009-10-19 15:27           ` Anthony Liguori
2009-10-19 15:39             ` Daniel P. Berrange
2009-10-13 16:57 ` [Qemu-devel] [PATCH 8/9] QError: Add do_info_balloon() errors Luiz Capitulino
2009-10-13 16:57 ` [Qemu-devel] [PATCH 9/9] monitor: do_info_balloon(): use QError Luiz Capitulino
2009-10-15 19:24 ` [Qemu-devel] [PATCH v0 0/9] QError Anthony Liguori
2009-10-15 19:37   ` Luiz Capitulino
2009-10-19 13:13 ` Markus Armbruster
2009-10-19 14:11   ` Anthony Liguori

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=1255453026-18637-5-git-send-email-lcapitulino@redhat.com \
    --to=lcapitulino@redhat.com \
    --cc=aliguori@us.ibm.com \
    --cc=kraxel@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).