xref: /qemu/scripts/qapi/events.py (revision 1158bb2a058fcdd0c8fc3e60dc77f7a57ddbb271)
121cd70dfSWenchao Xia#
221cd70dfSWenchao Xia# QAPI event generator
321cd70dfSWenchao Xia#
421cd70dfSWenchao Xia# Copyright (c) 2014 Wenchao Xia
5a16e3e5cSEric Blake# Copyright (c) 2015-2016 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
310949e95bSEric Blake# Declare and initialize an object 'qapi' using parameters from gen_params()
320949e95bSEric Blakedef gen_param_var(typ):
330949e95bSEric Blake    assert not typ.variants
340949e95bSEric Blake    ret = mcgen('''
350949e95bSEric Blake    %(c_name)s param = {
360949e95bSEric Blake''',
370949e95bSEric Blake                c_name=typ.c_name())
380949e95bSEric Blake    sep = '        '
390949e95bSEric Blake    for memb in typ.members:
400949e95bSEric Blake        ret += sep
410949e95bSEric Blake        sep = ', '
420949e95bSEric Blake        if memb.optional:
430949e95bSEric Blake            ret += 'has_' + c_name(memb.name) + sep
440949e95bSEric Blake        if memb.type.name == 'str':
450949e95bSEric Blake            # Cast away const added in gen_params()
460949e95bSEric Blake            ret += '(char *)'
470949e95bSEric Blake        ret += c_name(memb.name)
480949e95bSEric Blake    ret += mcgen('''
490949e95bSEric Blake
500949e95bSEric Blake    };
510949e95bSEric Blake''')
520949e95bSEric Blake    return ret
530949e95bSEric Blake
540949e95bSEric Blake
55e98859a9SMarkus Armbrusterdef gen_event_send(name, arg_type):
560949e95bSEric Blake    # FIXME: Our declaration of local variables (and of 'errp' in the
570949e95bSEric Blake    # parameter list) can collide with exploded members of the event's
580949e95bSEric Blake    # data type passed in as parameters.  If this collision ever hits in
590949e95bSEric Blake    # practice, we can rename our local variables with a leading _ prefix,
600949e95bSEric Blake    # or split the code into a wrapper function that creates a boxed
610949e95bSEric Blake    # 'param' object then calls another to do the real work.
62e98859a9SMarkus Armbruster    ret = mcgen('''
63e98859a9SMarkus Armbruster
64e98859a9SMarkus Armbruster%(proto)s
6521cd70dfSWenchao Xia{
6621cd70dfSWenchao Xia    QDict *qmp;
672a0f50e8SEric Blake    Error *err = NULL;
6821cd70dfSWenchao Xia    QMPEventFuncEmit emit;
69e98859a9SMarkus Armbruster''',
70e98859a9SMarkus Armbruster                proto=gen_event_send_proto(name, arg_type))
7121cd70dfSWenchao Xia
72e98859a9SMarkus Armbruster    if arg_type and arg_type.members:
73e98859a9SMarkus Armbruster        ret += mcgen('''
7421cd70dfSWenchao Xia    QmpOutputVisitor *qov;
7521cd70dfSWenchao Xia    Visitor *v;
76e98859a9SMarkus Armbruster''')
770949e95bSEric Blake        ret += gen_param_var(arg_type)
7821cd70dfSWenchao Xia
79e98859a9SMarkus Armbruster    ret += mcgen('''
800949e95bSEric Blake
8121cd70dfSWenchao Xia    emit = qmp_event_get_func_emit();
8221cd70dfSWenchao Xia    if (!emit) {
8321cd70dfSWenchao Xia        return;
8421cd70dfSWenchao Xia    }
8521cd70dfSWenchao Xia
86e98859a9SMarkus Armbruster    qmp = qmp_event_build_dict("%(name)s");
8721cd70dfSWenchao Xia
88e98859a9SMarkus Armbruster''',
89e98859a9SMarkus Armbruster                 name=name)
9021cd70dfSWenchao Xia
91e98859a9SMarkus Armbruster    if arg_type and arg_type.members:
92e98859a9SMarkus Armbruster        ret += mcgen('''
9321cd70dfSWenchao Xia    qov = qmp_output_visitor_new();
9421cd70dfSWenchao Xia    v = qmp_output_get_visitor(qov);
9521cd70dfSWenchao Xia
96337283dfSEric Blake    visit_start_struct(v, "%(name)s", NULL, 0, &err);
970949e95bSEric Blake    if (err) {
980949e95bSEric Blake        goto out;
990949e95bSEric Blake    }
1000949e95bSEric Blake    visit_type_%(c_name)s_members(v, &param, &err);
10115c2f669SEric Blake    if (!err) {
10215c2f669SEric Blake        visit_check_struct(v, &err);
10315c2f669SEric Blake    }
104*1158bb2aSEric Blake    visit_end_struct(v, NULL);
1052a0f50e8SEric Blake    if (err) {
106f782399cSEric Blake        goto out;
10721cd70dfSWenchao Xia    }
10821cd70dfSWenchao Xia
1098df59565SEric Blake    qdict_put_obj(qmp, "data", qmp_output_get_qobject(qov));
1100949e95bSEric Blake''',
1110949e95bSEric Blake                     name=name, c_name=arg_type.c_name())
11221cd70dfSWenchao Xia
113e98859a9SMarkus Armbruster    ret += mcgen('''
1142a0f50e8SEric Blake    emit(%(c_enum)s, qmp, &err);
11521cd70dfSWenchao Xia
116e98859a9SMarkus Armbruster''',
117e98859a9SMarkus Armbruster                 c_enum=c_enum_const(event_enum_name, name))
11821cd70dfSWenchao Xia
119e98859a9SMarkus Armbruster    if arg_type and arg_type.members:
120e98859a9SMarkus Armbruster        ret += mcgen('''
121f782399cSEric Blakeout:
12221cd70dfSWenchao Xia    qmp_output_visitor_cleanup(qov);
123e98859a9SMarkus Armbruster''')
124e98859a9SMarkus Armbruster    ret += mcgen('''
1252a0f50e8SEric Blake    error_propagate(errp, err);
12621cd70dfSWenchao Xia    QDECREF(qmp);
12721cd70dfSWenchao Xia}
128e98859a9SMarkus Armbruster''')
12921cd70dfSWenchao Xia    return ret
13021cd70dfSWenchao Xia
13105f43a96SMarkus Armbruster
13205f43a96SMarkus Armbrusterclass QAPISchemaGenEventVisitor(QAPISchemaVisitor):
13305f43a96SMarkus Armbruster    def __init__(self):
13405f43a96SMarkus Armbruster        self.decl = None
13505f43a96SMarkus Armbruster        self.defn = None
13605f43a96SMarkus Armbruster        self._event_names = None
13705f43a96SMarkus Armbruster
13805f43a96SMarkus Armbruster    def visit_begin(self, schema):
13905f43a96SMarkus Armbruster        self.decl = ''
14005f43a96SMarkus Armbruster        self.defn = ''
14105f43a96SMarkus Armbruster        self._event_names = []
14205f43a96SMarkus Armbruster
14305f43a96SMarkus Armbruster    def visit_end(self):
144e98859a9SMarkus Armbruster        self.decl += gen_enum(event_enum_name, self._event_names)
145e98859a9SMarkus Armbruster        self.defn += gen_enum_lookup(event_enum_name, self._event_names)
14605f43a96SMarkus Armbruster        self._event_names = None
14705f43a96SMarkus Armbruster
14805f43a96SMarkus Armbruster    def visit_event(self, name, info, arg_type):
149e98859a9SMarkus Armbruster        self.decl += gen_event_send_decl(name, arg_type)
150e98859a9SMarkus Armbruster        self.defn += gen_event_send(name, arg_type)
15105f43a96SMarkus Armbruster        self._event_names.append(name)
15205f43a96SMarkus Armbruster
15305f43a96SMarkus Armbruster
1542114f5a9SMarkus Armbruster(input_file, output_dir, do_c, do_h, prefix, dummy) = parse_command_line()
15521cd70dfSWenchao Xia
15612f8e1b9SMarkus Armbrusterc_comment = '''
15721cd70dfSWenchao Xia/*
15821cd70dfSWenchao Xia * schema-defined QAPI event functions
15921cd70dfSWenchao Xia *
16021cd70dfSWenchao Xia * Copyright (c) 2014 Wenchao Xia
16121cd70dfSWenchao Xia *
16221cd70dfSWenchao Xia * Authors:
16321cd70dfSWenchao Xia *  Wenchao Xia   <wenchaoqemu@gmail.com>
16421cd70dfSWenchao Xia *
16521cd70dfSWenchao Xia * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
16621cd70dfSWenchao Xia * See the COPYING.LIB file in the top-level directory.
16721cd70dfSWenchao Xia *
16821cd70dfSWenchao Xia */
16912f8e1b9SMarkus Armbruster'''
17012f8e1b9SMarkus Armbrusterh_comment = '''
17112f8e1b9SMarkus Armbruster/*
17212f8e1b9SMarkus Armbruster * schema-defined QAPI event functions
17312f8e1b9SMarkus Armbruster *
17412f8e1b9SMarkus Armbruster * Copyright (c) 2014 Wenchao Xia
17512f8e1b9SMarkus Armbruster *
17612f8e1b9SMarkus Armbruster * Authors:
17712f8e1b9SMarkus Armbruster *  Wenchao Xia  <wenchaoqemu@gmail.com>
17812f8e1b9SMarkus Armbruster *
17912f8e1b9SMarkus Armbruster * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
18012f8e1b9SMarkus Armbruster * See the COPYING.LIB file in the top-level directory.
18112f8e1b9SMarkus Armbruster *
18212f8e1b9SMarkus Armbruster */
18312f8e1b9SMarkus Armbruster'''
18421cd70dfSWenchao Xia
18512f8e1b9SMarkus Armbruster(fdef, fdecl) = open_output(output_dir, do_c, do_h, prefix,
18612f8e1b9SMarkus Armbruster                            'qapi-event.c', 'qapi-event.h',
18712f8e1b9SMarkus Armbruster                            c_comment, h_comment)
18812f8e1b9SMarkus Armbruster
18912f8e1b9SMarkus Armbrusterfdef.write(mcgen('''
1909167ebd9SEric Blake#include "qemu/osdep.h"
19121cd70dfSWenchao Xia#include "qemu-common.h"
19212f8e1b9SMarkus Armbruster#include "%(prefix)sqapi-event.h"
19321cd70dfSWenchao Xia#include "%(prefix)sqapi-visit.h"
19421cd70dfSWenchao Xia#include "qapi/qmp-output-visitor.h"
19521cd70dfSWenchao Xia#include "qapi/qmp-event.h"
19621cd70dfSWenchao Xia
19721cd70dfSWenchao Xia''',
19812f8e1b9SMarkus Armbruster                 prefix=prefix))
19921cd70dfSWenchao Xia
20021cd70dfSWenchao Xiafdecl.write(mcgen('''
20121cd70dfSWenchao Xia#include "qapi/error.h"
20221cd70dfSWenchao Xia#include "qapi/qmp/qdict.h"
20321cd70dfSWenchao Xia#include "%(prefix)sqapi-types.h"
20421cd70dfSWenchao Xia
20521cd70dfSWenchao Xia''',
20612f8e1b9SMarkus Armbruster                  prefix=prefix))
20721cd70dfSWenchao Xia
208016a335bSMarkus Armbrusterevent_enum_name = c_name(prefix + "QAPIEvent", protect=False)
20921cd70dfSWenchao Xia
21005f43a96SMarkus Armbrusterschema = QAPISchema(input_file)
21105f43a96SMarkus Armbrustergen = QAPISchemaGenEventVisitor()
21205f43a96SMarkus Armbrusterschema.visit(gen)
21305f43a96SMarkus Armbrusterfdef.write(gen.defn)
21405f43a96SMarkus Armbrusterfdecl.write(gen.decl)
21521cd70dfSWenchao Xia
21612f8e1b9SMarkus Armbrusterclose_output(fdef, fdecl)
217