root / scripts / qapi-visit.py @ 34bb443e
History | View | Annotate | Download (7.5 kB)
1 | 06d64c62 | Michael Roth | #
|
---|---|---|---|
2 | 06d64c62 | Michael Roth | # QAPI visitor generator
|
3 | 06d64c62 | Michael Roth | #
|
4 | 06d64c62 | Michael Roth | # Copyright IBM, Corp. 2011
|
5 | 06d64c62 | Michael Roth | #
|
6 | 06d64c62 | Michael Roth | # Authors:
|
7 | 06d64c62 | Michael Roth | # Anthony Liguori <aliguori@us.ibm.com>
|
8 | 06d64c62 | Michael Roth | # Michael Roth <mdroth@linux.vnet.ibm.com>
|
9 | 06d64c62 | Michael Roth | #
|
10 | 06d64c62 | Michael Roth | # This work is licensed under the terms of the GNU GPLv2.
|
11 | 06d64c62 | Michael Roth | # See the COPYING.LIB file in the top-level directory.
|
12 | 06d64c62 | Michael Roth | |
13 | 06d64c62 | Michael Roth | from ordereddict import OrderedDict |
14 | 06d64c62 | Michael Roth | from qapi import * |
15 | 06d64c62 | Michael Roth | import sys |
16 | 06d64c62 | Michael Roth | import os |
17 | 06d64c62 | Michael Roth | import getopt |
18 | 06d64c62 | Michael Roth | import errno |
19 | 06d64c62 | Michael Roth | |
20 | 06d64c62 | Michael Roth | def generate_visit_struct_body(field_prefix, members): |
21 | 06d64c62 | Michael Roth | ret = ""
|
22 | 06d64c62 | Michael Roth | if len(field_prefix): |
23 | 06d64c62 | Michael Roth | field_prefix = field_prefix + "."
|
24 | 06d64c62 | Michael Roth | for argname, argentry, optional, structured in parse_args(members):
|
25 | 06d64c62 | Michael Roth | if optional:
|
26 | 06d64c62 | Michael Roth | ret += mcgen('''
|
27 | 06d64c62 | Michael Roth | visit_start_optional(m, (obj && *obj) ? &(*obj)->%(c_prefix)shas_%(c_name)s : NULL, "%(name)s", errp);
|
28 | 06d64c62 | Michael Roth | if ((*obj)->%(prefix)shas_%(c_name)s) {
|
29 | 06d64c62 | Michael Roth | ''',
|
30 | 06d64c62 | Michael Roth | c_prefix=c_var(field_prefix), prefix=field_prefix, |
31 | 06d64c62 | Michael Roth | c_name=c_var(argname), name=argname) |
32 | 06d64c62 | Michael Roth | push_indent() |
33 | 06d64c62 | Michael Roth | |
34 | 06d64c62 | Michael Roth | if structured:
|
35 | 06d64c62 | Michael Roth | ret += mcgen('''
|
36 | 06d64c62 | Michael Roth | visit_start_struct(m, NULL, "", "%(name)s", 0, errp);
|
37 | 06d64c62 | Michael Roth | ''',
|
38 | 06d64c62 | Michael Roth | name=argname) |
39 | 06d64c62 | Michael Roth | ret += generate_visit_struct_body(field_prefix + argname, argentry) |
40 | 06d64c62 | Michael Roth | ret += mcgen('''
|
41 | 06d64c62 | Michael Roth | visit_end_struct(m, errp);
|
42 | 06d64c62 | Michael Roth | ''')
|
43 | 06d64c62 | Michael Roth | else:
|
44 | 06d64c62 | Michael Roth | ret += mcgen('''
|
45 | 06d64c62 | Michael Roth | visit_type_%(type)s(m, (obj && *obj) ? &(*obj)->%(c_prefix)s%(c_name)s : NULL, "%(name)s", errp);
|
46 | 06d64c62 | Michael Roth | ''',
|
47 | 06d64c62 | Michael Roth | c_prefix=c_var(field_prefix), prefix=field_prefix, |
48 | 06d64c62 | Michael Roth | type=type_name(argentry), c_name=c_var(argname), |
49 | 06d64c62 | Michael Roth | name=argname) |
50 | 06d64c62 | Michael Roth | |
51 | 06d64c62 | Michael Roth | if optional:
|
52 | 06d64c62 | Michael Roth | pop_indent() |
53 | 06d64c62 | Michael Roth | ret += mcgen('''
|
54 | 06d64c62 | Michael Roth | }
|
55 | 06d64c62 | Michael Roth | visit_end_optional(m, errp);
|
56 | 06d64c62 | Michael Roth | ''')
|
57 | 06d64c62 | Michael Roth | return ret
|
58 | 06d64c62 | Michael Roth | |
59 | 06d64c62 | Michael Roth | def generate_visit_struct(name, members): |
60 | 06d64c62 | Michael Roth | ret = mcgen('''
|
61 | 06d64c62 | Michael Roth |
|
62 | 06d64c62 | Michael Roth | void visit_type_%(name)s(Visitor *m, %(name)s ** obj, const char *name, Error **errp)
|
63 | 06d64c62 | Michael Roth | {
|
64 | b6f0474f | Paolo Bonzini | if (error_is_set(errp)) {
|
65 | b6f0474f | Paolo Bonzini | return;
|
66 | b6f0474f | Paolo Bonzini | }
|
67 | 06d64c62 | Michael Roth | visit_start_struct(m, (void **)obj, "%(name)s", name, sizeof(%(name)s), errp);
|
68 | 69b50071 | Paolo Bonzini | if (obj && !*obj) {
|
69 | 69b50071 | Paolo Bonzini | goto end;
|
70 | 69b50071 | Paolo Bonzini | }
|
71 | 06d64c62 | Michael Roth | ''',
|
72 | 06d64c62 | Michael Roth | name=name) |
73 | 06d64c62 | Michael Roth | push_indent() |
74 | 06d64c62 | Michael Roth | ret += generate_visit_struct_body("", members)
|
75 | 06d64c62 | Michael Roth | pop_indent() |
76 | 06d64c62 | Michael Roth | |
77 | 06d64c62 | Michael Roth | ret += mcgen('''
|
78 | 69b50071 | Paolo Bonzini | end:
|
79 | 06d64c62 | Michael Roth | visit_end_struct(m, errp);
|
80 | 06d64c62 | Michael Roth | }
|
81 | 06d64c62 | Michael Roth | ''')
|
82 | 06d64c62 | Michael Roth | return ret
|
83 | 06d64c62 | Michael Roth | |
84 | 06d64c62 | Michael Roth | def generate_visit_list(name, members): |
85 | 06d64c62 | Michael Roth | return mcgen(''' |
86 | 06d64c62 | Michael Roth |
|
87 | 06d64c62 | Michael Roth | void visit_type_%(name)sList(Visitor *m, %(name)sList ** obj, const char *name, Error **errp)
|
88 | 06d64c62 | Michael Roth | {
|
89 | 3a86a0fa | Paolo Bonzini | GenericList *i, **prev = (GenericList **)obj;
|
90 | 06d64c62 | Michael Roth |
|
91 | b6f0474f | Paolo Bonzini | if (error_is_set(errp)) {
|
92 | b6f0474f | Paolo Bonzini | return;
|
93 | b6f0474f | Paolo Bonzini | }
|
94 | 06d64c62 | Michael Roth | visit_start_list(m, name, errp);
|
95 | 06d64c62 | Michael Roth |
|
96 | 3a86a0fa | Paolo Bonzini | for (; (i = visit_next_list(m, prev, errp)) != NULL; prev = &i) {
|
97 | 06d64c62 | Michael Roth | %(name)sList *native_i = (%(name)sList *)i;
|
98 | 06d64c62 | Michael Roth | visit_type_%(name)s(m, &native_i->value, NULL, errp);
|
99 | 06d64c62 | Michael Roth | }
|
100 | 06d64c62 | Michael Roth |
|
101 | 06d64c62 | Michael Roth | visit_end_list(m, errp);
|
102 | 06d64c62 | Michael Roth | }
|
103 | 06d64c62 | Michael Roth | ''',
|
104 | 06d64c62 | Michael Roth | name=name) |
105 | 06d64c62 | Michael Roth | |
106 | 06d64c62 | Michael Roth | def generate_visit_enum(name, members): |
107 | 06d64c62 | Michael Roth | return mcgen(''' |
108 | 06d64c62 | Michael Roth |
|
109 | 06d64c62 | Michael Roth | void visit_type_%(name)s(Visitor *m, %(name)s * obj, const char *name, Error **errp)
|
110 | 06d64c62 | Michael Roth | {
|
111 | 06d64c62 | Michael Roth | visit_type_enum(m, (int *)obj, %(name)s_lookup, "%(name)s", name, errp);
|
112 | 06d64c62 | Michael Roth | }
|
113 | 06d64c62 | Michael Roth | ''',
|
114 | 06d64c62 | Michael Roth | name=name) |
115 | 06d64c62 | Michael Roth | |
116 | 06d64c62 | Michael Roth | def generate_visit_union(name, members): |
117 | 06d64c62 | Michael Roth | ret = generate_visit_enum('%sKind' % name, members.keys())
|
118 | 06d64c62 | Michael Roth | |
119 | 06d64c62 | Michael Roth | ret += mcgen('''
|
120 | 06d64c62 | Michael Roth |
|
121 | 06d64c62 | Michael Roth | void visit_type_%(name)s(Visitor *m, %(name)s ** obj, const char *name, Error **errp)
|
122 | 06d64c62 | Michael Roth | {
|
123 | dc8fb6df | Paolo Bonzini | Error *err = NULL;
|
124 | dc8fb6df | Paolo Bonzini |
|
125 | b6f0474f | Paolo Bonzini | if (error_is_set(errp)) {
|
126 | b6f0474f | Paolo Bonzini | return;
|
127 | b6f0474f | Paolo Bonzini | }
|
128 | dc8fb6df | Paolo Bonzini | visit_start_struct(m, (void **)obj, "%(name)s", name, sizeof(%(name)s), &err);
|
129 | 69b50071 | Paolo Bonzini | if (obj && !*obj) {
|
130 | 69b50071 | Paolo Bonzini | goto end;
|
131 | 69b50071 | Paolo Bonzini | }
|
132 | dc8fb6df | Paolo Bonzini | visit_type_%(name)sKind(m, &(*obj)->kind, "type", &err);
|
133 | dc8fb6df | Paolo Bonzini | if (err) {
|
134 | dc8fb6df | Paolo Bonzini | error_propagate(errp, err);
|
135 | dc8fb6df | Paolo Bonzini | goto end;
|
136 | dc8fb6df | Paolo Bonzini | }
|
137 | dc8fb6df | Paolo Bonzini | switch ((*obj)->kind) {
|
138 | 06d64c62 | Michael Roth | ''',
|
139 | 06d64c62 | Michael Roth | name=name) |
140 | 06d64c62 | Michael Roth | |
141 | dc8fb6df | Paolo Bonzini | for key in members: |
142 | dc8fb6df | Paolo Bonzini | ret += mcgen('''
|
143 | dc8fb6df | Paolo Bonzini | case %(abbrev)s_KIND_%(enum)s:
|
144 | dc8fb6df | Paolo Bonzini | visit_type_%(c_type)s(m, &(*obj)->%(c_name)s, "data", errp);
|
145 | dc8fb6df | Paolo Bonzini | break;
|
146 | dc8fb6df | Paolo Bonzini | ''',
|
147 | dc8fb6df | Paolo Bonzini | abbrev = de_camel_case(name).upper(), |
148 | c9da228b | Federico Simoncelli | enum = c_fun(de_camel_case(key)).upper(), |
149 | dc8fb6df | Paolo Bonzini | c_type=members[key], |
150 | c9da228b | Federico Simoncelli | c_name=c_fun(key)) |
151 | dc8fb6df | Paolo Bonzini | |
152 | dc8fb6df | Paolo Bonzini | ret += mcgen('''
|
153 | dc8fb6df | Paolo Bonzini | default:
|
154 | dc8fb6df | Paolo Bonzini | abort();
|
155 | dc8fb6df | Paolo Bonzini | }
|
156 | dc8fb6df | Paolo Bonzini | end:
|
157 | dc8fb6df | Paolo Bonzini | visit_end_struct(m, errp);
|
158 | dc8fb6df | Paolo Bonzini | }
|
159 | dc8fb6df | Paolo Bonzini | ''')
|
160 | dc8fb6df | Paolo Bonzini | |
161 | 06d64c62 | Michael Roth | return ret
|
162 | 06d64c62 | Michael Roth | |
163 | 06d64c62 | Michael Roth | def generate_declaration(name, members, genlist=True): |
164 | 06d64c62 | Michael Roth | ret = mcgen('''
|
165 | 06d64c62 | Michael Roth |
|
166 | 06d64c62 | Michael Roth | void visit_type_%(name)s(Visitor *m, %(name)s ** obj, const char *name, Error **errp);
|
167 | 06d64c62 | Michael Roth | ''',
|
168 | 06d64c62 | Michael Roth | name=name) |
169 | 06d64c62 | Michael Roth | |
170 | 06d64c62 | Michael Roth | if genlist:
|
171 | 06d64c62 | Michael Roth | ret += mcgen('''
|
172 | 06d64c62 | Michael Roth | void visit_type_%(name)sList(Visitor *m, %(name)sList ** obj, const char *name, Error **errp);
|
173 | 06d64c62 | Michael Roth | ''',
|
174 | 06d64c62 | Michael Roth | name=name) |
175 | 06d64c62 | Michael Roth | |
176 | 06d64c62 | Michael Roth | return ret
|
177 | 06d64c62 | Michael Roth | |
178 | 06d64c62 | Michael Roth | def generate_decl_enum(name, members, genlist=True): |
179 | 06d64c62 | Michael Roth | return mcgen(''' |
180 | 06d64c62 | Michael Roth |
|
181 | 06d64c62 | Michael Roth | void visit_type_%(name)s(Visitor *m, %(name)s * obj, const char *name, Error **errp);
|
182 | 06d64c62 | Michael Roth | ''',
|
183 | 06d64c62 | Michael Roth | name=name) |
184 | 06d64c62 | Michael Roth | |
185 | 06d64c62 | Michael Roth | try:
|
186 | 8d3bc517 | Avi Kivity | opts, args = getopt.gnu_getopt(sys.argv[1:], "chp:o:", |
187 | 8d3bc517 | Avi Kivity | ["source", "header", "prefix=", "output-dir="]) |
188 | 06d64c62 | Michael Roth | except getopt.GetoptError, err:
|
189 | 06d64c62 | Michael Roth | print str(err) |
190 | 06d64c62 | Michael Roth | sys.exit(1)
|
191 | 06d64c62 | Michael Roth | |
192 | 06d64c62 | Michael Roth | output_dir = ""
|
193 | 06d64c62 | Michael Roth | prefix = ""
|
194 | 06d64c62 | Michael Roth | c_file = 'qapi-visit.c'
|
195 | 06d64c62 | Michael Roth | h_file = 'qapi-visit.h'
|
196 | 06d64c62 | Michael Roth | |
197 | 8d3bc517 | Avi Kivity | do_c = False
|
198 | 8d3bc517 | Avi Kivity | do_h = False
|
199 | 8d3bc517 | Avi Kivity | |
200 | 06d64c62 | Michael Roth | for o, a in opts: |
201 | 06d64c62 | Michael Roth | if o in ("-p", "--prefix"): |
202 | 06d64c62 | Michael Roth | prefix = a |
203 | 06d64c62 | Michael Roth | elif o in ("-o", "--output-dir"): |
204 | 06d64c62 | Michael Roth | output_dir = a + "/"
|
205 | 8d3bc517 | Avi Kivity | elif o in ("-c", "--source"): |
206 | 8d3bc517 | Avi Kivity | do_c = True
|
207 | 19bf7c87 | Avi Kivity | elif o in ("-h", "--header"): |
208 | 19bf7c87 | Avi Kivity | do_h = True
|
209 | 8d3bc517 | Avi Kivity | |
210 | 8d3bc517 | Avi Kivity | if not do_c and not do_h: |
211 | 8d3bc517 | Avi Kivity | do_c = True
|
212 | 8d3bc517 | Avi Kivity | do_h = True
|
213 | 06d64c62 | Michael Roth | |
214 | 06d64c62 | Michael Roth | c_file = output_dir + prefix + c_file |
215 | 06d64c62 | Michael Roth | h_file = output_dir + prefix + h_file |
216 | 06d64c62 | Michael Roth | |
217 | 06d64c62 | Michael Roth | try:
|
218 | 06d64c62 | Michael Roth | os.makedirs(output_dir) |
219 | 06d64c62 | Michael Roth | except os.error, e:
|
220 | 06d64c62 | Michael Roth | if e.errno != errno.EEXIST:
|
221 | 06d64c62 | Michael Roth | raise
|
222 | 06d64c62 | Michael Roth | |
223 | 8d3bc517 | Avi Kivity | def maybe_open(really, name, opt): |
224 | 8d3bc517 | Avi Kivity | if really:
|
225 | 8d3bc517 | Avi Kivity | return open(name, opt) |
226 | 19bf7c87 | Avi Kivity | else:
|
227 | 19bf7c87 | Avi Kivity | import StringIO |
228 | 19bf7c87 | Avi Kivity | return StringIO.StringIO()
|
229 | 8d3bc517 | Avi Kivity | |
230 | 8d3bc517 | Avi Kivity | fdef = maybe_open(do_c, c_file, 'w')
|
231 | 8d3bc517 | Avi Kivity | fdecl = maybe_open(do_h, h_file, 'w')
|
232 | 06d64c62 | Michael Roth | |
233 | 06d64c62 | Michael Roth | fdef.write(mcgen('''
|
234 | 06d64c62 | Michael Roth | /* THIS FILE IS AUTOMATICALLY GENERATED, DO NOT MODIFY */
|
235 | 06d64c62 | Michael Roth |
|
236 | 06d64c62 | Michael Roth | /*
|
237 | 06d64c62 | Michael Roth | * schema-defined QAPI visitor functions
|
238 | 06d64c62 | Michael Roth | *
|
239 | 06d64c62 | Michael Roth | * Copyright IBM, Corp. 2011
|
240 | 06d64c62 | Michael Roth | *
|
241 | 06d64c62 | Michael Roth | * Authors:
|
242 | 06d64c62 | Michael Roth | * Anthony Liguori <aliguori@us.ibm.com>
|
243 | 06d64c62 | Michael Roth | *
|
244 | 06d64c62 | Michael Roth | * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
|
245 | 06d64c62 | Michael Roth | * See the COPYING.LIB file in the top-level directory.
|
246 | 06d64c62 | Michael Roth | *
|
247 | 06d64c62 | Michael Roth | */
|
248 | 06d64c62 | Michael Roth |
|
249 | 06d64c62 | Michael Roth | #include "%(header)s"
|
250 | 06d64c62 | Michael Roth | ''',
|
251 | 06d64c62 | Michael Roth | header=basename(h_file))) |
252 | 06d64c62 | Michael Roth | |
253 | 06d64c62 | Michael Roth | fdecl.write(mcgen('''
|
254 | 06d64c62 | Michael Roth | /* THIS FILE IS AUTOMATICALLY GENERATED, DO NOT MODIFY */
|
255 | 06d64c62 | Michael Roth |
|
256 | 06d64c62 | Michael Roth | /*
|
257 | 06d64c62 | Michael Roth | * schema-defined QAPI visitor function
|
258 | 06d64c62 | Michael Roth | *
|
259 | 06d64c62 | Michael Roth | * Copyright IBM, Corp. 2011
|
260 | 06d64c62 | Michael Roth | *
|
261 | 06d64c62 | Michael Roth | * Authors:
|
262 | 06d64c62 | Michael Roth | * Anthony Liguori <aliguori@us.ibm.com>
|
263 | 06d64c62 | Michael Roth | *
|
264 | 06d64c62 | Michael Roth | * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
|
265 | 06d64c62 | Michael Roth | * See the COPYING.LIB file in the top-level directory.
|
266 | 06d64c62 | Michael Roth | *
|
267 | 06d64c62 | Michael Roth | */
|
268 | 06d64c62 | Michael Roth |
|
269 | 06d64c62 | Michael Roth | #ifndef %(guard)s
|
270 | 06d64c62 | Michael Roth | #define %(guard)s
|
271 | 06d64c62 | Michael Roth |
|
272 | 06d64c62 | Michael Roth | #include "qapi/qapi-visit-core.h"
|
273 | 06d64c62 | Michael Roth | #include "%(prefix)sqapi-types.h"
|
274 | 06d64c62 | Michael Roth | ''',
|
275 | 06d64c62 | Michael Roth | prefix=prefix, guard=guardname(h_file))) |
276 | 06d64c62 | Michael Roth | |
277 | 06d64c62 | Michael Roth | exprs = parse_schema(sys.stdin) |
278 | 06d64c62 | Michael Roth | |
279 | 06d64c62 | Michael Roth | for expr in exprs: |
280 | 06d64c62 | Michael Roth | if expr.has_key('type'): |
281 | 06d64c62 | Michael Roth | ret = generate_visit_struct(expr['type'], expr['data']) |
282 | 06d64c62 | Michael Roth | ret += generate_visit_list(expr['type'], expr['data']) |
283 | 06d64c62 | Michael Roth | fdef.write(ret) |
284 | 06d64c62 | Michael Roth | |
285 | 06d64c62 | Michael Roth | ret = generate_declaration(expr['type'], expr['data']) |
286 | 06d64c62 | Michael Roth | fdecl.write(ret) |
287 | 06d64c62 | Michael Roth | elif expr.has_key('union'): |
288 | 06d64c62 | Michael Roth | ret = generate_visit_union(expr['union'], expr['data']) |
289 | dc8fb6df | Paolo Bonzini | ret += generate_visit_list(expr['union'], expr['data']) |
290 | 06d64c62 | Michael Roth | fdef.write(ret) |
291 | 06d64c62 | Michael Roth | |
292 | 06d64c62 | Michael Roth | ret = generate_decl_enum('%sKind' % expr['union'], expr['data'].keys()) |
293 | 06d64c62 | Michael Roth | ret += generate_declaration(expr['union'], expr['data']) |
294 | 06d64c62 | Michael Roth | fdecl.write(ret) |
295 | 06d64c62 | Michael Roth | elif expr.has_key('enum'): |
296 | 06d64c62 | Michael Roth | ret = generate_visit_enum(expr['enum'], expr['data']) |
297 | 06d64c62 | Michael Roth | fdef.write(ret) |
298 | 06d64c62 | Michael Roth | |
299 | 06d64c62 | Michael Roth | ret = generate_decl_enum(expr['enum'], expr['data']) |
300 | 06d64c62 | Michael Roth | fdecl.write(ret) |
301 | 06d64c62 | Michael Roth | |
302 | 06d64c62 | Michael Roth | fdecl.write('''
|
303 | 06d64c62 | Michael Roth | #endif
|
304 | 06d64c62 | Michael Roth | ''')
|
305 | 06d64c62 | Michael Roth | |
306 | 06d64c62 | Michael Roth | fdecl.flush() |
307 | 06d64c62 | Michael Roth | fdecl.close() |
308 | 06d64c62 | Michael Roth | |
309 | 06d64c62 | Michael Roth | fdef.flush() |
310 | 06d64c62 | Michael Roth | fdef.close() |