]> git.proxmox.com Git - mirror_qemu.git/blame - scripts/qapi-event.py
qapi: Reuse code for flat union base validation
[mirror_qemu.git] / scripts / qapi-event.py
CommitLineData
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 14from qapi import *
21cd70df 15
e98859a9
MA
16
17def 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 23def 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
31def 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
141class 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 165c_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'''
179h_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
198fdef.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
208fdecl.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 216event_enum_name = c_name(prefix + "QAPIEvent", protect=False)
05f43a96
MA
217
218schema = QAPISchema(input_file)
219gen = QAPISchemaGenEventVisitor()
220schema.visit(gen)
221fdef.write(gen.defn)
222fdecl.write(gen.decl)
21cd70df 223
12f8e1b9 224close_output(fdef, fdecl)