diff options
Diffstat (limited to 'contrib/qemu/qobject/qerror.c')
| -rw-r--r-- | contrib/qemu/qobject/qerror.c | 156 | 
1 files changed, 156 insertions, 0 deletions
diff --git a/contrib/qemu/qobject/qerror.c b/contrib/qemu/qobject/qerror.c new file mode 100644 index 00000000000..3aee1cf6a69 --- /dev/null +++ b/contrib/qemu/qobject/qerror.c @@ -0,0 +1,156 @@ +/* + * 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 "monitor/monitor.h" +#include "qapi/qmp/qjson.h" +#include "qapi/qmp/qerror.h" +#include "qemu-common.h" + +static void qerror_destroy_obj(QObject *obj); + +static const QType qerror_type = { +    .code = QTYPE_QERROR, +    .destroy = qerror_destroy_obj, +}; + +/** + * qerror_new(): Create a new QError + * + * Return strong reference. + */ +static QError *qerror_new(void) +{ +    QError *qerr; + +    qerr = g_malloc0(sizeof(*qerr)); +    QOBJECT_INIT(qerr, &qerror_type); + +    return qerr; +} + +/** + * qerror_from_info(): Create a new QError from error information + * + * Return strong reference. + */ +static QError *qerror_from_info(ErrorClass err_class, const char *fmt, +                                va_list *va) +{ +    QError *qerr; + +    qerr = qerror_new(); +    loc_save(&qerr->loc); + +    qerr->err_msg = g_strdup_vprintf(fmt, *va); +    qerr->err_class = err_class; + +    return qerr; +} + +/** + * qerror_human(): Format QError data into human-readable string. + */ +QString *qerror_human(const QError *qerror) +{ +    return qstring_from_str(qerror->err_msg); +} + +/** + * 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). + */ +static 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(ErrorClass eclass, const char *fmt, ...) +{ +    va_list va; +    QError *qerror; + +    va_start(va, fmt); +    qerror = qerror_from_info(eclass, fmt, &va); +    va_end(va); + +    if (monitor_cur_is_qmp()) { +        monitor_set_error(cur_mon, qerror); +    } else { +        qerror_print(qerror); +        QDECREF(qerror); +    } +} + +/* Evil... */ +struct Error +{ +    char *msg; +    ErrorClass err_class; +}; + +void qerror_report_err(Error *err) +{ +    QError *qerr; + +    qerr = qerror_new(); +    loc_save(&qerr->loc); +    qerr->err_msg = g_strdup(err->msg); +    qerr->err_class = err->err_class; + +    if (monitor_cur_is_qmp()) { +        monitor_set_error(cur_mon, qerr); +    } else { +        qerror_print(qerr); +        QDECREF(qerr); +    } +} + +void assert_no_error(Error *err) +{ +    if (err) { +        qerror_report_err(err); +        abort(); +    } +} + +/** + * qobject_to_qerror(): Convert a QObject into a QError + */ +static 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); + +    g_free(qerr->err_msg); +    g_free(qerr); +}  | 
