]> Git Repo - qemu.git/blob - test-visitor.c
m48t59: Convert to isa_register_ioport
[qemu.git] / test-visitor.c
1 #include <glib.h>
2 #include "qapi/qmp-output-visitor.h"
3 #include "qapi/qmp-input-visitor.h"
4 #include "test-qapi-types.h"
5 #include "test-qapi-visit.h"
6 #include "qemu-objects.h"
7
8 typedef struct TestStruct
9 {
10     int64_t x;
11     int64_t y;
12 } TestStruct;
13
14 typedef struct TestStructList
15 {
16     TestStruct *value;
17     struct TestStructList *next;
18 } TestStructList;
19
20 static void visit_type_TestStruct(Visitor *v, TestStruct **obj, const char *name, Error **errp)
21 {
22     visit_start_struct(v, (void **)obj, "TestStruct", name, sizeof(TestStruct), errp);
23     visit_type_int(v, &(*obj)->x, "x", errp);
24     visit_type_int(v, &(*obj)->y, "y", errp);
25     visit_end_struct(v, errp);
26 }
27
28 static void visit_type_TestStructList(Visitor *m, TestStructList ** obj, const char *name, Error **errp)
29 {
30     GenericList *i;
31
32     visit_start_list(m, name, errp);
33
34     for (i = visit_next_list(m, (GenericList **)obj, errp); i; i = visit_next_list(m, &i, errp)) {
35         TestStructList *native_i = (TestStructList *)i;
36         visit_type_TestStruct(m, &native_i->value, NULL, errp);
37     }
38
39     visit_end_list(m, errp);
40 }
41
42 /* test core visitor methods */
43 static void test_visitor_core(void)
44 {
45     QmpOutputVisitor *mo;
46     QmpInputVisitor *mi;
47     Visitor *v;
48     TestStruct ts = { 42, 82 };
49     TestStruct *pts = &ts;
50     TestStructList *lts = NULL;
51     Error *err = NULL;
52     QObject *obj;
53     QString *str;
54     int64_t value = 0;
55
56     mo = qmp_output_visitor_new();
57     v = qmp_output_get_visitor(mo);
58
59     visit_type_TestStruct(v, &pts, NULL, &err);
60
61     obj = qmp_output_get_qobject(mo);
62
63     str = qobject_to_json(obj);
64
65     printf("%s\n", qstring_get_str(str));
66
67     QDECREF(str);
68
69     obj = QOBJECT(qint_from_int(0x42));
70
71     mi = qmp_input_visitor_new(obj);
72     v = qmp_input_get_visitor(mi);
73
74     visit_type_int(v, &value, NULL, &err);
75     if (err) {
76         g_error("%s", error_get_pretty(err));
77     }
78
79     g_assert(value == 0x42);
80
81     qobject_decref(obj);
82
83     obj = qobject_from_json("{'x': 42, 'y': 84}");
84     mi = qmp_input_visitor_new(obj);
85     v = qmp_input_get_visitor(mi);
86
87     pts = NULL;
88
89     visit_type_TestStruct(v, &pts, NULL, &err);
90     if (err) {
91         g_error("%s", error_get_pretty(err));
92     }
93
94     g_assert(pts != NULL);
95     g_assert(pts->x == 42);
96     g_assert(pts->y == 84);
97
98     qobject_decref(obj);
99
100     obj = qobject_from_json("[{'x': 42, 'y': 84}, {'x': 12, 'y': 24}]");
101     mi = qmp_input_visitor_new(obj);
102     v = qmp_input_get_visitor(mi);
103
104     visit_type_TestStructList(v, &lts, NULL, &err);
105     if (err) {
106         g_error("%s", error_get_pretty(err));
107     }
108
109     g_assert(lts != NULL);
110     g_assert(lts->value->x == 42);
111     g_assert(lts->value->y == 84);
112
113     lts = lts->next;
114     g_assert(lts != NULL);
115     g_assert(lts->value->x == 12);
116     g_assert(lts->value->y == 24);
117
118     g_assert(lts->next == NULL);
119
120     qobject_decref(obj);
121 }
122
123 /* test deep nesting with refs to other user-defined types */
124 static void test_nested_structs(void)
125 {
126     QmpOutputVisitor *mo;
127     QmpInputVisitor *mi;
128     Visitor *v;
129     UserDefOne ud1;
130     UserDefOne *ud1_p = &ud1, *ud1c_p = NULL;
131     UserDefTwo ud2;
132     UserDefTwo *ud2_p = &ud2, *ud2c_p = NULL;
133     Error *err = NULL;
134     QObject *obj;
135     QString *str;
136
137     ud1.integer = 42;
138     ud1.string = strdup("fourty two");
139
140     /* sanity check */
141     mo = qmp_output_visitor_new();
142     v = qmp_output_get_visitor(mo);
143     visit_type_UserDefOne(v, &ud1_p, "o_O", &err);
144     if (err) {
145         g_error("%s", error_get_pretty(err));
146     }
147     obj = qmp_output_get_qobject(mo);
148     g_assert(obj);
149     qobject_decref(obj);
150
151     ud2.string = strdup("fourty three");
152     ud2.dict.string = strdup("fourty four");
153     ud2.dict.dict.userdef = ud1_p;
154     ud2.dict.dict.string = strdup("fourty five");
155     ud2.dict.has_dict2 = true;
156     ud2.dict.dict2.userdef = ud1_p;
157     ud2.dict.dict2.string = strdup("fourty six");
158
159     /* c type -> qobject */
160     mo = qmp_output_visitor_new();
161     v = qmp_output_get_visitor(mo);
162     visit_type_UserDefTwo(v, &ud2_p, "unused", &err);
163     if (err) {
164         g_error("%s", error_get_pretty(err));
165     }
166     obj = qmp_output_get_qobject(mo);
167     g_assert(obj);
168     str = qobject_to_json_pretty(obj);
169     g_print("%s\n", qstring_get_str(str));
170     QDECREF(str);
171
172     /* qobject -> c type, should match original struct */
173     mi = qmp_input_visitor_new(obj);
174     v = qmp_input_get_visitor(mi);
175     visit_type_UserDefTwo(v, &ud2c_p, NULL, &err);
176     if (err) {
177         g_error("%s", error_get_pretty(err));
178     }
179
180     g_assert(!g_strcmp0(ud2c_p->string, ud2.string));
181     g_assert(!g_strcmp0(ud2c_p->dict.string, ud2.dict.string));
182
183     ud1c_p = ud2c_p->dict.dict.userdef;
184     g_assert(ud1c_p->integer == ud1_p->integer);
185     g_assert(!g_strcmp0(ud1c_p->string, ud1_p->string));
186
187     g_assert(!g_strcmp0(ud2c_p->dict.dict.string, ud2.dict.dict.string));
188
189     ud1c_p = ud2c_p->dict.dict2.userdef;
190     g_assert(ud1c_p->integer == ud1_p->integer);
191     g_assert(!g_strcmp0(ud1c_p->string, ud1_p->string));
192
193     g_assert(!g_strcmp0(ud2c_p->dict.dict2.string, ud2.dict.dict2.string));
194     g_free(ud1.string);
195     g_free(ud2.string);
196     g_free(ud2.dict.string);
197     g_free(ud2.dict.dict.string);
198     g_free(ud2.dict.dict2.string);
199
200     qapi_free_UserDefTwo(ud2c_p);
201
202     qobject_decref(obj);
203 }
204
205 /* test enum values */
206 static void test_enums(void)
207 {
208     QmpOutputVisitor *mo;
209     QmpInputVisitor *mi;
210     Visitor *v;
211     EnumOne enum1 = ENUM_ONE_VALUE2, enum1_cpy = ENUM_ONE_VALUE1;
212     Error *err = NULL;
213     QObject *obj;
214     QString *str;
215
216     /* C type -> QObject */
217     mo = qmp_output_visitor_new();
218     v = qmp_output_get_visitor(mo);
219     visit_type_EnumOne(v, &enum1, "unused", &err);
220     if (err) {
221         g_error("%s", error_get_pretty(err));
222     }
223     obj = qmp_output_get_qobject(mo);
224     g_assert(obj);
225     str = qobject_to_json_pretty(obj);
226     g_print("%s\n", qstring_get_str(str));
227     QDECREF(str);
228     g_assert(g_strcmp0(qstring_get_str(qobject_to_qstring(obj)), "value2") == 0);
229
230     /* QObject -> C type */
231     mi = qmp_input_visitor_new(obj);
232     v = qmp_input_get_visitor(mi);
233     visit_type_EnumOne(v, &enum1_cpy, "unused", &err);
234     if (err) {
235         g_error("%s", error_get_pretty(err));
236     }
237     g_debug("enum1_cpy, enum1: %d, %d", enum1_cpy, enum1);
238     g_assert(enum1_cpy == enum1);
239
240     qobject_decref(obj);
241 }
242
243 /* test enum values nested in schema-defined structs */
244 static void test_nested_enums(void)
245 {
246     QmpOutputVisitor *mo;
247     QmpInputVisitor *mi;
248     Visitor *v;
249     NestedEnumsOne *nested_enums, *nested_enums_cpy = NULL;
250     Error *err = NULL;
251     QObject *obj;
252     QString *str;
253
254     nested_enums = g_malloc0(sizeof(NestedEnumsOne));
255     nested_enums->enum1 = ENUM_ONE_VALUE1;
256     nested_enums->enum2 = ENUM_ONE_VALUE2;
257     nested_enums->enum3 = ENUM_ONE_VALUE3;
258     nested_enums->enum4 = ENUM_ONE_VALUE3;
259     nested_enums->has_enum2 = false;
260     nested_enums->has_enum4 = true;
261
262     /* C type -> QObject */
263     mo = qmp_output_visitor_new();
264     v = qmp_output_get_visitor(mo);
265     visit_type_NestedEnumsOne(v, &nested_enums, NULL, &err);
266     if (err) {
267         g_error("%s", error_get_pretty(err));
268     }
269     obj = qmp_output_get_qobject(mo);
270     g_assert(obj);
271     str = qobject_to_json_pretty(obj);
272     g_print("%s\n", qstring_get_str(str));
273     QDECREF(str);
274
275     /* QObject -> C type */
276     mi = qmp_input_visitor_new(obj);
277     v = qmp_input_get_visitor(mi);
278     visit_type_NestedEnumsOne(v, &nested_enums_cpy, NULL, &err);
279     if (err) {
280         g_error("%s", error_get_pretty(err));
281     }
282     g_assert(nested_enums_cpy);
283     g_assert(nested_enums_cpy->enum1 == nested_enums->enum1);
284     g_assert(nested_enums_cpy->enum3 == nested_enums->enum3);
285     g_assert(nested_enums_cpy->enum4 == nested_enums->enum4);
286     g_assert(nested_enums_cpy->has_enum2 == false);
287     g_assert(nested_enums_cpy->has_enum4 == true);
288
289     qobject_decref(obj);
290     qapi_free_NestedEnumsOne(nested_enums);
291     qapi_free_NestedEnumsOne(nested_enums_cpy);
292 }
293
294 int main(int argc, char **argv)
295 {
296     g_test_init(&argc, &argv, NULL);
297
298     g_test_add_func("/0.15/visitor_core", test_visitor_core);
299     g_test_add_func("/0.15/nested_structs", test_nested_structs);
300     g_test_add_func("/0.15/enums", test_enums);
301     g_test_add_func("/0.15/nested_enums", test_nested_enums);
302
303     g_test_run();
304
305     return 0;
306 }
This page took 0.041736 seconds and 4 git commands to generate.