From 675b214bc6ba2c1d8ac499e339a8cb99c7f23c7c Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Fri, 13 Sep 2019 22:13:41 +0200 Subject: [PATCH] qapi: Permit 'boxed' with empty type We reject empty types with 'boxed': true. We don't really need that to work, but making it work is actually simpler than rejecting it, so do that. Signed-off-by: Markus Armbruster Reviewed-by: Eric Blake Message-Id: <20190913201349.24332-9-armbru@redhat.com> --- scripts/qapi/commands.py | 4 ++-- scripts/qapi/common.py | 14 ++------------ scripts/qapi/events.py | 10 +++++----- tests/Makefile.include | 1 - tests/qapi-schema/args-boxed-empty.err | 1 - tests/qapi-schema/args-boxed-empty.exit | 1 - tests/qapi-schema/args-boxed-empty.json | 3 --- tests/qapi-schema/args-boxed-empty.out | 0 tests/qapi-schema/qapi-schema-test.json | 2 ++ tests/qapi-schema/qapi-schema-test.out | 4 ++++ tests/test-qmp-cmds.c | 4 ++++ 11 files changed, 19 insertions(+), 25 deletions(-) delete mode 100644 tests/qapi-schema/args-boxed-empty.err delete mode 100644 tests/qapi-schema/args-boxed-empty.exit delete mode 100644 tests/qapi-schema/args-boxed-empty.json delete mode 100644 tests/qapi-schema/args-boxed-empty.out diff --git a/scripts/qapi/commands.py b/scripts/qapi/commands.py index b929e07be4..7e3dd1068a 100644 --- a/scripts/qapi/commands.py +++ b/scripts/qapi/commands.py @@ -30,7 +30,7 @@ def gen_call(name, arg_type, boxed, ret_type): argstr = '' if boxed: - assert arg_type and not arg_type.is_empty() + assert arg_type argstr = '&arg, ' elif arg_type: assert not arg_type.variants @@ -96,7 +96,7 @@ def gen_marshal_decl(name): def gen_marshal(name, arg_type, boxed, ret_type): - have_args = arg_type and not arg_type.is_empty() + have_args = boxed or (arg_type and not arg_type.is_empty()) ret = mcgen(''' diff --git a/scripts/qapi/common.py b/scripts/qapi/common.py index 0fb1d1956a..c5c71287c3 100644 --- a/scripts/qapi/common.py +++ b/scripts/qapi/common.py @@ -1687,12 +1687,7 @@ class QAPISchemaCommand(QAPISchemaEntity): self.arg_type = schema.lookup_type(self._arg_type_name) assert isinstance(self.arg_type, QAPISchemaObjectType) self.arg_type.check(schema) - if self.boxed: - if self.arg_type.is_empty(): - raise QAPISemError(self.info, - "Cannot use 'boxed' with empty type") - else: - assert not self.arg_type.variants + assert not self.arg_type.variants or self.boxed elif self.boxed: raise QAPISemError(self.info, "Use of 'boxed' requires 'data'") if self._ret_type_name: @@ -1721,12 +1716,7 @@ class QAPISchemaEvent(QAPISchemaEntity): self.arg_type = schema.lookup_type(self._arg_type_name) assert isinstance(self.arg_type, QAPISchemaObjectType) self.arg_type.check(schema) - if self.boxed: - if self.arg_type.is_empty(): - raise QAPISemError(self.info, - "Cannot use 'boxed' with empty type") - else: - assert not self.arg_type.variants + assert not self.arg_type.variants or self.boxed elif self.boxed: raise QAPISemError(self.info, "Use of 'boxed' requires 'data'") diff --git a/scripts/qapi/events.py b/scripts/qapi/events.py index b732581046..e0abfef7b0 100644 --- a/scripts/qapi/events.py +++ b/scripts/qapi/events.py @@ -65,6 +65,8 @@ def gen_event_send(name, arg_type, boxed, event_enum_name, event_emit): # practice, we can rename our local variables with a leading _ prefix, # or split the code into a wrapper function that creates a boxed # 'param' object then calls another to do the real work. + have_args = boxed or (arg_type and not arg_type.is_empty()) + ret = mcgen(''' %(proto)s @@ -73,15 +75,13 @@ def gen_event_send(name, arg_type, boxed, event_enum_name, event_emit): ''', proto=build_event_send_proto(name, arg_type, boxed)) - if arg_type and not arg_type.is_empty(): + if have_args: ret += mcgen(''' QObject *obj; Visitor *v; ''') if not boxed: ret += gen_param_var(arg_type) - else: - assert not boxed ret += mcgen(''' @@ -90,7 +90,7 @@ def gen_event_send(name, arg_type, boxed, event_enum_name, event_emit): ''', name=name) - if arg_type and not arg_type.is_empty(): + if have_args: ret += mcgen(''' v = qobject_output_visitor_new(&obj); ''') @@ -121,7 +121,7 @@ def gen_event_send(name, arg_type, boxed, event_enum_name, event_emit): event_emit=event_emit, c_enum=c_enum_const(event_enum_name, name)) - if arg_type and not arg_type.is_empty(): + if have_args: ret += mcgen(''' visit_free(v); ''') diff --git a/tests/Makefile.include b/tests/Makefile.include index 8585e7ed26..2c3adb1530 100644 --- a/tests/Makefile.include +++ b/tests/Makefile.include @@ -311,7 +311,6 @@ qapi-schema += args-array-empty.json qapi-schema += args-array-unknown.json qapi-schema += args-bad-boxed.json qapi-schema += args-boxed-anon.json -qapi-schema += args-boxed-empty.json qapi-schema += args-boxed-string.json qapi-schema += args-int.json qapi-schema += args-invalid.json diff --git a/tests/qapi-schema/args-boxed-empty.err b/tests/qapi-schema/args-boxed-empty.err deleted file mode 100644 index 039603e85c..0000000000 --- a/tests/qapi-schema/args-boxed-empty.err +++ /dev/null @@ -1 +0,0 @@ -tests/qapi-schema/args-boxed-empty.json:3: Cannot use 'boxed' with empty type diff --git a/tests/qapi-schema/args-boxed-empty.exit b/tests/qapi-schema/args-boxed-empty.exit deleted file mode 100644 index d00491fd7e..0000000000 --- a/tests/qapi-schema/args-boxed-empty.exit +++ /dev/null @@ -1 +0,0 @@ -1 diff --git a/tests/qapi-schema/args-boxed-empty.json b/tests/qapi-schema/args-boxed-empty.json deleted file mode 100644 index 52717e065f..0000000000 --- a/tests/qapi-schema/args-boxed-empty.json +++ /dev/null @@ -1,3 +0,0 @@ -# 'boxed' requires a non-empty type -{ 'struct': 'Empty', 'data': {} } -{ 'command': 'foo', 'boxed': true, 'data': 'Empty' } diff --git a/tests/qapi-schema/args-boxed-empty.out b/tests/qapi-schema/args-boxed-empty.out deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/tests/qapi-schema/qapi-schema-test.json b/tests/qapi-schema/qapi-schema-test.json index 0fadb4ddd7..e6dbbbd328 100644 --- a/tests/qapi-schema/qapi-schema-test.json +++ b/tests/qapi-schema/qapi-schema-test.json @@ -149,6 +149,7 @@ { 'command': 'guest-sync', 'data': { 'arg': 'any' }, 'returns': 'any' } { 'command': 'boxed-struct', 'boxed': true, 'data': 'UserDefZero' } { 'command': 'boxed-union', 'data': 'UserDefListUnion', 'boxed': true } +{ 'command': 'boxed-empty', 'boxed': true, 'data': 'Empty1' } # Smoke test on out-of-band and allow-preconfig-test { 'command': 'test-flags-command', 'allow-oob': true, 'allow-preconfig': true } @@ -181,6 +182,7 @@ 'data': { 'a' : 'EventStructOne', 'b' : 'str', '*c': 'str', '*enum3': 'EnumOne' } } { 'event': 'EVENT_E', 'boxed': true, 'data': 'UserDefZero' } { 'event': 'EVENT_F', 'boxed': true, 'data': 'UserDefFlatUnion' } +{ 'event': 'EVENT_G', 'boxed': true, 'data': 'Empty1' } # test that we correctly compile downstream extensions, as well as munge # ticklish names diff --git a/tests/qapi-schema/qapi-schema-test.out b/tests/qapi-schema/qapi-schema-test.out index 5470a525f5..fb00a21996 100644 --- a/tests/qapi-schema/qapi-schema-test.out +++ b/tests/qapi-schema/qapi-schema-test.out @@ -221,6 +221,8 @@ command boxed-struct UserDefZero -> None gen=True success_response=True boxed=True oob=False preconfig=False command boxed-union UserDefListUnion -> None gen=True success_response=True boxed=True oob=False preconfig=False +command boxed-empty Empty1 -> None + gen=True success_response=True boxed=True oob=False preconfig=False command test-flags-command None -> None gen=True success_response=True boxed=False oob=True preconfig=True object UserDefOptions @@ -254,6 +256,8 @@ event EVENT_E UserDefZero boxed=True event EVENT_F UserDefFlatUnion boxed=True +event EVENT_G Empty1 + boxed=True enum __org.qemu_x-Enum member __org.qemu_x-value object __org.qemu_x-Base diff --git a/tests/test-qmp-cmds.c b/tests/test-qmp-cmds.c index ab389f42da..36fdf5b115 100644 --- a/tests/test-qmp-cmds.c +++ b/tests/test-qmp-cmds.c @@ -97,6 +97,10 @@ void qmp_boxed_union(UserDefListUnion *arg, Error **errp) { } +void qmp_boxed_empty(Empty1 *arg, Error **errp) +{ +} + __org_qemu_x_Union1 *qmp___org_qemu_x_command(__org_qemu_x_EnumList *a, __org_qemu_x_StructList *b, __org_qemu_x_Union2 *c,