Statistics
| Branch: | Revision:

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()