QAPI patches patches for 2021-09-03
-----BEGIN PGP SIGNATURE----- iQJGBAABCAAwFiEENUvIs9frKmtoZ05fOHC0AOuRhlMFAmEyPVESHGFybWJydUBy ZWRoYXQuY29tAAoJEDhwtADrkYZTu9UP+wawlxnMaxG3/3kkCT6g8i1poD+xTRSU Z64VK/aAtGy4K0Z/3KQpW2cNeO/bkhrMb8bwB3Nn/jfwqMav0CPVhLsrasXOu78u AM1nMVCGfcbqW5oINTdysWAI1z4cgsv8T8g3BOSUWAM4teKDx+Lkme/dSTOgAuE5 6uixZZ53QUHuhY3K11mryQs/vWAWdzMBwy3Eawge6WEu48DnRH2C2wax+vb79LVa P/s7Bo4HKkJcPXfgyyzugd5NQCQ8uo6FIXEt2VHEThQIwHIHZC7lTn+VyzJAVlIO OnuayM5/5YTPxTFOrZgHwHZdBcmDwPKzNxvpayZZfh9lLVcqFhLY7SM4WxDQw8hF nJ0DCbUYV/JKrjv5ly0s1r7RfeXtAFBWLXWh4xlvuj2p6TdfXb6pjuxLlLdpLYfS qkeMteT21JEfE5U108d7AGDJ98HbQD+SXao90c8N6K1MsBh+jfifpgbcfcttOLoX +UItu6zOxZvDd/NO9m7JgE8o8Btd1uXK0PAwdK5V8xBf7TBgqk8FIQTPZo5SwYWI VUmtxc8f2NvsgLaHglXmouOXM5V2BgluW3iVmq/IIAcJo7qvFdPZnRG/BZ5bVuHG f6KQNRNUK3ef5rbMfMIusN7BNeCJr4yGXNr9WRhK5zP6I/AuP21kMrZ25Z+he2yV RhKNWF3BbSkv =rHX+ -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/armbru/tags/pull-qapi-2021-09-03' into staging QAPI patches patches for 2021-09-03 # gpg: Signature made Fri 03 Sep 2021 16:20:49 BST # gpg: using RSA key 354BC8B3D7EB2A6B68674E5F3870B400EB918653 # gpg: issuer "armbru@redhat.com" # gpg: Good signature from "Markus Armbruster <armbru@redhat.com>" [full] # gpg: aka "Markus Armbruster <armbru@pond.sub.org>" [full] # Primary key fingerprint: 354B C8B3 D7EB 2A6B 6867 4E5F 3870 B400 EB91 8653 * remotes/armbru/tags/pull-qapi-2021-09-03: qapi: Tweak error messages for unknown / conflicting 'if' keys qapi: Tweak error messages for missing / conflicting meta-type tests/qapi-schema: Hide OrderedDict in test output qapi: Use re.fullmatch() where appropriate qapi: Use "not COND" instead of "!COND" for generated documentation qapi: Avoid redundant parens in code generated for conditionals qapi: Factor common recursion out of cgen_ifcond(), docgen_ifcond() qapi: Fix C code generation for 'if' tests/qapi-schema: Demonstrate broken C code for 'if' tests/qapi-schema: Correct two 'if' conditionals qapi: Simplify how QAPISchemaIfCond represents "no condition" qapi: Simplify QAPISchemaIfCond's interface for generating C qapi: Set boolean value correctly in examples Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
31ebff513f
@ -99,7 +99,7 @@
|
||||
# Example:
|
||||
#
|
||||
# -> { "execute": "trace-event-set-state",
|
||||
# "arguments": { "name": "qemu_memalign", "enable": "true" } }
|
||||
# "arguments": { "name": "qemu_memalign", "enable": true } }
|
||||
# <- { "return": {} }
|
||||
#
|
||||
##
|
||||
|
@ -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 + ')'
|
||||
|
||||
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) + ')'
|
||||
return do_gen(ifcond, False)
|
||||
|
||||
|
||||
def docgen_ifcond(ifcond: Union[str, Dict[str, Any]]) -> str:
|
||||
def cgen_ifcond(ifcond: Optional[Union[str, Dict[str, Any]]]) -> str:
|
||||
return gen_ifcond(ifcond, 'defined(%s)', '!%s', ' && ', ' || ')
|
||||
|
||||
|
||||
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:
|
||||
|
@ -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])
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
@ -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 = ''
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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:
|
||||
|
@ -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'.
|
||||
|
@ -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
|
||||
|
@ -127,7 +127,7 @@
|
||||
{ 'alternate': 'Alternate',
|
||||
'features': [ 'alt-feat' ],
|
||||
'data': { 'i': 'int', 'b': 'bool' },
|
||||
'if': { 'not': 'IFNOT' } }
|
||||
'if': { 'not': { 'any': [ 'IFONE', 'IFTWO' ] } } }
|
||||
|
||||
##
|
||||
# == Another subsection
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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'
|
||||
|
@ -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'.
|
||||
|
@ -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'
|
||||
|
@ -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',
|
||||
|
@ -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
|
||||
|
@ -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):
|
||||
|
Loading…
Reference in New Issue
Block a user