1# 2# QAPI event generator 3# 4# Copyright (c) 2014 Wenchao Xia 5# Copyright (c) 2015-2016 Red Hat Inc. 6# 7# Authors: 8# Wenchao Xia <wenchaoqemu@gmail.com> 9# Markus Armbruster <armbru@redhat.com> 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 14from qapi import * 15 16 17def gen_event_send_proto(name, arg_type): 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')} 21 22 23def gen_event_send_decl(name, arg_type): 24 return mcgen(''' 25 26%(proto)s; 27''', 28 proto=gen_event_send_proto(name, arg_type)) 29 30 31def gen_event_send(name, arg_type): 32 ret = mcgen(''' 33 34%(proto)s 35{ 36 QDict *qmp; 37 Error *err = NULL; 38 QMPEventFuncEmit emit; 39''', 40 proto=gen_event_send_proto(name, arg_type)) 41 42 if arg_type and arg_type.members: 43 ret += mcgen(''' 44 QmpOutputVisitor *qov; 45 Visitor *v; 46 QObject *obj; 47 48''') 49 50 ret += mcgen(''' 51 emit = qmp_event_get_func_emit(); 52 if (!emit) { 53 return; 54 } 55 56 qmp = qmp_event_build_dict("%(name)s"); 57 58''', 59 name=name) 60 61 if arg_type and arg_type.members: 62 assert not arg_type.variants 63 ret += mcgen(''' 64 qov = qmp_output_visitor_new(); 65 v = qmp_output_get_visitor(qov); 66 67 visit_start_struct(v, "%(name)s", NULL, 0, &err); 68''', 69 name=name) 70 ret += gen_err_check() 71 ret += gen_visit_members(arg_type.members, need_cast=True, 72 label='out_obj') 73 ret += mcgen(''' 74out_obj: 75 visit_end_struct(v, err ? NULL : &err); 76 if (err) { 77 goto out; 78 } 79 80 obj = qmp_output_get_qobject(qov); 81 g_assert(obj); 82 83 qdict_put_obj(qmp, "data", obj); 84''') 85 86 ret += mcgen(''' 87 emit(%(c_enum)s, qmp, &err); 88 89''', 90 c_enum=c_enum_const(event_enum_name, name)) 91 92 if arg_type and arg_type.members: 93 ret += mcgen(''' 94out: 95 qmp_output_visitor_cleanup(qov); 96''') 97 ret += mcgen(''' 98 error_propagate(errp, err); 99 QDECREF(qmp); 100} 101''') 102 return ret 103 104 105class QAPISchemaGenEventVisitor(QAPISchemaVisitor): 106 def __init__(self): 107 self.decl = None 108 self.defn = None 109 self._event_names = None 110 111 def visit_begin(self, schema): 112 self.decl = '' 113 self.defn = '' 114 self._event_names = [] 115 116 def visit_end(self): 117 self.decl += gen_enum(event_enum_name, self._event_names) 118 self.defn += gen_enum_lookup(event_enum_name, self._event_names) 119 self._event_names = None 120 121 def visit_event(self, name, info, arg_type): 122 self.decl += gen_event_send_decl(name, arg_type) 123 self.defn += gen_event_send(name, arg_type) 124 self._event_names.append(name) 125 126 127(input_file, output_dir, do_c, do_h, prefix, dummy) = parse_command_line() 128 129c_comment = ''' 130/* 131 * schema-defined QAPI event functions 132 * 133 * Copyright (c) 2014 Wenchao Xia 134 * 135 * Authors: 136 * Wenchao Xia <wenchaoqemu@gmail.com> 137 * 138 * This work is licensed under the terms of the GNU LGPL, version 2.1 or later. 139 * See the COPYING.LIB file in the top-level directory. 140 * 141 */ 142''' 143h_comment = ''' 144/* 145 * schema-defined QAPI event functions 146 * 147 * Copyright (c) 2014 Wenchao Xia 148 * 149 * Authors: 150 * Wenchao Xia <wenchaoqemu@gmail.com> 151 * 152 * This work is licensed under the terms of the GNU LGPL, version 2.1 or later. 153 * See the COPYING.LIB file in the top-level directory. 154 * 155 */ 156''' 157 158(fdef, fdecl) = open_output(output_dir, do_c, do_h, prefix, 159 'qapi-event.c', 'qapi-event.h', 160 c_comment, h_comment) 161 162fdef.write(mcgen(''' 163#include "qemu/osdep.h" 164#include "qemu-common.h" 165#include "%(prefix)sqapi-event.h" 166#include "%(prefix)sqapi-visit.h" 167#include "qapi/qmp-output-visitor.h" 168#include "qapi/qmp-event.h" 169 170''', 171 prefix=prefix)) 172 173fdecl.write(mcgen(''' 174#include "qapi/error.h" 175#include "qapi/qmp/qdict.h" 176#include "%(prefix)sqapi-types.h" 177 178''', 179 prefix=prefix)) 180 181event_enum_name = c_name(prefix + "QAPIEvent", protect=False) 182 183schema = QAPISchema(input_file) 184gen = QAPISchemaGenEventVisitor() 185schema.visit(gen) 186fdef.write(gen.defn) 187fdecl.write(gen.decl) 188 189close_output(fdef, fdecl) 190