Statistics
| Branch: | Revision:

root / scripts / qapi-visit.py @ 19bf7c87

History | View | Annotate | Download (6.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 06d64c62 Michael Roth
    visit_start_struct(m, (void **)obj, "%(name)s", name, sizeof(%(name)s), errp);
65 06d64c62 Michael Roth
''',
66 06d64c62 Michael Roth
                name=name)
67 06d64c62 Michael Roth
    push_indent()
68 06d64c62 Michael Roth
    ret += generate_visit_struct_body("", members)
69 06d64c62 Michael Roth
    pop_indent()
70 06d64c62 Michael Roth
71 06d64c62 Michael Roth
    ret += mcgen('''
72 06d64c62 Michael Roth
    visit_end_struct(m, errp);
73 06d64c62 Michael Roth
}
74 06d64c62 Michael Roth
''')
75 06d64c62 Michael Roth
    return ret
76 06d64c62 Michael Roth
77 06d64c62 Michael Roth
def generate_visit_list(name, members):
78 06d64c62 Michael Roth
    return mcgen('''
79 06d64c62 Michael Roth

80 06d64c62 Michael Roth
void visit_type_%(name)sList(Visitor *m, %(name)sList ** obj, const char *name, Error **errp)
81 06d64c62 Michael Roth
{
82 e1bc2f7b Michael Roth
    GenericList *i, **head = (GenericList **)obj;
83 06d64c62 Michael Roth

84 06d64c62 Michael Roth
    visit_start_list(m, name, errp);
85 06d64c62 Michael Roth

86 e1bc2f7b Michael Roth
    for (*head = i = visit_next_list(m, head, errp); i; i = visit_next_list(m, &i, errp)) {
87 06d64c62 Michael Roth
        %(name)sList *native_i = (%(name)sList *)i;
88 06d64c62 Michael Roth
        visit_type_%(name)s(m, &native_i->value, NULL, errp);
89 06d64c62 Michael Roth
    }
90 06d64c62 Michael Roth

91 06d64c62 Michael Roth
    visit_end_list(m, errp);
92 06d64c62 Michael Roth
}
93 06d64c62 Michael Roth
''',
94 06d64c62 Michael Roth
                name=name)
95 06d64c62 Michael Roth
96 06d64c62 Michael Roth
def generate_visit_enum(name, members):
97 06d64c62 Michael Roth
    return mcgen('''
98 06d64c62 Michael Roth

99 06d64c62 Michael Roth
void visit_type_%(name)s(Visitor *m, %(name)s * obj, const char *name, Error **errp)
100 06d64c62 Michael Roth
{
101 06d64c62 Michael Roth
    visit_type_enum(m, (int *)obj, %(name)s_lookup, "%(name)s", name, 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_union(name, members):
107 06d64c62 Michael Roth
    ret = generate_visit_enum('%sKind' % name, members.keys())
108 06d64c62 Michael Roth
109 06d64c62 Michael Roth
    ret += mcgen('''
110 06d64c62 Michael Roth

111 06d64c62 Michael Roth
void visit_type_%(name)s(Visitor *m, %(name)s ** obj, const char *name, Error **errp)
112 06d64c62 Michael Roth
{
113 06d64c62 Michael Roth
}
114 06d64c62 Michael Roth
''',
115 06d64c62 Michael Roth
                 name=name)
116 06d64c62 Michael Roth
117 06d64c62 Michael Roth
    return ret
118 06d64c62 Michael Roth
119 06d64c62 Michael Roth
def generate_declaration(name, members, genlist=True):
120 06d64c62 Michael Roth
    ret = mcgen('''
121 06d64c62 Michael Roth

122 06d64c62 Michael Roth
void visit_type_%(name)s(Visitor *m, %(name)s ** obj, const char *name, Error **errp);
123 06d64c62 Michael Roth
''',
124 06d64c62 Michael Roth
                name=name)
125 06d64c62 Michael Roth
126 06d64c62 Michael Roth
    if genlist:
127 06d64c62 Michael Roth
        ret += mcgen('''
128 06d64c62 Michael Roth
void visit_type_%(name)sList(Visitor *m, %(name)sList ** obj, const char *name, Error **errp);
129 06d64c62 Michael Roth
''',
130 06d64c62 Michael Roth
                 name=name)
131 06d64c62 Michael Roth
132 06d64c62 Michael Roth
    return ret
133 06d64c62 Michael Roth
134 06d64c62 Michael Roth
def generate_decl_enum(name, members, genlist=True):
135 06d64c62 Michael Roth
    return mcgen('''
136 06d64c62 Michael Roth

137 06d64c62 Michael Roth
void visit_type_%(name)s(Visitor *m, %(name)s * obj, const char *name, Error **errp);
138 06d64c62 Michael Roth
''',
139 06d64c62 Michael Roth
                name=name)
140 06d64c62 Michael Roth
141 06d64c62 Michael Roth
try:
142 8d3bc517 Avi Kivity
    opts, args = getopt.gnu_getopt(sys.argv[1:], "chp:o:",
143 8d3bc517 Avi Kivity
                                   ["source", "header", "prefix=", "output-dir="])
144 06d64c62 Michael Roth
except getopt.GetoptError, err:
145 06d64c62 Michael Roth
    print str(err)
146 06d64c62 Michael Roth
    sys.exit(1)
147 06d64c62 Michael Roth
148 06d64c62 Michael Roth
output_dir = ""
149 06d64c62 Michael Roth
prefix = ""
150 06d64c62 Michael Roth
c_file = 'qapi-visit.c'
151 06d64c62 Michael Roth
h_file = 'qapi-visit.h'
152 06d64c62 Michael Roth
153 8d3bc517 Avi Kivity
do_c = False
154 8d3bc517 Avi Kivity
do_h = False
155 8d3bc517 Avi Kivity
156 06d64c62 Michael Roth
for o, a in opts:
157 06d64c62 Michael Roth
    if o in ("-p", "--prefix"):
158 06d64c62 Michael Roth
        prefix = a
159 06d64c62 Michael Roth
    elif o in ("-o", "--output-dir"):
160 06d64c62 Michael Roth
        output_dir = a + "/"
161 8d3bc517 Avi Kivity
    elif o in ("-c", "--source"):
162 8d3bc517 Avi Kivity
        do_c = True
163 19bf7c87 Avi Kivity
    elif o in ("-h", "--header"):
164 19bf7c87 Avi Kivity
        do_h = True
165 8d3bc517 Avi Kivity
166 8d3bc517 Avi Kivity
if not do_c and not do_h:
167 8d3bc517 Avi Kivity
    do_c = True
168 8d3bc517 Avi Kivity
    do_h = True
169 06d64c62 Michael Roth
170 06d64c62 Michael Roth
c_file = output_dir + prefix + c_file
171 06d64c62 Michael Roth
h_file = output_dir + prefix + h_file
172 06d64c62 Michael Roth
173 06d64c62 Michael Roth
try:
174 06d64c62 Michael Roth
    os.makedirs(output_dir)
175 06d64c62 Michael Roth
except os.error, e:
176 06d64c62 Michael Roth
    if e.errno != errno.EEXIST:
177 06d64c62 Michael Roth
        raise
178 06d64c62 Michael Roth
179 8d3bc517 Avi Kivity
def maybe_open(really, name, opt):
180 8d3bc517 Avi Kivity
    if really:
181 8d3bc517 Avi Kivity
        return open(name, opt)
182 19bf7c87 Avi Kivity
    else:
183 19bf7c87 Avi Kivity
        import StringIO
184 19bf7c87 Avi Kivity
        return StringIO.StringIO()
185 8d3bc517 Avi Kivity
186 8d3bc517 Avi Kivity
fdef = maybe_open(do_c, c_file, 'w')
187 8d3bc517 Avi Kivity
fdecl = maybe_open(do_h, h_file, 'w')
188 06d64c62 Michael Roth
189 06d64c62 Michael Roth
fdef.write(mcgen('''
190 06d64c62 Michael Roth
/* THIS FILE IS AUTOMATICALLY GENERATED, DO NOT MODIFY */
191 06d64c62 Michael Roth

192 06d64c62 Michael Roth
/*
193 06d64c62 Michael Roth
 * schema-defined QAPI visitor functions
194 06d64c62 Michael Roth
 *
195 06d64c62 Michael Roth
 * Copyright IBM, Corp. 2011
196 06d64c62 Michael Roth
 *
197 06d64c62 Michael Roth
 * Authors:
198 06d64c62 Michael Roth
 *  Anthony Liguori   <aliguori@us.ibm.com>
199 06d64c62 Michael Roth
 *
200 06d64c62 Michael Roth
 * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
201 06d64c62 Michael Roth
 * See the COPYING.LIB file in the top-level directory.
202 06d64c62 Michael Roth
 *
203 06d64c62 Michael Roth
 */
204 06d64c62 Michael Roth

205 06d64c62 Michael Roth
#include "%(header)s"
206 06d64c62 Michael Roth
''',
207 06d64c62 Michael Roth
                 header=basename(h_file)))
208 06d64c62 Michael Roth
209 06d64c62 Michael Roth
fdecl.write(mcgen('''
210 06d64c62 Michael Roth
/* THIS FILE IS AUTOMATICALLY GENERATED, DO NOT MODIFY */
211 06d64c62 Michael Roth

212 06d64c62 Michael Roth
/*
213 06d64c62 Michael Roth
 * schema-defined QAPI visitor function
214 06d64c62 Michael Roth
 *
215 06d64c62 Michael Roth
 * Copyright IBM, Corp. 2011
216 06d64c62 Michael Roth
 *
217 06d64c62 Michael Roth
 * Authors:
218 06d64c62 Michael Roth
 *  Anthony Liguori   <aliguori@us.ibm.com>
219 06d64c62 Michael Roth
 *
220 06d64c62 Michael Roth
 * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
221 06d64c62 Michael Roth
 * See the COPYING.LIB file in the top-level directory.
222 06d64c62 Michael Roth
 *
223 06d64c62 Michael Roth
 */
224 06d64c62 Michael Roth

225 06d64c62 Michael Roth
#ifndef %(guard)s
226 06d64c62 Michael Roth
#define %(guard)s
227 06d64c62 Michael Roth

228 06d64c62 Michael Roth
#include "qapi/qapi-visit-core.h"
229 06d64c62 Michael Roth
#include "%(prefix)sqapi-types.h"
230 06d64c62 Michael Roth
''',
231 06d64c62 Michael Roth
                  prefix=prefix, guard=guardname(h_file)))
232 06d64c62 Michael Roth
233 06d64c62 Michael Roth
exprs = parse_schema(sys.stdin)
234 06d64c62 Michael Roth
235 06d64c62 Michael Roth
for expr in exprs:
236 06d64c62 Michael Roth
    if expr.has_key('type'):
237 06d64c62 Michael Roth
        ret = generate_visit_struct(expr['type'], expr['data'])
238 06d64c62 Michael Roth
        ret += generate_visit_list(expr['type'], expr['data'])
239 06d64c62 Michael Roth
        fdef.write(ret)
240 06d64c62 Michael Roth
241 06d64c62 Michael Roth
        ret = generate_declaration(expr['type'], expr['data'])
242 06d64c62 Michael Roth
        fdecl.write(ret)
243 06d64c62 Michael Roth
    elif expr.has_key('union'):
244 06d64c62 Michael Roth
        ret = generate_visit_union(expr['union'], expr['data'])
245 06d64c62 Michael Roth
        fdef.write(ret)
246 06d64c62 Michael Roth
247 06d64c62 Michael Roth
        ret = generate_decl_enum('%sKind' % expr['union'], expr['data'].keys())
248 06d64c62 Michael Roth
        ret += generate_declaration(expr['union'], expr['data'])
249 06d64c62 Michael Roth
        fdecl.write(ret)
250 06d64c62 Michael Roth
    elif expr.has_key('enum'):
251 06d64c62 Michael Roth
        ret = generate_visit_enum(expr['enum'], expr['data'])
252 06d64c62 Michael Roth
        fdef.write(ret)
253 06d64c62 Michael Roth
254 06d64c62 Michael Roth
        ret = generate_decl_enum(expr['enum'], expr['data'])
255 06d64c62 Michael Roth
        fdecl.write(ret)
256 06d64c62 Michael Roth
257 06d64c62 Michael Roth
fdecl.write('''
258 06d64c62 Michael Roth
#endif
259 06d64c62 Michael Roth
''')
260 06d64c62 Michael Roth
261 06d64c62 Michael Roth
fdecl.flush()
262 06d64c62 Michael Roth
fdecl.close()
263 06d64c62 Michael Roth
264 06d64c62 Michael Roth
fdef.flush()
265 06d64c62 Michael Roth
fdef.close()