Skip to content

Commit

Permalink
qapi-event: Convert to QAPISchemaVisitor, fixing data with base
Browse files Browse the repository at this point in the history
Fixes events whose data is struct with base to include the struct's
base members.  Test case is qapi-schema-test.json's event
__org.qemu_x-command:

    { 'event': '__ORG.QEMU_X-EVENT', 'data': '__org.qemu_x-Struct' }

    { 'struct': '__org.qemu_x-Struct', 'base': '__org.qemu_x-Base',
      'data': { '__org.qemu_x-member2': 'str' } }

    { 'struct': '__org.qemu_x-Base',
      'data': { '__org.qemu_x-member1': '__org.qemu_x-Enum' } }

Patch's effect on generated qapi_event_send___org_qemu_x_event():

    -void qapi_event_send___org_qemu_x_event(const char *__org_qemu_x_member2,
    +void qapi_event_send___org_qemu_x_event(__org_qemu_x_Enum __org_qemu_x_member1,
    +                                        const char *__org_qemu_x_member2,
                                             Error **errp)
     {
         QDict *qmp;
    @@ -224,6 +225,10 @@ void qapi_event_send___org_qemu_x_event(
             goto clean;
         }

    +    visit_type___org_qemu_x_Enum(v, &__org_qemu_x_member1, "__org.qemu_x-member1", &local_err);
    +    if (local_err) {
    +        goto clean;
    +    }
         visit_type_str(v, (char **)&__org_qemu_x_member2, "__org.qemu_x-member2", &local_err);
         if (local_err) {
             goto clean;

Code is generated in a different order now, but that doesn't matter.

Signed-off-by: Markus Armbruster <[email protected]>
Reviewed-by: Eric Blake <[email protected]>
Reviewed-by: Daniel P. Berrange <[email protected]>
  • Loading branch information
Markus Armbruster committed Sep 21, 2015
1 parent 7b24626 commit 05f43a9
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 46 deletions.
91 changes: 48 additions & 43 deletions scripts/qapi-event.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,29 @@
# QAPI event generator
#
# Copyright (c) 2014 Wenchao Xia
# Copyright (c) 2015 Red Hat Inc.
#
# Authors:
# Wenchao Xia <[email protected]>
# Markus Armbruster <[email protected]>
#
# This work is licensed under the terms of the GNU GPL, version 2.
# See the COPYING file in the top-level directory.

from ordereddict import OrderedDict
from qapi import *

def _generate_event_api_name(event_name, params):
api_name = "void qapi_event_send_%s(" % c_name(event_name).lower();
l = len(api_name)

if params:
for argname, argentry, optional in parse_args(params):
if optional:
api_name += "bool has_%s,\n" % c_name(argname)
for m in params.members:
if m.optional:
api_name += "bool has_%s,\n" % c_name(m.name)
api_name += "".ljust(l)

api_name += "%s %s,\n" % (c_type(argentry, is_param=True),
c_name(argname))
api_name += "%s %s,\n" % (m.type.c_type(is_param=True),
c_name(m.name))
api_name += "".ljust(l)

api_name += "Error **errp)"
Expand Down Expand Up @@ -51,7 +52,7 @@ def generate_event_implement(api_name, event_name, params):
""",
api_name = api_name)

if params:
if params and params.members:
ret += mcgen("""
QmpOutputVisitor *qov;
Visitor *v;
Expand All @@ -72,7 +73,7 @@ def generate_event_implement(api_name, event_name, params):
event_name = event_name)

# step 3: visit the params if params != None
if params:
if params and params.members:
ret += mcgen("""
qov = qmp_output_visitor_new();
g_assert(qov);
Expand All @@ -89,15 +90,15 @@ def generate_event_implement(api_name, event_name, params):
""",
event_name = event_name)

for argname, argentry, optional in parse_args(params):
if optional:
for memb in params.members:
if memb.optional:
ret += mcgen("""
if (has_%(var)s) {
""",
var = c_name(argname))
var=c_name(memb.name))
push_indent()

if argentry == "str":
if memb.type.name == "str":
var_type = "(char **)"
else:
var_type = ""
Expand All @@ -109,11 +110,11 @@ def generate_event_implement(api_name, event_name, params):
}
""",
var_type = var_type,
var = c_name(argname),
type = type_name(argentry),
name = argname)
var=c_name(memb.name),
type=memb.type.c_name(),
name=memb.name)

if optional:
if memb.optional:
pop_indent()
ret += mcgen("""
}
Expand All @@ -140,7 +141,7 @@ def generate_event_implement(api_name, event_name, params):
event_enum_value = c_enum_const(event_enum_name, event_name))

# step 5: clean up
if params:
if params and params.members:
ret += mcgen("""
clean:
qmp_output_visitor_cleanup(qov);
Expand All @@ -153,6 +154,30 @@ def generate_event_implement(api_name, event_name, params):

return ret


class QAPISchemaGenEventVisitor(QAPISchemaVisitor):
def __init__(self):
self.decl = None
self.defn = None
self._event_names = None

def visit_begin(self, schema):
self.decl = ''
self.defn = ''
self._event_names = []

def visit_end(self):
self.decl += generate_enum(event_enum_name, self._event_names)
self.defn += generate_enum_lookup(event_enum_name, self._event_names)
self._event_names = None

def visit_event(self, name, info, arg_type):
api_name = _generate_event_api_name(name, arg_type)
self.decl += generate_event_declaration(api_name)
self.defn += generate_event_implement(api_name, name, arg_type)
self._event_names.append(name)


(input_file, output_dir, do_c, do_h, prefix, dummy) = parse_command_line()

c_comment = '''
Expand Down Expand Up @@ -206,32 +231,12 @@ def generate_event_implement(api_name, event_name, params):
''',
prefix=prefix))

exprs = QAPISchema(input_file).get_exprs()

event_enum_name = c_name(prefix + "QAPIEvent", protect=False)
event_names = []

for expr in exprs:
if expr.has_key('event'):
event_name = expr['event']
params = expr.get('data')
if params and len(params) == 0:
params = None

api_name = _generate_event_api_name(event_name, params)
ret = generate_event_declaration(api_name)
fdecl.write(ret)

# We need an enum value per event
ret = generate_event_implement(api_name, event_name, params)
fdef.write(ret)

# Record it, and generate enum later
event_names.append(event_name)

ret = generate_enum(event_enum_name, event_names)
fdecl.write(ret)
ret = generate_enum_lookup(event_enum_name, event_names)
fdef.write(ret)

schema = QAPISchema(input_file)
gen = QAPISchemaGenEventVisitor()
schema.visit(gen)
fdef.write(gen.defn)
fdecl.write(gen.decl)

close_output(fdef, fdecl)
3 changes: 0 additions & 3 deletions tests/qapi-schema/qapi-schema-test.json
Original file line number Diff line number Diff line change
Expand Up @@ -131,9 +131,6 @@
{ 'alternate': '__org.qemu_x-Alt',
'data': { '__org.qemu_x-branch': 'str', 'b': '__org.qemu_x-Base' } }
{ 'event': '__ORG.QEMU_X-EVENT', 'data': '__org.qemu_x-Struct' }
# FIXME generated qapi_event_send___org_qemu_x_event() has only a
# parameter for data's member __org_qemu_x_member2, none for its base
# __org.qemu_x-Base's member __org_qemu_x_member1
{ 'command': '__org.qemu_x-command',
'data': { 'a': ['__org.qemu_x-Enum'], 'b': ['__org.qemu_x-Struct'],
'c': '__org.qemu_x-Union2', 'd': '__org.qemu_x-Alt' },
Expand Down

0 comments on commit 05f43a9

Please sign in to comment.