Home | History | Annotate | Download | only in qobject
      1 /*
      2  * QError Module
      3  *
      4  * Copyright (C) 2009 Red Hat Inc.
      5  *
      6  * Authors:
      7  *  Luiz Capitulino <lcapitulino (at) redhat.com>
      8  *
      9  * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
     10  * See the COPYING.LIB file in the top-level directory.
     11  */
     12 
     13 #include "monitor/monitor.h"
     14 #include "qapi/qmp/qjson.h"
     15 #include "qapi/qmp/qerror.h"
     16 #include "qemu-common.h"
     17 
     18 static void qerror_destroy_obj(QObject *obj);
     19 
     20 static const QType qerror_type = {
     21     .code = QTYPE_QERROR,
     22     .destroy = qerror_destroy_obj,
     23 };
     24 
     25 /**
     26  * qerror_new(): Create a new QError
     27  *
     28  * Return strong reference.
     29  */
     30 static QError *qerror_new(void)
     31 {
     32     QError *qerr;
     33 
     34     qerr = g_malloc0(sizeof(*qerr));
     35     QOBJECT_INIT(qerr, &qerror_type);
     36 
     37     return qerr;
     38 }
     39 
     40 /**
     41  * qerror_from_info(): Create a new QError from error information
     42  *
     43  * Return strong reference.
     44  */
     45 static QError * GCC_FMT_ATTR(2, 0)
     46 qerror_from_info(ErrorClass err_class, const char *fmt, va_list *va)
     47 {
     48     QError *qerr;
     49 
     50     qerr = qerror_new();
     51     loc_save(&qerr->loc);
     52 
     53     qerr->err_msg = g_strdup_vprintf(fmt, *va);
     54     qerr->err_class = err_class;
     55 
     56     return qerr;
     57 }
     58 
     59 /**
     60  * qerror_human(): Format QError data into human-readable string.
     61  */
     62 QString *qerror_human(const QError *qerror)
     63 {
     64     return qstring_from_str(qerror->err_msg);
     65 }
     66 
     67 /**
     68  * qerror_print(): Print QError data
     69  *
     70  * This function will print the member 'desc' of the specified QError object,
     71  * it uses error_report() for this, so that the output is routed to the right
     72  * place (ie. stderr or Monitor's device).
     73  */
     74 static void qerror_print(QError *qerror)
     75 {
     76     QString *qstring = qerror_human(qerror);
     77     loc_push_restore(&qerror->loc);
     78     error_report("%s", qstring_get_str(qstring));
     79     loc_pop(&qerror->loc);
     80     QDECREF(qstring);
     81 }
     82 
     83 void qerror_report(ErrorClass eclass, const char *fmt, ...)
     84 {
     85     va_list va;
     86     QError *qerror;
     87 
     88     va_start(va, fmt);
     89     qerror = qerror_from_info(eclass, fmt, &va);
     90     va_end(va);
     91 
     92     if (monitor_cur_is_qmp()) {
     93         monitor_set_error(cur_mon, qerror);
     94     } else {
     95         qerror_print(qerror);
     96         QDECREF(qerror);
     97     }
     98 }
     99 
    100 /* Evil... */
    101 struct Error
    102 {
    103     char *msg;
    104     ErrorClass err_class;
    105 };
    106 
    107 void qerror_report_err(Error *err)
    108 {
    109     QError *qerr;
    110 
    111     qerr = qerror_new();
    112     loc_save(&qerr->loc);
    113     qerr->err_msg = g_strdup(err->msg);
    114     qerr->err_class = err->err_class;
    115 
    116     if (monitor_cur_is_qmp()) {
    117         monitor_set_error(cur_mon, qerr);
    118     } else {
    119         qerror_print(qerr);
    120         QDECREF(qerr);
    121     }
    122 }
    123 
    124 void assert_no_error(Error *err)
    125 {
    126     if (err) {
    127         qerror_report_err(err);
    128         abort();
    129     }
    130 }
    131 
    132 /**
    133  * qobject_to_qerror(): Convert a QObject into a QError
    134  */
    135 static QError *qobject_to_qerror(const QObject *obj)
    136 {
    137     if (qobject_type(obj) != QTYPE_QERROR) {
    138         return NULL;
    139     }
    140 
    141     return container_of(obj, QError, base);
    142 }
    143 
    144 /**
    145  * qerror_destroy_obj(): Free all memory allocated by a QError
    146  */
    147 static void qerror_destroy_obj(QObject *obj)
    148 {
    149     QError *qerr;
    150 
    151     assert(obj != NULL);
    152     qerr = qobject_to_qerror(obj);
    153 
    154     g_free(qerr->err_msg);
    155     g_free(qerr);
    156 }
    157