diff options
| author | Peter Maydell <peter.maydell@linaro.org> | 2021-09-04 19:21:19 +0100 |
|---|---|---|
| committer | Peter Maydell <peter.maydell@linaro.org> | 2021-09-04 19:21:19 +0100 |
| commit | 31ebff513fad11f315377f6b07447169be8d9f86 (patch) | |
| tree | d95b132eee4136110e5f8edb3ae90c7065c8829b /scripts/qapi/common.py | |
| parent | 9c03aa87e52567f6c9a7bf456e5dd94dc84088de (diff) | |
| parent | 34f7b25e575a93182b7c0a3558caac34e26227cf (diff) | |
| download | focaccia-qemu-31ebff513fad11f315377f6b07447169be8d9f86.tar.gz focaccia-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: |