xref: /qemu/scripts/qapi/events.py (revision 2a0f50e8d973b01eda4c63bac4a5c79ea0f584ef)
121cd70dfSWenchao Xia#
221cd70dfSWenchao Xia# QAPI event generator
321cd70dfSWenchao Xia#
421cd70dfSWenchao Xia# Copyright (c) 2014 Wenchao Xia
505f43a96SMarkus Armbruster# Copyright (c) 2015 Red Hat Inc.
621cd70dfSWenchao Xia#
721cd70dfSWenchao Xia# Authors:
821cd70dfSWenchao Xia#  Wenchao Xia <wenchaoqemu@gmail.com>
905f43a96SMarkus Armbruster#  Markus Armbruster <armbru@redhat.com>
1021cd70dfSWenchao Xia#
1121cd70dfSWenchao Xia# This work is licensed under the terms of the GNU GPL, version 2.
1221cd70dfSWenchao Xia# See the COPYING file in the top-level directory.
1321cd70dfSWenchao Xia
1421cd70dfSWenchao Xiafrom qapi import *
1521cd70dfSWenchao Xia
16e98859a9SMarkus Armbruster
17e98859a9SMarkus Armbrusterdef gen_event_send_proto(name, arg_type):
1803b4367aSMarkus Armbruster    return 'void qapi_event_send_%(c_name)s(%(param)s)' % {
1903b4367aSMarkus Armbruster        'c_name': c_name(name.lower()),
2003b4367aSMarkus Armbruster        'param': gen_params(arg_type, 'Error **errp')}
2121cd70dfSWenchao Xia
2221cd70dfSWenchao Xia
23e98859a9SMarkus Armbrusterdef gen_event_send_decl(name, arg_type):
2421cd70dfSWenchao Xia    return mcgen('''
2521cd70dfSWenchao Xia
26e98859a9SMarkus Armbruster%(proto)s;
2721cd70dfSWenchao Xia''',
28e98859a9SMarkus Armbruster                 proto=gen_event_send_proto(name, arg_type))
2921cd70dfSWenchao Xia
3021cd70dfSWenchao Xia
31e98859a9SMarkus Armbrusterdef gen_event_send(name, arg_type):
32e98859a9SMarkus Armbruster    ret = mcgen('''
33e98859a9SMarkus Armbruster
34e98859a9SMarkus Armbruster%(proto)s
3521cd70dfSWenchao Xia{
3621cd70dfSWenchao Xia    QDict *qmp;
37*2a0f50e8SEric Blake    Error *err = NULL;
3821cd70dfSWenchao Xia    QMPEventFuncEmit emit;
39e98859a9SMarkus Armbruster''',
40e98859a9SMarkus Armbruster                proto=gen_event_send_proto(name, arg_type))
4121cd70dfSWenchao Xia
42e98859a9SMarkus Armbruster    if arg_type and arg_type.members:
43e98859a9SMarkus Armbruster        ret += mcgen('''
4421cd70dfSWenchao Xia    QmpOutputVisitor *qov;
4521cd70dfSWenchao Xia    Visitor *v;
4621cd70dfSWenchao Xia    QObject *obj;
4721cd70dfSWenchao Xia
48e98859a9SMarkus Armbruster''')
4921cd70dfSWenchao Xia
50e98859a9SMarkus Armbruster    ret += mcgen('''
5121cd70dfSWenchao Xia    emit = qmp_event_get_func_emit();
5221cd70dfSWenchao Xia    if (!emit) {
5321cd70dfSWenchao Xia        return;
5421cd70dfSWenchao Xia    }
5521cd70dfSWenchao Xia
56e98859a9SMarkus Armbruster    qmp = qmp_event_build_dict("%(name)s");
5721cd70dfSWenchao Xia
58e98859a9SMarkus Armbruster''',
59e98859a9SMarkus Armbruster                 name=name)
6021cd70dfSWenchao Xia
61e98859a9SMarkus Armbruster    if arg_type and arg_type.members:
62e98859a9SMarkus Armbruster        ret += mcgen('''
6321cd70dfSWenchao Xia    qov = qmp_output_visitor_new();
6421cd70dfSWenchao Xia    g_assert(qov);
6521cd70dfSWenchao Xia
6621cd70dfSWenchao Xia    v = qmp_output_get_visitor(qov);
6721cd70dfSWenchao Xia    g_assert(v);
6821cd70dfSWenchao Xia
6921cd70dfSWenchao Xia    /* Fake visit, as if all members are under a structure */
70*2a0f50e8SEric Blake    visit_start_struct(v, NULL, "", "%(name)s", 0, &err);
71*2a0f50e8SEric Blake    if (err) {
7221cd70dfSWenchao Xia        goto clean;
7321cd70dfSWenchao Xia    }
7421cd70dfSWenchao Xia
75e98859a9SMarkus Armbruster''',
76e98859a9SMarkus Armbruster                     name=name)
7721cd70dfSWenchao Xia
78e98859a9SMarkus Armbruster        for memb in arg_type.members:
7905f43a96SMarkus Armbruster            if memb.optional:
80e98859a9SMarkus Armbruster                ret += mcgen('''
81e98859a9SMarkus Armbruster    if (has_%(c_name)s) {
82e98859a9SMarkus Armbruster''',
83e98859a9SMarkus Armbruster                             c_name=c_name(memb.name))
8421cd70dfSWenchao Xia                push_indent()
8521cd70dfSWenchao Xia
86e98859a9SMarkus Armbruster            # Ugly: need to cast away the const
8705f43a96SMarkus Armbruster            if memb.type.name == "str":
88e98859a9SMarkus Armbruster                cast = '(char **)'
8921cd70dfSWenchao Xia            else:
90e98859a9SMarkus Armbruster                cast = ''
9121cd70dfSWenchao Xia
92e98859a9SMarkus Armbruster            ret += mcgen('''
93*2a0f50e8SEric Blake    visit_type_%(c_type)s(v, %(cast)s&%(c_name)s, "%(name)s", &err);
94*2a0f50e8SEric Blake    if (err) {
9521cd70dfSWenchao Xia        goto clean;
9621cd70dfSWenchao Xia    }
97e98859a9SMarkus Armbruster''',
98e98859a9SMarkus Armbruster                         cast=cast,
99e98859a9SMarkus Armbruster                         c_name=c_name(memb.name),
100e98859a9SMarkus Armbruster                         c_type=memb.type.c_name(),
10105f43a96SMarkus Armbruster                         name=memb.name)
10221cd70dfSWenchao Xia
10305f43a96SMarkus Armbruster            if memb.optional:
10421cd70dfSWenchao Xia                pop_indent()
105e98859a9SMarkus Armbruster                ret += mcgen('''
10621cd70dfSWenchao Xia    }
107e98859a9SMarkus Armbruster''')
10821cd70dfSWenchao Xia
109e98859a9SMarkus Armbruster        ret += mcgen('''
11021cd70dfSWenchao Xia
111*2a0f50e8SEric Blake    visit_end_struct(v, &err);
112*2a0f50e8SEric Blake    if (err) {
11321cd70dfSWenchao Xia        goto clean;
11421cd70dfSWenchao Xia    }
11521cd70dfSWenchao Xia
11621cd70dfSWenchao Xia    obj = qmp_output_get_qobject(qov);
11721cd70dfSWenchao Xia    g_assert(obj != NULL);
11821cd70dfSWenchao Xia
11921cd70dfSWenchao Xia    qdict_put_obj(qmp, "data", obj);
120e98859a9SMarkus Armbruster''')
12121cd70dfSWenchao Xia
122e98859a9SMarkus Armbruster    ret += mcgen('''
123*2a0f50e8SEric Blake    emit(%(c_enum)s, qmp, &err);
12421cd70dfSWenchao Xia
125e98859a9SMarkus Armbruster''',
126e98859a9SMarkus Armbruster                 c_enum=c_enum_const(event_enum_name, name))
12721cd70dfSWenchao Xia
128e98859a9SMarkus Armbruster    if arg_type and arg_type.members:
129e98859a9SMarkus Armbruster        ret += mcgen('''
13021cd70dfSWenchao Xia clean:
13121cd70dfSWenchao Xia    qmp_output_visitor_cleanup(qov);
132e98859a9SMarkus Armbruster''')
133e98859a9SMarkus Armbruster    ret += mcgen('''
134*2a0f50e8SEric Blake    error_propagate(errp, err);
13521cd70dfSWenchao Xia    QDECREF(qmp);
13621cd70dfSWenchao Xia}
137e98859a9SMarkus Armbruster''')
13821cd70dfSWenchao Xia    return ret
13921cd70dfSWenchao Xia
14005f43a96SMarkus Armbruster
14105f43a96SMarkus Armbrusterclass QAPISchemaGenEventVisitor(QAPISchemaVisitor):
14205f43a96SMarkus Armbruster    def __init__(self):
14305f43a96SMarkus Armbruster        self.decl = None
14405f43a96SMarkus Armbruster        self.defn = None
14505f43a96SMarkus Armbruster        self._event_names = None
14605f43a96SMarkus Armbruster
14705f43a96SMarkus Armbruster    def visit_begin(self, schema):
14805f43a96SMarkus Armbruster        self.decl = ''
14905f43a96SMarkus Armbruster        self.defn = ''
15005f43a96SMarkus Armbruster        self._event_names = []
15105f43a96SMarkus Armbruster
15205f43a96SMarkus Armbruster    def visit_end(self):
153e98859a9SMarkus Armbruster        self.decl += gen_enum(event_enum_name, self._event_names)
154e98859a9SMarkus Armbruster        self.defn += gen_enum_lookup(event_enum_name, self._event_names)
15505f43a96SMarkus Armbruster        self._event_names = None
15605f43a96SMarkus Armbruster
15705f43a96SMarkus Armbruster    def visit_event(self, name, info, arg_type):
158e98859a9SMarkus Armbruster        self.decl += gen_event_send_decl(name, arg_type)
159e98859a9SMarkus Armbruster        self.defn += gen_event_send(name, arg_type)
16005f43a96SMarkus Armbruster        self._event_names.append(name)
16105f43a96SMarkus Armbruster
16205f43a96SMarkus Armbruster
1632114f5a9SMarkus Armbruster(input_file, output_dir, do_c, do_h, prefix, dummy) = parse_command_line()
16421cd70dfSWenchao Xia
16512f8e1b9SMarkus Armbrusterc_comment = '''
16621cd70dfSWenchao Xia/*
16721cd70dfSWenchao Xia * schema-defined QAPI event functions
16821cd70dfSWenchao Xia *
16921cd70dfSWenchao Xia * Copyright (c) 2014 Wenchao Xia
17021cd70dfSWenchao Xia *
17121cd70dfSWenchao Xia * Authors:
17221cd70dfSWenchao Xia *  Wenchao Xia   <wenchaoqemu@gmail.com>
17321cd70dfSWenchao Xia *
17421cd70dfSWenchao Xia * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
17521cd70dfSWenchao Xia * See the COPYING.LIB file in the top-level directory.
17621cd70dfSWenchao Xia *
17721cd70dfSWenchao Xia */
17812f8e1b9SMarkus Armbruster'''
17912f8e1b9SMarkus Armbrusterh_comment = '''
18012f8e1b9SMarkus Armbruster/*
18112f8e1b9SMarkus Armbruster * schema-defined QAPI event functions
18212f8e1b9SMarkus Armbruster *
18312f8e1b9SMarkus Armbruster * Copyright (c) 2014 Wenchao Xia
18412f8e1b9SMarkus Armbruster *
18512f8e1b9SMarkus Armbruster * Authors:
18612f8e1b9SMarkus Armbruster *  Wenchao Xia  <wenchaoqemu@gmail.com>
18712f8e1b9SMarkus Armbruster *
18812f8e1b9SMarkus Armbruster * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
18912f8e1b9SMarkus Armbruster * See the COPYING.LIB file in the top-level directory.
19012f8e1b9SMarkus Armbruster *
19112f8e1b9SMarkus Armbruster */
19212f8e1b9SMarkus Armbruster'''
19321cd70dfSWenchao Xia
19412f8e1b9SMarkus Armbruster(fdef, fdecl) = open_output(output_dir, do_c, do_h, prefix,
19512f8e1b9SMarkus Armbruster                            'qapi-event.c', 'qapi-event.h',
19612f8e1b9SMarkus Armbruster                            c_comment, h_comment)
19712f8e1b9SMarkus Armbruster
19812f8e1b9SMarkus Armbrusterfdef.write(mcgen('''
19921cd70dfSWenchao Xia#include "qemu-common.h"
20012f8e1b9SMarkus Armbruster#include "%(prefix)sqapi-event.h"
20121cd70dfSWenchao Xia#include "%(prefix)sqapi-visit.h"
20221cd70dfSWenchao Xia#include "qapi/qmp-output-visitor.h"
20321cd70dfSWenchao Xia#include "qapi/qmp-event.h"
20421cd70dfSWenchao Xia
20521cd70dfSWenchao Xia''',
20612f8e1b9SMarkus Armbruster                 prefix=prefix))
20721cd70dfSWenchao Xia
20821cd70dfSWenchao Xiafdecl.write(mcgen('''
20921cd70dfSWenchao Xia#include "qapi/error.h"
21021cd70dfSWenchao Xia#include "qapi/qmp/qdict.h"
21121cd70dfSWenchao Xia#include "%(prefix)sqapi-types.h"
21221cd70dfSWenchao Xia
21321cd70dfSWenchao Xia''',
21412f8e1b9SMarkus Armbruster                  prefix=prefix))
21521cd70dfSWenchao Xia
216016a335bSMarkus Armbrusterevent_enum_name = c_name(prefix + "QAPIEvent", protect=False)
21721cd70dfSWenchao Xia
21805f43a96SMarkus Armbrusterschema = QAPISchema(input_file)
21905f43a96SMarkus Armbrustergen = QAPISchemaGenEventVisitor()
22005f43a96SMarkus Armbrusterschema.visit(gen)
22105f43a96SMarkus Armbrusterfdef.write(gen.defn)
22205f43a96SMarkus Armbrusterfdecl.write(gen.decl)
22321cd70dfSWenchao Xia
22412f8e1b9SMarkus Armbrusterclose_output(fdef, fdecl)
225