|
11 | 11 | #ifndef QAPI_CLONE_VISITOR_H
|
12 | 12 | #define QAPI_CLONE_VISITOR_H
|
13 | 13 |
|
| 14 | +#include "qapi/error.h" |
14 | 15 | #include "qapi/visitor.h"
|
15 | 16 |
|
16 | 17 | /*
|
|
20 | 21 | */
|
21 | 22 | typedef struct QapiCloneVisitor QapiCloneVisitor;
|
22 | 23 |
|
23 |
| -void *qapi_clone(const void *src, bool (*visit_type)(Visitor *, const char *, |
24 |
| - void **, Error **)); |
25 |
| -void qapi_clone_members(void *dst, const void *src, size_t sz, |
26 |
| - bool (*visit_type_members)(Visitor *, void *, |
27 |
| - Error **)); |
| 24 | +Visitor *qapi_clone_visitor_new(void); |
| 25 | +Visitor *qapi_clone_members_visitor_new(void); |
28 | 26 |
|
29 | 27 | /*
|
30 | 28 | * Deep-clone QAPI object @src of the given @type, and return the result.
|
31 | 29 | *
|
32 | 30 | * Not usable on QAPI scalars (integers, strings, enums), nor on a
|
33 | 31 | * QAPI object that references the 'any' type. Safe when @src is NULL.
|
34 | 32 | */
|
35 |
| -#define QAPI_CLONE(type, src) \ |
36 |
| - ((type *)qapi_clone(src, \ |
37 |
| - (bool (*)(Visitor *, const char *, void **, \ |
38 |
| - Error **))visit_type_ ## type)) |
| 33 | +#define QAPI_CLONE(type, src) \ |
| 34 | + ({ \ |
| 35 | + Visitor *v_; \ |
| 36 | + type *dst_ = (type *) (src); /* Cast away const */ \ |
| 37 | + \ |
| 38 | + if (dst_) { \ |
| 39 | + v_ = qapi_clone_visitor_new(); \ |
| 40 | + visit_type_ ## type(v_, NULL, &dst_, &error_abort); \ |
| 41 | + visit_free(v_); \ |
| 42 | + } \ |
| 43 | + dst_; \ |
| 44 | + }) |
39 | 45 |
|
40 | 46 | /*
|
41 | 47 | * Copy deep clones of @type members from @src to @dst.
|
42 | 48 | *
|
43 | 49 | * Not usable on QAPI scalars (integers, strings, enums), nor on a
|
44 | 50 | * QAPI object that references the 'any' type.
|
45 | 51 | */
|
46 |
| -#define QAPI_CLONE_MEMBERS(type, dst, src) \ |
47 |
| - qapi_clone_members(dst, src, sizeof(type), \ |
48 |
| - (bool (*)(Visitor *, void *, \ |
49 |
| - Error **))visit_type_ ## type ## _members) |
| 52 | +#define QAPI_CLONE_MEMBERS(type, dst, src) \ |
| 53 | + ({ \ |
| 54 | + Visitor *v_; \ |
| 55 | + \ |
| 56 | + v_ = qapi_clone_members_visitor_new(); \ |
| 57 | + *(type *)(dst) = *(src); \ |
| 58 | + visit_type_ ## type ## _members(v_, (type *)(dst), &error_abort); \ |
| 59 | + visit_free(v_); \ |
| 60 | + }) |
50 | 61 |
|
51 | 62 | #endif
|
0 commit comments