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