@@ -491,10 +491,18 @@ def check_member_clash(expr_info, base_name, data, source = ""):
def check_command(expr, expr_info):
name = expr['command']
+ box = expr.get('box', False)
+ args_meta = ['struct']
+ if box:
+ args_meta += ['union']
+ if not expr.get('data'):
+ raise QAPIExprError(expr_info,
+ "Use of 'box' requires 'data' for command '%s'"
+ % name)
check_type(expr_info, "'data' for command '%s'" % name,
- expr.get('data'), allow_dict=True, allow_optional=True,
- allow_metas=['struct'])
+ expr.get('data'), allow_dict=not box, allow_optional=True,
+ allow_metas=args_meta)
returns_meta = ['union', 'struct']
if name in returns_whitelist:
returns_meta += ['built-in', 'alternate', 'enum']
@@ -505,13 +513,17 @@ def check_command(expr, expr_info):
def check_event(expr, expr_info):
global events
name = expr['event']
+ box = expr.get('box', False)
+ meta = ['struct']
+ if box:
+ meta += ['union']
if name.upper() == 'MAX':
raise QAPIExprError(expr_info, "Event name 'MAX' cannot be created")
events.append(name)
check_type(expr_info, "'data' for event '%s'" % name,
- expr.get('data'), allow_dict=True, allow_optional=True,
- allow_metas=['struct'])
+ expr.get('data'), allow_dict=not box, allow_optional=True,
+ allow_metas=meta)
def check_union(expr, expr_info):
name = expr['union']
@@ -228,11 +228,11 @@ check-qapi-schema-y := $(addprefix tests/qapi-schema/, \
bad-type-dict.json double-data.json unknown-expr-key.json \
redefined-type.json redefined-command.json redefined-builtin.json \
redefined-event.json command-int.json bad-data.json event-max.json \
- type-bypass-bad-gen.json \
+ type-bypass-bad-gen.json args-bad-box.json \
args-array-empty.json args-array-unknown.json args-int.json \
args-unknown.json args-member-unknown.json args-member-array.json \
args-member-array-bad.json args-alternate.json args-union.json \
- args-any.json \
+ args-any.json args-box-anon.json args-box-empty.json \
returns-array-bad.json returns-int.json returns-dict.json \
returns-unknown.json returns-alternate.json returns-whitelist.json \
missing-colon.json missing-comma-list.json missing-comma-object.json \
new file mode 100644
@@ -0,0 +1 @@
+tests/qapi-schema/args-bad-box.json:2: 'box' of command 'foo' should only use true value
new file mode 100644
@@ -0,0 +1 @@
+1
new file mode 100644
@@ -0,0 +1,2 @@
+# 'box' should only appear with value true
+{ 'command': 'foo', 'box': false }
new file mode 100644
new file mode 100644
@@ -0,0 +1 @@
+tests/qapi-schema/args-box-anon.json:2: 'data' for command 'foo' should be a type name
new file mode 100644
@@ -0,0 +1 @@
+1
new file mode 100644
@@ -0,0 +1,2 @@
+# 'box' can only be used with named types
+{ 'command': 'foo', 'box': true, 'data': { 'string': 'str' } }
new file mode 100644
new file mode 100644
@@ -0,0 +1 @@
+tests/qapi-schema/args-box-empty.json:2: Use of 'box' requires 'data' for command 'foo'
new file mode 100644
@@ -0,0 +1 @@
+1
new file mode 100644
@@ -0,0 +1,2 @@
+# 'box' can only be used with named types
+{ 'command': 'foo', 'box': true }
new file mode 100644
@@ -1 +1 @@
-tests/qapi-schema/args-union.json:4: 'data' for command 'oops' cannot use union type 'Uni'
+tests/qapi-schema/args-union.json:3: 'data' for command 'oops' cannot use union type 'Uni'
@@ -1,4 +1,3 @@
-# we do not allow union arguments
-# TODO should we support this?
+# use of union arguments requires 'box':true
{ 'union': 'Uni', 'data': { 'case1': 'int', 'case2': 'str' } }
{ 'command': 'oops', 'data': 'Uni' }
@@ -94,6 +94,7 @@
# note: command name 'guest-sync' chosen to avoid "cannot use built-in" error
{ 'command': 'guest-sync', 'data': { 'arg': 'any' }, 'returns': 'any' }
{ 'command': 'boxed', 'box': true, 'data': 'UserDefZero' }
+{ 'command': 'boxed2', 'data': 'UserDefNativeListUnion', 'box': true }
# For testing integer range flattening in opts-visitor. The following schema
# corresponds to the option format:
@@ -114,7 +115,7 @@
{ 'struct': 'EventStructOne',
'data': { 'struct1': 'UserDefOne', 'string': 'str', '*enum2': 'EnumOne' } }
-{ 'event': 'EVENT_A' }
+{ 'event': 'EVENT_A', 'box': true }
{ 'event': 'EVENT_B',
'data': { } }
{ 'event': 'EVENT_C',
@@ -70,7 +70,7 @@ alternate AltTwo
case s: str
case n: number
event EVENT_A None
- box=False
+ box=True
event EVENT_B None
box=False
event EVENT_C :obj-EVENT_C-arg
@@ -177,6 +177,8 @@ command __org.qemu_x-command :obj-__org.qemu_x-command-arg -> __org.qemu_x-Union
gen=True success_response=True box=False
command boxed UserDefZero -> None
gen=True success_response=True box=True
+command boxed2 UserDefNativeListUnion -> None
+ gen=True success_response=True box=True
command guest-sync :obj-guest-sync-arg -> any
gen=True success_response=True box=False
command user_def_cmd None -> None
@@ -58,6 +58,10 @@ void qmp_boxed(UserDefZero *arg, Error **errp)
{
}
+void qmp_boxed2(UserDefNativeListUnion *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,
This patch completes support for boxed types, by allowing union types to be used when 'box':true is specified. It also avoids a python crash when attempting to use boxing on an anonymous type. While it was possible to support 'box':true on an empty event, it was easier to just reject missing 'data' for commands. Add some tests to cover new error messages, as well as enhancing qapi-schema-test to cover situations that are now valid. Signed-off-by: Eric Blake <eblake@redhat.com> --- scripts/qapi.py | 20 ++++++++++++++++---- tests/Makefile | 4 ++-- tests/qapi-schema/args-bad-box.err | 1 + tests/qapi-schema/args-bad-box.exit | 1 + tests/qapi-schema/args-bad-box.json | 2 ++ tests/qapi-schema/args-bad-box.out | 0 tests/qapi-schema/args-box-anon.err | 1 + tests/qapi-schema/args-box-anon.exit | 1 + tests/qapi-schema/args-box-anon.json | 2 ++ tests/qapi-schema/args-box-anon.out | 0 tests/qapi-schema/args-box-empty.err | 1 + tests/qapi-schema/args-box-empty.exit | 1 + tests/qapi-schema/args-box-empty.json | 2 ++ tests/qapi-schema/args-box-empty.out | 0 tests/qapi-schema/args-union.err | 2 +- tests/qapi-schema/args-union.json | 3 +-- tests/qapi-schema/qapi-schema-test.json | 3 ++- tests/qapi-schema/qapi-schema-test.out | 4 +++- tests/test-qmp-commands.c | 4 ++++ 19 files changed, 41 insertions(+), 11 deletions(-) create mode 100644 tests/qapi-schema/args-bad-box.err create mode 100644 tests/qapi-schema/args-bad-box.exit create mode 100644 tests/qapi-schema/args-bad-box.json create mode 100644 tests/qapi-schema/args-bad-box.out create mode 100644 tests/qapi-schema/args-box-anon.err create mode 100644 tests/qapi-schema/args-box-anon.exit create mode 100644 tests/qapi-schema/args-box-anon.json create mode 100644 tests/qapi-schema/args-box-anon.out create mode 100644 tests/qapi-schema/args-box-empty.err create mode 100644 tests/qapi-schema/args-box-empty.exit create mode 100644 tests/qapi-schema/args-box-empty.json create mode 100644 tests/qapi-schema/args-box-empty.out