xref: /qemu/qapi/qapi-visit-core.c (revision 91fa93e516d080d440ead2ad4f88960545bd5b2c)
12345c77cSMichael Roth /*
22345c77cSMichael Roth  * Core Definitions for QAPI Visitor Classes
32345c77cSMichael Roth  *
47c91aabdSEric Blake  * Copyright (C) 2012-2016 Red Hat, Inc.
52345c77cSMichael Roth  * Copyright IBM, Corp. 2011
62345c77cSMichael Roth  *
72345c77cSMichael Roth  * Authors:
82345c77cSMichael Roth  *  Anthony Liguori   <aliguori@us.ibm.com>
92345c77cSMichael Roth  *
102345c77cSMichael Roth  * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
112345c77cSMichael Roth  * See the COPYING.LIB file in the top-level directory.
122345c77cSMichael Roth  *
132345c77cSMichael Roth  */
142345c77cSMichael Roth 
15cbf21151SPeter Maydell #include "qemu/osdep.h"
16da34e65cSMarkus Armbruster #include "qapi/error.h"
177b1b5d19SPaolo Bonzini #include "qapi/qmp/qerror.h"
187b1b5d19SPaolo Bonzini #include "qapi/visitor.h"
197b1b5d19SPaolo Bonzini #include "qapi/visitor-impl.h"
20ebfd93b6SDaniel P. Berrange #include "trace.h"
212345c77cSMichael Roth 
223b098d56SEric Blake void visit_complete(Visitor *v, void *opaque)
233b098d56SEric Blake {
243b098d56SEric Blake     assert(v->type != VISITOR_OUTPUT || v->complete);
25ebfd93b6SDaniel P. Berrange     trace_visit_complete(v, opaque);
263b098d56SEric Blake     if (v->complete) {
273b098d56SEric Blake         v->complete(v, opaque);
283b098d56SEric Blake     }
293b098d56SEric Blake }
303b098d56SEric Blake 
312c0ef9f4SEric Blake void visit_free(Visitor *v)
322c0ef9f4SEric Blake {
33ebfd93b6SDaniel P. Berrange     trace_visit_free(v);
342c0ef9f4SEric Blake     if (v) {
352c0ef9f4SEric Blake         v->free(v);
362c0ef9f4SEric Blake     }
372c0ef9f4SEric Blake }
382c0ef9f4SEric Blake 
39012d4c96SMarkus Armbruster bool visit_start_struct(Visitor *v, const char *name, void **obj,
40337283dfSEric Blake                         size_t size, Error **errp)
412345c77cSMichael Roth {
427b3cb803SMarkus Armbruster     bool ok;
43e58d695eSEric Blake 
44ebfd93b6SDaniel P. Berrange     trace_visit_start_struct(v, name, obj, size);
45adfb264cSEric Blake     if (obj) {
46adfb264cSEric Blake         assert(size);
47a15fcc3cSEric Blake         assert(!(v->type & VISITOR_OUTPUT) || *obj);
48adfb264cSEric Blake     }
497b3cb803SMarkus Armbruster     ok = v->start_struct(v, name, obj, size, errp);
50a15fcc3cSEric Blake     if (obj && (v->type & VISITOR_INPUT)) {
517b3cb803SMarkus Armbruster         assert(ok != !*obj);
52e58d695eSEric Blake     }
537b3cb803SMarkus Armbruster     return ok;
542345c77cSMichael Roth }
552345c77cSMichael Roth 
56012d4c96SMarkus Armbruster bool visit_check_struct(Visitor *v, Error **errp)
572345c77cSMichael Roth {
58ebfd93b6SDaniel P. Berrange     trace_visit_check_struct(v);
59012d4c96SMarkus Armbruster     return v->check_struct ? v->check_struct(v, errp) : true;
6015c2f669SEric Blake }
6115c2f669SEric Blake 
621158bb2aSEric Blake void visit_end_struct(Visitor *v, void **obj)
6315c2f669SEric Blake {
64ebfd93b6SDaniel P. Berrange     trace_visit_end_struct(v, obj);
651158bb2aSEric Blake     v->end_struct(v, obj);
662345c77cSMichael Roth }
672345c77cSMichael Roth 
68012d4c96SMarkus Armbruster bool visit_start_list(Visitor *v, const char *name, GenericList **list,
69d9f62ddeSEric Blake                       size_t size, Error **errp)
702345c77cSMichael Roth {
717b3cb803SMarkus Armbruster     bool ok;
72d9f62ddeSEric Blake 
73d9f62ddeSEric Blake     assert(!list || size >= sizeof(GenericList));
74ebfd93b6SDaniel P. Berrange     trace_visit_start_list(v, name, list, size);
757b3cb803SMarkus Armbruster     ok = v->start_list(v, name, list, size, errp);
76a15fcc3cSEric Blake     if (list && (v->type & VISITOR_INPUT)) {
777b3cb803SMarkus Armbruster         assert(ok || !*list);
78d9f62ddeSEric Blake     }
797b3cb803SMarkus Armbruster     return ok;
802345c77cSMichael Roth }
812345c77cSMichael Roth 
82d9f62ddeSEric Blake GenericList *visit_next_list(Visitor *v, GenericList *tail, size_t size)
832345c77cSMichael Roth {
84d9f62ddeSEric Blake     assert(tail && size >= sizeof(GenericList));
85ebfd93b6SDaniel P. Berrange     trace_visit_next_list(v, tail, size);
86d9f62ddeSEric Blake     return v->next_list(v, tail, size);
872345c77cSMichael Roth }
882345c77cSMichael Roth 
89012d4c96SMarkus Armbruster bool visit_check_list(Visitor *v, Error **errp)
90a4a1c70dSMarkus Armbruster {
91a4a1c70dSMarkus Armbruster     trace_visit_check_list(v);
92012d4c96SMarkus Armbruster     return v->check_list ? v->check_list(v, errp) : true;
93a4a1c70dSMarkus Armbruster }
94a4a1c70dSMarkus Armbruster 
951158bb2aSEric Blake void visit_end_list(Visitor *v, void **obj)
962345c77cSMichael Roth {
97ebfd93b6SDaniel P. Berrange     trace_visit_end_list(v, obj);
981158bb2aSEric Blake     v->end_list(v, obj);
992345c77cSMichael Roth }
1002345c77cSMichael Roth 
101012d4c96SMarkus Armbruster bool visit_start_alternate(Visitor *v, const char *name,
102dbf11922SEric Blake                            GenericAlternate **obj, size_t size,
10360390d2dSMarc-André Lureau                            Error **errp)
104dbf11922SEric Blake {
1057b3cb803SMarkus Armbruster     bool ok;
106e58d695eSEric Blake 
107dbf11922SEric Blake     assert(obj && size >= sizeof(GenericAlternate));
108a15fcc3cSEric Blake     assert(!(v->type & VISITOR_OUTPUT) || *obj);
10960390d2dSMarc-André Lureau     trace_visit_start_alternate(v, name, obj, size);
1107b3cb803SMarkus Armbruster     if (!v->start_alternate) {
1117b3cb803SMarkus Armbruster         assert(!(v->type & VISITOR_INPUT));
1127b3cb803SMarkus Armbruster         return true;
113dbf11922SEric Blake     }
1147b3cb803SMarkus Armbruster     ok = v->start_alternate(v, name, obj, size, errp);
115a15fcc3cSEric Blake     if (v->type & VISITOR_INPUT) {
1167b3cb803SMarkus Armbruster         assert(ok != !*obj);
117e58d695eSEric Blake     }
1187b3cb803SMarkus Armbruster     return ok;
119dbf11922SEric Blake }
120dbf11922SEric Blake 
1211158bb2aSEric Blake void visit_end_alternate(Visitor *v, void **obj)
122dbf11922SEric Blake {
123ebfd93b6SDaniel P. Berrange     trace_visit_end_alternate(v, obj);
124dbf11922SEric Blake     if (v->end_alternate) {
1251158bb2aSEric Blake         v->end_alternate(v, obj);
126dbf11922SEric Blake     }
127dbf11922SEric Blake }
128dbf11922SEric Blake 
12951e72bc1SEric Blake bool visit_optional(Visitor *v, const char *name, bool *present)
1302345c77cSMichael Roth {
131ebfd93b6SDaniel P. Berrange     trace_visit_optional(v, name, present);
132297a3646SMarkus Armbruster     if (v->optional) {
1330b2a0d6bSEric Blake         v->optional(v, name, present);
1342345c77cSMichael Roth     }
13529637a6eSEric Blake     return *present;
1362345c77cSMichael Roth }
1372345c77cSMichael Roth 
138*91fa93e5SMarkus Armbruster bool visit_deprecated(Visitor *v, const char *name)
139*91fa93e5SMarkus Armbruster {
140*91fa93e5SMarkus Armbruster     trace_visit_deprecated(v, name);
141*91fa93e5SMarkus Armbruster     if (v->deprecated) {
142*91fa93e5SMarkus Armbruster         return v->deprecated(v, name);
143*91fa93e5SMarkus Armbruster     }
144*91fa93e5SMarkus Armbruster     return true;
145*91fa93e5SMarkus Armbruster }
146*91fa93e5SMarkus Armbruster 
14768ab47e4SEric Blake bool visit_is_input(Visitor *v)
14868ab47e4SEric Blake {
14968ab47e4SEric Blake     return v->type == VISITOR_INPUT;
15068ab47e4SEric Blake }
15168ab47e4SEric Blake 
1528e08bf4eSMarkus Armbruster bool visit_is_dealloc(Visitor *v)
1538e08bf4eSMarkus Armbruster {
1548e08bf4eSMarkus Armbruster     return v->type == VISITOR_DEALLOC;
1558e08bf4eSMarkus Armbruster }
1568e08bf4eSMarkus Armbruster 
157012d4c96SMarkus Armbruster bool visit_type_int(Visitor *v, const char *name, int64_t *obj, Error **errp)
1582345c77cSMichael Roth {
159adfb264cSEric Blake     assert(obj);
160ebfd93b6SDaniel P. Berrange     trace_visit_type_int(v, name, obj);
161012d4c96SMarkus Armbruster     return v->type_int64(v, name, obj, errp);
1622345c77cSMichael Roth }
1632345c77cSMichael Roth 
164012d4c96SMarkus Armbruster static bool visit_type_uintN(Visitor *v, uint64_t *obj, const char *name,
16504e070d2SEric Blake                              uint64_t max, const char *type, Error **errp)
16604e070d2SEric Blake {
16704e070d2SEric Blake     uint64_t value = *obj;
16804e070d2SEric Blake 
169faad584aSMarkus Armbruster     assert(v->type == VISITOR_INPUT || value <= max);
170faad584aSMarkus Armbruster 
171012d4c96SMarkus Armbruster     if (!v->type_uint64(v, name, &value, errp)) {
172012d4c96SMarkus Armbruster         return false;
173012d4c96SMarkus Armbruster     }
174012d4c96SMarkus Armbruster     if (value > max) {
175faad584aSMarkus Armbruster         assert(v->type == VISITOR_INPUT);
17604e070d2SEric Blake         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
17704e070d2SEric Blake                    name ? name : "null", type);
178012d4c96SMarkus Armbruster         return false;
17904e070d2SEric Blake     }
180012d4c96SMarkus Armbruster     *obj = value;
181012d4c96SMarkus Armbruster     return true;
18204e070d2SEric Blake }
18304e070d2SEric Blake 
184012d4c96SMarkus Armbruster bool visit_type_uint8(Visitor *v, const char *name, uint8_t *obj,
18551e72bc1SEric Blake                       Error **errp)
1864e27e819SMichael Roth {
187ebfd93b6SDaniel P. Berrange     uint64_t value;
188012d4c96SMarkus Armbruster     bool ok;
189ebfd93b6SDaniel P. Berrange 
190ebfd93b6SDaniel P. Berrange     trace_visit_type_uint8(v, name, obj);
191ebfd93b6SDaniel P. Berrange     value = *obj;
192012d4c96SMarkus Armbruster     ok = visit_type_uintN(v, &value, name, UINT8_MAX, "uint8_t", errp);
1934e27e819SMichael Roth     *obj = value;
194012d4c96SMarkus Armbruster     return ok;
1954e27e819SMichael Roth }
1964e27e819SMichael Roth 
197012d4c96SMarkus Armbruster bool visit_type_uint16(Visitor *v, const char *name, uint16_t *obj,
19804e070d2SEric Blake                        Error **errp)
1994e27e819SMichael Roth {
200ebfd93b6SDaniel P. Berrange     uint64_t value;
201012d4c96SMarkus Armbruster     bool ok;
202ebfd93b6SDaniel P. Berrange 
203ebfd93b6SDaniel P. Berrange     trace_visit_type_uint16(v, name, obj);
204ebfd93b6SDaniel P. Berrange     value = *obj;
205012d4c96SMarkus Armbruster     ok = visit_type_uintN(v, &value, name, UINT16_MAX, "uint16_t", errp);
2064e27e819SMichael Roth     *obj = value;
207012d4c96SMarkus Armbruster     return ok;
2084e27e819SMichael Roth }
2094e27e819SMichael Roth 
210012d4c96SMarkus Armbruster bool visit_type_uint32(Visitor *v, const char *name, uint32_t *obj,
21104e070d2SEric Blake                        Error **errp)
2124e27e819SMichael Roth {
213ebfd93b6SDaniel P. Berrange     uint64_t value;
214012d4c96SMarkus Armbruster     bool ok;
215ebfd93b6SDaniel P. Berrange 
216ebfd93b6SDaniel P. Berrange     trace_visit_type_uint32(v, name, obj);
217ebfd93b6SDaniel P. Berrange     value = *obj;
218012d4c96SMarkus Armbruster     ok = visit_type_uintN(v, &value, name, UINT32_MAX, "uint32_t", errp);
2194e27e819SMichael Roth     *obj = value;
220012d4c96SMarkus Armbruster     return ok;
2214e27e819SMichael Roth }
2224e27e819SMichael Roth 
223012d4c96SMarkus Armbruster bool visit_type_uint64(Visitor *v, const char *name, uint64_t *obj,
22404e070d2SEric Blake                        Error **errp)
2254e27e819SMichael Roth {
226adfb264cSEric Blake     assert(obj);
227ebfd93b6SDaniel P. Berrange     trace_visit_type_uint64(v, name, obj);
228012d4c96SMarkus Armbruster     return v->type_uint64(v, name, obj, errp);
2294e27e819SMichael Roth }
2304e27e819SMichael Roth 
231012d4c96SMarkus Armbruster static bool visit_type_intN(Visitor *v, int64_t *obj, const char *name,
23204e070d2SEric Blake                             int64_t min, int64_t max, const char *type,
23304e070d2SEric Blake                             Error **errp)
2344e27e819SMichael Roth {
23504e070d2SEric Blake     int64_t value = *obj;
236297a3646SMarkus Armbruster 
237faad584aSMarkus Armbruster     assert(v->type == VISITOR_INPUT || (value >= min && value <= max));
238faad584aSMarkus Armbruster 
239012d4c96SMarkus Armbruster     if (!v->type_int64(v, name, &value, errp)) {
240012d4c96SMarkus Armbruster         return false;
241012d4c96SMarkus Armbruster     }
242012d4c96SMarkus Armbruster     if (value < min || value > max) {
243faad584aSMarkus Armbruster         assert(v->type == VISITOR_INPUT);
244c6bd8c70SMarkus Armbruster         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
24504e070d2SEric Blake                    name ? name : "null", type);
246012d4c96SMarkus Armbruster         return false;
2474e27e819SMichael Roth     }
248012d4c96SMarkus Armbruster     *obj = value;
249012d4c96SMarkus Armbruster     return true;
2504e27e819SMichael Roth }
2514e27e819SMichael Roth 
252012d4c96SMarkus Armbruster bool visit_type_int8(Visitor *v, const char *name, int8_t *obj, Error **errp)
25304e070d2SEric Blake {
254ebfd93b6SDaniel P. Berrange     int64_t value;
255012d4c96SMarkus Armbruster     bool ok;
256ebfd93b6SDaniel P. Berrange 
257ebfd93b6SDaniel P. Berrange     trace_visit_type_int8(v, name, obj);
258ebfd93b6SDaniel P. Berrange     value = *obj;
259012d4c96SMarkus Armbruster     ok = visit_type_intN(v, &value, name, INT8_MIN, INT8_MAX, "int8_t", errp);
26004e070d2SEric Blake     *obj = value;
261012d4c96SMarkus Armbruster     return ok;
26204e070d2SEric Blake }
26304e070d2SEric Blake 
264012d4c96SMarkus Armbruster bool visit_type_int16(Visitor *v, const char *name, int16_t *obj,
26551e72bc1SEric Blake                       Error **errp)
2664e27e819SMichael Roth {
267ebfd93b6SDaniel P. Berrange     int64_t value;
268012d4c96SMarkus Armbruster     bool ok;
269ebfd93b6SDaniel P. Berrange 
270ebfd93b6SDaniel P. Berrange     trace_visit_type_int16(v, name, obj);
271ebfd93b6SDaniel P. Berrange     value = *obj;
272012d4c96SMarkus Armbruster     ok = visit_type_intN(v, &value, name, INT16_MIN, INT16_MAX, "int16_t",
273012d4c96SMarkus Armbruster                          errp);
2744e27e819SMichael Roth     *obj = value;
275012d4c96SMarkus Armbruster     return ok;
2764e27e819SMichael Roth }
2774e27e819SMichael Roth 
278012d4c96SMarkus Armbruster bool visit_type_int32(Visitor *v, const char *name, int32_t *obj,
27951e72bc1SEric Blake                       Error **errp)
2804e27e819SMichael Roth {
281ebfd93b6SDaniel P. Berrange     int64_t value;
282012d4c96SMarkus Armbruster     bool ok;
283ebfd93b6SDaniel P. Berrange 
284ebfd93b6SDaniel P. Berrange     trace_visit_type_int32(v, name, obj);
285ebfd93b6SDaniel P. Berrange     value = *obj;
286012d4c96SMarkus Armbruster     ok = visit_type_intN(v, &value, name, INT32_MIN, INT32_MAX, "int32_t",
287012d4c96SMarkus Armbruster                         errp);
2884e27e819SMichael Roth     *obj = value;
289012d4c96SMarkus Armbruster     return ok;
2904e27e819SMichael Roth }
2914e27e819SMichael Roth 
292012d4c96SMarkus Armbruster bool visit_type_int64(Visitor *v, const char *name, int64_t *obj,
29351e72bc1SEric Blake                       Error **errp)
2944e27e819SMichael Roth {
295adfb264cSEric Blake     assert(obj);
296ebfd93b6SDaniel P. Berrange     trace_visit_type_int64(v, name, obj);
297012d4c96SMarkus Armbruster     return v->type_int64(v, name, obj, errp);
2984e27e819SMichael Roth }
2994e27e819SMichael Roth 
300012d4c96SMarkus Armbruster bool visit_type_size(Visitor *v, const char *name, uint64_t *obj,
30151e72bc1SEric Blake                      Error **errp)
302092705d4SLaszlo Ersek {
303adfb264cSEric Blake     assert(obj);
304ebfd93b6SDaniel P. Berrange     trace_visit_type_size(v, name, obj);
305b8877962SVasilis Liaskovitis     if (v->type_size) {
306012d4c96SMarkus Armbruster         return v->type_size(v, name, obj, errp);
307b8877962SVasilis Liaskovitis     }
308012d4c96SMarkus Armbruster     return v->type_uint64(v, name, obj, errp);
309092705d4SLaszlo Ersek }
310092705d4SLaszlo Ersek 
311012d4c96SMarkus Armbruster bool visit_type_bool(Visitor *v, const char *name, bool *obj, Error **errp)
3122345c77cSMichael Roth {
313adfb264cSEric Blake     assert(obj);
314ebfd93b6SDaniel P. Berrange     trace_visit_type_bool(v, name, obj);
315012d4c96SMarkus Armbruster     return v->type_bool(v, name, obj, errp);
3162345c77cSMichael Roth }
3172345c77cSMichael Roth 
318012d4c96SMarkus Armbruster bool visit_type_str(Visitor *v, const char *name, char **obj, Error **errp)
3192345c77cSMichael Roth {
3207b3cb803SMarkus Armbruster     bool ok;
321e58d695eSEric Blake 
322e58d695eSEric Blake     assert(obj);
323adfb264cSEric Blake     /* TODO: Fix callers to not pass NULL when they mean "", so that we
324adfb264cSEric Blake      * can enable:
325a15fcc3cSEric Blake     assert(!(v->type & VISITOR_OUTPUT) || *obj);
326adfb264cSEric Blake      */
327ebfd93b6SDaniel P. Berrange     trace_visit_type_str(v, name, obj);
3287b3cb803SMarkus Armbruster     ok = v->type_str(v, name, obj, errp);
329a15fcc3cSEric Blake     if (v->type & VISITOR_INPUT) {
3307b3cb803SMarkus Armbruster         assert(ok != !*obj);
331e58d695eSEric Blake     }
3327b3cb803SMarkus Armbruster     return ok;
3332345c77cSMichael Roth }
3342345c77cSMichael Roth 
335012d4c96SMarkus Armbruster bool visit_type_number(Visitor *v, const char *name, double *obj,
33651e72bc1SEric Blake                        Error **errp)
3372345c77cSMichael Roth {
338adfb264cSEric Blake     assert(obj);
339ebfd93b6SDaniel P. Berrange     trace_visit_type_number(v, name, obj);
340012d4c96SMarkus Armbruster     return v->type_number(v, name, obj, errp);
3412345c77cSMichael Roth }
3420f71a1e0SPaolo Bonzini 
343012d4c96SMarkus Armbruster bool visit_type_any(Visitor *v, const char *name, QObject **obj, Error **errp)
34428770e05SMarkus Armbruster {
345012d4c96SMarkus Armbruster     bool ok;
346e58d695eSEric Blake 
347e58d695eSEric Blake     assert(obj);
348adfb264cSEric Blake     assert(v->type != VISITOR_OUTPUT || *obj);
349ebfd93b6SDaniel P. Berrange     trace_visit_type_any(v, name, obj);
350012d4c96SMarkus Armbruster     ok = v->type_any(v, name, obj, errp);
351e58d695eSEric Blake     if (v->type == VISITOR_INPUT) {
352012d4c96SMarkus Armbruster         assert(ok != !*obj);
353e58d695eSEric Blake     }
354012d4c96SMarkus Armbruster     return ok;
35528770e05SMarkus Armbruster }
35628770e05SMarkus Armbruster 
357012d4c96SMarkus Armbruster bool visit_type_null(Visitor *v, const char *name, QNull **obj,
358d2f95f4dSMarkus Armbruster                      Error **errp)
3593bc97fd5SEric Blake {
360d2f95f4dSMarkus Armbruster     trace_visit_type_null(v, name, obj);
361012d4c96SMarkus Armbruster     return v->type_null(v, name, obj, errp);
3623bc97fd5SEric Blake }
3633bc97fd5SEric Blake 
364012d4c96SMarkus Armbruster static bool output_type_enum(Visitor *v, const char *name, int *obj,
365f7abe0ecSMarc-André Lureau                              const QEnumLookup *lookup, Error **errp)
3660f71a1e0SPaolo Bonzini {
3670f71a1e0SPaolo Bonzini     int value = *obj;
3680f71a1e0SPaolo Bonzini     char *enum_str;
3690f71a1e0SPaolo Bonzini 
370f7abe0ecSMarc-André Lureau     enum_str = (char *)qapi_enum_lookup(lookup, value);
371012d4c96SMarkus Armbruster     return visit_type_str(v, name, &enum_str, errp);
3720f71a1e0SPaolo Bonzini }
3730f71a1e0SPaolo Bonzini 
374012d4c96SMarkus Armbruster static bool input_type_enum(Visitor *v, const char *name, int *obj,
375f7abe0ecSMarc-André Lureau                             const QEnumLookup *lookup, Error **errp)
3760f71a1e0SPaolo Bonzini {
377113e47aeSMarkus Armbruster     int64_t value;
3780f71a1e0SPaolo Bonzini     char *enum_str;
3790f71a1e0SPaolo Bonzini 
380012d4c96SMarkus Armbruster     if (!visit_type_str(v, name, &enum_str, errp)) {
381012d4c96SMarkus Armbruster         return false;
3820f71a1e0SPaolo Bonzini     }
3830f71a1e0SPaolo Bonzini 
384f7abe0ecSMarc-André Lureau     value = qapi_enum_parse(lookup, enum_str, -1, NULL);
385113e47aeSMarkus Armbruster     if (value < 0) {
386c6bd8c70SMarkus Armbruster         error_setg(errp, QERR_INVALID_PARAMETER, enum_str);
3870f71a1e0SPaolo Bonzini         g_free(enum_str);
388012d4c96SMarkus Armbruster         return false;
3890f71a1e0SPaolo Bonzini     }
3900f71a1e0SPaolo Bonzini 
3910f71a1e0SPaolo Bonzini     g_free(enum_str);
3920f71a1e0SPaolo Bonzini     *obj = value;
393012d4c96SMarkus Armbruster     return true;
3940f71a1e0SPaolo Bonzini }
395983f52d4SEric Blake 
396012d4c96SMarkus Armbruster bool visit_type_enum(Visitor *v, const char *name, int *obj,
397f7abe0ecSMarc-André Lureau                      const QEnumLookup *lookup, Error **errp)
398983f52d4SEric Blake {
399f7abe0ecSMarc-André Lureau     assert(obj && lookup);
4006514532fSStefan Hajnoczi     trace_visit_type_enum(v, name, obj);
401a15fcc3cSEric Blake     switch (v->type) {
402a15fcc3cSEric Blake     case VISITOR_INPUT:
403012d4c96SMarkus Armbruster         return input_type_enum(v, name, obj, lookup, errp);
404a15fcc3cSEric Blake     case VISITOR_OUTPUT:
405012d4c96SMarkus Armbruster         return output_type_enum(v, name, obj, lookup, errp);
406a15fcc3cSEric Blake     case VISITOR_CLONE:
407a15fcc3cSEric Blake         /* nothing further to do, scalar value was already copied by
408a15fcc3cSEric Blake          * g_memdup() during visit_start_*() */
409012d4c96SMarkus Armbruster         return true;
410a15fcc3cSEric Blake     case VISITOR_DEALLOC:
411a15fcc3cSEric Blake         /* nothing to deallocate for a scalar */
412012d4c96SMarkus Armbruster         return true;
413012d4c96SMarkus Armbruster     default:
414012d4c96SMarkus Armbruster         abort();
415983f52d4SEric Blake     }
416983f52d4SEric Blake }
417