Wenchao Xia | 21cd70d | 2014-06-18 08:43:28 +0200 | [diff] [blame] | 1 | # |
| 2 | # QAPI event generator |
| 3 | # |
| 4 | # Copyright (c) 2014 Wenchao Xia |
Eric Blake | a16e3e5 | 2016-01-29 06:48:46 -0700 | [diff] [blame] | 5 | # Copyright (c) 2015-2016 Red Hat Inc. |
Wenchao Xia | 21cd70d | 2014-06-18 08:43:28 +0200 | [diff] [blame] | 6 | # |
| 7 | # Authors: |
| 8 | # Wenchao Xia <wenchaoqemu@gmail.com> |
Markus Armbruster | 05f43a9 | 2015-09-16 13:06:14 +0200 | [diff] [blame] | 9 | # Markus Armbruster <armbru@redhat.com> |
Wenchao Xia | 21cd70d | 2014-06-18 08:43:28 +0200 | [diff] [blame] | 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 | |
Wenchao Xia | 21cd70d | 2014-06-18 08:43:28 +0200 | [diff] [blame] | 14 | from qapi import * |
Wenchao Xia | 21cd70d | 2014-06-18 08:43:28 +0200 | [diff] [blame] | 15 | |
Markus Armbruster | e98859a | 2015-09-16 13:06:16 +0200 | [diff] [blame] | 16 | |
Eric Blake | 48825ca | 2016-07-13 21:50:19 -0600 | [diff] [blame] | 17 | def gen_event_send_proto(name, arg_type, boxed): |
Markus Armbruster | 03b4367 | 2015-09-16 13:06:20 +0200 | [diff] [blame] | 18 | return 'void qapi_event_send_%(c_name)s(%(param)s)' % { |
| 19 | 'c_name': c_name(name.lower()), |
Eric Blake | 48825ca | 2016-07-13 21:50:19 -0600 | [diff] [blame] | 20 | 'param': gen_params(arg_type, boxed, 'Error **errp')} |
Wenchao Xia | 21cd70d | 2014-06-18 08:43:28 +0200 | [diff] [blame] | 21 | |
| 22 | |
Eric Blake | 48825ca | 2016-07-13 21:50:19 -0600 | [diff] [blame] | 23 | def gen_event_send_decl(name, arg_type, boxed): |
Wenchao Xia | 21cd70d | 2014-06-18 08:43:28 +0200 | [diff] [blame] | 24 | return mcgen(''' |
| 25 | |
Markus Armbruster | e98859a | 2015-09-16 13:06:16 +0200 | [diff] [blame] | 26 | %(proto)s; |
Wenchao Xia | 21cd70d | 2014-06-18 08:43:28 +0200 | [diff] [blame] | 27 | ''', |
Eric Blake | 48825ca | 2016-07-13 21:50:19 -0600 | [diff] [blame] | 28 | proto=gen_event_send_proto(name, arg_type, boxed)) |
Wenchao Xia | 21cd70d | 2014-06-18 08:43:28 +0200 | [diff] [blame] | 29 | |
Wenchao Xia | 21cd70d | 2014-06-18 08:43:28 +0200 | [diff] [blame] | 30 | |
Eric Blake | 0949e95 | 2016-03-17 16:48:32 -0600 | [diff] [blame] | 31 | # Declare and initialize an object 'qapi' using parameters from gen_params() |
| 32 | def gen_param_var(typ): |
| 33 | assert not typ.variants |
| 34 | ret = mcgen(''' |
| 35 | %(c_name)s param = { |
| 36 | ''', |
| 37 | c_name=typ.c_name()) |
| 38 | sep = ' ' |
| 39 | for memb in typ.members: |
| 40 | ret += sep |
| 41 | sep = ', ' |
| 42 | if memb.optional: |
| 43 | ret += 'has_' + c_name(memb.name) + sep |
| 44 | if memb.type.name == 'str': |
| 45 | # Cast away const added in gen_params() |
| 46 | ret += '(char *)' |
| 47 | ret += c_name(memb.name) |
| 48 | ret += mcgen(''' |
| 49 | |
| 50 | }; |
| 51 | ''') |
Eric Blake | 4d0b268 | 2016-07-13 21:50:18 -0600 | [diff] [blame] | 52 | if not typ.is_implicit(): |
| 53 | ret += mcgen(''' |
| 54 | %(c_name)s *arg = ¶m; |
| 55 | ''', |
| 56 | c_name=typ.c_name()) |
Eric Blake | 0949e95 | 2016-03-17 16:48:32 -0600 | [diff] [blame] | 57 | return ret |
| 58 | |
| 59 | |
Eric Blake | 48825ca | 2016-07-13 21:50:19 -0600 | [diff] [blame] | 60 | def gen_event_send(name, arg_type, boxed): |
Eric Blake | 0949e95 | 2016-03-17 16:48:32 -0600 | [diff] [blame] | 61 | # FIXME: Our declaration of local variables (and of 'errp' in the |
| 62 | # parameter list) can collide with exploded members of the event's |
| 63 | # data type passed in as parameters. If this collision ever hits in |
| 64 | # practice, we can rename our local variables with a leading _ prefix, |
| 65 | # or split the code into a wrapper function that creates a boxed |
| 66 | # 'param' object then calls another to do the real work. |
Markus Armbruster | e98859a | 2015-09-16 13:06:16 +0200 | [diff] [blame] | 67 | ret = mcgen(''' |
| 68 | |
| 69 | %(proto)s |
Wenchao Xia | 21cd70d | 2014-06-18 08:43:28 +0200 | [diff] [blame] | 70 | { |
| 71 | QDict *qmp; |
Eric Blake | 2a0f50e | 2015-09-29 16:21:08 -0600 | [diff] [blame] | 72 | Error *err = NULL; |
Wenchao Xia | 21cd70d | 2014-06-18 08:43:28 +0200 | [diff] [blame] | 73 | QMPEventFuncEmit emit; |
Markus Armbruster | e98859a | 2015-09-16 13:06:16 +0200 | [diff] [blame] | 74 | ''', |
Eric Blake | 48825ca | 2016-07-13 21:50:19 -0600 | [diff] [blame] | 75 | proto=gen_event_send_proto(name, arg_type, boxed)) |
Wenchao Xia | 21cd70d | 2014-06-18 08:43:28 +0200 | [diff] [blame] | 76 | |
Eric Blake | b616770 | 2016-07-13 21:50:16 -0600 | [diff] [blame] | 77 | if arg_type and not arg_type.is_empty(): |
Markus Armbruster | e98859a | 2015-09-16 13:06:16 +0200 | [diff] [blame] | 78 | ret += mcgen(''' |
Eric Blake | 3b098d5 | 2016-06-09 10:48:43 -0600 | [diff] [blame] | 79 | QObject *obj; |
Wenchao Xia | 21cd70d | 2014-06-18 08:43:28 +0200 | [diff] [blame] | 80 | Visitor *v; |
Markus Armbruster | e98859a | 2015-09-16 13:06:16 +0200 | [diff] [blame] | 81 | ''') |
Eric Blake | c818408 | 2016-07-13 21:50:20 -0600 | [diff] [blame] | 82 | if not boxed: |
| 83 | ret += gen_param_var(arg_type) |
| 84 | else: |
| 85 | assert not boxed |
Wenchao Xia | 21cd70d | 2014-06-18 08:43:28 +0200 | [diff] [blame] | 86 | |
Markus Armbruster | e98859a | 2015-09-16 13:06:16 +0200 | [diff] [blame] | 87 | ret += mcgen(''' |
Eric Blake | 0949e95 | 2016-03-17 16:48:32 -0600 | [diff] [blame] | 88 | |
Wenchao Xia | 21cd70d | 2014-06-18 08:43:28 +0200 | [diff] [blame] | 89 | emit = qmp_event_get_func_emit(); |
| 90 | if (!emit) { |
| 91 | return; |
| 92 | } |
| 93 | |
Markus Armbruster | e98859a | 2015-09-16 13:06:16 +0200 | [diff] [blame] | 94 | qmp = qmp_event_build_dict("%(name)s"); |
Wenchao Xia | 21cd70d | 2014-06-18 08:43:28 +0200 | [diff] [blame] | 95 | |
Markus Armbruster | e98859a | 2015-09-16 13:06:16 +0200 | [diff] [blame] | 96 | ''', |
| 97 | name=name) |
Wenchao Xia | 21cd70d | 2014-06-18 08:43:28 +0200 | [diff] [blame] | 98 | |
Eric Blake | b616770 | 2016-07-13 21:50:16 -0600 | [diff] [blame] | 99 | if arg_type and not arg_type.is_empty(): |
Markus Armbruster | e98859a | 2015-09-16 13:06:16 +0200 | [diff] [blame] | 100 | ret += mcgen(''' |
Daniel P. Berrange | 7d5e199 | 2016-09-30 15:45:28 +0100 | [diff] [blame] | 101 | v = qobject_output_visitor_new(&obj); |
Eric Blake | 4d0b268 | 2016-07-13 21:50:18 -0600 | [diff] [blame] | 102 | ''') |
| 103 | if not arg_type.is_implicit(): |
| 104 | ret += mcgen(''' |
| 105 | visit_type_%(c_name)s(v, "%(name)s", &arg, &err); |
| 106 | ''', |
| 107 | name=name, c_name=arg_type.c_name()) |
| 108 | else: |
| 109 | ret += mcgen(''' |
Wenchao Xia | 21cd70d | 2014-06-18 08:43:28 +0200 | [diff] [blame] | 110 | |
Eric Blake | 337283d | 2016-01-29 06:48:57 -0700 | [diff] [blame] | 111 | visit_start_struct(v, "%(name)s", NULL, 0, &err); |
Eric Blake | 0949e95 | 2016-03-17 16:48:32 -0600 | [diff] [blame] | 112 | if (err) { |
| 113 | goto out; |
| 114 | } |
| 115 | visit_type_%(c_name)s_members(v, ¶m, &err); |
Eric Blake | 15c2f66 | 2016-04-28 15:45:27 -0600 | [diff] [blame] | 116 | if (!err) { |
| 117 | visit_check_struct(v, &err); |
| 118 | } |
Eric Blake | 1158bb2 | 2016-06-09 10:48:34 -0600 | [diff] [blame] | 119 | visit_end_struct(v, NULL); |
Eric Blake | 4d0b268 | 2016-07-13 21:50:18 -0600 | [diff] [blame] | 120 | ''', |
| 121 | name=name, c_name=arg_type.c_name()) |
| 122 | ret += mcgen(''' |
Eric Blake | 2a0f50e | 2015-09-29 16:21:08 -0600 | [diff] [blame] | 123 | if (err) { |
Eric Blake | f782399 | 2015-09-29 16:21:10 -0600 | [diff] [blame] | 124 | goto out; |
Wenchao Xia | 21cd70d | 2014-06-18 08:43:28 +0200 | [diff] [blame] | 125 | } |
| 126 | |
Eric Blake | 3b098d5 | 2016-06-09 10:48:43 -0600 | [diff] [blame] | 127 | visit_complete(v, &obj); |
| 128 | qdict_put_obj(qmp, "data", obj); |
Eric Blake | 4d0b268 | 2016-07-13 21:50:18 -0600 | [diff] [blame] | 129 | ''') |
Wenchao Xia | 21cd70d | 2014-06-18 08:43:28 +0200 | [diff] [blame] | 130 | |
Markus Armbruster | e98859a | 2015-09-16 13:06:16 +0200 | [diff] [blame] | 131 | ret += mcgen(''' |
Eric Blake | 2a0f50e | 2015-09-29 16:21:08 -0600 | [diff] [blame] | 132 | emit(%(c_enum)s, qmp, &err); |
Wenchao Xia | 21cd70d | 2014-06-18 08:43:28 +0200 | [diff] [blame] | 133 | |
Markus Armbruster | e98859a | 2015-09-16 13:06:16 +0200 | [diff] [blame] | 134 | ''', |
| 135 | c_enum=c_enum_const(event_enum_name, name)) |
Wenchao Xia | 21cd70d | 2014-06-18 08:43:28 +0200 | [diff] [blame] | 136 | |
Eric Blake | b616770 | 2016-07-13 21:50:16 -0600 | [diff] [blame] | 137 | if arg_type and not arg_type.is_empty(): |
Markus Armbruster | e98859a | 2015-09-16 13:06:16 +0200 | [diff] [blame] | 138 | ret += mcgen(''' |
Eric Blake | f782399 | 2015-09-29 16:21:10 -0600 | [diff] [blame] | 139 | out: |
Eric Blake | 2c0ef9f | 2016-06-09 10:48:35 -0600 | [diff] [blame] | 140 | visit_free(v); |
Markus Armbruster | e98859a | 2015-09-16 13:06:16 +0200 | [diff] [blame] | 141 | ''') |
| 142 | ret += mcgen(''' |
Eric Blake | 2a0f50e | 2015-09-29 16:21:08 -0600 | [diff] [blame] | 143 | error_propagate(errp, err); |
Wenchao Xia | 21cd70d | 2014-06-18 08:43:28 +0200 | [diff] [blame] | 144 | QDECREF(qmp); |
| 145 | } |
Markus Armbruster | e98859a | 2015-09-16 13:06:16 +0200 | [diff] [blame] | 146 | ''') |
Wenchao Xia | 21cd70d | 2014-06-18 08:43:28 +0200 | [diff] [blame] | 147 | return ret |
| 148 | |
Markus Armbruster | 05f43a9 | 2015-09-16 13:06:14 +0200 | [diff] [blame] | 149 | |
| 150 | class QAPISchemaGenEventVisitor(QAPISchemaVisitor): |
| 151 | def __init__(self): |
| 152 | self.decl = None |
| 153 | self.defn = None |
| 154 | self._event_names = None |
| 155 | |
| 156 | def visit_begin(self, schema): |
| 157 | self.decl = '' |
| 158 | self.defn = '' |
| 159 | self._event_names = [] |
| 160 | |
| 161 | def visit_end(self): |
Markus Armbruster | e98859a | 2015-09-16 13:06:16 +0200 | [diff] [blame] | 162 | self.decl += gen_enum(event_enum_name, self._event_names) |
| 163 | self.defn += gen_enum_lookup(event_enum_name, self._event_names) |
Markus Armbruster | 05f43a9 | 2015-09-16 13:06:14 +0200 | [diff] [blame] | 164 | self._event_names = None |
| 165 | |
Eric Blake | 48825ca | 2016-07-13 21:50:19 -0600 | [diff] [blame] | 166 | def visit_event(self, name, info, arg_type, boxed): |
| 167 | self.decl += gen_event_send_decl(name, arg_type, boxed) |
| 168 | self.defn += gen_event_send(name, arg_type, boxed) |
Markus Armbruster | 05f43a9 | 2015-09-16 13:06:14 +0200 | [diff] [blame] | 169 | self._event_names.append(name) |
| 170 | |
| 171 | |
Markus Armbruster | 2114f5a | 2015-04-02 13:12:21 +0200 | [diff] [blame] | 172 | (input_file, output_dir, do_c, do_h, prefix, dummy) = parse_command_line() |
Wenchao Xia | 21cd70d | 2014-06-18 08:43:28 +0200 | [diff] [blame] | 173 | |
Markus Armbruster | 12f8e1b | 2015-04-02 14:46:39 +0200 | [diff] [blame] | 174 | c_comment = ''' |
Wenchao Xia | 21cd70d | 2014-06-18 08:43:28 +0200 | [diff] [blame] | 175 | /* |
| 176 | * schema-defined QAPI event functions |
| 177 | * |
| 178 | * Copyright (c) 2014 Wenchao Xia |
| 179 | * |
| 180 | * Authors: |
| 181 | * Wenchao Xia <wenchaoqemu@gmail.com> |
| 182 | * |
| 183 | * This work is licensed under the terms of the GNU LGPL, version 2.1 or later. |
| 184 | * See the COPYING.LIB file in the top-level directory. |
| 185 | * |
| 186 | */ |
Markus Armbruster | 12f8e1b | 2015-04-02 14:46:39 +0200 | [diff] [blame] | 187 | ''' |
| 188 | h_comment = ''' |
Wenchao Xia | 21cd70d | 2014-06-18 08:43:28 +0200 | [diff] [blame] | 189 | /* |
| 190 | * schema-defined QAPI event functions |
| 191 | * |
| 192 | * Copyright (c) 2014 Wenchao Xia |
| 193 | * |
| 194 | * Authors: |
| 195 | * Wenchao Xia <wenchaoqemu@gmail.com> |
| 196 | * |
| 197 | * This work is licensed under the terms of the GNU LGPL, version 2.1 or later. |
| 198 | * See the COPYING.LIB file in the top-level directory. |
| 199 | * |
| 200 | */ |
Markus Armbruster | 12f8e1b | 2015-04-02 14:46:39 +0200 | [diff] [blame] | 201 | ''' |
Wenchao Xia | 21cd70d | 2014-06-18 08:43:28 +0200 | [diff] [blame] | 202 | |
Markus Armbruster | 12f8e1b | 2015-04-02 14:46:39 +0200 | [diff] [blame] | 203 | (fdef, fdecl) = open_output(output_dir, do_c, do_h, prefix, |
| 204 | 'qapi-event.c', 'qapi-event.h', |
| 205 | c_comment, h_comment) |
Wenchao Xia | 21cd70d | 2014-06-18 08:43:28 +0200 | [diff] [blame] | 206 | |
Markus Armbruster | 12f8e1b | 2015-04-02 14:46:39 +0200 | [diff] [blame] | 207 | fdef.write(mcgen(''' |
Eric Blake | 9167ebd | 2016-02-08 08:36:46 -0700 | [diff] [blame] | 208 | #include "qemu/osdep.h" |
Markus Armbruster | 12f8e1b | 2015-04-02 14:46:39 +0200 | [diff] [blame] | 209 | #include "qemu-common.h" |
| 210 | #include "%(prefix)sqapi-event.h" |
| 211 | #include "%(prefix)sqapi-visit.h" |
Daniel P. Berrange | b3db211 | 2016-09-30 15:45:27 +0100 | [diff] [blame] | 212 | #include "qapi/qobject-output-visitor.h" |
Markus Armbruster | 12f8e1b | 2015-04-02 14:46:39 +0200 | [diff] [blame] | 213 | #include "qapi/qmp-event.h" |
| 214 | |
| 215 | ''', |
| 216 | prefix=prefix)) |
| 217 | |
| 218 | fdecl.write(mcgen(''' |
Wenchao Xia | 21cd70d | 2014-06-18 08:43:28 +0200 | [diff] [blame] | 219 | #include "qapi/error.h" |
| 220 | #include "qapi/qmp/qdict.h" |
| 221 | #include "%(prefix)sqapi-types.h" |
| 222 | |
| 223 | ''', |
Markus Armbruster | 12f8e1b | 2015-04-02 14:46:39 +0200 | [diff] [blame] | 224 | prefix=prefix)) |
Wenchao Xia | 21cd70d | 2014-06-18 08:43:28 +0200 | [diff] [blame] | 225 | |
Markus Armbruster | ef801a9 | 2017-03-15 13:57:08 +0100 | [diff] [blame] | 226 | event_enum_name = c_name(prefix + 'QAPIEvent', protect=False) |
Wenchao Xia | 21cd70d | 2014-06-18 08:43:28 +0200 | [diff] [blame] | 227 | |
Markus Armbruster | 05f43a9 | 2015-09-16 13:06:14 +0200 | [diff] [blame] | 228 | schema = QAPISchema(input_file) |
| 229 | gen = QAPISchemaGenEventVisitor() |
| 230 | schema.visit(gen) |
| 231 | fdef.write(gen.defn) |
| 232 | fdecl.write(gen.decl) |
Wenchao Xia | 21cd70d | 2014-06-18 08:43:28 +0200 | [diff] [blame] | 233 | |
Markus Armbruster | 12f8e1b | 2015-04-02 14:46:39 +0200 | [diff] [blame] | 234 | close_output(fdef, fdecl) |