Statistics
| Branch: | Revision:

root / scripts / qapi-types.py @ 9943e0ec

History | View | Annotate | Download (6.7 kB)

1 fb3182ce Michael Roth
#
2 fb3182ce Michael Roth
# QAPI types generator
3 fb3182ce Michael Roth
#
4 fb3182ce Michael Roth
# Copyright IBM, Corp. 2011
5 fb3182ce Michael Roth
#
6 fb3182ce Michael Roth
# Authors:
7 fb3182ce Michael Roth
#  Anthony Liguori <aliguori@us.ibm.com>
8 fb3182ce Michael Roth
#
9 fb3182ce Michael Roth
# This work is licensed under the terms of the GNU GPLv2.
10 fb3182ce Michael Roth
# See the COPYING.LIB file in the top-level directory.
11 fb3182ce Michael Roth
12 fb3182ce Michael Roth
from ordereddict import OrderedDict
13 fb3182ce Michael Roth
from qapi import *
14 fb3182ce Michael Roth
import sys
15 fb3182ce Michael Roth
import os
16 fb3182ce Michael Roth
import getopt
17 fb3182ce Michael Roth
import errno
18 fb3182ce Michael Roth
19 fb3182ce Michael Roth
def generate_fwd_struct(name, members):
20 fb3182ce Michael Roth
    return mcgen('''
21 fb3182ce Michael Roth
typedef struct %(name)s %(name)s;
22 fb3182ce Michael Roth

23 fb3182ce Michael Roth
typedef struct %(name)sList
24 fb3182ce Michael Roth
{
25 fb3182ce Michael Roth
    %(name)s *value;
26 fb3182ce Michael Roth
    struct %(name)sList *next;
27 fb3182ce Michael Roth
} %(name)sList;
28 fb3182ce Michael Roth
''',
29 fb3182ce Michael Roth
                 name=name)
30 fb3182ce Michael Roth
31 fb3182ce Michael Roth
def generate_struct(structname, fieldname, members):
32 fb3182ce Michael Roth
    ret = mcgen('''
33 fb3182ce Michael Roth
struct %(name)s
34 fb3182ce Michael Roth
{
35 fb3182ce Michael Roth
''',
36 fb3182ce Michael Roth
          name=structname)
37 fb3182ce Michael Roth
38 fb3182ce Michael Roth
    for argname, argentry, optional, structured in parse_args(members):
39 fb3182ce Michael Roth
        if optional:
40 fb3182ce Michael Roth
            ret += mcgen('''
41 fb3182ce Michael Roth
    bool has_%(c_name)s;
42 fb3182ce Michael Roth
''',
43 fb3182ce Michael Roth
                         c_name=c_var(argname))
44 fb3182ce Michael Roth
        if structured:
45 fb3182ce Michael Roth
            push_indent()
46 fb3182ce Michael Roth
            ret += generate_struct("", argname, argentry)
47 fb3182ce Michael Roth
            pop_indent()
48 fb3182ce Michael Roth
        else:
49 fb3182ce Michael Roth
            ret += mcgen('''
50 fb3182ce Michael Roth
    %(c_type)s %(c_name)s;
51 fb3182ce Michael Roth
''',
52 fb3182ce Michael Roth
                     c_type=c_type(argentry), c_name=c_var(argname))
53 fb3182ce Michael Roth
54 fb3182ce Michael Roth
    if len(fieldname):
55 fb3182ce Michael Roth
        fieldname = " " + fieldname
56 fb3182ce Michael Roth
    ret += mcgen('''
57 fb3182ce Michael Roth
}%(field)s;
58 fb3182ce Michael Roth
''',
59 fb3182ce Michael Roth
            field=fieldname)
60 fb3182ce Michael Roth
61 fb3182ce Michael Roth
    return ret
62 fb3182ce Michael Roth
63 fb3182ce Michael Roth
def generate_enum_lookup(name, values):
64 fb3182ce Michael Roth
    ret = mcgen('''
65 fb3182ce Michael Roth
const char *%(name)s_lookup[] = {
66 fb3182ce Michael Roth
''',
67 fb3182ce Michael Roth
                         name=name)
68 fb3182ce Michael Roth
    i = 0
69 fb3182ce Michael Roth
    for value in values:
70 fb3182ce Michael Roth
        ret += mcgen('''
71 fb3182ce Michael Roth
    "%(value)s",
72 fb3182ce Michael Roth
''',
73 d2a80d6b Luiz Capitulino
                     value=value.lower())
74 fb3182ce Michael Roth
75 fb3182ce Michael Roth
    ret += mcgen('''
76 fb3182ce Michael Roth
    NULL,
77 fb3182ce Michael Roth
};
78 fb3182ce Michael Roth

79 fb3182ce Michael Roth
''')
80 fb3182ce Michael Roth
    return ret
81 fb3182ce Michael Roth
82 fb3182ce Michael Roth
def generate_enum(name, values):
83 fb3182ce Michael Roth
    lookup_decl = mcgen('''
84 fb3182ce Michael Roth
extern const char *%(name)s_lookup[];
85 fb3182ce Michael Roth
''',
86 fb3182ce Michael Roth
                name=name)
87 fb3182ce Michael Roth
88 fb3182ce Michael Roth
    enum_decl = mcgen('''
89 fb3182ce Michael Roth
typedef enum %(name)s
90 fb3182ce Michael Roth
{
91 fb3182ce Michael Roth
''',
92 fb3182ce Michael Roth
                name=name)
93 fb3182ce Michael Roth
94 303b54b1 Luiz Capitulino
    # append automatically generated _MAX value
95 303b54b1 Luiz Capitulino
    enum_values = values + [ 'MAX' ]
96 303b54b1 Luiz Capitulino
97 fb3182ce Michael Roth
    i = 0
98 303b54b1 Luiz Capitulino
    for value in enum_values:
99 fb3182ce Michael Roth
        enum_decl += mcgen('''
100 fb3182ce Michael Roth
    %(abbrev)s_%(value)s = %(i)d,
101 fb3182ce Michael Roth
''',
102 fb3182ce Michael Roth
                     abbrev=de_camel_case(name).upper(),
103 c9da228b Federico Simoncelli
                     value=c_fun(value).upper(),
104 fb3182ce Michael Roth
                     i=i)
105 fb3182ce Michael Roth
        i += 1
106 fb3182ce Michael Roth
107 fb3182ce Michael Roth
    enum_decl += mcgen('''
108 fb3182ce Michael Roth
} %(name)s;
109 fb3182ce Michael Roth
''',
110 fb3182ce Michael Roth
                 name=name)
111 fb3182ce Michael Roth
112 fb3182ce Michael Roth
    return lookup_decl + enum_decl
113 fb3182ce Michael Roth
114 fb3182ce Michael Roth
def generate_union(name, typeinfo):
115 fb3182ce Michael Roth
    ret = mcgen('''
116 fb3182ce Michael Roth
struct %(name)s
117 fb3182ce Michael Roth
{
118 fb3182ce Michael Roth
    %(name)sKind kind;
119 fb3182ce Michael Roth
    union {
120 dc8fb6df Paolo Bonzini
        void *data;
121 fb3182ce Michael Roth
''',
122 fb3182ce Michael Roth
                name=name)
123 fb3182ce Michael Roth
124 fb3182ce Michael Roth
    for key in typeinfo:
125 fb3182ce Michael Roth
        ret += mcgen('''
126 fb3182ce Michael Roth
        %(c_type)s %(c_name)s;
127 fb3182ce Michael Roth
''',
128 fb3182ce Michael Roth
                     c_type=c_type(typeinfo[key]),
129 c9da228b Federico Simoncelli
                     c_name=c_fun(key))
130 fb3182ce Michael Roth
131 fb3182ce Michael Roth
    ret += mcgen('''
132 fb3182ce Michael Roth
    };
133 fb3182ce Michael Roth
};
134 fb3182ce Michael Roth
''')
135 fb3182ce Michael Roth
136 fb3182ce Michael Roth
    return ret
137 fb3182ce Michael Roth
138 fb3182ce Michael Roth
def generate_type_cleanup_decl(name):
139 fb3182ce Michael Roth
    ret = mcgen('''
140 fb3182ce Michael Roth
void qapi_free_%(type)s(%(c_type)s obj);
141 fb3182ce Michael Roth
''',
142 fb3182ce Michael Roth
                c_type=c_type(name),type=name)
143 fb3182ce Michael Roth
    return ret
144 fb3182ce Michael Roth
145 fb3182ce Michael Roth
def generate_type_cleanup(name):
146 fb3182ce Michael Roth
    ret = mcgen('''
147 fb3182ce Michael Roth
void qapi_free_%(type)s(%(c_type)s obj)
148 fb3182ce Michael Roth
{
149 fb3182ce Michael Roth
    QapiDeallocVisitor *md;
150 fb3182ce Michael Roth
    Visitor *v;
151 fb3182ce Michael Roth

152 fb3182ce Michael Roth
    if (!obj) {
153 fb3182ce Michael Roth
        return;
154 fb3182ce Michael Roth
    }
155 fb3182ce Michael Roth

156 fb3182ce Michael Roth
    md = qapi_dealloc_visitor_new();
157 fb3182ce Michael Roth
    v = qapi_dealloc_get_visitor(md);
158 fb3182ce Michael Roth
    visit_type_%(type)s(v, &obj, NULL, NULL);
159 fb3182ce Michael Roth
    qapi_dealloc_visitor_cleanup(md);
160 fb3182ce Michael Roth
}
161 fb3182ce Michael Roth
''',
162 fb3182ce Michael Roth
                c_type=c_type(name),type=name)
163 fb3182ce Michael Roth
    return ret
164 fb3182ce Michael Roth
165 fb3182ce Michael Roth
166 fb3182ce Michael Roth
try:
167 8d3bc517 Avi Kivity
    opts, args = getopt.gnu_getopt(sys.argv[1:], "chp:o:",
168 8d3bc517 Avi Kivity
                                   ["source", "header", "prefix=", "output-dir="])
169 fb3182ce Michael Roth
except getopt.GetoptError, err:
170 fb3182ce Michael Roth
    print str(err)
171 fb3182ce Michael Roth
    sys.exit(1)
172 fb3182ce Michael Roth
173 fb3182ce Michael Roth
output_dir = ""
174 fb3182ce Michael Roth
prefix = ""
175 fb3182ce Michael Roth
c_file = 'qapi-types.c'
176 fb3182ce Michael Roth
h_file = 'qapi-types.h'
177 fb3182ce Michael Roth
178 8d3bc517 Avi Kivity
do_c = False
179 8d3bc517 Avi Kivity
do_h = False
180 8d3bc517 Avi Kivity
181 fb3182ce Michael Roth
for o, a in opts:
182 fb3182ce Michael Roth
    if o in ("-p", "--prefix"):
183 fb3182ce Michael Roth
        prefix = a
184 fb3182ce Michael Roth
    elif o in ("-o", "--output-dir"):
185 fb3182ce Michael Roth
        output_dir = a + "/"
186 8d3bc517 Avi Kivity
    elif o in ("-c", "--source"):
187 8d3bc517 Avi Kivity
        do_c = True
188 19bf7c87 Avi Kivity
    elif o in ("-h", "--header"):
189 19bf7c87 Avi Kivity
        do_h = True
190 8d3bc517 Avi Kivity
191 8d3bc517 Avi Kivity
if not do_c and not do_h:
192 8d3bc517 Avi Kivity
    do_c = True
193 8d3bc517 Avi Kivity
    do_h = True
194 fb3182ce Michael Roth
195 fb3182ce Michael Roth
c_file = output_dir + prefix + c_file
196 fb3182ce Michael Roth
h_file = output_dir + prefix + h_file
197 fb3182ce Michael Roth
198 fb3182ce Michael Roth
try:
199 fb3182ce Michael Roth
    os.makedirs(output_dir)
200 fb3182ce Michael Roth
except os.error, e:
201 fb3182ce Michael Roth
    if e.errno != errno.EEXIST:
202 fb3182ce Michael Roth
        raise
203 fb3182ce Michael Roth
204 8d3bc517 Avi Kivity
def maybe_open(really, name, opt):
205 8d3bc517 Avi Kivity
    if really:
206 8d3bc517 Avi Kivity
        return open(name, opt)
207 19bf7c87 Avi Kivity
    else:
208 19bf7c87 Avi Kivity
        import StringIO
209 19bf7c87 Avi Kivity
        return StringIO.StringIO()
210 8d3bc517 Avi Kivity
211 8d3bc517 Avi Kivity
fdef = maybe_open(do_c, c_file, 'w')
212 8d3bc517 Avi Kivity
fdecl = maybe_open(do_h, h_file, 'w')
213 fb3182ce Michael Roth
214 fb3182ce Michael Roth
fdef.write(mcgen('''
215 fb3182ce Michael Roth
/* AUTOMATICALLY GENERATED, DO NOT MODIFY */
216 fb3182ce Michael Roth

217 fb3182ce Michael Roth
/*
218 fb3182ce Michael Roth
 * deallocation functions for schema-defined QAPI types
219 fb3182ce Michael Roth
 *
220 fb3182ce Michael Roth
 * Copyright IBM, Corp. 2011
221 fb3182ce Michael Roth
 *
222 fb3182ce Michael Roth
 * Authors:
223 fb3182ce Michael Roth
 *  Anthony Liguori   <aliguori@us.ibm.com>
224 fb3182ce Michael Roth
 *  Michael Roth      <mdroth@linux.vnet.ibm.com>
225 fb3182ce Michael Roth
 *
226 fb3182ce Michael Roth
 * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
227 fb3182ce Michael Roth
 * See the COPYING.LIB file in the top-level directory.
228 fb3182ce Michael Roth
 *
229 fb3182ce Michael Roth
 */
230 fb3182ce Michael Roth

231 fb3182ce Michael Roth
#include "qapi/qapi-dealloc-visitor.h"
232 fb3182ce Michael Roth
#include "%(prefix)sqapi-types.h"
233 fb3182ce Michael Roth
#include "%(prefix)sqapi-visit.h"
234 fb3182ce Michael Roth

235 fb3182ce Michael Roth
''',             prefix=prefix))
236 fb3182ce Michael Roth
237 fb3182ce Michael Roth
fdecl.write(mcgen('''
238 fb3182ce Michael Roth
/* AUTOMATICALLY GENERATED, DO NOT MODIFY */
239 fb3182ce Michael Roth

240 fb3182ce Michael Roth
/*
241 fb3182ce Michael Roth
 * schema-defined QAPI types
242 fb3182ce Michael Roth
 *
243 fb3182ce Michael Roth
 * Copyright IBM, Corp. 2011
244 fb3182ce Michael Roth
 *
245 fb3182ce Michael Roth
 * Authors:
246 fb3182ce Michael Roth
 *  Anthony Liguori   <aliguori@us.ibm.com>
247 fb3182ce Michael Roth
 *
248 fb3182ce Michael Roth
 * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
249 fb3182ce Michael Roth
 * See the COPYING.LIB file in the top-level directory.
250 fb3182ce Michael Roth
 *
251 fb3182ce Michael Roth
 */
252 fb3182ce Michael Roth

253 fb3182ce Michael Roth
#ifndef %(guard)s
254 fb3182ce Michael Roth
#define %(guard)s
255 fb3182ce Michael Roth

256 fb3182ce Michael Roth
#include "qapi/qapi-types-core.h"
257 fb3182ce Michael Roth
''',
258 fb3182ce Michael Roth
                  guard=guardname(h_file)))
259 fb3182ce Michael Roth
260 fb3182ce Michael Roth
exprs = parse_schema(sys.stdin)
261 5dbee474 Anthony Liguori
exprs = filter(lambda expr: not expr.has_key('gen'), exprs)
262 fb3182ce Michael Roth
263 fb3182ce Michael Roth
for expr in exprs:
264 fb3182ce Michael Roth
    ret = "\n"
265 fb3182ce Michael Roth
    if expr.has_key('type'):
266 fb3182ce Michael Roth
        ret += generate_fwd_struct(expr['type'], expr['data'])
267 fb3182ce Michael Roth
    elif expr.has_key('enum'):
268 fb3182ce Michael Roth
        ret += generate_enum(expr['enum'], expr['data'])
269 fb3182ce Michael Roth
        fdef.write(generate_enum_lookup(expr['enum'], expr['data']))
270 fb3182ce Michael Roth
    elif expr.has_key('union'):
271 fb3182ce Michael Roth
        ret += generate_fwd_struct(expr['union'], expr['data']) + "\n"
272 fb3182ce Michael Roth
        ret += generate_enum('%sKind' % expr['union'], expr['data'].keys())
273 dc8fb6df Paolo Bonzini
        fdef.write(generate_enum_lookup('%sKind' % expr['union'], expr['data'].keys()))
274 fb3182ce Michael Roth
    else:
275 fb3182ce Michael Roth
        continue
276 fb3182ce Michael Roth
    fdecl.write(ret)
277 fb3182ce Michael Roth
278 fb3182ce Michael Roth
for expr in exprs:
279 fb3182ce Michael Roth
    ret = "\n"
280 fb3182ce Michael Roth
    if expr.has_key('type'):
281 fb3182ce Michael Roth
        ret += generate_struct(expr['type'], "", expr['data']) + "\n"
282 75b96aca Michael Roth
        ret += generate_type_cleanup_decl(expr['type'] + "List")
283 75b96aca Michael Roth
        fdef.write(generate_type_cleanup(expr['type'] + "List") + "\n")
284 fb3182ce Michael Roth
        ret += generate_type_cleanup_decl(expr['type'])
285 fb3182ce Michael Roth
        fdef.write(generate_type_cleanup(expr['type']) + "\n")
286 fb3182ce Michael Roth
    elif expr.has_key('union'):
287 fb3182ce Michael Roth
        ret += generate_union(expr['union'], expr['data'])
288 dc8fb6df Paolo Bonzini
        ret += generate_type_cleanup_decl(expr['union'] + "List")
289 dc8fb6df Paolo Bonzini
        fdef.write(generate_type_cleanup(expr['union'] + "List") + "\n")
290 dc8fb6df Paolo Bonzini
        ret += generate_type_cleanup_decl(expr['union'])
291 dc8fb6df Paolo Bonzini
        fdef.write(generate_type_cleanup(expr['union']) + "\n")
292 fb3182ce Michael Roth
    else:
293 fb3182ce Michael Roth
        continue
294 fb3182ce Michael Roth
    fdecl.write(ret)
295 fb3182ce Michael Roth
296 fb3182ce Michael Roth
fdecl.write('''
297 fb3182ce Michael Roth
#endif
298 fb3182ce Michael Roth
''')
299 fb3182ce Michael Roth
300 fb3182ce Michael Roth
fdecl.flush()
301 fb3182ce Michael Roth
fdecl.close()
302 776574d6 Anthony Liguori
303 776574d6 Anthony Liguori
fdef.flush()
304 776574d6 Anthony Liguori
fdef.close()