qemu/error.c
<<
>>
Prefs
   1/*
   2 * QEMU Error Objects
   3 *
   4 * Copyright IBM, Corp. 2011
   5 *
   6 * Authors:
   7 *  Anthony Liguori   <aliguori@us.ibm.com>
   8 *
   9 * This work is licensed under the terms of the GNU LGPL, version 2.  See
  10 * the COPYING.LIB file in the top-level directory.
  11 */
  12
  13#include "qemu-common.h"
  14#include "error.h"
  15#include "qjson.h"
  16#include "qdict.h"
  17#include "error_int.h"
  18#include "qerror.h"
  19
  20struct Error
  21{
  22    QDict *obj;
  23    const char *fmt;
  24    char *msg;
  25};
  26
  27void error_set(Error **errp, const char *fmt, ...)
  28{
  29    Error *err;
  30    va_list ap;
  31
  32    if (errp == NULL) {
  33        return;
  34    }
  35
  36    err = g_malloc0(sizeof(*err));
  37
  38    va_start(ap, fmt);
  39    err->obj = qobject_to_qdict(qobject_from_jsonv(fmt, &ap));
  40    va_end(ap);
  41    err->fmt = fmt;
  42
  43    *errp = err;
  44}
  45
  46Error *error_copy(const Error *err)
  47{
  48    Error *err_new;
  49
  50    err_new = g_malloc0(sizeof(*err));
  51    err_new->msg = g_strdup(err->msg);
  52    err_new->fmt = err->fmt;
  53    err_new->obj = err->obj;
  54    QINCREF(err_new->obj);
  55
  56    return err_new;
  57}
  58
  59bool error_is_set(Error **errp)
  60{
  61    return (errp && *errp);
  62}
  63
  64const char *error_get_pretty(Error *err)
  65{
  66    if (err->msg == NULL) {
  67        QString *str;
  68        str = qerror_format(err->fmt, err->obj);
  69        err->msg = g_strdup(qstring_get_str(str));
  70        QDECREF(str);
  71    }
  72
  73    return err->msg;
  74}
  75
  76const char *error_get_field(Error *err, const char *field)
  77{
  78    if (strcmp(field, "class") == 0) {
  79        return qdict_get_str(err->obj, field);
  80    } else {
  81        QDict *dict = qdict_get_qdict(err->obj, "data");
  82        return qdict_get_str(dict, field);
  83    }
  84}
  85
  86QDict *error_get_data(Error *err)
  87{
  88    QDict *data = qdict_get_qdict(err->obj, "data");
  89    QINCREF(data);
  90    return data;
  91}
  92
  93void error_set_field(Error *err, const char *field, const char *value)
  94{
  95    QDict *dict = qdict_get_qdict(err->obj, "data");
  96    qdict_put(dict, field, qstring_from_str(value));
  97}
  98
  99void error_free(Error *err)
 100{
 101    if (err) {
 102        QDECREF(err->obj);
 103        g_free(err->msg);
 104        g_free(err);
 105    }
 106}
 107
 108bool error_is_type(Error *err, const char *fmt)
 109{
 110    const char *error_class;
 111    char *ptr;
 112    char *end;
 113
 114    if (!err) {
 115        return false;
 116    }
 117
 118    ptr = strstr(fmt, "'class': '");
 119    assert(ptr != NULL);
 120    ptr += strlen("'class': '");
 121
 122    end = strchr(ptr, '\'');
 123    assert(end != NULL);
 124
 125    error_class = error_get_field(err, "class");
 126    if (strlen(error_class) != end - ptr) {
 127        return false;
 128    }
 129
 130    return strncmp(ptr, error_class, end - ptr) == 0;
 131}
 132
 133void error_propagate(Error **dst_err, Error *local_err)
 134{
 135    if (dst_err) {
 136        *dst_err = local_err;
 137    } else if (local_err) {
 138        error_free(local_err);
 139    }
 140}
 141
 142QObject *error_get_qobject(Error *err)
 143{
 144    QINCREF(err->obj);
 145    return QOBJECT(err->obj);
 146}
 147
 148void error_set_qobject(Error **errp, QObject *obj)
 149{
 150    Error *err;
 151    if (errp == NULL) {
 152        return;
 153    }
 154    err = g_malloc0(sizeof(*err));
 155    err->obj = qobject_to_qdict(obj);
 156    qobject_incref(obj);
 157
 158    *errp = err;
 159}
 160