]>
Commit | Line | Data |
---|---|---|
21cd70df WX |
1 | # |
2 | # QAPI event generator | |
3 | # | |
4 | # Copyright (c) 2014 Wenchao Xia | |
05f43a96 | 5 | # Copyright (c) 2015 Red Hat Inc. |
21cd70df WX |
6 | # |
7 | # Authors: | |
8 | # Wenchao Xia <wenchaoqemu@gmail.com> | |
05f43a96 | 9 | # Markus Armbruster <armbru@redhat.com> |
21cd70df WX |
10 | # |
11 | # This work is licensed under the terms of the GNU GPL, version 2. | |
12 | # See the COPYING file in the top-level directory. | |
13 | ||
21cd70df | 14 | from qapi import * |
21cd70df | 15 | |
e98859a9 MA |
16 | |
17 | def gen_event_send_proto(name, arg_type): | |
03b4367a MA |
18 | return 'void qapi_event_send_%(c_name)s(%(param)s)' % { |
19 | 'c_name': c_name(name.lower()), | |
20 | 'param': gen_params(arg_type, 'Error **errp')} | |
21cd70df | 21 | |
21cd70df | 22 | |
e98859a9 | 23 | def gen_event_send_decl(name, arg_type): |
21cd70df WX |
24 | return mcgen(''' |
25 | ||
e98859a9 | 26 | %(proto)s; |
21cd70df | 27 | ''', |
e98859a9 MA |
28 | proto=gen_event_send_proto(name, arg_type)) |
29 | ||
21cd70df | 30 | |
e98859a9 MA |
31 | def gen_event_send(name, arg_type): |
32 | ret = mcgen(''' | |
21cd70df | 33 | |
e98859a9 | 34 | %(proto)s |
21cd70df WX |
35 | { |
36 | QDict *qmp; | |
37 | Error *local_err = NULL; | |
38 | QMPEventFuncEmit emit; | |
e98859a9 MA |
39 | ''', |
40 | proto=gen_event_send_proto(name, arg_type)) | |
21cd70df | 41 | |
e98859a9 MA |
42 | if arg_type and arg_type.members: |
43 | ret += mcgen(''' | |
21cd70df WX |
44 | QmpOutputVisitor *qov; |
45 | Visitor *v; | |
46 | QObject *obj; | |
47 | ||
e98859a9 | 48 | ''') |
21cd70df | 49 | |
e98859a9 | 50 | ret += mcgen(''' |
21cd70df WX |
51 | emit = qmp_event_get_func_emit(); |
52 | if (!emit) { | |
53 | return; | |
54 | } | |
55 | ||
e98859a9 | 56 | qmp = qmp_event_build_dict("%(name)s"); |
21cd70df | 57 | |
e98859a9 MA |
58 | ''', |
59 | name=name) | |
21cd70df | 60 | |
e98859a9 MA |
61 | if arg_type and arg_type.members: |
62 | ret += mcgen(''' | |
21cd70df WX |
63 | qov = qmp_output_visitor_new(); |
64 | g_assert(qov); | |
65 | ||
66 | v = qmp_output_get_visitor(qov); | |
67 | g_assert(v); | |
68 | ||
69 | /* Fake visit, as if all members are under a structure */ | |
e98859a9 | 70 | visit_start_struct(v, NULL, "", "%(name)s", 0, &local_err); |
21cd70df WX |
71 | if (local_err) { |
72 | goto clean; | |
73 | } | |
74 | ||
e98859a9 MA |
75 | ''', |
76 | name=name) | |
21cd70df | 77 | |
e98859a9 | 78 | for memb in arg_type.members: |
05f43a96 | 79 | if memb.optional: |
e98859a9 MA |
80 | ret += mcgen(''' |
81 | if (has_%(c_name)s) { | |
82 | ''', | |
83 | c_name=c_name(memb.name)) | |
21cd70df WX |
84 | push_indent() |
85 | ||
e98859a9 | 86 | # Ugly: need to cast away the const |
05f43a96 | 87 | if memb.type.name == "str": |
e98859a9 | 88 | cast = '(char **)' |
21cd70df | 89 | else: |
e98859a9 | 90 | cast = '' |
21cd70df | 91 | |
e98859a9 MA |
92 | ret += mcgen(''' |
93 | visit_type_%(c_type)s(v, %(cast)s&%(c_name)s, "%(name)s", &local_err); | |
21cd70df WX |
94 | if (local_err) { |
95 | goto clean; | |
96 | } | |
e98859a9 MA |
97 | ''', |
98 | cast=cast, | |
99 | c_name=c_name(memb.name), | |
100 | c_type=memb.type.c_name(), | |
05f43a96 | 101 | name=memb.name) |
21cd70df | 102 | |
05f43a96 | 103 | if memb.optional: |
21cd70df | 104 | pop_indent() |
e98859a9 | 105 | ret += mcgen(''' |
21cd70df | 106 | } |
e98859a9 | 107 | ''') |
21cd70df | 108 | |
e98859a9 | 109 | ret += mcgen(''' |
21cd70df WX |
110 | |
111 | visit_end_struct(v, &local_err); | |
112 | if (local_err) { | |
113 | goto clean; | |
114 | } | |
115 | ||
116 | obj = qmp_output_get_qobject(qov); | |
117 | g_assert(obj != NULL); | |
118 | ||
119 | qdict_put_obj(qmp, "data", obj); | |
e98859a9 | 120 | ''') |
21cd70df | 121 | |
e98859a9 MA |
122 | ret += mcgen(''' |
123 | emit(%(c_enum)s, qmp, &local_err); | |
21cd70df | 124 | |
e98859a9 MA |
125 | ''', |
126 | c_enum=c_enum_const(event_enum_name, name)) | |
21cd70df | 127 | |
e98859a9 MA |
128 | if arg_type and arg_type.members: |
129 | ret += mcgen(''' | |
21cd70df WX |
130 | clean: |
131 | qmp_output_visitor_cleanup(qov); | |
e98859a9 MA |
132 | ''') |
133 | ret += mcgen(''' | |
21cd70df WX |
134 | error_propagate(errp, local_err); |
135 | QDECREF(qmp); | |
136 | } | |
e98859a9 | 137 | ''') |
21cd70df WX |
138 | return ret |
139 | ||
05f43a96 MA |
140 | |
141 | class QAPISchemaGenEventVisitor(QAPISchemaVisitor): | |
142 | def __init__(self): | |
143 | self.decl = None | |
144 | self.defn = None | |
145 | self._event_names = None | |
146 | ||
147 | def visit_begin(self, schema): | |
148 | self.decl = '' | |
149 | self.defn = '' | |
150 | self._event_names = [] | |
151 | ||
152 | def visit_end(self): | |
e98859a9 MA |
153 | self.decl += gen_enum(event_enum_name, self._event_names) |
154 | self.defn += gen_enum_lookup(event_enum_name, self._event_names) | |
05f43a96 MA |
155 | self._event_names = None |
156 | ||
157 | def visit_event(self, name, info, arg_type): | |
e98859a9 MA |
158 | self.decl += gen_event_send_decl(name, arg_type) |
159 | self.defn += gen_event_send(name, arg_type) | |
05f43a96 MA |
160 | self._event_names.append(name) |
161 | ||
162 | ||
2114f5a9 | 163 | (input_file, output_dir, do_c, do_h, prefix, dummy) = parse_command_line() |
21cd70df | 164 | |
12f8e1b9 | 165 | c_comment = ''' |
21cd70df WX |
166 | /* |
167 | * schema-defined QAPI event functions | |
168 | * | |
169 | * Copyright (c) 2014 Wenchao Xia | |
170 | * | |
171 | * Authors: | |
172 | * Wenchao Xia <wenchaoqemu@gmail.com> | |
173 | * | |
174 | * This work is licensed under the terms of the GNU LGPL, version 2.1 or later. | |
175 | * See the COPYING.LIB file in the top-level directory. | |
176 | * | |
177 | */ | |
12f8e1b9 MA |
178 | ''' |
179 | h_comment = ''' | |
21cd70df WX |
180 | /* |
181 | * schema-defined QAPI event functions | |
182 | * | |
183 | * Copyright (c) 2014 Wenchao Xia | |
184 | * | |
185 | * Authors: | |
186 | * Wenchao Xia <wenchaoqemu@gmail.com> | |
187 | * | |
188 | * This work is licensed under the terms of the GNU LGPL, version 2.1 or later. | |
189 | * See the COPYING.LIB file in the top-level directory. | |
190 | * | |
191 | */ | |
12f8e1b9 | 192 | ''' |
21cd70df | 193 | |
12f8e1b9 MA |
194 | (fdef, fdecl) = open_output(output_dir, do_c, do_h, prefix, |
195 | 'qapi-event.c', 'qapi-event.h', | |
196 | c_comment, h_comment) | |
21cd70df | 197 | |
12f8e1b9 MA |
198 | fdef.write(mcgen(''' |
199 | #include "qemu-common.h" | |
200 | #include "%(prefix)sqapi-event.h" | |
201 | #include "%(prefix)sqapi-visit.h" | |
202 | #include "qapi/qmp-output-visitor.h" | |
203 | #include "qapi/qmp-event.h" | |
204 | ||
205 | ''', | |
206 | prefix=prefix)) | |
207 | ||
208 | fdecl.write(mcgen(''' | |
21cd70df WX |
209 | #include "qapi/error.h" |
210 | #include "qapi/qmp/qdict.h" | |
211 | #include "%(prefix)sqapi-types.h" | |
212 | ||
213 | ''', | |
12f8e1b9 | 214 | prefix=prefix)) |
21cd70df | 215 | |
016a335b | 216 | event_enum_name = c_name(prefix + "QAPIEvent", protect=False) |
05f43a96 MA |
217 | |
218 | schema = QAPISchema(input_file) | |
219 | gen = QAPISchemaGenEventVisitor() | |
220 | schema.visit(gen) | |
221 | fdef.write(gen.defn) | |
222 | fdecl.write(gen.decl) | |
21cd70df | 223 | |
12f8e1b9 | 224 | close_output(fdef, fdecl) |