]> git.proxmox.com Git - qemu.git/blame - scripts/qapi-types.py
janitor: add guards to headers
[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 <aliguori@us.ibm.com>
8#
9# This work is licensed under the terms of the GNU GPLv2.
10# See the COPYING.LIB file in the top-level directory.
11
12from ordereddict import OrderedDict
13from qapi import *
14import sys
15import os
16import getopt
17import errno
18
19def generate_fwd_struct(name, members):
20 return mcgen('''
21typedef struct %(name)s %(name)s;
22
23typedef struct %(name)sList
24{
25 %(name)s *value;
26 struct %(name)sList *next;
27} %(name)sList;
28''',
29 name=name)
30
b9c4b48d
AK
31def generate_fwd_enum_struct(name, members):
32 return mcgen('''
33typedef struct %(name)sList
34{
35 %(name)s value;
36 struct %(name)sList *next;
37} %(name)sList;
38''',
39 name=name)
40
fb3182ce
MR
41def generate_struct(structname, fieldname, members):
42 ret = mcgen('''
43struct %(name)s
44{
45''',
46 name=structname)
47
48 for argname, argentry, optional, structured in parse_args(members):
49 if optional:
50 ret += mcgen('''
51 bool has_%(c_name)s;
52''',
53 c_name=c_var(argname))
54 if structured:
55 push_indent()
56 ret += generate_struct("", argname, argentry)
57 pop_indent()
58 else:
59 ret += mcgen('''
60 %(c_type)s %(c_name)s;
61''',
62 c_type=c_type(argentry), c_name=c_var(argname))
63
64 if len(fieldname):
65 fieldname = " " + fieldname
66 ret += mcgen('''
67}%(field)s;
68''',
69 field=fieldname)
70
71 return ret
72
73def generate_enum_lookup(name, values):
74 ret = mcgen('''
75const char *%(name)s_lookup[] = {
76''',
77 name=name)
78 i = 0
79 for value in values:
80 ret += mcgen('''
81 "%(value)s",
82''',
ac4ff701 83 value=value)
fb3182ce
MR
84
85 ret += mcgen('''
86 NULL,
87};
88
89''')
90 return ret
91
f01f594b
LC
92def generate_enum_name(name):
93 if name.isupper():
eda50a65 94 return c_fun(name, False)
f01f594b 95 new_name = ''
eda50a65 96 for c in c_fun(name, False):
f01f594b
LC
97 if c.isupper():
98 new_name += '_'
99 new_name += c
100 return new_name.lstrip('_').upper()
101
fb3182ce
MR
102def generate_enum(name, values):
103 lookup_decl = mcgen('''
104extern const char *%(name)s_lookup[];
105''',
106 name=name)
107
108 enum_decl = mcgen('''
109typedef enum %(name)s
110{
111''',
112 name=name)
113
303b54b1
LC
114 # append automatically generated _MAX value
115 enum_values = values + [ 'MAX' ]
116
fb3182ce 117 i = 0
303b54b1 118 for value in enum_values:
fb3182ce
MR
119 enum_decl += mcgen('''
120 %(abbrev)s_%(value)s = %(i)d,
121''',
122 abbrev=de_camel_case(name).upper(),
f01f594b 123 value=generate_enum_name(value),
fb3182ce
MR
124 i=i)
125 i += 1
126
127 enum_decl += mcgen('''
128} %(name)s;
129''',
130 name=name)
131
132 return lookup_decl + enum_decl
133
134def generate_union(name, typeinfo):
135 ret = mcgen('''
136struct %(name)s
137{
138 %(name)sKind kind;
139 union {
dc8fb6df 140 void *data;
fb3182ce
MR
141''',
142 name=name)
143
144 for key in typeinfo:
145 ret += mcgen('''
146 %(c_type)s %(c_name)s;
147''',
148 c_type=c_type(typeinfo[key]),
c9da228b 149 c_name=c_fun(key))
fb3182ce
MR
150
151 ret += mcgen('''
152 };
153};
154''')
155
156 return ret
157
158def generate_type_cleanup_decl(name):
159 ret = mcgen('''
160void qapi_free_%(type)s(%(c_type)s obj);
161''',
162 c_type=c_type(name),type=name)
163 return ret
164
165def generate_type_cleanup(name):
166 ret = mcgen('''
167void qapi_free_%(type)s(%(c_type)s obj)
168{
169 QapiDeallocVisitor *md;
170 Visitor *v;
171
172 if (!obj) {
173 return;
174 }
175
176 md = qapi_dealloc_visitor_new();
177 v = qapi_dealloc_get_visitor(md);
178 visit_type_%(type)s(v, &obj, NULL, NULL);
179 qapi_dealloc_visitor_cleanup(md);
180}
181''',
182 c_type=c_type(name),type=name)
183 return ret
184
185
186try:
8d3bc517
AK
187 opts, args = getopt.gnu_getopt(sys.argv[1:], "chp:o:",
188 ["source", "header", "prefix=", "output-dir="])
fb3182ce
MR
189except getopt.GetoptError, err:
190 print str(err)
191 sys.exit(1)
192
193output_dir = ""
194prefix = ""
195c_file = 'qapi-types.c'
196h_file = 'qapi-types.h'
197
8d3bc517
AK
198do_c = False
199do_h = False
200
fb3182ce
MR
201for o, a in opts:
202 if o in ("-p", "--prefix"):
203 prefix = a
204 elif o in ("-o", "--output-dir"):
205 output_dir = a + "/"
8d3bc517 206 elif o in ("-c", "--source"):
8d3bc517 207 do_c = True
19bf7c87
AK
208 elif o in ("-h", "--header"):
209 do_h = True
8d3bc517
AK
210
211if not do_c and not do_h:
212 do_c = True
213 do_h = True
fb3182ce
MR
214
215c_file = output_dir + prefix + c_file
216h_file = output_dir + prefix + h_file
217
218try:
219 os.makedirs(output_dir)
220except os.error, e:
221 if e.errno != errno.EEXIST:
222 raise
223
8d3bc517 224def maybe_open(really, name, opt):
8d3bc517
AK
225 if really:
226 return open(name, opt)
19bf7c87
AK
227 else:
228 import StringIO
229 return StringIO.StringIO()
8d3bc517
AK
230
231fdef = maybe_open(do_c, c_file, 'w')
232fdecl = maybe_open(do_h, h_file, 'w')
fb3182ce
MR
233
234fdef.write(mcgen('''
235/* AUTOMATICALLY GENERATED, DO NOT MODIFY */
236
237/*
238 * deallocation functions for schema-defined QAPI types
239 *
240 * Copyright IBM, Corp. 2011
241 *
242 * Authors:
243 * Anthony Liguori <aliguori@us.ibm.com>
244 * Michael Roth <mdroth@linux.vnet.ibm.com>
245 *
246 * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
247 * See the COPYING.LIB file in the top-level directory.
248 *
249 */
250
251#include "qapi/qapi-dealloc-visitor.h"
252#include "%(prefix)sqapi-types.h"
253#include "%(prefix)sqapi-visit.h"
254
255''', prefix=prefix))
256
257fdecl.write(mcgen('''
258/* AUTOMATICALLY GENERATED, DO NOT MODIFY */
259
260/*
261 * schema-defined QAPI types
262 *
263 * Copyright IBM, Corp. 2011
264 *
265 * Authors:
266 * Anthony Liguori <aliguori@us.ibm.com>
267 *
268 * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
269 * See the COPYING.LIB file in the top-level directory.
270 *
271 */
272
273#ifndef %(guard)s
274#define %(guard)s
275
da4fea06
IM
276#include <stdbool.h>
277#include <stdint.h>
b68a8472 278
fb3182ce
MR
279''',
280 guard=guardname(h_file)))
281
282exprs = parse_schema(sys.stdin)
5dbee474 283exprs = filter(lambda expr: not expr.has_key('gen'), exprs)
fb3182ce
MR
284
285for expr in exprs:
286 ret = "\n"
287 if expr.has_key('type'):
288 ret += generate_fwd_struct(expr['type'], expr['data'])
289 elif expr.has_key('enum'):
b9c4b48d
AK
290 ret += generate_enum(expr['enum'], expr['data']) + "\n"
291 ret += generate_fwd_enum_struct(expr['enum'], expr['data'])
fb3182ce
MR
292 fdef.write(generate_enum_lookup(expr['enum'], expr['data']))
293 elif expr.has_key('union'):
294 ret += generate_fwd_struct(expr['union'], expr['data']) + "\n"
295 ret += generate_enum('%sKind' % expr['union'], expr['data'].keys())
dc8fb6df 296 fdef.write(generate_enum_lookup('%sKind' % expr['union'], expr['data'].keys()))
fb3182ce
MR
297 else:
298 continue
299 fdecl.write(ret)
300
301for expr in exprs:
302 ret = "\n"
303 if expr.has_key('type'):
304 ret += generate_struct(expr['type'], "", expr['data']) + "\n"
75b96aca
MR
305 ret += generate_type_cleanup_decl(expr['type'] + "List")
306 fdef.write(generate_type_cleanup(expr['type'] + "List") + "\n")
fb3182ce
MR
307 ret += generate_type_cleanup_decl(expr['type'])
308 fdef.write(generate_type_cleanup(expr['type']) + "\n")
309 elif expr.has_key('union'):
310 ret += generate_union(expr['union'], expr['data'])
dc8fb6df
PB
311 ret += generate_type_cleanup_decl(expr['union'] + "List")
312 fdef.write(generate_type_cleanup(expr['union'] + "List") + "\n")
313 ret += generate_type_cleanup_decl(expr['union'])
314 fdef.write(generate_type_cleanup(expr['union']) + "\n")
b9c4b48d
AK
315 elif expr.has_key('enum'):
316 ret += generate_type_cleanup_decl(expr['enum'] + "List")
317 fdef.write(generate_type_cleanup(expr['enum'] + "List") + "\n")
fb3182ce
MR
318 else:
319 continue
320 fdecl.write(ret)
321
322fdecl.write('''
323#endif
324''')
325
326fdecl.flush()
327fdecl.close()
776574d6
AL
328
329fdef.flush()
330fdef.close()