Statistics
| Branch: | Revision:

root / scripts / qapi-visit.py @ 85938981

History | View | Annotate | Download (13.6 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 622f557f Kevin Wolf
def generate_visit_struct_fields(name, field_prefix, fn_prefix, members, base = None):
21 50f2bdc7 Kevin Wolf
    substructs = []
22 d131c897 Kevin Wolf
    ret = ''
23 50f2bdc7 Kevin Wolf
    full_name = name if not fn_prefix else "%s_%s" % (name, fn_prefix)
24 50f2bdc7 Kevin Wolf
25 50f2bdc7 Kevin Wolf
    for argname, argentry, optional, structured in parse_args(members):
26 50f2bdc7 Kevin Wolf
        if structured:
27 50f2bdc7 Kevin Wolf
            if not fn_prefix:
28 50f2bdc7 Kevin Wolf
                nested_fn_prefix = argname
29 50f2bdc7 Kevin Wolf
            else:
30 50f2bdc7 Kevin Wolf
                nested_fn_prefix = "%s_%s" % (fn_prefix, argname)
31 50f2bdc7 Kevin Wolf
32 50f2bdc7 Kevin Wolf
            nested_field_prefix = "%s%s." % (field_prefix, argname)
33 50f2bdc7 Kevin Wolf
            ret += generate_visit_struct_fields(name, nested_field_prefix,
34 50f2bdc7 Kevin Wolf
                                                nested_fn_prefix, argentry)
35 50f2bdc7 Kevin Wolf
36 50f2bdc7 Kevin Wolf
    ret += mcgen('''
37 50f2bdc7 Kevin Wolf

38 50f2bdc7 Kevin Wolf
static void visit_type_%(full_name)s_fields(Visitor *m, %(name)s ** obj, Error **errp)
39 50f2bdc7 Kevin Wolf
{
40 50f2bdc7 Kevin Wolf
    Error *err = NULL;
41 50f2bdc7 Kevin Wolf
''',
42 50f2bdc7 Kevin Wolf
        name=name, full_name=full_name)
43 50f2bdc7 Kevin Wolf
    push_indent()
44 d195325b Paolo Bonzini
45 622f557f Kevin Wolf
    if base:
46 622f557f Kevin Wolf
        ret += mcgen('''
47 622f557f Kevin Wolf
visit_start_implicit_struct(m, obj ? (void**) &(*obj)->%(c_name)s : NULL, sizeof(%(type)s), &err);
48 622f557f Kevin Wolf
if (!err) {
49 622f557f Kevin Wolf
    visit_type_%(type)s_fields(m, obj ? &(*obj)->%(c_prefix)s%(c_name)s : NULL, &err);
50 622f557f Kevin Wolf
    error_propagate(errp, err);
51 622f557f Kevin Wolf
    err = NULL;
52 622f557f Kevin Wolf
    visit_end_implicit_struct(m, &err);
53 622f557f Kevin Wolf
}
54 622f557f Kevin Wolf
''',
55 622f557f Kevin Wolf
                     c_prefix=c_var(field_prefix),
56 622f557f Kevin Wolf
                     type=type_name(base), c_name=c_var('base'))
57 622f557f Kevin Wolf
58 06d64c62 Michael Roth
    for argname, argentry, optional, structured in parse_args(members):
59 06d64c62 Michael Roth
        if optional:
60 06d64c62 Michael Roth
            ret += mcgen('''
61 d195325b Paolo Bonzini
visit_start_optional(m, obj ? &(*obj)->%(c_prefix)shas_%(c_name)s : NULL, "%(name)s", &err);
62 d195325b Paolo Bonzini
if (obj && (*obj)->%(prefix)shas_%(c_name)s) {
63 06d64c62 Michael Roth
''',
64 06d64c62 Michael Roth
                         c_prefix=c_var(field_prefix), prefix=field_prefix,
65 06d64c62 Michael Roth
                         c_name=c_var(argname), name=argname)
66 06d64c62 Michael Roth
            push_indent()
67 06d64c62 Michael Roth
68 06d64c62 Michael Roth
        if structured:
69 50f2bdc7 Kevin Wolf
            ret += generate_visit_struct_body(full_name, argname, argentry)
70 06d64c62 Michael Roth
        else:
71 06d64c62 Michael Roth
            ret += mcgen('''
72 d195325b Paolo Bonzini
visit_type_%(type)s(m, obj ? &(*obj)->%(c_prefix)s%(c_name)s : NULL, "%(name)s", &err);
73 06d64c62 Michael Roth
''',
74 06d64c62 Michael Roth
                         c_prefix=c_var(field_prefix), prefix=field_prefix,
75 06d64c62 Michael Roth
                         type=type_name(argentry), c_name=c_var(argname),
76 06d64c62 Michael Roth
                         name=argname)
77 06d64c62 Michael Roth
78 06d64c62 Michael Roth
        if optional:
79 06d64c62 Michael Roth
            pop_indent()
80 06d64c62 Michael Roth
            ret += mcgen('''
81 06d64c62 Michael Roth
}
82 d195325b Paolo Bonzini
visit_end_optional(m, &err);
83 d195325b Paolo Bonzini
''')
84 d195325b Paolo Bonzini
85 50f2bdc7 Kevin Wolf
    pop_indent()
86 50f2bdc7 Kevin Wolf
    ret += mcgen('''
87 50f2bdc7 Kevin Wolf

88 50f2bdc7 Kevin Wolf
    error_propagate(errp, err);
89 50f2bdc7 Kevin Wolf
}
90 50f2bdc7 Kevin Wolf
''')
91 d131c897 Kevin Wolf
    return ret
92 d131c897 Kevin Wolf
93 d131c897 Kevin Wolf
94 d131c897 Kevin Wolf
def generate_visit_struct_body(field_prefix, name, members):
95 d131c897 Kevin Wolf
    ret = mcgen('''
96 d131c897 Kevin Wolf
if (!error_is_set(errp)) {
97 d131c897 Kevin Wolf
''')
98 d131c897 Kevin Wolf
    push_indent()
99 d131c897 Kevin Wolf
100 50f2bdc7 Kevin Wolf
    full_name = name if not field_prefix else "%s_%s" % (field_prefix, name)
101 50f2bdc7 Kevin Wolf
102 d131c897 Kevin Wolf
    if len(field_prefix):
103 d131c897 Kevin Wolf
        ret += mcgen('''
104 d131c897 Kevin Wolf
Error **errp = &err; /* from outer scope */
105 d131c897 Kevin Wolf
Error *err = NULL;
106 d131c897 Kevin Wolf
visit_start_struct(m, NULL, "", "%(name)s", 0, &err);
107 d131c897 Kevin Wolf
''',
108 d131c897 Kevin Wolf
                name=name)
109 d131c897 Kevin Wolf
    else:
110 d131c897 Kevin Wolf
        ret += mcgen('''
111 d131c897 Kevin Wolf
Error *err = NULL;
112 d131c897 Kevin Wolf
visit_start_struct(m, (void **)obj, "%(name)s", name, sizeof(%(name)s), &err);
113 d131c897 Kevin Wolf
''',
114 d131c897 Kevin Wolf
                name=name)
115 d131c897 Kevin Wolf
116 d195325b Paolo Bonzini
    ret += mcgen('''
117 d131c897 Kevin Wolf
if (!err) {
118 d131c897 Kevin Wolf
    if (!obj || *obj) {
119 50f2bdc7 Kevin Wolf
        visit_type_%(name)s_fields(m, obj, &err);
120 50f2bdc7 Kevin Wolf
        error_propagate(errp, err);
121 50f2bdc7 Kevin Wolf
        err = NULL;
122 50f2bdc7 Kevin Wolf
    }
123 50f2bdc7 Kevin Wolf
''',
124 50f2bdc7 Kevin Wolf
        name=full_name)
125 d195325b Paolo Bonzini
126 d195325b Paolo Bonzini
    pop_indent()
127 d195325b Paolo Bonzini
    ret += mcgen('''
128 d195325b Paolo Bonzini
        /* Always call end_struct if start_struct succeeded.  */
129 d195325b Paolo Bonzini
        visit_end_struct(m, &err);
130 d195325b Paolo Bonzini
    }
131 d195325b Paolo Bonzini
    error_propagate(errp, err);
132 d195325b Paolo Bonzini
}
133 06d64c62 Michael Roth
''')
134 06d64c62 Michael Roth
    return ret
135 06d64c62 Michael Roth
136 14d36307 Kevin Wolf
def generate_visit_struct(expr):
137 14d36307 Kevin Wolf
138 14d36307 Kevin Wolf
    name = expr['type']
139 14d36307 Kevin Wolf
    members = expr['data']
140 622f557f Kevin Wolf
    base = expr.get('base')
141 14d36307 Kevin Wolf
142 622f557f Kevin Wolf
    ret = generate_visit_struct_fields(name, "", "", members, base)
143 50f2bdc7 Kevin Wolf
144 50f2bdc7 Kevin Wolf
    ret += mcgen('''
145 06d64c62 Michael Roth

146 06d64c62 Michael Roth
void visit_type_%(name)s(Visitor *m, %(name)s ** obj, const char *name, Error **errp)
147 06d64c62 Michael Roth
{
148 06d64c62 Michael Roth
''',
149 06d64c62 Michael Roth
                name=name)
150 d195325b Paolo Bonzini
151 06d64c62 Michael Roth
    push_indent()
152 d195325b Paolo Bonzini
    ret += generate_visit_struct_body("", name, members)
153 06d64c62 Michael Roth
    pop_indent()
154 06d64c62 Michael Roth
155 06d64c62 Michael Roth
    ret += mcgen('''
156 06d64c62 Michael Roth
}
157 06d64c62 Michael Roth
''')
158 06d64c62 Michael Roth
    return ret
159 06d64c62 Michael Roth
160 06d64c62 Michael Roth
def generate_visit_list(name, members):
161 06d64c62 Michael Roth
    return mcgen('''
162 06d64c62 Michael Roth

163 06d64c62 Michael Roth
void visit_type_%(name)sList(Visitor *m, %(name)sList ** obj, const char *name, Error **errp)
164 06d64c62 Michael Roth
{
165 3a86a0fa Paolo Bonzini
    GenericList *i, **prev = (GenericList **)obj;
166 d195325b Paolo Bonzini
    Error *err = NULL;
167 06d64c62 Michael Roth

168 d195325b Paolo Bonzini
    if (!error_is_set(errp)) {
169 d195325b Paolo Bonzini
        visit_start_list(m, name, &err);
170 d195325b Paolo Bonzini
        if (!err) {
171 d195325b Paolo Bonzini
            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
172 d195325b Paolo Bonzini
                %(name)sList *native_i = (%(name)sList *)i;
173 d195325b Paolo Bonzini
                visit_type_%(name)s(m, &native_i->value, NULL, &err);
174 d195325b Paolo Bonzini
            }
175 d195325b Paolo Bonzini
            error_propagate(errp, err);
176 d195325b Paolo Bonzini
            err = NULL;
177 d195325b Paolo Bonzini

178 d195325b Paolo Bonzini
            /* Always call end_list if start_list succeeded.  */
179 d195325b Paolo Bonzini
            visit_end_list(m, &err);
180 d195325b Paolo Bonzini
        }
181 d195325b Paolo Bonzini
        error_propagate(errp, err);
182 06d64c62 Michael Roth
    }
183 06d64c62 Michael Roth
}
184 06d64c62 Michael Roth
''',
185 06d64c62 Michael Roth
                name=name)
186 06d64c62 Michael Roth
187 06d64c62 Michael Roth
def generate_visit_enum(name, members):
188 06d64c62 Michael Roth
    return mcgen('''
189 06d64c62 Michael Roth

190 06d64c62 Michael Roth
void visit_type_%(name)s(Visitor *m, %(name)s * obj, const char *name, Error **errp)
191 06d64c62 Michael Roth
{
192 06d64c62 Michael Roth
    visit_type_enum(m, (int *)obj, %(name)s_lookup, "%(name)s", name, errp);
193 06d64c62 Michael Roth
}
194 06d64c62 Michael Roth
''',
195 06d64c62 Michael Roth
                 name=name)
196 06d64c62 Michael Roth
197 69dd62df Kevin Wolf
def generate_visit_anon_union(name, members):
198 69dd62df Kevin Wolf
    ret = mcgen('''
199 69dd62df Kevin Wolf

200 69dd62df Kevin Wolf
void visit_type_%(name)s(Visitor *m, %(name)s ** obj, const char *name, Error **errp)
201 69dd62df Kevin Wolf
{
202 69dd62df Kevin Wolf
    Error *err = NULL;
203 69dd62df Kevin Wolf

204 69dd62df Kevin Wolf
    if (!error_is_set(errp)) {
205 69dd62df Kevin Wolf
        visit_start_implicit_struct(m, (void**) obj, sizeof(%(name)s), &err);
206 69dd62df Kevin Wolf
        visit_get_next_type(m, (int*) &(*obj)->kind, %(name)s_qtypes, name, &err);
207 69dd62df Kevin Wolf
        switch ((*obj)->kind) {
208 69dd62df Kevin Wolf
''',
209 69dd62df Kevin Wolf
    name=name)
210 69dd62df Kevin Wolf
211 69dd62df Kevin Wolf
    for key in members:
212 69dd62df Kevin Wolf
        assert (members[key] in builtin_types
213 69dd62df Kevin Wolf
            or find_struct(members[key])
214 69dd62df Kevin Wolf
            or find_union(members[key])), "Invalid anonymous union member"
215 69dd62df Kevin Wolf
216 69dd62df Kevin Wolf
        ret += mcgen('''
217 69dd62df Kevin Wolf
        case %(abbrev)s_KIND_%(enum)s:
218 69dd62df Kevin Wolf
            visit_type_%(c_type)s(m, &(*obj)->%(c_name)s, name, &err);
219 69dd62df Kevin Wolf
            break;
220 69dd62df Kevin Wolf
''',
221 69dd62df Kevin Wolf
                abbrev = de_camel_case(name).upper(),
222 69dd62df Kevin Wolf
                enum = c_fun(de_camel_case(key),False).upper(),
223 69dd62df Kevin Wolf
                c_type = type_name(members[key]),
224 69dd62df Kevin Wolf
                c_name = c_fun(key))
225 69dd62df Kevin Wolf
226 69dd62df Kevin Wolf
    ret += mcgen('''
227 69dd62df Kevin Wolf
        default:
228 69dd62df Kevin Wolf
            abort();
229 69dd62df Kevin Wolf
        }
230 69dd62df Kevin Wolf
        error_propagate(errp, err);
231 69dd62df Kevin Wolf
        err = NULL;
232 69dd62df Kevin Wolf
        visit_end_implicit_struct(m, &err);
233 69dd62df Kevin Wolf
    }
234 69dd62df Kevin Wolf
}
235 69dd62df Kevin Wolf
''')
236 69dd62df Kevin Wolf
237 69dd62df Kevin Wolf
    return ret
238 69dd62df Kevin Wolf
239 69dd62df Kevin Wolf
240 0aef92b9 Kevin Wolf
def generate_visit_union(expr):
241 0aef92b9 Kevin Wolf
242 0aef92b9 Kevin Wolf
    name = expr['union']
243 0aef92b9 Kevin Wolf
    members = expr['data']
244 0aef92b9 Kevin Wolf
245 0aef92b9 Kevin Wolf
    base = expr.get('base')
246 50f2bdc7 Kevin Wolf
    discriminator = expr.get('discriminator')
247 0aef92b9 Kevin Wolf
248 69dd62df Kevin Wolf
    if discriminator == {}:
249 69dd62df Kevin Wolf
        assert not base
250 69dd62df Kevin Wolf
        return generate_visit_anon_union(name, members)
251 69dd62df Kevin Wolf
252 06d64c62 Michael Roth
    ret = generate_visit_enum('%sKind' % name, members.keys())
253 06d64c62 Michael Roth
254 50f2bdc7 Kevin Wolf
    if base:
255 50f2bdc7 Kevin Wolf
        base_fields = find_struct(base)['data']
256 50f2bdc7 Kevin Wolf
        if discriminator:
257 50f2bdc7 Kevin Wolf
            base_fields = base_fields.copy()
258 50f2bdc7 Kevin Wolf
            del base_fields[discriminator]
259 50f2bdc7 Kevin Wolf
        ret += generate_visit_struct_fields(name, "", "", base_fields)
260 50f2bdc7 Kevin Wolf
261 06d64c62 Michael Roth
    ret += mcgen('''
262 06d64c62 Michael Roth

263 06d64c62 Michael Roth
void visit_type_%(name)s(Visitor *m, %(name)s ** obj, const char *name, Error **errp)
264 06d64c62 Michael Roth
{
265 dc8fb6df Paolo Bonzini
    Error *err = NULL;
266 dc8fb6df Paolo Bonzini

267 d195325b Paolo Bonzini
    if (!error_is_set(errp)) {
268 d195325b Paolo Bonzini
        visit_start_struct(m, (void **)obj, "%(name)s", name, sizeof(%(name)s), &err);
269 d195325b Paolo Bonzini
        if (!err) {
270 227ccf6b Stefan Weil
            if (obj && *obj) {
271 06d64c62 Michael Roth
''',
272 06d64c62 Michael Roth
                 name=name)
273 06d64c62 Michael Roth
274 0aef92b9 Kevin Wolf
275 d195325b Paolo Bonzini
    push_indent()
276 d195325b Paolo Bonzini
    push_indent()
277 0aef92b9 Kevin Wolf
    push_indent()
278 0aef92b9 Kevin Wolf
279 0aef92b9 Kevin Wolf
    if base:
280 50f2bdc7 Kevin Wolf
        ret += mcgen('''
281 50f2bdc7 Kevin Wolf
    visit_type_%(name)s_fields(m, obj, &err);
282 50f2bdc7 Kevin Wolf
''',
283 50f2bdc7 Kevin Wolf
            name=name)
284 0aef92b9 Kevin Wolf
285 0aef92b9 Kevin Wolf
    pop_indent()
286 0aef92b9 Kevin Wolf
    ret += mcgen('''
287 50f2bdc7 Kevin Wolf
        visit_type_%(name)sKind(m, &(*obj)->kind, "%(type)s", &err);
288 0aef92b9 Kevin Wolf
        if (!err) {
289 0aef92b9 Kevin Wolf
            switch ((*obj)->kind) {
290 0aef92b9 Kevin Wolf
''',
291 50f2bdc7 Kevin Wolf
                 name=name, type="type" if not discriminator else discriminator)
292 0aef92b9 Kevin Wolf
293 dc8fb6df Paolo Bonzini
    for key in members:
294 50f2bdc7 Kevin Wolf
        if not discriminator:
295 50f2bdc7 Kevin Wolf
            fmt = 'visit_type_%(c_type)s(m, &(*obj)->%(c_name)s, "data", &err);'
296 50f2bdc7 Kevin Wolf
        else:
297 50f2bdc7 Kevin Wolf
            fmt = '''visit_start_implicit_struct(m, (void**) &(*obj)->%(c_name)s, sizeof(%(c_type)s), &err);
298 50f2bdc7 Kevin Wolf
                if (!err) {
299 50f2bdc7 Kevin Wolf
                    visit_type_%(c_type)s_fields(m, &(*obj)->%(c_name)s, &err);
300 50f2bdc7 Kevin Wolf
                    error_propagate(errp, err);
301 50f2bdc7 Kevin Wolf
                    err = NULL;
302 50f2bdc7 Kevin Wolf
                    visit_end_implicit_struct(m, &err);
303 50f2bdc7 Kevin Wolf
                }'''
304 50f2bdc7 Kevin Wolf
305 dc8fb6df Paolo Bonzini
        ret += mcgen('''
306 d195325b Paolo Bonzini
            case %(abbrev)s_KIND_%(enum)s:
307 50f2bdc7 Kevin Wolf
                ''' + fmt + '''
308 d195325b Paolo Bonzini
                break;
309 dc8fb6df Paolo Bonzini
''',
310 dc8fb6df Paolo Bonzini
                abbrev = de_camel_case(name).upper(),
311 eda50a65 Paolo Bonzini
                enum = c_fun(de_camel_case(key),False).upper(),
312 c664aef5 Michael Roth
                c_type=type_name(members[key]),
313 c9da228b Federico Simoncelli
                c_name=c_fun(key))
314 dc8fb6df Paolo Bonzini
315 dc8fb6df Paolo Bonzini
    ret += mcgen('''
316 d195325b Paolo Bonzini
            default:
317 d195325b Paolo Bonzini
                abort();
318 d195325b Paolo Bonzini
            }
319 d195325b Paolo Bonzini
        }
320 d195325b Paolo Bonzini
        error_propagate(errp, err);
321 d195325b Paolo Bonzini
        err = NULL;
322 d195325b Paolo Bonzini
    }
323 d195325b Paolo Bonzini
''')
324 d195325b Paolo Bonzini
    pop_indent()
325 d195325b Paolo Bonzini
    ret += mcgen('''
326 d195325b Paolo Bonzini
        /* Always call end_struct if start_struct succeeded.  */
327 d195325b Paolo Bonzini
        visit_end_struct(m, &err);
328 dc8fb6df Paolo Bonzini
    }
329 d195325b Paolo Bonzini
    error_propagate(errp, err);
330 d195325b Paolo Bonzini
}
331 d195325b Paolo Bonzini
''')
332 d195325b Paolo Bonzini
333 d195325b Paolo Bonzini
    pop_indent();
334 d195325b Paolo Bonzini
    ret += mcgen('''
335 dc8fb6df Paolo Bonzini
}
336 dc8fb6df Paolo Bonzini
''')
337 dc8fb6df Paolo Bonzini
338 06d64c62 Michael Roth
    return ret
339 06d64c62 Michael Roth
340 7c946bc4 Michael Roth
def generate_declaration(name, members, genlist=True, builtin_type=False):
341 7c946bc4 Michael Roth
    ret = ""
342 7c946bc4 Michael Roth
    if not builtin_type:
343 7c946bc4 Michael Roth
        ret += mcgen('''
344 06d64c62 Michael Roth

345 06d64c62 Michael Roth
void visit_type_%(name)s(Visitor *m, %(name)s ** obj, const char *name, Error **errp);
346 06d64c62 Michael Roth
''',
347 7c946bc4 Michael Roth
                    name=name)
348 06d64c62 Michael Roth
349 06d64c62 Michael Roth
    if genlist:
350 06d64c62 Michael Roth
        ret += mcgen('''
351 06d64c62 Michael Roth
void visit_type_%(name)sList(Visitor *m, %(name)sList ** obj, const char *name, Error **errp);
352 06d64c62 Michael Roth
''',
353 06d64c62 Michael Roth
                 name=name)
354 06d64c62 Michael Roth
355 06d64c62 Michael Roth
    return ret
356 06d64c62 Michael Roth
357 b9c4b48d Amos Kong
def generate_enum_declaration(name, members, genlist=True):
358 b9c4b48d Amos Kong
    ret = ""
359 b9c4b48d Amos Kong
    if genlist:
360 b9c4b48d Amos Kong
        ret += mcgen('''
361 b9c4b48d Amos Kong
void visit_type_%(name)sList(Visitor *m, %(name)sList ** obj, const char *name, Error **errp);
362 b9c4b48d Amos Kong
''',
363 b9c4b48d Amos Kong
                     name=name)
364 b9c4b48d Amos Kong
365 b9c4b48d Amos Kong
    return ret
366 b9c4b48d Amos Kong
367 06d64c62 Michael Roth
def generate_decl_enum(name, members, genlist=True):
368 06d64c62 Michael Roth
    return mcgen('''
369 06d64c62 Michael Roth

370 06d64c62 Michael Roth
void visit_type_%(name)s(Visitor *m, %(name)s * obj, const char *name, Error **errp);
371 06d64c62 Michael Roth
''',
372 06d64c62 Michael Roth
                name=name)
373 06d64c62 Michael Roth
374 06d64c62 Michael Roth
try:
375 7c946bc4 Michael Roth
    opts, args = getopt.gnu_getopt(sys.argv[1:], "chbp:o:",
376 7c946bc4 Michael Roth
                                   ["source", "header", "builtins", "prefix=",
377 7c946bc4 Michael Roth
                                    "output-dir="])
378 06d64c62 Michael Roth
except getopt.GetoptError, err:
379 06d64c62 Michael Roth
    print str(err)
380 06d64c62 Michael Roth
    sys.exit(1)
381 06d64c62 Michael Roth
382 06d64c62 Michael Roth
output_dir = ""
383 06d64c62 Michael Roth
prefix = ""
384 06d64c62 Michael Roth
c_file = 'qapi-visit.c'
385 06d64c62 Michael Roth
h_file = 'qapi-visit.h'
386 06d64c62 Michael Roth
387 8d3bc517 Avi Kivity
do_c = False
388 8d3bc517 Avi Kivity
do_h = False
389 7c946bc4 Michael Roth
do_builtins = False
390 8d3bc517 Avi Kivity
391 06d64c62 Michael Roth
for o, a in opts:
392 06d64c62 Michael Roth
    if o in ("-p", "--prefix"):
393 06d64c62 Michael Roth
        prefix = a
394 06d64c62 Michael Roth
    elif o in ("-o", "--output-dir"):
395 06d64c62 Michael Roth
        output_dir = a + "/"
396 8d3bc517 Avi Kivity
    elif o in ("-c", "--source"):
397 8d3bc517 Avi Kivity
        do_c = True
398 19bf7c87 Avi Kivity
    elif o in ("-h", "--header"):
399 19bf7c87 Avi Kivity
        do_h = True
400 7c946bc4 Michael Roth
    elif o in ("-b", "--builtins"):
401 7c946bc4 Michael Roth
        do_builtins = True
402 8d3bc517 Avi Kivity
403 8d3bc517 Avi Kivity
if not do_c and not do_h:
404 8d3bc517 Avi Kivity
    do_c = True
405 8d3bc517 Avi Kivity
    do_h = True
406 06d64c62 Michael Roth
407 06d64c62 Michael Roth
c_file = output_dir + prefix + c_file
408 06d64c62 Michael Roth
h_file = output_dir + prefix + h_file
409 06d64c62 Michael Roth
410 06d64c62 Michael Roth
try:
411 06d64c62 Michael Roth
    os.makedirs(output_dir)
412 06d64c62 Michael Roth
except os.error, e:
413 06d64c62 Michael Roth
    if e.errno != errno.EEXIST:
414 06d64c62 Michael Roth
        raise
415 06d64c62 Michael Roth
416 8d3bc517 Avi Kivity
def maybe_open(really, name, opt):
417 8d3bc517 Avi Kivity
    if really:
418 8d3bc517 Avi Kivity
        return open(name, opt)
419 19bf7c87 Avi Kivity
    else:
420 19bf7c87 Avi Kivity
        import StringIO
421 19bf7c87 Avi Kivity
        return StringIO.StringIO()
422 8d3bc517 Avi Kivity
423 8d3bc517 Avi Kivity
fdef = maybe_open(do_c, c_file, 'w')
424 8d3bc517 Avi Kivity
fdecl = maybe_open(do_h, h_file, 'w')
425 06d64c62 Michael Roth
426 06d64c62 Michael Roth
fdef.write(mcgen('''
427 06d64c62 Michael Roth
/* THIS FILE IS AUTOMATICALLY GENERATED, DO NOT MODIFY */
428 06d64c62 Michael Roth

429 06d64c62 Michael Roth
/*
430 06d64c62 Michael Roth
 * schema-defined QAPI visitor functions
431 06d64c62 Michael Roth
 *
432 06d64c62 Michael Roth
 * Copyright IBM, Corp. 2011
433 06d64c62 Michael Roth
 *
434 06d64c62 Michael Roth
 * Authors:
435 06d64c62 Michael Roth
 *  Anthony Liguori   <aliguori@us.ibm.com>
436 06d64c62 Michael Roth
 *
437 06d64c62 Michael Roth
 * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
438 06d64c62 Michael Roth
 * See the COPYING.LIB file in the top-level directory.
439 06d64c62 Michael Roth
 *
440 06d64c62 Michael Roth
 */
441 06d64c62 Michael Roth

442 79ee7df8 Paolo Bonzini
#include "qemu-common.h"
443 06d64c62 Michael Roth
#include "%(header)s"
444 06d64c62 Michael Roth
''',
445 06d64c62 Michael Roth
                 header=basename(h_file)))
446 06d64c62 Michael Roth
447 06d64c62 Michael Roth
fdecl.write(mcgen('''
448 06d64c62 Michael Roth
/* THIS FILE IS AUTOMATICALLY GENERATED, DO NOT MODIFY */
449 06d64c62 Michael Roth

450 06d64c62 Michael Roth
/*
451 06d64c62 Michael Roth
 * schema-defined QAPI visitor function
452 06d64c62 Michael Roth
 *
453 06d64c62 Michael Roth
 * Copyright IBM, Corp. 2011
454 06d64c62 Michael Roth
 *
455 06d64c62 Michael Roth
 * Authors:
456 06d64c62 Michael Roth
 *  Anthony Liguori   <aliguori@us.ibm.com>
457 06d64c62 Michael Roth
 *
458 06d64c62 Michael Roth
 * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
459 06d64c62 Michael Roth
 * See the COPYING.LIB file in the top-level directory.
460 06d64c62 Michael Roth
 *
461 06d64c62 Michael Roth
 */
462 06d64c62 Michael Roth

463 06d64c62 Michael Roth
#ifndef %(guard)s
464 06d64c62 Michael Roth
#define %(guard)s
465 06d64c62 Michael Roth

466 7b1b5d19 Paolo Bonzini
#include "qapi/visitor.h"
467 06d64c62 Michael Roth
#include "%(prefix)sqapi-types.h"
468 7c946bc4 Michael Roth

469 06d64c62 Michael Roth
''',
470 06d64c62 Michael Roth
                  prefix=prefix, guard=guardname(h_file)))
471 06d64c62 Michael Roth
472 06d64c62 Michael Roth
exprs = parse_schema(sys.stdin)
473 06d64c62 Michael Roth
474 7c946bc4 Michael Roth
# to avoid header dependency hell, we always generate declarations
475 7c946bc4 Michael Roth
# for built-in types in our header files and simply guard them
476 7c946bc4 Michael Roth
fdecl.write(guardstart("QAPI_VISIT_BUILTIN_VISITOR_DECL"))
477 7c946bc4 Michael Roth
for typename in builtin_types:
478 7c946bc4 Michael Roth
    fdecl.write(generate_declaration(typename, None, genlist=True,
479 7c946bc4 Michael Roth
                                     builtin_type=True))
480 7c946bc4 Michael Roth
fdecl.write(guardend("QAPI_VISIT_BUILTIN_VISITOR_DECL"))
481 7c946bc4 Michael Roth
482 7c946bc4 Michael Roth
# ...this doesn't work for cases where we link in multiple objects that
483 7c946bc4 Michael Roth
# have the functions defined, so we use -b option to provide control
484 7c946bc4 Michael Roth
# over these cases
485 7c946bc4 Michael Roth
if do_builtins:
486 7c946bc4 Michael Roth
    fdef.write(guardstart("QAPI_VISIT_BUILTIN_VISITOR_DEF"))
487 7c946bc4 Michael Roth
    for typename in builtin_types:
488 7c946bc4 Michael Roth
        fdef.write(generate_visit_list(typename, None))
489 7c946bc4 Michael Roth
    fdef.write(guardend("QAPI_VISIT_BUILTIN_VISITOR_DEF"))
490 7c946bc4 Michael Roth
491 06d64c62 Michael Roth
for expr in exprs:
492 06d64c62 Michael Roth
    if expr.has_key('type'):
493 14d36307 Kevin Wolf
        ret = generate_visit_struct(expr)
494 06d64c62 Michael Roth
        ret += generate_visit_list(expr['type'], expr['data'])
495 06d64c62 Michael Roth
        fdef.write(ret)
496 06d64c62 Michael Roth
497 06d64c62 Michael Roth
        ret = generate_declaration(expr['type'], expr['data'])
498 06d64c62 Michael Roth
        fdecl.write(ret)
499 06d64c62 Michael Roth
    elif expr.has_key('union'):
500 0aef92b9 Kevin Wolf
        ret = generate_visit_union(expr)
501 dc8fb6df Paolo Bonzini
        ret += generate_visit_list(expr['union'], expr['data'])
502 06d64c62 Michael Roth
        fdef.write(ret)
503 06d64c62 Michael Roth
504 06d64c62 Michael Roth
        ret = generate_decl_enum('%sKind' % expr['union'], expr['data'].keys())
505 06d64c62 Michael Roth
        ret += generate_declaration(expr['union'], expr['data'])
506 06d64c62 Michael Roth
        fdecl.write(ret)
507 06d64c62 Michael Roth
    elif expr.has_key('enum'):
508 b9c4b48d Amos Kong
        ret = generate_visit_list(expr['enum'], expr['data'])
509 b9c4b48d Amos Kong
        ret += generate_visit_enum(expr['enum'], expr['data'])
510 06d64c62 Michael Roth
        fdef.write(ret)
511 06d64c62 Michael Roth
512 06d64c62 Michael Roth
        ret = generate_decl_enum(expr['enum'], expr['data'])
513 b9c4b48d Amos Kong
        ret += generate_enum_declaration(expr['enum'], expr['data'])
514 06d64c62 Michael Roth
        fdecl.write(ret)
515 06d64c62 Michael Roth
516 06d64c62 Michael Roth
fdecl.write('''
517 06d64c62 Michael Roth
#endif
518 06d64c62 Michael Roth
''')
519 06d64c62 Michael Roth
520 06d64c62 Michael Roth
fdecl.flush()
521 06d64c62 Michael Roth
fdecl.close()
522 06d64c62 Michael Roth
523 06d64c62 Michael Roth
fdef.flush()
524 06d64c62 Michael Roth
fdef.close()