aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--qapi/trace.json2
-rw-r--r--scripts/qapi/common.py49
-rw-r--r--scripts/qapi/expr.py32
-rw-r--r--scripts/qapi/gen.py6
-rw-r--r--scripts/qapi/introspect.py11
-rw-r--r--scripts/qapi/schema.py12
-rw-r--r--scripts/qapi/types.py28
-rw-r--r--scripts/qapi/visit.py14
-rw-r--r--tests/qapi-schema/bad-if-key.err2
-rw-r--r--tests/qapi-schema/bad-if-keys.err2
-rw-r--r--tests/qapi-schema/doc-good.json2
-rw-r--r--tests/qapi-schema/doc-good.out6
-rw-r--r--tests/qapi-schema/doc-good.txt8
-rw-r--r--tests/qapi-schema/double-type.err4
-rw-r--r--tests/qapi-schema/enum-if-invalid.err2
-rw-r--r--tests/qapi-schema/missing-type.err2
-rw-r--r--tests/qapi-schema/qapi-schema-test.json9
-rw-r--r--tests/qapi-schema/qapi-schema-test.out31
-rwxr-xr-xtests/qapi-schema/test-qapi.py11
19 files changed, 120 insertions, 113 deletions
diff --git a/qapi/trace.json b/qapi/trace.json
index 47c68f04da..eedfded512 100644
--- a/qapi/trace.json
+++ b/qapi/trace.json
@@ -99,7 +99,7 @@
# Example:
#
# -> { "execute": "trace-event-set-state",
-# "arguments": { "name": "qemu_memalign", "enable": "true" } }
+# "arguments": { "name": "qemu_memalign", "enable": true } }
# <- { "return": {} }
#
##
diff --git a/scripts/qapi/common.py b/scripts/qapi/common.py
index 1724ac32db..5f8f76e5b2 100644
--- a/scripts/qapi/common.py
+++ b/scripts/qapi/common.py
@@ -17,6 +17,7 @@ from typing import (
Dict,
Match,
Optional,
+ Sequence,
Union,
)
@@ -200,33 +201,39 @@ def guardend(name: str) -> str:
name=c_fname(name).upper())
-def cgen_ifcond(ifcond: Union[str, Dict[str, Any]]) -> str:
+def gen_ifcond(ifcond: Optional[Union[str, Dict[str, Any]]],
+ cond_fmt: str, not_fmt: str,
+ all_operator: str, any_operator: str) -> str:
+
+ def do_gen(ifcond: Union[str, Dict[str, Any]], need_parens: bool):
+ if isinstance(ifcond, str):
+ return cond_fmt % ifcond
+ assert isinstance(ifcond, dict) and len(ifcond) == 1
+ if 'not' in ifcond:
+ return not_fmt % do_gen(ifcond['not'], True)
+ if 'all' in ifcond:
+ gen = gen_infix(all_operator, ifcond['all'])
+ else:
+ gen = gen_infix(any_operator, ifcond['any'])
+ if need_parens:
+ gen = '(' + gen + ')'
+ return gen
+
+ def gen_infix(operator: str, operands: Sequence[Any]) -> str:
+ return operator.join([do_gen(o, True) for o in operands])
+
if not ifcond:
return ''
- if isinstance(ifcond, str):
- return 'defined(' + ifcond + ')'
+ return do_gen(ifcond, False)
- oper, operands = next(iter(ifcond.items()))
- if oper == 'not':
- return '!' + cgen_ifcond(operands)
- oper = {'all': '&&', 'any': '||'}[oper]
- operands = [cgen_ifcond(o) for o in operands]
- return '(' + (') ' + oper + ' (').join(operands) + ')'
+def cgen_ifcond(ifcond: Optional[Union[str, Dict[str, Any]]]) -> str:
+ return gen_ifcond(ifcond, 'defined(%s)', '!%s', ' && ', ' || ')
-def docgen_ifcond(ifcond: Union[str, Dict[str, Any]]) -> str:
+
+def docgen_ifcond(ifcond: Optional[Union[str, Dict[str, Any]]]) -> str:
# TODO Doc generated for conditions needs polish
- if not ifcond:
- return ''
- if isinstance(ifcond, str):
- return ifcond
-
- oper, operands = next(iter(ifcond.items()))
- if oper == 'not':
- return '!' + docgen_ifcond(operands)
- oper = {'all': ' and ', 'any': ' or '}[oper]
- operands = [docgen_ifcond(o) for o in operands]
- return '(' + oper.join(operands) + ')'
+ return gen_ifcond(ifcond, '%s', 'not %s', ' and ', ' or ')
def gen_if(cond: str) -> str:
diff --git a/scripts/qapi/expr.py b/scripts/qapi/expr.py
index 019f4c97aa..b62f0a3640 100644
--- a/scripts/qapi/expr.py
+++ b/scripts/qapi/expr.py
@@ -275,7 +275,7 @@ def check_if(expr: _JSONObject, info: QAPISourceInfo, source: str) -> None:
def _check_if(cond: Union[str, object]) -> None:
if isinstance(cond, str):
- if not re.match(r'^[A-Z][A-Z0-9_]*$', cond):
+ if not re.fullmatch(r'[A-Z][A-Z0-9_]*', cond):
raise QAPISemError(
info,
"'if' condition '%s' of %s is not a valid identifier"
@@ -286,13 +286,12 @@ def check_if(expr: _JSONObject, info: QAPISourceInfo, source: str) -> None:
raise QAPISemError(
info,
"'if' condition of %s must be a string or an object" % source)
+ check_keys(cond, info, "'if' condition of %s" % source, [],
+ ["all", "any", "not"])
if len(cond) != 1:
raise QAPISemError(
info,
- "'if' condition dict of %s must have one key: "
- "'all', 'any' or 'not'" % source)
- check_keys(cond, info, "'if' condition", [],
- ["all", "any", "not"])
+ "'if' condition of %s has conflicting keys" % source)
oper, operands = next(iter(cond.items()))
if not operands:
@@ -630,20 +629,15 @@ def check_exprs(exprs: List[_JSONObject]) -> List[_JSONObject]:
if 'include' in expr:
continue
- if 'enum' in expr:
- meta = 'enum'
- elif 'union' in expr:
- meta = 'union'
- elif 'alternate' in expr:
- meta = 'alternate'
- elif 'struct' in expr:
- meta = 'struct'
- elif 'command' in expr:
- meta = 'command'
- elif 'event' in expr:
- meta = 'event'
- else:
- raise QAPISemError(info, "expression is missing metatype")
+ metas = expr.keys() & {'enum', 'struct', 'union', 'alternate',
+ 'command', 'event'}
+ if len(metas) != 1:
+ raise QAPISemError(
+ info,
+ "expression must have exactly one key"
+ " 'enum', 'struct', 'union', 'alternate',"
+ " 'command', 'event'")
+ meta = metas.pop()
check_name_is_str(expr[meta], info, "'%s'" % meta)
name = cast(str, expr[meta])
diff --git a/scripts/qapi/gen.py b/scripts/qapi/gen.py
index 51a597a025..ab26d5c937 100644
--- a/scripts/qapi/gen.py
+++ b/scripts/qapi/gen.py
@@ -24,8 +24,6 @@ from typing import (
from .common import (
c_fname,
c_name,
- gen_endif,
- gen_if,
guardend,
guardstart,
mcgen,
@@ -95,9 +93,9 @@ def _wrap_ifcond(ifcond: QAPISchemaIfCond, before: str, after: str) -> str:
if added[0] == '\n':
out += '\n'
added = added[1:]
- out += gen_if(ifcond.cgen())
+ out += ifcond.gen_if()
out += added
- out += gen_endif(ifcond.cgen())
+ out += ifcond.gen_endif()
return out
diff --git a/scripts/qapi/introspect.py b/scripts/qapi/introspect.py
index bd4233ecee..4c079ee627 100644
--- a/scripts/qapi/introspect.py
+++ b/scripts/qapi/introspect.py
@@ -22,12 +22,7 @@ from typing import (
Union,
)
-from .common import (
- c_name,
- gen_endif,
- gen_if,
- mcgen,
-)
+from .common import c_name, mcgen
from .gen import QAPISchemaMonolithicCVisitor
from .schema import (
QAPISchema,
@@ -124,10 +119,10 @@ def _tree_to_qlit(obj: JSONValue,
if obj.comment:
ret += indent(level) + f"/* {obj.comment} */\n"
if obj.ifcond.is_present():
- ret += gen_if(obj.ifcond.cgen())
+ ret += obj.ifcond.gen_if()
ret += _tree_to_qlit(obj.value, level)
if obj.ifcond.is_present():
- ret += '\n' + gen_endif(obj.ifcond.cgen())
+ ret += '\n' + obj.ifcond.gen_endif()
return ret
ret = ''
diff --git a/scripts/qapi/schema.py b/scripts/qapi/schema.py
index 229d24fce9..3d72c7dfc9 100644
--- a/scripts/qapi/schema.py
+++ b/scripts/qapi/schema.py
@@ -24,6 +24,8 @@ from .common import (
c_name,
cgen_ifcond,
docgen_ifcond,
+ gen_endif,
+ gen_if,
)
from .error import QAPIError, QAPISemError, QAPISourceError
from .expr import check_exprs
@@ -32,11 +34,17 @@ from .parser import QAPISchemaParser
class QAPISchemaIfCond:
def __init__(self, ifcond=None):
- self.ifcond = ifcond or {}
+ self.ifcond = ifcond
- def cgen(self):
+ def _cgen(self):
return cgen_ifcond(self.ifcond)
+ def gen_if(self):
+ return gen_if(self._cgen())
+
+ def gen_endif(self):
+ return gen_endif(self._cgen())
+
def docgen(self):
return docgen_ifcond(self.ifcond)
diff --git a/scripts/qapi/types.py b/scripts/qapi/types.py
index db9ff95bd1..831294fe42 100644
--- a/scripts/qapi/types.py
+++ b/scripts/qapi/types.py
@@ -15,13 +15,7 @@ This work is licensed under the terms of the GNU GPL, version 2.
from typing import List, Optional
-from .common import (
- c_enum_const,
- c_name,
- gen_endif,
- gen_if,
- mcgen,
-)
+from .common import c_enum_const, c_name, mcgen
from .gen import QAPISchemaModularCVisitor, ifcontext
from .schema import (
QAPISchema,
@@ -51,13 +45,13 @@ const QEnumLookup %(c_name)s_lookup = {
''',
c_name=c_name(name))
for memb in members:
- ret += gen_if(memb.ifcond.cgen())
+ ret += memb.ifcond.gen_if()
index = c_enum_const(name, memb.name, prefix)
ret += mcgen('''
[%(index)s] = "%(name)s",
''',
index=index, name=memb.name)
- ret += gen_endif(memb.ifcond.cgen())
+ ret += memb.ifcond.gen_endif()
ret += mcgen('''
},
@@ -81,12 +75,12 @@ typedef enum %(c_name)s {
c_name=c_name(name))
for memb in enum_members:
- ret += gen_if(memb.ifcond.cgen())
+ ret += memb.ifcond.gen_if()
ret += mcgen('''
%(c_enum)s,
''',
c_enum=c_enum_const(name, memb.name, prefix))
- ret += gen_endif(memb.ifcond.cgen())
+ ret += memb.ifcond.gen_endif()
ret += mcgen('''
} %(c_name)s;
@@ -126,7 +120,7 @@ struct %(c_name)s {
def gen_struct_members(members: List[QAPISchemaObjectTypeMember]) -> str:
ret = ''
for memb in members:
- ret += gen_if(memb.ifcond.cgen())
+ ret += memb.ifcond.gen_if()
if memb.optional:
ret += mcgen('''
bool has_%(c_name)s;
@@ -136,7 +130,7 @@ def gen_struct_members(members: List[QAPISchemaObjectTypeMember]) -> str:
%(c_type)s %(c_name)s;
''',
c_type=memb.type.c_type(), c_name=c_name(memb.name))
- ret += gen_endif(memb.ifcond.cgen())
+ ret += memb.ifcond.gen_endif()
return ret
@@ -159,7 +153,7 @@ def gen_object(name: str, ifcond: QAPISchemaIfCond,
ret += mcgen('''
''')
- ret += gen_if(ifcond.cgen())
+ ret += ifcond.gen_if()
ret += mcgen('''
struct %(c_name)s {
''',
@@ -193,7 +187,7 @@ struct %(c_name)s {
ret += mcgen('''
};
''')
- ret += gen_endif(ifcond.cgen())
+ ret += ifcond.gen_endif()
return ret
@@ -220,13 +214,13 @@ def gen_variants(variants: QAPISchemaVariants) -> str:
for var in variants.variants:
if var.type.name == 'q_empty':
continue
- ret += gen_if(var.ifcond.cgen())
+ ret += var.ifcond.gen_if()
ret += mcgen('''
%(c_type)s %(c_name)s;
''',
c_type=var.type.c_unboxed_type(),
c_name=c_name(var.name))
- ret += gen_endif(var.ifcond.cgen())
+ ret += var.ifcond.gen_endif()
ret += mcgen('''
} u;
diff --git a/scripts/qapi/visit.py b/scripts/qapi/visit.py
index 56ea516399..9d9196a143 100644
--- a/scripts/qapi/visit.py
+++ b/scripts/qapi/visit.py
@@ -18,8 +18,6 @@ from typing import List, Optional
from .common import (
c_enum_const,
c_name,
- gen_endif,
- gen_if,
indent,
mcgen,
)
@@ -79,7 +77,7 @@ bool visit_type_%(c_name)s_members(Visitor *v, %(c_name)s *obj, Error **errp)
for memb in members:
deprecated = 'deprecated' in [f.name for f in memb.features]
- ret += gen_if(memb.ifcond.cgen())
+ ret += memb.ifcond.gen_if()
if memb.optional:
ret += mcgen('''
if (visit_optional(v, "%(name)s", &obj->has_%(c_name)s)) {
@@ -112,7 +110,7 @@ bool visit_type_%(c_name)s_members(Visitor *v, %(c_name)s *obj, Error **errp)
ret += mcgen('''
}
''')
- ret += gen_endif(memb.ifcond.cgen())
+ ret += memb.ifcond.gen_endif()
if variants:
tag_member = variants.tag_member
@@ -126,7 +124,7 @@ bool visit_type_%(c_name)s_members(Visitor *v, %(c_name)s *obj, Error **errp)
for var in variants.variants:
case_str = c_enum_const(tag_member.type.name, var.name,
tag_member.type.prefix)
- ret += gen_if(var.ifcond.cgen())
+ ret += var.ifcond.gen_if()
if var.type.name == 'q_empty':
# valid variant and nothing to do
ret += mcgen('''
@@ -142,7 +140,7 @@ bool visit_type_%(c_name)s_members(Visitor *v, %(c_name)s *obj, Error **errp)
case=case_str,
c_type=var.type.c_name(), c_name=c_name(var.name))
- ret += gen_endif(var.ifcond.cgen())
+ ret += var.ifcond.gen_endif()
ret += mcgen('''
default:
abort();
@@ -228,7 +226,7 @@ bool visit_type_%(c_name)s(Visitor *v, const char *name,
c_name=c_name(name))
for var in variants.variants:
- ret += gen_if(var.ifcond.cgen())
+ ret += var.ifcond.gen_if()
ret += mcgen('''
case %(case)s:
''',
@@ -254,7 +252,7 @@ bool visit_type_%(c_name)s(Visitor *v, const char *name,
ret += mcgen('''
break;
''')
- ret += gen_endif(var.ifcond.cgen())
+ ret += var.ifcond.gen_endif()
ret += mcgen('''
case QTYPE_NONE:
diff --git a/tests/qapi-schema/bad-if-key.err b/tests/qapi-schema/bad-if-key.err
index a69dc9ee86..38cf44b687 100644
--- a/tests/qapi-schema/bad-if-key.err
+++ b/tests/qapi-schema/bad-if-key.err
@@ -1,3 +1,3 @@
bad-if-key.json: In struct 'TestIfStruct':
-bad-if-key.json:2: 'if' condition has unknown key 'value'
+bad-if-key.json:2: 'if' condition of struct has unknown key 'value'
Valid keys are 'all', 'any', 'not'.
diff --git a/tests/qapi-schema/bad-if-keys.err b/tests/qapi-schema/bad-if-keys.err
index aceb31dc6d..fe87bd30ac 100644
--- a/tests/qapi-schema/bad-if-keys.err
+++ b/tests/qapi-schema/bad-if-keys.err
@@ -1,2 +1,2 @@
bad-if-keys.json: In struct 'TestIfStruct':
-bad-if-keys.json:2: 'if' condition dict of struct must have one key: 'all', 'any' or 'not'
+bad-if-keys.json:2: 'if' condition of struct has conflicting keys
diff --git a/tests/qapi-schema/doc-good.json b/tests/qapi-schema/doc-good.json
index 5e30790730..e0027e4cf6 100644
--- a/tests/qapi-schema/doc-good.json
+++ b/tests/qapi-schema/doc-good.json
@@ -127,7 +127,7 @@
{ 'alternate': 'Alternate',
'features': [ 'alt-feat' ],
'data': { 'i': 'int', 'b': 'bool' },
- 'if': { 'not': 'IFNOT' } }
+ 'if': { 'not': { 'any': [ 'IFONE', 'IFTWO' ] } } }
##
# == Another subsection
diff --git a/tests/qapi-schema/doc-good.out b/tests/qapi-schema/doc-good.out
index 26d1fa5d28..478fe6f82e 100644
--- a/tests/qapi-schema/doc-good.out
+++ b/tests/qapi-schema/doc-good.out
@@ -18,7 +18,7 @@ enum Enum
feature enum-feat
object Base
member base1: Enum optional=False
- if OrderedDict([('all', ['IFALL1', 'IFALL2'])])
+ if {'all': ['IFALL1', 'IFALL2']}
object Variant1
member var1: str optional=False
if IFSTR
@@ -30,7 +30,7 @@ object Object
tag base1
case one: Variant1
case two: Variant2
- if OrderedDict([('any', ['IFONE', 'IFTWO'])])
+ if {'any': ['IFONE', 'IFTWO']}
feature union-feat1
object q_obj_Variant1-wrapper
member data: Variant1 optional=False
@@ -51,7 +51,7 @@ alternate Alternate
tag type
case i: int
case b: bool
- if OrderedDict([('not', 'IFNOT')])
+ if {'not': {'any': ['IFONE', 'IFTWO']}}
feature alt-feat
object q_obj_cmd-arg
member arg1: int optional=False
diff --git a/tests/qapi-schema/doc-good.txt b/tests/qapi-schema/doc-good.txt
index 5bfe06e14e..0c59d75964 100644
--- a/tests/qapi-schema/doc-good.txt
+++ b/tests/qapi-schema/doc-good.txt
@@ -79,7 +79,7 @@ Members
If
~~
-"(IFALL1 and IFALL2)"
+"IFALL1 and IFALL2"
"Variant1" (Object)
@@ -120,8 +120,8 @@ Members
The members of "Base"
The members of "Variant1" when "base1" is ""one""
-The members of "Variant2" when "base1" is ""two"" (**If: **"(IFONE or
-IFTWO)")
+The members of "Variant2" when "base1" is ""two"" (**If: **"IFONE or
+IFTWO")
Features
~~~~~~~~
@@ -174,7 +174,7 @@ Features
If
~~
-"!IFNOT"
+"not (IFONE or IFTWO)"
Another subsection
diff --git a/tests/qapi-schema/double-type.err b/tests/qapi-schema/double-type.err
index 576e716197..6a1e8a5990 100644
--- a/tests/qapi-schema/double-type.err
+++ b/tests/qapi-schema/double-type.err
@@ -1,3 +1 @@
-double-type.json: In struct 'Bar':
-double-type.json:2: struct has unknown key 'command'
-Valid keys are 'base', 'data', 'features', 'if', 'struct'.
+double-type.json:2: expression must have exactly one key 'enum', 'struct', 'union', 'alternate', 'command', 'event'
diff --git a/tests/qapi-schema/enum-if-invalid.err b/tests/qapi-schema/enum-if-invalid.err
index 3bb84075a9..2b2bbffb65 100644
--- a/tests/qapi-schema/enum-if-invalid.err
+++ b/tests/qapi-schema/enum-if-invalid.err
@@ -1,3 +1,3 @@
enum-if-invalid.json: In enum 'TestIfEnum':
-enum-if-invalid.json:2: 'if' condition has unknown key 'val'
+enum-if-invalid.json:2: 'if' condition of 'data' member 'bar' has unknown key 'val'
Valid keys are 'all', 'any', 'not'.
diff --git a/tests/qapi-schema/missing-type.err b/tests/qapi-schema/missing-type.err
index 5755386a18..cb39569e49 100644
--- a/tests/qapi-schema/missing-type.err
+++ b/tests/qapi-schema/missing-type.err
@@ -1 +1 @@
-missing-type.json:2: expression is missing metatype
+missing-type.json:2: expression must have exactly one key 'enum', 'struct', 'union', 'alternate', 'command', 'event'
diff --git a/tests/qapi-schema/qapi-schema-test.json b/tests/qapi-schema/qapi-schema-test.json
index fe028145e4..b6c36a9eee 100644
--- a/tests/qapi-schema/qapi-schema-test.json
+++ b/tests/qapi-schema/qapi-schema-test.json
@@ -236,7 +236,7 @@
{ 'command': 'test-if-union-cmd',
'data': { 'union-cmd-arg': 'TestIfUnion' },
- 'if': 'TEST_IF_UNION' }
+ 'if': { 'all': ['TEST_IF_UNION', 'TEST_IF_STRUCT'] } }
{ 'alternate': 'TestIfAlternate', 'data':
{ 'foo': 'int',
@@ -245,8 +245,7 @@
{ 'command': 'test-if-alternate-cmd',
'data': { 'alt-cmd-arg': 'TestIfAlternate' },
- 'if': { 'all': ['TEST_IF_ALT',
- {'not': 'TEST_IF_NOT_ALT'}] } }
+ 'if': { 'all': ['TEST_IF_ALT', 'TEST_IF_STRUCT'] } }
{ 'command': 'test-if-cmd',
'data': {
@@ -262,6 +261,10 @@
'bar': { 'type': ['TestIfEnum'], 'if': 'TEST_IF_EVT_BAR' } },
'if': { 'all': ['TEST_IF_EVT', 'TEST_IF_STRUCT'] } }
+{ 'event': 'TEST_IF_EVENT2', 'data': {},
+ 'if': { 'not': { 'any': [ { 'not': 'TEST_IF_EVT' },
+ { 'not': 'TEST_IF_STRUCT' } ] } } }
+
# test 'features'
{ 'struct': 'FeatureStruct0',
diff --git a/tests/qapi-schema/qapi-schema-test.out b/tests/qapi-schema/qapi-schema-test.out
index 3d0c6a8f28..d557fe2d89 100644
--- a/tests/qapi-schema/qapi-schema-test.out
+++ b/tests/qapi-schema/qapi-schema-test.out
@@ -311,40 +311,40 @@ enum TestIfUnionKind
member foo
member bar
if TEST_IF_UNION_BAR
- if OrderedDict([('all', ['TEST_IF_UNION', 'TEST_IF_STRUCT'])])
+ if {'all': ['TEST_IF_UNION', 'TEST_IF_STRUCT']}
object TestIfUnion
member type: TestIfUnionKind optional=False
tag type
case foo: q_obj_TestStruct-wrapper
case bar: q_obj_str-wrapper
if TEST_IF_UNION_BAR
- if OrderedDict([('all', ['TEST_IF_UNION', 'TEST_IF_STRUCT'])])
+ if {'all': ['TEST_IF_UNION', 'TEST_IF_STRUCT']}
object q_obj_test-if-union-cmd-arg
member union-cmd-arg: TestIfUnion optional=False
- if TEST_IF_UNION
+ if {'all': ['TEST_IF_UNION', 'TEST_IF_STRUCT']}
command test-if-union-cmd q_obj_test-if-union-cmd-arg -> None
gen=True success_response=True boxed=False oob=False preconfig=False
- if TEST_IF_UNION
+ if {'all': ['TEST_IF_UNION', 'TEST_IF_STRUCT']}
alternate TestIfAlternate
tag type
case foo: int
case bar: TestStruct
if TEST_IF_ALT_BAR
- if OrderedDict([('all', ['TEST_IF_ALT', 'TEST_IF_STRUCT'])])
+ if {'all': ['TEST_IF_ALT', 'TEST_IF_STRUCT']}
object q_obj_test-if-alternate-cmd-arg
member alt-cmd-arg: TestIfAlternate optional=False
- if OrderedDict([('all', ['TEST_IF_ALT', OrderedDict([('not', 'TEST_IF_NOT_ALT')])])])
+ if {'all': ['TEST_IF_ALT', 'TEST_IF_STRUCT']}
command test-if-alternate-cmd q_obj_test-if-alternate-cmd-arg -> None
gen=True success_response=True boxed=False oob=False preconfig=False
- if OrderedDict([('all', ['TEST_IF_ALT', OrderedDict([('not', 'TEST_IF_NOT_ALT')])])])
+ if {'all': ['TEST_IF_ALT', 'TEST_IF_STRUCT']}
object q_obj_test-if-cmd-arg
member foo: TestIfStruct optional=False
member bar: TestIfEnum optional=False
if TEST_IF_CMD_BAR
- if OrderedDict([('all', ['TEST_IF_CMD', 'TEST_IF_STRUCT'])])
+ if {'all': ['TEST_IF_CMD', 'TEST_IF_STRUCT']}
command test-if-cmd q_obj_test-if-cmd-arg -> UserDefThree
gen=True success_response=True boxed=False oob=False preconfig=False
- if OrderedDict([('all', ['TEST_IF_CMD', 'TEST_IF_STRUCT'])])
+ if {'all': ['TEST_IF_CMD', 'TEST_IF_STRUCT']}
command test-cmd-return-def-three None -> UserDefThree
gen=True success_response=True boxed=False oob=False preconfig=False
array TestIfEnumList TestIfEnum
@@ -353,10 +353,13 @@ object q_obj_TEST_IF_EVENT-arg
member foo: TestIfStruct optional=False
member bar: TestIfEnumList optional=False
if TEST_IF_EVT_BAR
- if OrderedDict([('all', ['TEST_IF_EVT', 'TEST_IF_STRUCT'])])
+ if {'all': ['TEST_IF_EVT', 'TEST_IF_STRUCT']}
event TEST_IF_EVENT q_obj_TEST_IF_EVENT-arg
boxed=False
- if OrderedDict([('all', ['TEST_IF_EVT', 'TEST_IF_STRUCT'])])
+ if {'all': ['TEST_IF_EVT', 'TEST_IF_STRUCT']}
+event TEST_IF_EVENT2 None
+ boxed=False
+ if {'not': {'any': [{'not': 'TEST_IF_EVT'}, {'not': 'TEST_IF_STRUCT'}]}}
object FeatureStruct0
member foo: int optional=False
object FeatureStruct1
@@ -389,11 +392,11 @@ object CondFeatureStruct2
object CondFeatureStruct3
member foo: int optional=False
feature feature1
- if OrderedDict([('all', ['TEST_IF_COND_1', 'TEST_IF_COND_2'])])
+ if {'all': ['TEST_IF_COND_1', 'TEST_IF_COND_2']}
object CondFeatureStruct4
member foo: int optional=False
feature feature1
- if OrderedDict([('any', ['TEST_IF_COND_1', 'TEST_IF_COND_2'])])
+ if {'any': ['TEST_IF_COND_1', 'TEST_IF_COND_2']}
enum FeatureEnum1
member eins
member zwei
@@ -444,7 +447,7 @@ command test-command-cond-features2 None -> None
command test-command-cond-features3 None -> None
gen=True success_response=True boxed=False oob=False preconfig=False
feature feature1
- if OrderedDict([('all', ['TEST_IF_COND_1', 'TEST_IF_COND_2'])])
+ if {'all': ['TEST_IF_COND_1', 'TEST_IF_COND_2']}
event TEST_EVENT_FEATURES0 FeatureStruct1
boxed=False
event TEST_EVENT_FEATURES1 None
diff --git a/tests/qapi-schema/test-qapi.py b/tests/qapi-schema/test-qapi.py
index c92be2d086..73cffae2b6 100755
--- a/tests/qapi-schema/test-qapi.py
+++ b/tests/qapi-schema/test-qapi.py
@@ -94,8 +94,17 @@ class QAPISchemaTestVisitor(QAPISchemaVisitor):
@staticmethod
def _print_if(ifcond, indent=4):
+ # TODO Drop this hack after replacing OrderedDict by plain
+ # dict (requires Python 3.7)
+ def _massage(subcond):
+ if isinstance(subcond, str):
+ return subcond
+ if isinstance(subcond, list):
+ return [_massage(val) for val in subcond]
+ return {key: _massage(val) for key, val in subcond.items()}
+
if ifcond.is_present():
- print('%sif %s' % (' ' * indent, ifcond.ifcond))
+ print('%sif %s' % (' ' * indent, _massage(ifcond.ifcond)))
@classmethod
def _print_features(cls, features, indent=4):