diff options
author | Peter Maydell | 2021-09-04 20:21:19 +0200 |
---|---|---|
committer | Peter Maydell | 2021-09-04 20:21:19 +0200 |
commit | 31ebff513fad11f315377f6b07447169be8d9f86 (patch) | |
tree | d95b132eee4136110e5f8edb3ae90c7065c8829b /scripts/qapi/common.py | |
parent | Merge remote-tracking branch 'remotes/stsquad/tags/pull-for-6.2-020921-1' int... (diff) | |
parent | qapi: Tweak error messages for unknown / conflicting 'if' keys (diff) | |
download | qemu-31ebff513fad11f315377f6b07447169be8d9f86.tar.gz qemu-31ebff513fad11f315377f6b07447169be8d9f86.tar.xz qemu-31ebff513fad11f315377f6b07447169be8d9f86.zip |
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>
Diffstat (limited to 'scripts/qapi/common.py')
-rw-r--r-- | scripts/qapi/common.py | 49 |
1 files changed, 28 insertions, 21 deletions
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: |