hw: Don't call visit_end_struct() after visit_start_struct() fails
[qemu/ar7.git] / qapi / qapi-visit-core.c
blobffd76372d1fd69855a1425b76e154a40ab75260c
1 /*
2 * Core Definitions for QAPI Visitor Classes
4 * Copyright IBM, Corp. 2011
6 * Authors:
7 * Anthony Liguori <aliguori@us.ibm.com>
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.
14 #include "qemu-common.h"
15 #include "qapi/qmp/qobject.h"
16 #include "qapi/qmp/qerror.h"
17 #include "qapi/visitor.h"
18 #include "qapi/visitor-impl.h"
20 void visit_start_struct(Visitor *v, void **obj, const char *kind,
21 const char *name, size_t size, Error **errp)
23 if (!error_is_set(errp)) {
24 v->start_struct(v, obj, kind, name, size, errp);
28 void visit_end_struct(Visitor *v, Error **errp)
30 assert(!error_is_set(errp));
31 v->end_struct(v, errp);
34 void visit_start_implicit_struct(Visitor *v, void **obj, size_t size,
35 Error **errp)
37 if (!error_is_set(errp) && v->start_implicit_struct) {
38 v->start_implicit_struct(v, obj, size, errp);
42 void visit_end_implicit_struct(Visitor *v, Error **errp)
44 assert(!error_is_set(errp));
45 if (v->end_implicit_struct) {
46 v->end_implicit_struct(v, errp);
50 void visit_start_list(Visitor *v, const char *name, Error **errp)
52 if (!error_is_set(errp)) {
53 v->start_list(v, name, errp);
57 GenericList *visit_next_list(Visitor *v, GenericList **list, Error **errp)
59 if (!error_is_set(errp)) {
60 return v->next_list(v, list, errp);
63 return 0;
66 void visit_end_list(Visitor *v, Error **errp)
68 assert(!error_is_set(errp));
69 v->end_list(v, errp);
72 void visit_optional(Visitor *v, bool *present, const char *name,
73 Error **errp)
75 if (!error_is_set(errp) && v->optional) {
76 v->optional(v, present, name, errp);
80 void visit_get_next_type(Visitor *v, int *obj, const int *qtypes,
81 const char *name, Error **errp)
83 if (!error_is_set(errp) && v->get_next_type) {
84 v->get_next_type(v, obj, qtypes, name, errp);
88 void visit_type_enum(Visitor *v, int *obj, const char *strings[],
89 const char *kind, const char *name, Error **errp)
91 if (!error_is_set(errp)) {
92 v->type_enum(v, obj, strings, kind, name, errp);
96 void visit_type_int(Visitor *v, int64_t *obj, const char *name, Error **errp)
98 if (!error_is_set(errp)) {
99 v->type_int(v, obj, name, errp);
103 void visit_type_uint8(Visitor *v, uint8_t *obj, const char *name, Error **errp)
105 int64_t value;
106 if (!error_is_set(errp)) {
107 if (v->type_uint8) {
108 v->type_uint8(v, obj, name, errp);
109 } else {
110 value = *obj;
111 v->type_int(v, &value, name, errp);
112 if (value < 0 || value > UINT8_MAX) {
113 error_set(errp, QERR_INVALID_PARAMETER_VALUE, name ? name : "null",
114 "uint8_t");
115 return;
117 *obj = value;
122 void visit_type_uint16(Visitor *v, uint16_t *obj, const char *name, Error **errp)
124 int64_t value;
125 if (!error_is_set(errp)) {
126 if (v->type_uint16) {
127 v->type_uint16(v, obj, name, errp);
128 } else {
129 value = *obj;
130 v->type_int(v, &value, name, errp);
131 if (value < 0 || value > UINT16_MAX) {
132 error_set(errp, QERR_INVALID_PARAMETER_VALUE, name ? name : "null",
133 "uint16_t");
134 return;
136 *obj = value;
141 void visit_type_uint32(Visitor *v, uint32_t *obj, const char *name, Error **errp)
143 int64_t value;
144 if (!error_is_set(errp)) {
145 if (v->type_uint32) {
146 v->type_uint32(v, obj, name, errp);
147 } else {
148 value = *obj;
149 v->type_int(v, &value, name, errp);
150 if (value < 0 || value > UINT32_MAX) {
151 error_set(errp, QERR_INVALID_PARAMETER_VALUE, name ? name : "null",
152 "uint32_t");
153 return;
155 *obj = value;
160 void visit_type_uint64(Visitor *v, uint64_t *obj, const char *name, Error **errp)
162 int64_t value;
163 if (!error_is_set(errp)) {
164 if (v->type_uint64) {
165 v->type_uint64(v, obj, name, errp);
166 } else {
167 value = *obj;
168 v->type_int(v, &value, name, errp);
169 *obj = value;
174 void visit_type_int8(Visitor *v, int8_t *obj, const char *name, Error **errp)
176 int64_t value;
177 if (!error_is_set(errp)) {
178 if (v->type_int8) {
179 v->type_int8(v, obj, name, errp);
180 } else {
181 value = *obj;
182 v->type_int(v, &value, name, errp);
183 if (value < INT8_MIN || value > INT8_MAX) {
184 error_set(errp, QERR_INVALID_PARAMETER_VALUE, name ? name : "null",
185 "int8_t");
186 return;
188 *obj = value;
193 void visit_type_int16(Visitor *v, int16_t *obj, const char *name, Error **errp)
195 int64_t value;
196 if (!error_is_set(errp)) {
197 if (v->type_int16) {
198 v->type_int16(v, obj, name, errp);
199 } else {
200 value = *obj;
201 v->type_int(v, &value, name, errp);
202 if (value < INT16_MIN || value > INT16_MAX) {
203 error_set(errp, QERR_INVALID_PARAMETER_VALUE, name ? name : "null",
204 "int16_t");
205 return;
207 *obj = value;
212 void visit_type_int32(Visitor *v, int32_t *obj, const char *name, Error **errp)
214 int64_t value;
215 if (!error_is_set(errp)) {
216 if (v->type_int32) {
217 v->type_int32(v, obj, name, errp);
218 } else {
219 value = *obj;
220 v->type_int(v, &value, name, errp);
221 if (value < INT32_MIN || value > INT32_MAX) {
222 error_set(errp, QERR_INVALID_PARAMETER_VALUE, name ? name : "null",
223 "int32_t");
224 return;
226 *obj = value;
231 void visit_type_int64(Visitor *v, int64_t *obj, const char *name, Error **errp)
233 if (!error_is_set(errp)) {
234 if (v->type_int64) {
235 v->type_int64(v, obj, name, errp);
236 } else {
237 v->type_int(v, obj, name, errp);
242 void visit_type_size(Visitor *v, uint64_t *obj, const char *name, Error **errp)
244 int64_t value;
245 if (!error_is_set(errp)) {
246 if (v->type_size) {
247 v->type_size(v, obj, name, errp);
248 } else if (v->type_uint64) {
249 v->type_uint64(v, obj, name, errp);
250 } else {
251 value = *obj;
252 v->type_int(v, &value, name, errp);
253 *obj = value;
258 void visit_type_bool(Visitor *v, bool *obj, const char *name, Error **errp)
260 if (!error_is_set(errp)) {
261 v->type_bool(v, obj, name, errp);
265 void visit_type_str(Visitor *v, char **obj, const char *name, Error **errp)
267 if (!error_is_set(errp)) {
268 v->type_str(v, obj, name, errp);
272 void visit_type_number(Visitor *v, double *obj, const char *name, Error **errp)
274 if (!error_is_set(errp)) {
275 v->type_number(v, obj, name, errp);
279 void output_type_enum(Visitor *v, int *obj, const char *strings[],
280 const char *kind, const char *name,
281 Error **errp)
283 int i = 0;
284 int value = *obj;
285 char *enum_str;
287 assert(strings);
288 while (strings[i++] != NULL);
289 if (value < 0 || value >= i - 1) {
290 error_set(errp, QERR_INVALID_PARAMETER, name ? name : "null");
291 return;
294 enum_str = (char *)strings[value];
295 visit_type_str(v, &enum_str, name, errp);
298 void input_type_enum(Visitor *v, int *obj, const char *strings[],
299 const char *kind, const char *name,
300 Error **errp)
302 int64_t value = 0;
303 char *enum_str;
305 assert(strings);
307 visit_type_str(v, &enum_str, name, errp);
308 if (error_is_set(errp)) {
309 return;
312 while (strings[value] != NULL) {
313 if (strcmp(strings[value], enum_str) == 0) {
314 break;
316 value++;
319 if (strings[value] == NULL) {
320 error_set(errp, QERR_INVALID_PARAMETER, enum_str);
321 g_free(enum_str);
322 return;
325 g_free(enum_str);
326 *obj = value;