]> Git Repo - qemu.git/blame - scripts/qapi-types.py
target-arm: Add arm_boot_info secure_boot control
[qemu.git] / scripts / qapi-types.py
CommitLineData
fb3182ce
MR
1#
2# QAPI types generator
3#
4# Copyright IBM, Corp. 2011
5#
6# Authors:
7# Anthony Liguori <[email protected]>
8#
678e48a2
MA
9# This work is licensed under the terms of the GNU GPL, version 2.
10# See the COPYING file in the top-level directory.
fb3182ce
MR
11
12from ordereddict import OrderedDict
13from qapi import *
14import sys
15import os
16import getopt
17import errno
18
c0afa9c5
MR
19def generate_fwd_struct(name, members, builtin_type=False):
20 if builtin_type:
21 return mcgen('''
22
23typedef struct %(name)sList
24{
a678e26c
MR
25 union {
26 %(type)s value;
27 uint64_t padding;
28 };
c0afa9c5
MR
29 struct %(name)sList *next;
30} %(name)sList;
31''',
32 type=c_type(name),
33 name=name)
34
fb3182ce 35 return mcgen('''
c0afa9c5 36
fb3182ce
MR
37typedef struct %(name)s %(name)s;
38
39typedef struct %(name)sList
40{
a678e26c
MR
41 union {
42 %(name)s *value;
43 uint64_t padding;
44 };
fb3182ce
MR
45 struct %(name)sList *next;
46} %(name)sList;
47''',
48 name=name)
49
b9c4b48d
AK
50def generate_fwd_enum_struct(name, members):
51 return mcgen('''
52typedef struct %(name)sList
53{
02dc4bf5
CR
54 union {
55 %(name)s value;
56 uint64_t padding;
57 };
b9c4b48d
AK
58 struct %(name)sList *next;
59} %(name)sList;
60''',
61 name=name)
62
01537030
KW
63def generate_struct_fields(members):
64 ret = ''
fb3182ce
MR
65
66 for argname, argentry, optional, structured in parse_args(members):
67 if optional:
68 ret += mcgen('''
69 bool has_%(c_name)s;
70''',
71 c_name=c_var(argname))
72 if structured:
73 push_indent()
14d36307 74 ret += generate_struct({ "field": argname, "data": argentry})
fb3182ce
MR
75 pop_indent()
76 else:
77 ret += mcgen('''
78 %(c_type)s %(c_name)s;
79''',
80 c_type=c_type(argentry), c_name=c_var(argname))
81
01537030
KW
82 return ret
83
14d36307
KW
84def generate_struct(expr):
85
86 structname = expr.get('type', "")
87 fieldname = expr.get('field', "")
88 members = expr['data']
622f557f 89 base = expr.get('base')
14d36307 90
01537030
KW
91 ret = mcgen('''
92struct %(name)s
93{
94''',
95 name=structname)
96
622f557f
KW
97 if base:
98 ret += generate_struct_fields({'base': base})
99
01537030
KW
100 ret += generate_struct_fields(members)
101
fb3182ce
MR
102 if len(fieldname):
103 fieldname = " " + fieldname
104 ret += mcgen('''
105}%(field)s;
106''',
107 field=fieldname)
108
109 return ret
110
111def generate_enum_lookup(name, values):
112 ret = mcgen('''
113const char *%(name)s_lookup[] = {
114''',
115 name=name)
116 i = 0
117 for value in values:
118 ret += mcgen('''
119 "%(value)s",
120''',
ac4ff701 121 value=value)
fb3182ce
MR
122
123 ret += mcgen('''
124 NULL,
125};
126
127''')
128 return ret
129
130def generate_enum(name, values):
131 lookup_decl = mcgen('''
132extern const char *%(name)s_lookup[];
133''',
134 name=name)
135
136 enum_decl = mcgen('''
137typedef enum %(name)s
138{
139''',
140 name=name)
141
303b54b1
LC
142 # append automatically generated _MAX value
143 enum_values = values + [ 'MAX' ]
144
fb3182ce 145 i = 0
303b54b1 146 for value in enum_values:
b0b58195 147 enum_full_value = generate_enum_full_value(name, value)
fb3182ce 148 enum_decl += mcgen('''
b0b58195 149 %(enum_full_value)s = %(i)d,
fb3182ce 150''',
b0b58195 151 enum_full_value = enum_full_value,
fb3182ce
MR
152 i=i)
153 i += 1
154
155 enum_decl += mcgen('''
156} %(name)s;
157''',
158 name=name)
159
160 return lookup_decl + enum_decl
161
69dd62df
KW
162def generate_anon_union_qtypes(expr):
163
164 name = expr['union']
165 members = expr['data']
166
167 ret = mcgen('''
168const int %(name)s_qtypes[QTYPE_MAX] = {
169''',
170 name=name)
171
172 for key in members:
173 qapi_type = members[key]
174 if builtin_type_qtypes.has_key(qapi_type):
175 qtype = builtin_type_qtypes[qapi_type]
176 elif find_struct(qapi_type):
177 qtype = "QTYPE_QDICT"
178 elif find_union(qapi_type):
179 qtype = "QTYPE_QDICT"
e775ba77
HR
180 elif find_enum(qapi_type):
181 qtype = "QTYPE_QSTRING"
69dd62df
KW
182 else:
183 assert False, "Invalid anonymous union member"
184
185 ret += mcgen('''
186 [ %(qtype)s ] = %(abbrev)s_KIND_%(enum)s,
187''',
188 qtype = qtype,
189 abbrev = de_camel_case(name).upper(),
190 enum = c_fun(de_camel_case(key),False).upper())
191
192 ret += mcgen('''
193};
194''')
195 return ret
196
197
e2503f5e
KW
198def generate_union(expr):
199
200 name = expr['union']
201 typeinfo = expr['data']
50f2bdc7 202
e2503f5e 203 base = expr.get('base')
50f2bdc7 204 discriminator = expr.get('discriminator')
e2503f5e 205
bceae769
WX
206 enum_define = discriminator_find_enum_define(expr)
207 if enum_define:
208 discriminator_type_name = enum_define['enum_name']
209 else:
210 discriminator_type_name = '%sKind' % (name)
211
fb3182ce
MR
212 ret = mcgen('''
213struct %(name)s
214{
bceae769 215 %(discriminator_type_name)s kind;
fb3182ce 216 union {
dc8fb6df 217 void *data;
fb3182ce 218''',
bceae769
WX
219 name=name,
220 discriminator_type_name=discriminator_type_name)
fb3182ce
MR
221
222 for key in typeinfo:
223 ret += mcgen('''
224 %(c_type)s %(c_name)s;
225''',
226 c_type=c_type(typeinfo[key]),
c9da228b 227 c_name=c_fun(key))
fb3182ce
MR
228
229 ret += mcgen('''
230 };
e2503f5e
KW
231''')
232
233 if base:
50f2bdc7
KW
234 base_fields = find_struct(base)['data']
235 if discriminator:
236 base_fields = base_fields.copy()
237 del base_fields[discriminator]
238 ret += generate_struct_fields(base_fields)
239 else:
240 assert not discriminator
e2503f5e
KW
241
242 ret += mcgen('''
fb3182ce
MR
243};
244''')
69dd62df
KW
245 if discriminator == {}:
246 ret += mcgen('''
247extern const int %(name)s_qtypes[];
248''',
249 name=name)
250
fb3182ce
MR
251
252 return ret
253
254def generate_type_cleanup_decl(name):
255 ret = mcgen('''
256void qapi_free_%(type)s(%(c_type)s obj);
257''',
258 c_type=c_type(name),type=name)
259 return ret
260
261def generate_type_cleanup(name):
262 ret = mcgen('''
c0afa9c5 263
fb3182ce
MR
264void qapi_free_%(type)s(%(c_type)s obj)
265{
266 QapiDeallocVisitor *md;
267 Visitor *v;
268
269 if (!obj) {
270 return;
271 }
272
273 md = qapi_dealloc_visitor_new();
274 v = qapi_dealloc_get_visitor(md);
275 visit_type_%(type)s(v, &obj, NULL, NULL);
276 qapi_dealloc_visitor_cleanup(md);
277}
278''',
279 c_type=c_type(name),type=name)
280 return ret
281
282
283try:
33aaad52 284 opts, args = getopt.gnu_getopt(sys.argv[1:], "chbp:i:o:",
c0afa9c5 285 ["source", "header", "builtins",
33aaad52 286 "prefix=", "input-file=", "output-dir="])
fb3182ce
MR
287except getopt.GetoptError, err:
288 print str(err)
289 sys.exit(1)
290
291output_dir = ""
33aaad52 292input_file = ""
fb3182ce
MR
293prefix = ""
294c_file = 'qapi-types.c'
295h_file = 'qapi-types.h'
296
8d3bc517
AK
297do_c = False
298do_h = False
c0afa9c5 299do_builtins = False
8d3bc517 300
fb3182ce
MR
301for o, a in opts:
302 if o in ("-p", "--prefix"):
303 prefix = a
33aaad52
LV
304 elif o in ("-i", "--input-file"):
305 input_file = a
fb3182ce
MR
306 elif o in ("-o", "--output-dir"):
307 output_dir = a + "/"
8d3bc517 308 elif o in ("-c", "--source"):
8d3bc517 309 do_c = True
19bf7c87
AK
310 elif o in ("-h", "--header"):
311 do_h = True
c0afa9c5
MR
312 elif o in ("-b", "--builtins"):
313 do_builtins = True
8d3bc517
AK
314
315if not do_c and not do_h:
316 do_c = True
317 do_h = True
fb3182ce
MR
318
319c_file = output_dir + prefix + c_file
320h_file = output_dir + prefix + h_file
321
322try:
323 os.makedirs(output_dir)
324except os.error, e:
325 if e.errno != errno.EEXIST:
326 raise
327
8d3bc517 328def maybe_open(really, name, opt):
8d3bc517
AK
329 if really:
330 return open(name, opt)
19bf7c87
AK
331 else:
332 import StringIO
333 return StringIO.StringIO()
8d3bc517
AK
334
335fdef = maybe_open(do_c, c_file, 'w')
336fdecl = maybe_open(do_h, h_file, 'w')
fb3182ce
MR
337
338fdef.write(mcgen('''
339/* AUTOMATICALLY GENERATED, DO NOT MODIFY */
340
341/*
342 * deallocation functions for schema-defined QAPI types
343 *
344 * Copyright IBM, Corp. 2011
345 *
346 * Authors:
347 * Anthony Liguori <[email protected]>
348 * Michael Roth <[email protected]>
349 *
350 * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
351 * See the COPYING.LIB file in the top-level directory.
352 *
353 */
354
7b1b5d19 355#include "qapi/dealloc-visitor.h"
fb3182ce
MR
356#include "%(prefix)sqapi-types.h"
357#include "%(prefix)sqapi-visit.h"
358
359''', prefix=prefix))
360
361fdecl.write(mcgen('''
362/* AUTOMATICALLY GENERATED, DO NOT MODIFY */
363
364/*
365 * schema-defined QAPI types
366 *
367 * Copyright IBM, Corp. 2011
368 *
369 * Authors:
370 * Anthony Liguori <[email protected]>
371 *
372 * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
373 * See the COPYING.LIB file in the top-level directory.
374 *
375 */
376
377#ifndef %(guard)s
378#define %(guard)s
379
da4fea06
IM
380#include <stdbool.h>
381#include <stdint.h>
b68a8472 382
fb3182ce
MR
383''',
384 guard=guardname(h_file)))
385
33aaad52 386exprs = parse_schema(input_file)
5dbee474 387exprs = filter(lambda expr: not expr.has_key('gen'), exprs)
fb3182ce 388
c0afa9c5
MR
389fdecl.write(guardstart("QAPI_TYPES_BUILTIN_STRUCT_DECL"))
390for typename in builtin_types:
391 fdecl.write(generate_fwd_struct(typename, None, builtin_type=True))
392fdecl.write(guardend("QAPI_TYPES_BUILTIN_STRUCT_DECL"))
393
fb3182ce
MR
394for expr in exprs:
395 ret = "\n"
396 if expr.has_key('type'):
397 ret += generate_fwd_struct(expr['type'], expr['data'])
398 elif expr.has_key('enum'):
b9c4b48d
AK
399 ret += generate_enum(expr['enum'], expr['data']) + "\n"
400 ret += generate_fwd_enum_struct(expr['enum'], expr['data'])
fb3182ce
MR
401 fdef.write(generate_enum_lookup(expr['enum'], expr['data']))
402 elif expr.has_key('union'):
403 ret += generate_fwd_struct(expr['union'], expr['data']) + "\n"
bceae769
WX
404 enum_define = discriminator_find_enum_define(expr)
405 if not enum_define:
406 ret += generate_enum('%sKind' % expr['union'], expr['data'].keys())
407 fdef.write(generate_enum_lookup('%sKind' % expr['union'],
408 expr['data'].keys()))
69dd62df
KW
409 if expr.get('discriminator') == {}:
410 fdef.write(generate_anon_union_qtypes(expr))
fb3182ce
MR
411 else:
412 continue
413 fdecl.write(ret)
414
c0afa9c5
MR
415# to avoid header dependency hell, we always generate declarations
416# for built-in types in our header files and simply guard them
417fdecl.write(guardstart("QAPI_TYPES_BUILTIN_CLEANUP_DECL"))
418for typename in builtin_types:
419 fdecl.write(generate_type_cleanup_decl(typename + "List"))
420fdecl.write(guardend("QAPI_TYPES_BUILTIN_CLEANUP_DECL"))
421
422# ...this doesn't work for cases where we link in multiple objects that
423# have the functions defined, so we use -b option to provide control
424# over these cases
425if do_builtins:
426 fdef.write(guardstart("QAPI_TYPES_BUILTIN_CLEANUP_DEF"))
427 for typename in builtin_types:
428 fdef.write(generate_type_cleanup(typename + "List"))
429 fdef.write(guardend("QAPI_TYPES_BUILTIN_CLEANUP_DEF"))
430
fb3182ce
MR
431for expr in exprs:
432 ret = "\n"
433 if expr.has_key('type'):
14d36307 434 ret += generate_struct(expr) + "\n"
75b96aca
MR
435 ret += generate_type_cleanup_decl(expr['type'] + "List")
436 fdef.write(generate_type_cleanup(expr['type'] + "List") + "\n")
fb3182ce
MR
437 ret += generate_type_cleanup_decl(expr['type'])
438 fdef.write(generate_type_cleanup(expr['type']) + "\n")
439 elif expr.has_key('union'):
e2503f5e 440 ret += generate_union(expr)
dc8fb6df
PB
441 ret += generate_type_cleanup_decl(expr['union'] + "List")
442 fdef.write(generate_type_cleanup(expr['union'] + "List") + "\n")
443 ret += generate_type_cleanup_decl(expr['union'])
444 fdef.write(generate_type_cleanup(expr['union']) + "\n")
b9c4b48d
AK
445 elif expr.has_key('enum'):
446 ret += generate_type_cleanup_decl(expr['enum'] + "List")
447 fdef.write(generate_type_cleanup(expr['enum'] + "List") + "\n")
fb3182ce
MR
448 else:
449 continue
450 fdecl.write(ret)
451
452fdecl.write('''
453#endif
454''')
455
456fdecl.flush()
457fdecl.close()
776574d6
AL
458
459fdef.flush()
460fdef.close()
This page took 0.381134 seconds and 4 git commands to generate.