Patchwork [04/11] qerror: split out the reporting bits of QError

login
register
mail settings
Submitter Anthony Liguori
Date March 11, 2011, 9 p.m.
Message ID <1299877249-13433-5-git-send-email-aliguori@us.ibm.com>
Download mbox | patch
Permalink /patch/86451/
State New
Headers show

Comments

Anthony Liguori - March 11, 2011, 9 p.m.
These make it very hard to compile QError outside of QEMU.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
Luiz Capitulino - March 14, 2011, 7:18 p.m.
On Fri, 11 Mar 2011 15:00:42 -0600
Anthony Liguori <aliguori@us.ibm.com> wrote:

> These make it very hard to compile QError outside of QEMU.

Why would someone do this?

> 
> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
> 
> diff --git a/Makefile.objs b/Makefile.objs
> index da31530..69f0383 100644
> --- a/Makefile.objs
> +++ b/Makefile.objs
> @@ -2,7 +2,7 @@
>  # QObject
>  qobject-obj-y = qint.o qstring.o qdict.o qlist.o qfloat.o qbool.o
>  qobject-obj-y += qjson.o json-lexer.o json-streamer.o json-parser.o
> -qobject-obj-y += qerror.o
> +qobject-obj-y += qerror.o qerror-report.o
>  
>  #######################################################################
>  # oslib-obj-y is code depending on the OS (win32 vs posix)
> diff --git a/qerror-report.c b/qerror-report.c
> new file mode 100644
> index 0000000..1ebb111
> --- /dev/null
> +++ b/qerror-report.c
> @@ -0,0 +1,131 @@
> +/*
> + * QError Module
> + *
> + * Copyright (C) 2009 Red Hat Inc.
> + *
> + * Authors:
> + *  Luiz Capitulino <lcapitulino@redhat.com>
> + *
> + * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
> + * See the COPYING.LIB file in the top-level directory.
> + */
> +
> +#include "qemu-common.h"
> +#include "qerror.h"
> +#include "monitor.h"
> +#include "qjson.h"
> +
> +static void GCC_FMT_ATTR(2, 3) qerror_abort(const QError *qerr,
> +                                            const char *fmt, ...)
> +{
> +    va_list ap;
> +
> +    fprintf(stderr, "qerror: bad call in function '%s':\n", qerr->func);
> +    fprintf(stderr, "qerror: -> ");
> +
> +    va_start(ap, fmt);
> +    vfprintf(stderr, fmt, ap);
> +    va_end(ap);
> +
> +    fprintf(stderr, "\nqerror: call at %s:%d\n", qerr->file, qerr->linenr);
> +    abort();
> +}
> +
> +static void GCC_FMT_ATTR(2, 0) qerror_set_data(QError *qerr,
> +                                               const char *fmt, va_list *va)
> +{
> +    QObject *obj;
> +
> +    obj = qobject_from_jsonv(fmt, va);
> +    if (!obj) {
> +        qerror_abort(qerr, "invalid format '%s'", fmt);
> +    }
> +    if (qobject_type(obj) != QTYPE_QDICT) {
> +        qerror_abort(qerr, "error format is not a QDict '%s'", fmt);
> +    }
> +
> +    qerr->error = qobject_to_qdict(obj);
> +
> +    obj = qdict_get(qerr->error, "class");
> +    if (!obj) {
> +        qerror_abort(qerr, "missing 'class' key in '%s'", fmt);
> +    }
> +    if (qobject_type(obj) != QTYPE_QSTRING) {
> +        qerror_abort(qerr, "'class' key value should be a QString");
> +    }
> +    
> +    obj = qdict_get(qerr->error, "data");
> +    if (!obj) {
> +        qerror_abort(qerr, "missing 'data' key in '%s'", fmt);
> +    }
> +    if (qobject_type(obj) != QTYPE_QDICT) {
> +        qerror_abort(qerr, "'data' key value should be a QDICT");
> +    }
> +}
> +
> +/**
> + * qerror_from_info(): Create a new QError from error information
> + *
> + * The information consists of:
> + *
> + * - file   the file name of where the error occurred
> + * - linenr the line number of where the error occurred
> + * - func   the function name of where the error occurred
> + * - fmt    JSON printf-like dictionary, there must exist keys 'class' and
> + *          'data'
> + * - va     va_list of all arguments specified by fmt
> + *
> + * Return strong reference.
> + */
> +QError *qerror_from_info(const char *file, int linenr, const char *func,
> +                         const char *fmt, va_list *va)
> +{
> +    QError *qerr;
> +
> +    qerr = qerror_new();
> +    loc_save(&qerr->loc);
> +    qerr->linenr = linenr;
> +    qerr->file = file;
> +    qerr->func = func;
> +
> +    if (!fmt) {
> +        qerror_abort(qerr, "QDict not specified");
> +    }
> +
> +    qerror_set_data(qerr, fmt, va);
> +    qerror_set_desc(qerr, fmt);
> +
> +    return qerr;
> +}
> +
> +/**
> + * qerror_print(): Print QError data
> + *
> + * This function will print the member 'desc' of the specified QError object,
> + * it uses error_report() for this, so that the output is routed to the right
> + * place (ie. stderr or Monitor's device).
> + */
> +void qerror_print(QError *qerror)
> +{
> +    QString *qstring = qerror_human(qerror);
> +    loc_push_restore(&qerror->loc);
> +    error_report("%s", qstring_get_str(qstring));
> +    loc_pop(&qerror->loc);
> +    QDECREF(qstring);
> +}
> +
> +void qerror_report_internal(const char *file, int linenr, const char *func,
> +                            const char *fmt, ...)
> +{
> +    va_list va;
> +    QError *qerror;
> +
> +    va_start(va, fmt);
> +    qerror = qerror_from_info(file, linenr, func, fmt, &va);
> +    va_end(va);
> +
> +    qerror_print(qerror);
> +    QDECREF(qerror);
> +}
> +
> +
> diff --git a/qerror.c b/qerror.c
> index 13d53c9..78d3884 100644
> --- a/qerror.c
> +++ b/qerror.c
> @@ -243,39 +243,7 @@ static void GCC_FMT_ATTR(2, 3) qerror_abort(const QError *qerr,
>      abort();
>  }
>  
> -static void GCC_FMT_ATTR(2, 0) qerror_set_data(QError *qerr,
> -                                               const char *fmt, va_list *va)
> -{
> -    QObject *obj;
> -
> -    obj = qobject_from_jsonv(fmt, va);
> -    if (!obj) {
> -        qerror_abort(qerr, "invalid format '%s'", fmt);
> -    }
> -    if (qobject_type(obj) != QTYPE_QDICT) {
> -        qerror_abort(qerr, "error format is not a QDict '%s'", fmt);
> -    }
> -
> -    qerr->error = qobject_to_qdict(obj);
> -
> -    obj = qdict_get(qerr->error, "class");
> -    if (!obj) {
> -        qerror_abort(qerr, "missing 'class' key in '%s'", fmt);
> -    }
> -    if (qobject_type(obj) != QTYPE_QSTRING) {
> -        qerror_abort(qerr, "'class' key value should be a QString");
> -    }
> -    
> -    obj = qdict_get(qerr->error, "data");
> -    if (!obj) {
> -        qerror_abort(qerr, "missing 'data' key in '%s'", fmt);
> -    }
> -    if (qobject_type(obj) != QTYPE_QDICT) {
> -        qerror_abort(qerr, "'data' key value should be a QDICT");
> -    }
> -}
> -
> -static void qerror_set_desc(QError *qerr, const char *fmt)
> +void qerror_set_desc(QError *qerr, const char *fmt)
>  {
>      int i;
>  
> @@ -291,41 +259,6 @@ static void qerror_set_desc(QError *qerr, const char *fmt)
>      qerror_abort(qerr, "error format '%s' not found", fmt);
>  }
>  
> -/**
> - * qerror_from_info(): Create a new QError from error information
> - *
> - * The information consists of:
> - *
> - * - file   the file name of where the error occurred
> - * - linenr the line number of where the error occurred
> - * - func   the function name of where the error occurred
> - * - fmt    JSON printf-like dictionary, there must exist keys 'class' and
> - *          'data'
> - * - va     va_list of all arguments specified by fmt
> - *
> - * Return strong reference.
> - */
> -QError *qerror_from_info(const char *file, int linenr, const char *func,
> -                         const char *fmt, va_list *va)
> -{
> -    QError *qerr;
> -
> -    qerr = qerror_new();
> -    loc_save(&qerr->loc);
> -    qerr->linenr = linenr;
> -    qerr->file = file;
> -    qerr->func = func;
> -
> -    if (!fmt) {
> -        qerror_abort(qerr, "QDict not specified");
> -    }
> -
> -    qerror_set_data(qerr, fmt, va);
> -    qerror_set_desc(qerr, fmt);
> -
> -    return qerr;
> -}
> -
>  static void parse_error(const QErrorStringTable *entry, int c)
>  {
>  #if 0
> @@ -441,40 +374,6 @@ QString *qerror_human(const QError *qerror)
>  }
>  
>  /**
> - * qerror_print(): Print QError data
> - *
> - * This function will print the member 'desc' of the specified QError object,
> - * it uses error_report() for this, so that the output is routed to the right
> - * place (ie. stderr or Monitor's device).
> - */
> -void qerror_print(QError *qerror)
> -{
> -    QString *qstring = qerror_human(qerror);
> -    loc_push_restore(&qerror->loc);
> -    error_report("%s", qstring_get_str(qstring));
> -    loc_pop(&qerror->loc);
> -    QDECREF(qstring);
> -}
> -
> -void qerror_report_internal(const char *file, int linenr, const char *func,
> -                            const char *fmt, ...)
> -{
> -    va_list va;
> -    QError *qerror;
> -
> -    va_start(va, fmt);
> -    qerror = qerror_from_info(file, linenr, func, fmt, &va);
> -    va_end(va);
> -
> -    if (monitor_cur_is_qmp()) {
> -        monitor_set_error(cur_mon, qerror);
> -    } else {
> -        qerror_print(qerror);
> -        QDECREF(qerror);
> -    }
> -}
> -
> -/**
>   * qobject_to_qerror(): Convert a QObject into a QError
>   */
>  QError *qobject_to_qerror(const QObject *obj)
> diff --git a/qerror.h b/qerror.h
> index fd63ee9..495d0a4 100644
> --- a/qerror.h
> +++ b/qerror.h
> @@ -43,6 +43,7 @@ void qerror_report_internal(const char *file, int linenr, const char *func,
>      qerror_report_internal(__FILE__, __LINE__, __func__, fmt, ## __VA_ARGS__)
>  QError *qobject_to_qerror(const QObject *obj);
>  QString *qerror_format(const char *fmt, QDict *error);
> +void qerror_set_desc(QError *qerr, const char *fmt);
>  
>  /*
>   * QError class list
Anthony Liguori - March 14, 2011, 7:24 p.m.
On 03/14/2011 02:18 PM, Luiz Capitulino wrote:
> On Fri, 11 Mar 2011 15:00:42 -0600
> Anthony Liguori<aliguori@us.ibm.com>  wrote:
>
>> These make it very hard to compile QError outside of QEMU.
> Why would someone do this?

libqmp

It's very nice to have client code that convert QMP errors to human 
readable strings.

Regards,

Anthony Liguori
Luiz Capitulino - March 14, 2011, 7:30 p.m.
On Mon, 14 Mar 2011 14:24:37 -0500
Anthony Liguori <aliguori@us.ibm.com> wrote:

> On 03/14/2011 02:18 PM, Luiz Capitulino wrote:
> > On Fri, 11 Mar 2011 15:00:42 -0600
> > Anthony Liguori<aliguori@us.ibm.com>  wrote:
> >
> >> These make it very hard to compile QError outside of QEMU.
> > Why would someone do this?
> 
> libqmp
> 
> It's very nice to have client code that convert QMP errors to human 
> readable strings.

Ok. I'm not sure if I would bother doing this kind of change in this
series (as it's mainly re-working internal stuff) but,  this has to be
explained in the log message then.
Anthony Liguori - March 14, 2011, 8:30 p.m.
On 03/14/2011 02:30 PM, Luiz Capitulino wrote:
>> libqmp
>>
>> It's very nice to have client code that convert QMP errors to human
>> readable strings.
> Ok. I'm not sure if I would bother doing this kind of change in this
> series (as it's mainly re-working internal stuff) but,  this has to be
> explained in the log message then.

I'll clarify in the log.

There's a lot of code in this series to merge.  I'll do my best to make 
review as easy as possible but I need a bit of flexibility in terms of 
merging some infrastructure bits first followed by the bits that use it.

Everything is already written.  I just didn't want to bombard the list 
with a 200 patch series.

Regards,

Anthony Liguori

Patch

diff --git a/Makefile.objs b/Makefile.objs
index da31530..69f0383 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -2,7 +2,7 @@ 
 # QObject
 qobject-obj-y = qint.o qstring.o qdict.o qlist.o qfloat.o qbool.o
 qobject-obj-y += qjson.o json-lexer.o json-streamer.o json-parser.o
-qobject-obj-y += qerror.o
+qobject-obj-y += qerror.o qerror-report.o
 
 #######################################################################
 # oslib-obj-y is code depending on the OS (win32 vs posix)
diff --git a/qerror-report.c b/qerror-report.c
new file mode 100644
index 0000000..1ebb111
--- /dev/null
+++ b/qerror-report.c
@@ -0,0 +1,131 @@ 
+/*
+ * QError Module
+ *
+ * Copyright (C) 2009 Red Hat Inc.
+ *
+ * Authors:
+ *  Luiz Capitulino <lcapitulino@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ */
+
+#include "qemu-common.h"
+#include "qerror.h"
+#include "monitor.h"
+#include "qjson.h"
+
+static void GCC_FMT_ATTR(2, 3) qerror_abort(const QError *qerr,
+                                            const char *fmt, ...)
+{
+    va_list ap;
+
+    fprintf(stderr, "qerror: bad call in function '%s':\n", qerr->func);
+    fprintf(stderr, "qerror: -> ");
+
+    va_start(ap, fmt);
+    vfprintf(stderr, fmt, ap);
+    va_end(ap);
+
+    fprintf(stderr, "\nqerror: call at %s:%d\n", qerr->file, qerr->linenr);
+    abort();
+}
+
+static void GCC_FMT_ATTR(2, 0) qerror_set_data(QError *qerr,
+                                               const char *fmt, va_list *va)
+{
+    QObject *obj;
+
+    obj = qobject_from_jsonv(fmt, va);
+    if (!obj) {
+        qerror_abort(qerr, "invalid format '%s'", fmt);
+    }
+    if (qobject_type(obj) != QTYPE_QDICT) {
+        qerror_abort(qerr, "error format is not a QDict '%s'", fmt);
+    }
+
+    qerr->error = qobject_to_qdict(obj);
+
+    obj = qdict_get(qerr->error, "class");
+    if (!obj) {
+        qerror_abort(qerr, "missing 'class' key in '%s'", fmt);
+    }
+    if (qobject_type(obj) != QTYPE_QSTRING) {
+        qerror_abort(qerr, "'class' key value should be a QString");
+    }
+    
+    obj = qdict_get(qerr->error, "data");
+    if (!obj) {
+        qerror_abort(qerr, "missing 'data' key in '%s'", fmt);
+    }
+    if (qobject_type(obj) != QTYPE_QDICT) {
+        qerror_abort(qerr, "'data' key value should be a QDICT");
+    }
+}
+
+/**
+ * qerror_from_info(): Create a new QError from error information
+ *
+ * The information consists of:
+ *
+ * - file   the file name of where the error occurred
+ * - linenr the line number of where the error occurred
+ * - func   the function name of where the error occurred
+ * - fmt    JSON printf-like dictionary, there must exist keys 'class' and
+ *          'data'
+ * - va     va_list of all arguments specified by fmt
+ *
+ * Return strong reference.
+ */
+QError *qerror_from_info(const char *file, int linenr, const char *func,
+                         const char *fmt, va_list *va)
+{
+    QError *qerr;
+
+    qerr = qerror_new();
+    loc_save(&qerr->loc);
+    qerr->linenr = linenr;
+    qerr->file = file;
+    qerr->func = func;
+
+    if (!fmt) {
+        qerror_abort(qerr, "QDict not specified");
+    }
+
+    qerror_set_data(qerr, fmt, va);
+    qerror_set_desc(qerr, fmt);
+
+    return qerr;
+}
+
+/**
+ * qerror_print(): Print QError data
+ *
+ * This function will print the member 'desc' of the specified QError object,
+ * it uses error_report() for this, so that the output is routed to the right
+ * place (ie. stderr or Monitor's device).
+ */
+void qerror_print(QError *qerror)
+{
+    QString *qstring = qerror_human(qerror);
+    loc_push_restore(&qerror->loc);
+    error_report("%s", qstring_get_str(qstring));
+    loc_pop(&qerror->loc);
+    QDECREF(qstring);
+}
+
+void qerror_report_internal(const char *file, int linenr, const char *func,
+                            const char *fmt, ...)
+{
+    va_list va;
+    QError *qerror;
+
+    va_start(va, fmt);
+    qerror = qerror_from_info(file, linenr, func, fmt, &va);
+    va_end(va);
+
+    qerror_print(qerror);
+    QDECREF(qerror);
+}
+
+
diff --git a/qerror.c b/qerror.c
index 13d53c9..78d3884 100644
--- a/qerror.c
+++ b/qerror.c
@@ -243,39 +243,7 @@  static void GCC_FMT_ATTR(2, 3) qerror_abort(const QError *qerr,
     abort();
 }
 
-static void GCC_FMT_ATTR(2, 0) qerror_set_data(QError *qerr,
-                                               const char *fmt, va_list *va)
-{
-    QObject *obj;
-
-    obj = qobject_from_jsonv(fmt, va);
-    if (!obj) {
-        qerror_abort(qerr, "invalid format '%s'", fmt);
-    }
-    if (qobject_type(obj) != QTYPE_QDICT) {
-        qerror_abort(qerr, "error format is not a QDict '%s'", fmt);
-    }
-
-    qerr->error = qobject_to_qdict(obj);
-
-    obj = qdict_get(qerr->error, "class");
-    if (!obj) {
-        qerror_abort(qerr, "missing 'class' key in '%s'", fmt);
-    }
-    if (qobject_type(obj) != QTYPE_QSTRING) {
-        qerror_abort(qerr, "'class' key value should be a QString");
-    }
-    
-    obj = qdict_get(qerr->error, "data");
-    if (!obj) {
-        qerror_abort(qerr, "missing 'data' key in '%s'", fmt);
-    }
-    if (qobject_type(obj) != QTYPE_QDICT) {
-        qerror_abort(qerr, "'data' key value should be a QDICT");
-    }
-}
-
-static void qerror_set_desc(QError *qerr, const char *fmt)
+void qerror_set_desc(QError *qerr, const char *fmt)
 {
     int i;
 
@@ -291,41 +259,6 @@  static void qerror_set_desc(QError *qerr, const char *fmt)
     qerror_abort(qerr, "error format '%s' not found", fmt);
 }
 
-/**
- * qerror_from_info(): Create a new QError from error information
- *
- * The information consists of:
- *
- * - file   the file name of where the error occurred
- * - linenr the line number of where the error occurred
- * - func   the function name of where the error occurred
- * - fmt    JSON printf-like dictionary, there must exist keys 'class' and
- *          'data'
- * - va     va_list of all arguments specified by fmt
- *
- * Return strong reference.
- */
-QError *qerror_from_info(const char *file, int linenr, const char *func,
-                         const char *fmt, va_list *va)
-{
-    QError *qerr;
-
-    qerr = qerror_new();
-    loc_save(&qerr->loc);
-    qerr->linenr = linenr;
-    qerr->file = file;
-    qerr->func = func;
-
-    if (!fmt) {
-        qerror_abort(qerr, "QDict not specified");
-    }
-
-    qerror_set_data(qerr, fmt, va);
-    qerror_set_desc(qerr, fmt);
-
-    return qerr;
-}
-
 static void parse_error(const QErrorStringTable *entry, int c)
 {
 #if 0
@@ -441,40 +374,6 @@  QString *qerror_human(const QError *qerror)
 }
 
 /**
- * qerror_print(): Print QError data
- *
- * This function will print the member 'desc' of the specified QError object,
- * it uses error_report() for this, so that the output is routed to the right
- * place (ie. stderr or Monitor's device).
- */
-void qerror_print(QError *qerror)
-{
-    QString *qstring = qerror_human(qerror);
-    loc_push_restore(&qerror->loc);
-    error_report("%s", qstring_get_str(qstring));
-    loc_pop(&qerror->loc);
-    QDECREF(qstring);
-}
-
-void qerror_report_internal(const char *file, int linenr, const char *func,
-                            const char *fmt, ...)
-{
-    va_list va;
-    QError *qerror;
-
-    va_start(va, fmt);
-    qerror = qerror_from_info(file, linenr, func, fmt, &va);
-    va_end(va);
-
-    if (monitor_cur_is_qmp()) {
-        monitor_set_error(cur_mon, qerror);
-    } else {
-        qerror_print(qerror);
-        QDECREF(qerror);
-    }
-}
-
-/**
  * qobject_to_qerror(): Convert a QObject into a QError
  */
 QError *qobject_to_qerror(const QObject *obj)
diff --git a/qerror.h b/qerror.h
index fd63ee9..495d0a4 100644
--- a/qerror.h
+++ b/qerror.h
@@ -43,6 +43,7 @@  void qerror_report_internal(const char *file, int linenr, const char *func,
     qerror_report_internal(__FILE__, __LINE__, __func__, fmt, ## __VA_ARGS__)
 QError *qobject_to_qerror(const QObject *obj);
 QString *qerror_format(const char *fmt, QDict *error);
+void qerror_set_desc(QError *qerr, const char *fmt);
 
 /*
  * QError class list