Merge remote-tracking branch 'remotes/kraxel/tags/pull-seabios-1.7.5.1-20141113-1...
[qemu.git] / qobject / qerror.c
1 /*
2 * QError Module
3 *
4 * Copyright (C) 2009 Red Hat Inc.
5 *
6 * Authors:
7 * Luiz Capitulino <lcapitulino@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 /**
125 * qobject_to_qerror(): Convert a QObject into a QError
126 */
127 static QError *qobject_to_qerror(const QObject *obj)
128 {
129 if (qobject_type(obj) != QTYPE_QERROR) {
130 return NULL;
131 }
132
133 return container_of(obj, QError, base);
134 }
135
136 /**
137 * qerror_destroy_obj(): Free all memory allocated by a QError
138 */
139 static void qerror_destroy_obj(QObject *obj)
140 {
141 QError *qerr;
142
143 assert(obj != NULL);
144 qerr = qobject_to_qerror(obj);
145
146 g_free(qerr->err_msg);
147 g_free(qerr);
148 }