]>
Commit | Line | Data |
---|---|---|
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.h" | |
14 | #include "qjson.h" | |
15 | #include "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 *qerror_from_info(ErrorClass err_class, const char *fmt, | |
46 | 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 | } |