|
|
1.1 root 1: #
2: # QAPI visitor generator
3: #
4: # Copyright IBM, Corp. 2011
5: #
6: # Authors:
7: # Anthony Liguori <[email protected]>
8: # Michael Roth <[email protected]>
9: #
10: # This work is licensed under the terms of the GNU GPLv2.
11: # See the COPYING.LIB file in the top-level directory.
12:
13: from ordereddict import OrderedDict
14: from qapi import *
15: import sys
16: import os
17: import getopt
18: import errno
19:
20: def generate_visit_struct_body(field_prefix, members):
21: ret = ""
22: if len(field_prefix):
23: field_prefix = field_prefix + "."
24: for argname, argentry, optional, structured in parse_args(members):
25: if optional:
26: ret += mcgen('''
27: visit_start_optional(m, (obj && *obj) ? &(*obj)->%(c_prefix)shas_%(c_name)s : NULL, "%(name)s", errp);
28: if ((*obj)->%(prefix)shas_%(c_name)s) {
29: ''',
30: c_prefix=c_var(field_prefix), prefix=field_prefix,
31: c_name=c_var(argname), name=argname)
32: push_indent()
33:
34: if structured:
35: ret += mcgen('''
36: visit_start_struct(m, NULL, "", "%(name)s", 0, errp);
37: ''',
38: name=argname)
39: ret += generate_visit_struct_body(field_prefix + argname, argentry)
40: ret += mcgen('''
41: visit_end_struct(m, errp);
42: ''')
43: else:
44: ret += mcgen('''
45: visit_type_%(type)s(m, (obj && *obj) ? &(*obj)->%(c_prefix)s%(c_name)s : NULL, "%(name)s", errp);
46: ''',
47: c_prefix=c_var(field_prefix), prefix=field_prefix,
48: type=type_name(argentry), c_name=c_var(argname),
49: name=argname)
50:
51: if optional:
52: pop_indent()
53: ret += mcgen('''
54: }
55: visit_end_optional(m, errp);
56: ''')
57: return ret
58:
59: def generate_visit_struct(name, members):
60: ret = mcgen('''
61:
62: void visit_type_%(name)s(Visitor *m, %(name)s ** obj, const char *name, Error **errp)
63: {
64: visit_start_struct(m, (void **)obj, "%(name)s", name, sizeof(%(name)s), errp);
65: ''',
66: name=name)
67: push_indent()
68: ret += generate_visit_struct_body("", members)
69: pop_indent()
70:
71: ret += mcgen('''
72: visit_end_struct(m, errp);
73: }
74: ''')
75: return ret
76:
77: def generate_visit_list(name, members):
78: return mcgen('''
79:
80: void visit_type_%(name)sList(Visitor *m, %(name)sList ** obj, const char *name, Error **errp)
81: {
82: GenericList *i;
83:
84: visit_start_list(m, name, errp);
85:
86: for (i = visit_next_list(m, (GenericList **)obj, errp); i; i = visit_next_list(m, &i, errp)) {
87: %(name)sList *native_i = (%(name)sList *)i;
88: visit_type_%(name)s(m, &native_i->value, NULL, errp);
89: }
90:
91: visit_end_list(m, errp);
92: }
93: ''',
94: name=name)
95:
96: def generate_visit_enum(name, members):
97: return mcgen('''
98:
99: void visit_type_%(name)s(Visitor *m, %(name)s * obj, const char *name, Error **errp)
100: {
101: visit_type_enum(m, (int *)obj, %(name)s_lookup, "%(name)s", name, errp);
102: }
103: ''',
104: name=name)
105:
106: def generate_visit_union(name, members):
107: ret = generate_visit_enum('%sKind' % name, members.keys())
108:
109: ret += mcgen('''
110:
111: void visit_type_%(name)s(Visitor *m, %(name)s ** obj, const char *name, Error **errp)
112: {
113: }
114: ''',
115: name=name)
116:
117: return ret
118:
119: def generate_declaration(name, members, genlist=True):
120: ret = mcgen('''
121:
122: void visit_type_%(name)s(Visitor *m, %(name)s ** obj, const char *name, Error **errp);
123: ''',
124: name=name)
125:
126: if genlist:
127: ret += mcgen('''
128: void visit_type_%(name)sList(Visitor *m, %(name)sList ** obj, const char *name, Error **errp);
129: ''',
130: name=name)
131:
132: return ret
133:
134: def generate_decl_enum(name, members, genlist=True):
135: return mcgen('''
136:
137: void visit_type_%(name)s(Visitor *m, %(name)s * obj, const char *name, Error **errp);
138: ''',
139: name=name)
140:
141: try:
142: opts, args = getopt.gnu_getopt(sys.argv[1:], "p:o:", ["prefix=", "output-dir="])
143: except getopt.GetoptError, err:
144: print str(err)
145: sys.exit(1)
146:
147: output_dir = ""
148: prefix = ""
149: c_file = 'qapi-visit.c'
150: h_file = 'qapi-visit.h'
151:
152: for o, a in opts:
153: if o in ("-p", "--prefix"):
154: prefix = a
155: elif o in ("-o", "--output-dir"):
156: output_dir = a + "/"
157:
158: c_file = output_dir + prefix + c_file
159: h_file = output_dir + prefix + h_file
160:
161: try:
162: os.makedirs(output_dir)
163: except os.error, e:
164: if e.errno != errno.EEXIST:
165: raise
166:
167: fdef = open(c_file, 'w')
168: fdecl = open(h_file, 'w')
169:
170: fdef.write(mcgen('''
171: /* THIS FILE IS AUTOMATICALLY GENERATED, DO NOT MODIFY */
172:
173: /*
174: * schema-defined QAPI visitor functions
175: *
176: * Copyright IBM, Corp. 2011
177: *
178: * Authors:
179: * Anthony Liguori <[email protected]>
180: *
181: * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
182: * See the COPYING.LIB file in the top-level directory.
183: *
184: */
185:
186: #include "%(header)s"
187: ''',
188: header=basename(h_file)))
189:
190: fdecl.write(mcgen('''
191: /* THIS FILE IS AUTOMATICALLY GENERATED, DO NOT MODIFY */
192:
193: /*
194: * schema-defined QAPI visitor function
195: *
196: * Copyright IBM, Corp. 2011
197: *
198: * Authors:
199: * Anthony Liguori <[email protected]>
200: *
201: * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
202: * See the COPYING.LIB file in the top-level directory.
203: *
204: */
205:
206: #ifndef %(guard)s
207: #define %(guard)s
208:
209: #include "qapi/qapi-visit-core.h"
210: #include "%(prefix)sqapi-types.h"
211: ''',
212: prefix=prefix, guard=guardname(h_file)))
213:
214: exprs = parse_schema(sys.stdin)
215:
216: for expr in exprs:
217: if expr.has_key('type'):
218: ret = generate_visit_struct(expr['type'], expr['data'])
219: ret += generate_visit_list(expr['type'], expr['data'])
220: fdef.write(ret)
221:
222: ret = generate_declaration(expr['type'], expr['data'])
223: fdecl.write(ret)
224: elif expr.has_key('union'):
225: ret = generate_visit_union(expr['union'], expr['data'])
226: fdef.write(ret)
227:
228: ret = generate_decl_enum('%sKind' % expr['union'], expr['data'].keys())
229: ret += generate_declaration(expr['union'], expr['data'])
230: fdecl.write(ret)
231: elif expr.has_key('enum'):
232: ret = generate_visit_enum(expr['enum'], expr['data'])
233: fdef.write(ret)
234:
235: ret = generate_decl_enum(expr['enum'], expr['data'])
236: fdecl.write(ret)
237:
238: fdecl.write('''
239: #endif
240: ''')
241:
242: fdecl.flush()
243: fdecl.close()
244:
245: fdef.flush()
246: fdef.close()
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.