Statistics
| Branch: | Revision:

root / scripts / qapi-commands.py @ 8d3bc517

History | View | Annotate | Download (11.5 kB)

1 c17d9908 Michael Roth
#
2 c17d9908 Michael Roth
# QAPI command marshaller generator
3 c17d9908 Michael Roth
#
4 c17d9908 Michael Roth
# Copyright IBM, Corp. 2011
5 c17d9908 Michael Roth
#
6 c17d9908 Michael Roth
# Authors:
7 c17d9908 Michael Roth
#  Anthony Liguori <aliguori@us.ibm.com>
8 c17d9908 Michael Roth
#  Michael Roth    <mdroth@linux.vnet.ibm.com>
9 c17d9908 Michael Roth
#
10 c17d9908 Michael Roth
# This work is licensed under the terms of the GNU GPLv2.
11 c17d9908 Michael Roth
# See the COPYING.LIB file in the top-level directory.
12 c17d9908 Michael Roth
13 c17d9908 Michael Roth
from ordereddict import OrderedDict
14 c17d9908 Michael Roth
from qapi import *
15 c17d9908 Michael Roth
import sys
16 c17d9908 Michael Roth
import os
17 c17d9908 Michael Roth
import getopt
18 c17d9908 Michael Roth
import errno
19 c17d9908 Michael Roth
20 15e43e64 Anthony Liguori
def type_visitor(name):
21 15e43e64 Anthony Liguori
    if type(name) == list:
22 15e43e64 Anthony Liguori
        return 'visit_type_%sList' % name[0]
23 15e43e64 Anthony Liguori
    else:
24 15e43e64 Anthony Liguori
        return 'visit_type_%s' % name
25 15e43e64 Anthony Liguori
26 c17d9908 Michael Roth
def generate_decl_enum(name, members, genlist=True):
27 c17d9908 Michael Roth
    return mcgen('''
28 c17d9908 Michael Roth

29 15e43e64 Anthony Liguori
void %(visitor)s(Visitor *m, %(name)s * obj, const char *name, Error **errp);
30 c17d9908 Michael Roth
''',
31 15e43e64 Anthony Liguori
                 visitor=type_visitor(name))
32 c17d9908 Michael Roth
33 c17d9908 Michael Roth
def generate_command_decl(name, args, ret_type):
34 c17d9908 Michael Roth
    arglist=""
35 c17d9908 Michael Roth
    for argname, argtype, optional, structured in parse_args(args):
36 c17d9908 Michael Roth
        argtype = c_type(argtype)
37 c17d9908 Michael Roth
        if argtype == "char *":
38 c17d9908 Michael Roth
            argtype = "const char *"
39 c17d9908 Michael Roth
        if optional:
40 c17d9908 Michael Roth
            arglist += "bool has_%s, " % c_var(argname)
41 c17d9908 Michael Roth
        arglist += "%s %s, " % (argtype, c_var(argname))
42 c17d9908 Michael Roth
    return mcgen('''
43 c17d9908 Michael Roth
%(ret_type)s qmp_%(name)s(%(args)sError **errp);
44 c17d9908 Michael Roth
''',
45 c17d9908 Michael Roth
                 ret_type=c_type(ret_type), name=c_var(name), args=arglist).strip()
46 c17d9908 Michael Roth
47 c17d9908 Michael Roth
def gen_sync_call(name, args, ret_type, indent=0):
48 c17d9908 Michael Roth
    ret = ""
49 c17d9908 Michael Roth
    arglist=""
50 c17d9908 Michael Roth
    retval=""
51 c17d9908 Michael Roth
    if ret_type:
52 c17d9908 Michael Roth
        retval = "retval = "
53 c17d9908 Michael Roth
    for argname, argtype, optional, structured in parse_args(args):
54 c17d9908 Michael Roth
        if optional:
55 c17d9908 Michael Roth
            arglist += "has_%s, " % c_var(argname)
56 c17d9908 Michael Roth
        arglist += "%s, " % (c_var(argname))
57 c17d9908 Michael Roth
    push_indent(indent)
58 c17d9908 Michael Roth
    ret = mcgen('''
59 c17d9908 Michael Roth
%(retval)sqmp_%(name)s(%(args)serrp);
60 c17d9908 Michael Roth

61 c17d9908 Michael Roth
''',
62 c17d9908 Michael Roth
                name=c_var(name), args=arglist, retval=retval).rstrip()
63 c17d9908 Michael Roth
    if ret_type:
64 c17d9908 Michael Roth
        ret += "\n" + mcgen(''''
65 694a099a Luiz Capitulino
if (!error_is_set(errp)) {
66 694a099a Luiz Capitulino
    %(marshal_output_call)s
67 694a099a Luiz Capitulino
}
68 c17d9908 Michael Roth
''',
69 c17d9908 Michael Roth
                            marshal_output_call=gen_marshal_output_call(name, ret_type)).rstrip()
70 c17d9908 Michael Roth
    pop_indent(indent)
71 c17d9908 Michael Roth
    return ret.rstrip()
72 c17d9908 Michael Roth
73 c17d9908 Michael Roth
74 c17d9908 Michael Roth
def gen_marshal_output_call(name, ret_type):
75 c17d9908 Michael Roth
    if not ret_type:
76 c17d9908 Michael Roth
        return ""
77 c17d9908 Michael Roth
    return "qmp_marshal_output_%s(retval, ret, errp);" % c_var(name)
78 c17d9908 Michael Roth
79 c17d9908 Michael Roth
def gen_visitor_output_containers_decl(ret_type):
80 c17d9908 Michael Roth
    ret = ""
81 c17d9908 Michael Roth
    push_indent()
82 c17d9908 Michael Roth
    if ret_type:
83 c17d9908 Michael Roth
        ret += mcgen('''
84 c17d9908 Michael Roth
QmpOutputVisitor *mo;
85 c17d9908 Michael Roth
QapiDeallocVisitor *md;
86 c17d9908 Michael Roth
Visitor *v;
87 c17d9908 Michael Roth
''')
88 c17d9908 Michael Roth
    pop_indent()
89 c17d9908 Michael Roth
90 c17d9908 Michael Roth
    return ret
91 c17d9908 Michael Roth
92 c17d9908 Michael Roth
def gen_visitor_input_containers_decl(args):
93 c17d9908 Michael Roth
    ret = ""
94 c17d9908 Michael Roth
95 c17d9908 Michael Roth
    push_indent()
96 c17d9908 Michael Roth
    if len(args) > 0:
97 c17d9908 Michael Roth
        ret += mcgen('''
98 c17d9908 Michael Roth
QmpInputVisitor *mi;
99 c17d9908 Michael Roth
QapiDeallocVisitor *md;
100 c17d9908 Michael Roth
Visitor *v;
101 c17d9908 Michael Roth
''')
102 c17d9908 Michael Roth
    pop_indent()
103 c17d9908 Michael Roth
104 c17d9908 Michael Roth
    return ret.rstrip()
105 c17d9908 Michael Roth
106 c17d9908 Michael Roth
def gen_visitor_input_vars_decl(args):
107 c17d9908 Michael Roth
    ret = ""
108 c17d9908 Michael Roth
    push_indent()
109 c17d9908 Michael Roth
    for argname, argtype, optional, structured in parse_args(args):
110 c17d9908 Michael Roth
        if optional:
111 c17d9908 Michael Roth
            ret += mcgen('''
112 c17d9908 Michael Roth
bool has_%(argname)s = false;
113 c17d9908 Michael Roth
''',
114 c17d9908 Michael Roth
                         argname=c_var(argname))
115 c17d9908 Michael Roth
        if c_type(argtype).endswith("*"):
116 c17d9908 Michael Roth
            ret += mcgen('''
117 c17d9908 Michael Roth
%(argtype)s %(argname)s = NULL;
118 c17d9908 Michael Roth
''',
119 c17d9908 Michael Roth
                         argname=c_var(argname), argtype=c_type(argtype))
120 c17d9908 Michael Roth
        else:
121 c17d9908 Michael Roth
            ret += mcgen('''
122 c17d9908 Michael Roth
%(argtype)s %(argname)s;
123 c17d9908 Michael Roth
''',
124 c17d9908 Michael Roth
                         argname=c_var(argname), argtype=c_type(argtype))
125 c17d9908 Michael Roth
126 c17d9908 Michael Roth
    pop_indent()
127 c17d9908 Michael Roth
    return ret.rstrip()
128 c17d9908 Michael Roth
129 c17d9908 Michael Roth
def gen_visitor_input_block(args, obj, dealloc=False):
130 c17d9908 Michael Roth
    ret = ""
131 c17d9908 Michael Roth
    if len(args) == 0:
132 c17d9908 Michael Roth
        return ret
133 c17d9908 Michael Roth
134 c17d9908 Michael Roth
    push_indent()
135 c17d9908 Michael Roth
136 c17d9908 Michael Roth
    if dealloc:
137 c17d9908 Michael Roth
        ret += mcgen('''
138 c17d9908 Michael Roth
md = qapi_dealloc_visitor_new();
139 c17d9908 Michael Roth
v = qapi_dealloc_get_visitor(md);
140 c17d9908 Michael Roth
''')
141 c17d9908 Michael Roth
    else:
142 c17d9908 Michael Roth
        ret += mcgen('''
143 c17d9908 Michael Roth
mi = qmp_input_visitor_new(%(obj)s);
144 c17d9908 Michael Roth
v = qmp_input_get_visitor(mi);
145 c17d9908 Michael Roth
''',
146 c17d9908 Michael Roth
                     obj=obj)
147 c17d9908 Michael Roth
148 c17d9908 Michael Roth
    for argname, argtype, optional, structured in parse_args(args):
149 c17d9908 Michael Roth
        if optional:
150 c17d9908 Michael Roth
            ret += mcgen('''
151 c17d9908 Michael Roth
visit_start_optional(v, &has_%(c_name)s, "%(name)s", errp);
152 c17d9908 Michael Roth
if (has_%(c_name)s) {
153 c17d9908 Michael Roth
''',
154 c17d9908 Michael Roth
                         c_name=c_var(argname), name=argname)
155 c17d9908 Michael Roth
            push_indent()
156 c17d9908 Michael Roth
        ret += mcgen('''
157 15e43e64 Anthony Liguori
%(visitor)s(v, &%(c_name)s, "%(name)s", errp);
158 c17d9908 Michael Roth
''',
159 15e43e64 Anthony Liguori
                     c_name=c_var(argname), name=argname, argtype=argtype,
160 15e43e64 Anthony Liguori
                     visitor=type_visitor(argtype))
161 c17d9908 Michael Roth
        if optional:
162 c17d9908 Michael Roth
            pop_indent()
163 c17d9908 Michael Roth
            ret += mcgen('''
164 c17d9908 Michael Roth
}
165 c17d9908 Michael Roth
visit_end_optional(v, errp);
166 c17d9908 Michael Roth
''')
167 c17d9908 Michael Roth
168 c17d9908 Michael Roth
    if dealloc:
169 c17d9908 Michael Roth
        ret += mcgen('''
170 c17d9908 Michael Roth
qapi_dealloc_visitor_cleanup(md);
171 c17d9908 Michael Roth
''')
172 c17d9908 Michael Roth
    else:
173 c17d9908 Michael Roth
        ret += mcgen('''
174 c17d9908 Michael Roth
qmp_input_visitor_cleanup(mi);
175 c17d9908 Michael Roth
''')
176 c17d9908 Michael Roth
    pop_indent()
177 c17d9908 Michael Roth
    return ret.rstrip()
178 c17d9908 Michael Roth
179 776574d6 Anthony Liguori
def gen_marshal_output(name, args, ret_type, middle_mode):
180 c17d9908 Michael Roth
    if not ret_type:
181 c17d9908 Michael Roth
        return ""
182 776574d6 Anthony Liguori
183 c17d9908 Michael Roth
    ret = mcgen('''
184 c17d9908 Michael Roth
static void qmp_marshal_output_%(c_name)s(%(c_ret_type)s ret_in, QObject **ret_out, Error **errp)
185 c17d9908 Michael Roth
{
186 c17d9908 Michael Roth
    QapiDeallocVisitor *md = qapi_dealloc_visitor_new();
187 c17d9908 Michael Roth
    QmpOutputVisitor *mo = qmp_output_visitor_new();
188 c17d9908 Michael Roth
    Visitor *v;
189 c17d9908 Michael Roth

190 c17d9908 Michael Roth
    v = qmp_output_get_visitor(mo);
191 15e43e64 Anthony Liguori
    %(visitor)s(v, &ret_in, "unused", errp);
192 c17d9908 Michael Roth
    if (!error_is_set(errp)) {
193 c17d9908 Michael Roth
        *ret_out = qmp_output_get_qobject(mo);
194 c17d9908 Michael Roth
    }
195 c17d9908 Michael Roth
    qmp_output_visitor_cleanup(mo);
196 c17d9908 Michael Roth
    v = qapi_dealloc_get_visitor(md);
197 15e43e64 Anthony Liguori
    %(visitor)s(v, &ret_in, "unused", errp);
198 c17d9908 Michael Roth
    qapi_dealloc_visitor_cleanup(md);
199 c17d9908 Michael Roth
}
200 c17d9908 Michael Roth
''',
201 15e43e64 Anthony Liguori
                c_ret_type=c_type(ret_type), c_name=c_var(name),
202 15e43e64 Anthony Liguori
                visitor=type_visitor(ret_type))
203 c17d9908 Michael Roth
204 c17d9908 Michael Roth
    return ret
205 c17d9908 Michael Roth
206 776574d6 Anthony Liguori
def gen_marshal_input_decl(name, args, ret_type, middle_mode):
207 776574d6 Anthony Liguori
    if middle_mode:
208 776574d6 Anthony Liguori
        return 'int qmp_marshal_input_%s(Monitor *mon, const QDict *qdict, QObject **ret)' % c_var(name)
209 776574d6 Anthony Liguori
    else:
210 776574d6 Anthony Liguori
        return 'static void qmp_marshal_input_%s(QDict *args, QObject **ret, Error **errp)' % c_var(name)
211 776574d6 Anthony Liguori
212 776574d6 Anthony Liguori
213 776574d6 Anthony Liguori
214 776574d6 Anthony Liguori
def gen_marshal_input(name, args, ret_type, middle_mode):
215 776574d6 Anthony Liguori
    hdr = gen_marshal_input_decl(name, args, ret_type, middle_mode)
216 776574d6 Anthony Liguori
217 c17d9908 Michael Roth
    ret = mcgen('''
218 776574d6 Anthony Liguori
%(header)s
219 c17d9908 Michael Roth
{
220 c17d9908 Michael Roth
''',
221 776574d6 Anthony Liguori
                header=hdr)
222 776574d6 Anthony Liguori
223 776574d6 Anthony Liguori
    if middle_mode:
224 776574d6 Anthony Liguori
        ret += mcgen('''
225 776574d6 Anthony Liguori
    Error *local_err = NULL;
226 776574d6 Anthony Liguori
    Error **errp = &local_err;
227 776574d6 Anthony Liguori
    QDict *args = (QDict *)qdict;
228 776574d6 Anthony Liguori
''')
229 c17d9908 Michael Roth
230 c17d9908 Michael Roth
    if ret_type:
231 c17d9908 Michael Roth
        if c_type(ret_type).endswith("*"):
232 c17d9908 Michael Roth
            retval = "    %s retval = NULL;" % c_type(ret_type)
233 c17d9908 Michael Roth
        else:
234 c17d9908 Michael Roth
            retval = "    %s retval;" % c_type(ret_type)
235 c17d9908 Michael Roth
        ret += mcgen('''
236 c17d9908 Michael Roth
%(retval)s
237 c17d9908 Michael Roth
''',
238 c17d9908 Michael Roth
                     retval=retval)
239 c17d9908 Michael Roth
240 c17d9908 Michael Roth
    if len(args) > 0:
241 c17d9908 Michael Roth
        ret += mcgen('''
242 c17d9908 Michael Roth
%(visitor_input_containers_decl)s
243 c17d9908 Michael Roth
%(visitor_input_vars_decl)s
244 c17d9908 Michael Roth

245 c17d9908 Michael Roth
%(visitor_input_block)s
246 c17d9908 Michael Roth

247 c17d9908 Michael Roth
''',
248 c17d9908 Michael Roth
                     visitor_input_containers_decl=gen_visitor_input_containers_decl(args),
249 c17d9908 Michael Roth
                     visitor_input_vars_decl=gen_visitor_input_vars_decl(args),
250 c17d9908 Michael Roth
                     visitor_input_block=gen_visitor_input_block(args, "QOBJECT(args)"))
251 776574d6 Anthony Liguori
    else:
252 776574d6 Anthony Liguori
        ret += mcgen('''
253 776574d6 Anthony Liguori
    (void)args;
254 776574d6 Anthony Liguori
''')
255 c17d9908 Michael Roth
256 c17d9908 Michael Roth
    ret += mcgen('''
257 c17d9908 Michael Roth
    if (error_is_set(errp)) {
258 c17d9908 Michael Roth
        goto out;
259 c17d9908 Michael Roth
    }
260 c17d9908 Michael Roth
%(sync_call)s
261 c17d9908 Michael Roth
''',
262 c17d9908 Michael Roth
                 sync_call=gen_sync_call(name, args, ret_type, indent=4))
263 c17d9908 Michael Roth
    ret += mcgen('''
264 c17d9908 Michael Roth

265 c17d9908 Michael Roth
out:
266 c17d9908 Michael Roth
''')
267 c17d9908 Michael Roth
    ret += mcgen('''
268 c17d9908 Michael Roth
%(visitor_input_block_cleanup)s
269 776574d6 Anthony Liguori
''',
270 776574d6 Anthony Liguori
                 visitor_input_block_cleanup=gen_visitor_input_block(args, None,
271 776574d6 Anthony Liguori
                                                                     dealloc=True))
272 776574d6 Anthony Liguori
273 776574d6 Anthony Liguori
    if middle_mode:
274 776574d6 Anthony Liguori
        ret += mcgen('''
275 776574d6 Anthony Liguori

276 776574d6 Anthony Liguori
    if (local_err) {
277 776574d6 Anthony Liguori
        qerror_report_err(local_err);
278 776574d6 Anthony Liguori
        error_free(local_err);
279 776574d6 Anthony Liguori
        return -1;
280 776574d6 Anthony Liguori
    }
281 776574d6 Anthony Liguori
    return 0;
282 776574d6 Anthony Liguori
''')
283 776574d6 Anthony Liguori
    else:
284 776574d6 Anthony Liguori
        ret += mcgen('''
285 c17d9908 Michael Roth
    return;
286 776574d6 Anthony Liguori
''')
287 776574d6 Anthony Liguori
288 776574d6 Anthony Liguori
    ret += mcgen('''
289 c17d9908 Michael Roth
}
290 776574d6 Anthony Liguori
''')
291 776574d6 Anthony Liguori
292 c17d9908 Michael Roth
    return ret
293 c17d9908 Michael Roth
294 c17d9908 Michael Roth
def gen_registry(commands):
295 c17d9908 Michael Roth
    registry=""
296 c17d9908 Michael Roth
    push_indent()
297 c17d9908 Michael Roth
    for cmd in commands:
298 c17d9908 Michael Roth
        registry += mcgen('''
299 c17d9908 Michael Roth
qmp_register_command("%(name)s", qmp_marshal_input_%(c_name)s);
300 c17d9908 Michael Roth
''',
301 c17d9908 Michael Roth
                     name=cmd['command'], c_name=c_var(cmd['command']))
302 c17d9908 Michael Roth
    pop_indent()
303 c17d9908 Michael Roth
    ret = mcgen('''
304 c17d9908 Michael Roth
static void qmp_init_marshal(void)
305 c17d9908 Michael Roth
{
306 c17d9908 Michael Roth
%(registry)s
307 c17d9908 Michael Roth
}
308 c17d9908 Michael Roth

309 c17d9908 Michael Roth
qapi_init(qmp_init_marshal);
310 c17d9908 Michael Roth
''',
311 c17d9908 Michael Roth
                registry=registry.rstrip())
312 c17d9908 Michael Roth
    return ret
313 c17d9908 Michael Roth
314 c17d9908 Michael Roth
def gen_command_decl_prologue(header, guard, prefix=""):
315 c17d9908 Michael Roth
    ret = mcgen('''
316 c17d9908 Michael Roth
/* THIS FILE IS AUTOMATICALLY GENERATED, DO NOT MODIFY */
317 c17d9908 Michael Roth

318 c17d9908 Michael Roth
/*
319 c17d9908 Michael Roth
 * schema-defined QAPI function prototypes
320 c17d9908 Michael Roth
 *
321 c17d9908 Michael Roth
 * Copyright IBM, Corp. 2011
322 c17d9908 Michael Roth
 *
323 c17d9908 Michael Roth
 * Authors:
324 c17d9908 Michael Roth
 *  Anthony Liguori   <aliguori@us.ibm.com>
325 c17d9908 Michael Roth
 *
326 c17d9908 Michael Roth
 * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
327 c17d9908 Michael Roth
 * See the COPYING.LIB file in the top-level directory.
328 c17d9908 Michael Roth
 *
329 c17d9908 Michael Roth
 */
330 c17d9908 Michael Roth

331 c17d9908 Michael Roth
#ifndef %(guard)s
332 c17d9908 Michael Roth
#define %(guard)s
333 c17d9908 Michael Roth

334 c17d9908 Michael Roth
#include "%(prefix)sqapi-types.h"
335 c17d9908 Michael Roth
#include "error.h"
336 c17d9908 Michael Roth

337 c17d9908 Michael Roth
''',
338 776574d6 Anthony Liguori
                 header=basename(header), guard=guardname(header), prefix=prefix)
339 c17d9908 Michael Roth
    return ret
340 c17d9908 Michael Roth
341 c17d9908 Michael Roth
def gen_command_def_prologue(prefix="", proxy=False):
342 c17d9908 Michael Roth
    ret = mcgen('''
343 c17d9908 Michael Roth
/* THIS FILE IS AUTOMATICALLY GENERATED, DO NOT MODIFY */
344 c17d9908 Michael Roth

345 c17d9908 Michael Roth
/*
346 c17d9908 Michael Roth
 * schema-defined QMP->QAPI command dispatch
347 c17d9908 Michael Roth
 *
348 c17d9908 Michael Roth
 * Copyright IBM, Corp. 2011
349 c17d9908 Michael Roth
 *
350 c17d9908 Michael Roth
 * Authors:
351 c17d9908 Michael Roth
 *  Anthony Liguori   <aliguori@us.ibm.com>
352 c17d9908 Michael Roth
 *
353 c17d9908 Michael Roth
 * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
354 c17d9908 Michael Roth
 * See the COPYING.LIB file in the top-level directory.
355 c17d9908 Michael Roth
 *
356 c17d9908 Michael Roth
 */
357 c17d9908 Michael Roth

358 c17d9908 Michael Roth
#include "qemu-objects.h"
359 c17d9908 Michael Roth
#include "qapi/qmp-core.h"
360 c17d9908 Michael Roth
#include "qapi/qapi-visit-core.h"
361 c17d9908 Michael Roth
#include "qapi/qmp-output-visitor.h"
362 c17d9908 Michael Roth
#include "qapi/qmp-input-visitor.h"
363 c17d9908 Michael Roth
#include "qapi/qapi-dealloc-visitor.h"
364 c17d9908 Michael Roth
#include "%(prefix)sqapi-types.h"
365 c17d9908 Michael Roth
#include "%(prefix)sqapi-visit.h"
366 c17d9908 Michael Roth

367 c17d9908 Michael Roth
''',
368 c17d9908 Michael Roth
                prefix=prefix)
369 c17d9908 Michael Roth
    if not proxy:
370 c17d9908 Michael Roth
        ret += '#include "%sqmp-commands.h"' % prefix
371 776574d6 Anthony Liguori
    return ret + "\n\n"
372 c17d9908 Michael Roth
373 c17d9908 Michael Roth
374 c17d9908 Michael Roth
try:
375 8d3bc517 Avi Kivity
    opts, args = getopt.gnu_getopt(sys.argv[1:], "chp:o:m",
376 8d3bc517 Avi Kivity
                                   ["source", "header", "prefix=",
377 8d3bc517 Avi Kivity
                                    "output-dir=", "type=", "middle"])
378 c17d9908 Michael Roth
except getopt.GetoptError, err:
379 c17d9908 Michael Roth
    print str(err)
380 c17d9908 Michael Roth
    sys.exit(1)
381 c17d9908 Michael Roth
382 c17d9908 Michael Roth
output_dir = ""
383 c17d9908 Michael Roth
prefix = ""
384 c17d9908 Michael Roth
dispatch_type = "sync"
385 c17d9908 Michael Roth
c_file = 'qmp-marshal.c'
386 c17d9908 Michael Roth
h_file = 'qmp-commands.h'
387 776574d6 Anthony Liguori
middle_mode = False
388 c17d9908 Michael Roth
389 8d3bc517 Avi Kivity
do_c = False
390 8d3bc517 Avi Kivity
do_h = False
391 8d3bc517 Avi Kivity
392 c17d9908 Michael Roth
for o, a in opts:
393 c17d9908 Michael Roth
    if o in ("-p", "--prefix"):
394 c17d9908 Michael Roth
        prefix = a
395 c17d9908 Michael Roth
    elif o in ("-o", "--output-dir"):
396 c17d9908 Michael Roth
        output_dir = a + "/"
397 c17d9908 Michael Roth
    elif o in ("-t", "--type"):
398 c17d9908 Michael Roth
        dispatch_type = a
399 776574d6 Anthony Liguori
    elif o in ("-m", "--middle"):
400 776574d6 Anthony Liguori
        middle_mode = True
401 8d3bc517 Avi Kivity
    elif o in ("-c", "--source"):
402 8d3bc517 Avi Kivity
        do_h = True
403 8d3bc517 Avi Kivity
    elif o in ("-h", "--header"):
404 8d3bc517 Avi Kivity
        do_c = True
405 8d3bc517 Avi Kivity
406 8d3bc517 Avi Kivity
if not do_c and not do_h:
407 8d3bc517 Avi Kivity
    do_c = True
408 8d3bc517 Avi Kivity
    do_h = True
409 c17d9908 Michael Roth
410 c17d9908 Michael Roth
c_file = output_dir + prefix + c_file
411 c17d9908 Michael Roth
h_file = output_dir + prefix + h_file
412 c17d9908 Michael Roth
413 8d3bc517 Avi Kivity
def maybe_open(really, name, opt):
414 8d3bc517 Avi Kivity
    class Null(object):
415 8d3bc517 Avi Kivity
        def write(self, str):
416 8d3bc517 Avi Kivity
            pass
417 8d3bc517 Avi Kivity
        def read(self):
418 8d3bc517 Avi Kivity
            return ''
419 8d3bc517 Avi Kivity
    if really:
420 8d3bc517 Avi Kivity
        return open(name, opt)
421 8d3bc517 Avi Kivity
    else:
422 8d3bc517 Avi Kivity
        return Null()
423 8d3bc517 Avi Kivity
424 c17d9908 Michael Roth
try:
425 c17d9908 Michael Roth
    os.makedirs(output_dir)
426 c17d9908 Michael Roth
except os.error, e:
427 c17d9908 Michael Roth
    if e.errno != errno.EEXIST:
428 c17d9908 Michael Roth
        raise
429 c17d9908 Michael Roth
430 c17d9908 Michael Roth
exprs = parse_schema(sys.stdin)
431 c17d9908 Michael Roth
commands = filter(lambda expr: expr.has_key('command'), exprs)
432 5dbee474 Anthony Liguori
commands = filter(lambda expr: not expr.has_key('gen'), commands)
433 c17d9908 Michael Roth
434 c17d9908 Michael Roth
if dispatch_type == "sync":
435 8d3bc517 Avi Kivity
    fdecl = maybe_open(do_h, h_file, 'w')
436 8d3bc517 Avi Kivity
    fdef = maybe_open(do_c, c_file, 'w')
437 c17d9908 Michael Roth
    ret = gen_command_decl_prologue(header=basename(h_file), guard=guardname(h_file), prefix=prefix)
438 c17d9908 Michael Roth
    fdecl.write(ret)
439 c17d9908 Michael Roth
    ret = gen_command_def_prologue(prefix=prefix)
440 c17d9908 Michael Roth
    fdef.write(ret)
441 c17d9908 Michael Roth
442 c17d9908 Michael Roth
    for cmd in commands:
443 c17d9908 Michael Roth
        arglist = []
444 c17d9908 Michael Roth
        ret_type = None
445 c17d9908 Michael Roth
        if cmd.has_key('data'):
446 c17d9908 Michael Roth
            arglist = cmd['data']
447 c17d9908 Michael Roth
        if cmd.has_key('returns'):
448 c17d9908 Michael Roth
            ret_type = cmd['returns']
449 c17d9908 Michael Roth
        ret = generate_command_decl(cmd['command'], arglist, ret_type) + "\n"
450 c17d9908 Michael Roth
        fdecl.write(ret)
451 c17d9908 Michael Roth
        if ret_type:
452 776574d6 Anthony Liguori
            ret = gen_marshal_output(cmd['command'], arglist, ret_type, middle_mode) + "\n"
453 c17d9908 Michael Roth
            fdef.write(ret)
454 776574d6 Anthony Liguori
455 776574d6 Anthony Liguori
        if middle_mode:
456 776574d6 Anthony Liguori
            fdecl.write('%s;\n' % gen_marshal_input_decl(cmd['command'], arglist, ret_type, middle_mode))
457 776574d6 Anthony Liguori
458 776574d6 Anthony Liguori
        ret = gen_marshal_input(cmd['command'], arglist, ret_type, middle_mode) + "\n"
459 c17d9908 Michael Roth
        fdef.write(ret)
460 c17d9908 Michael Roth
461 7534ba01 Michael Roth
    fdecl.write("\n#endif\n");
462 776574d6 Anthony Liguori
463 776574d6 Anthony Liguori
    if not middle_mode:
464 776574d6 Anthony Liguori
        ret = gen_registry(commands)
465 776574d6 Anthony Liguori
        fdef.write(ret)
466 c17d9908 Michael Roth
467 c17d9908 Michael Roth
    fdef.flush()
468 c17d9908 Michael Roth
    fdef.close()
469 c17d9908 Michael Roth
    fdecl.flush()
470 c17d9908 Michael Roth
    fdecl.close()