[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [PATCH v7 06/10] qapi: replace if condition list with dict {'all': [
|
From: |
Markus Armbruster |
|
Subject: |
Re: [PATCH v7 06/10] qapi: replace if condition list with dict {'all': [...]} |
|
Date: |
Thu, 05 Aug 2021 17:14:35 +0200 |
|
User-agent: |
Gnus/5.13 (Gnus v5.13) Emacs/27.2 (gnu/linux) |
marcandre.lureau@redhat.com writes:
> From: Marc-André Lureau <marcandre.lureau@redhat.com>
>
> Replace the simple list sugar form with a recursive structure that will
> accept other operators in the following commits (all, any or not).
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
> scripts/qapi/common.py | 23 +++++--
> scripts/qapi/expr.py | 52 ++++++++++------
> scripts/qapi/schema.py | 2 +-
> tests/qapi-schema/bad-if-all.err | 2 +
> tests/qapi-schema/bad-if-all.json | 3 +
> tests/qapi-schema/bad-if-all.out | 0
> tests/qapi-schema/bad-if-empty-list.json | 2 +-
> tests/qapi-schema/bad-if-key.err | 3 +
> tests/qapi-schema/bad-if-key.json | 3 +
> tests/qapi-schema/bad-if-key.out | 0
> tests/qapi-schema/bad-if-keys.err | 2 +
> tests/qapi-schema/bad-if-keys.json | 3 +
> tests/qapi-schema/bad-if-keys.out | 0
> tests/qapi-schema/bad-if-list.json | 2 +-
> tests/qapi-schema/bad-if.err | 2 +-
> tests/qapi-schema/bad-if.json | 2 +-
> tests/qapi-schema/doc-good.json | 3 +-
> tests/qapi-schema/doc-good.out | 13 ++--
> tests/qapi-schema/doc-good.txt | 6 ++
> tests/qapi-schema/enum-if-invalid.err | 3 +-
> tests/qapi-schema/features-if-invalid.err | 2 +-
> tests/qapi-schema/meson.build | 3 +
> tests/qapi-schema/qapi-schema-test.json | 25 ++++----
> tests/qapi-schema/qapi-schema-test.out | 62 +++++++++----------
> .../qapi-schema/struct-member-if-invalid.err | 2 +-
> .../qapi-schema/union-branch-if-invalid.json | 2 +-
> 26 files changed, 138 insertions(+), 84 deletions(-)
> create mode 100644 tests/qapi-schema/bad-if-all.err
> create mode 100644 tests/qapi-schema/bad-if-all.json
> create mode 100644 tests/qapi-schema/bad-if-all.out
> create mode 100644 tests/qapi-schema/bad-if-key.err
> create mode 100644 tests/qapi-schema/bad-if-key.json
> create mode 100644 tests/qapi-schema/bad-if-key.out
> create mode 100644 tests/qapi-schema/bad-if-keys.err
> create mode 100644 tests/qapi-schema/bad-if-keys.json
> create mode 100644 tests/qapi-schema/bad-if-keys.out
>
> diff --git a/scripts/qapi/common.py b/scripts/qapi/common.py
> index 5181a0f167..51463510c9 100644
> --- a/scripts/qapi/common.py
> +++ b/scripts/qapi/common.py
> @@ -13,7 +13,8 @@
>
> import re
> from typing import (
> - List,
> + Any,
> + Dict,
> Match,
> Optional,
> Union,
> @@ -199,16 +200,28 @@ def guardend(name: str) -> str:
> name=c_fname(name).upper())
>
>
> -def cgen_ifcond(ifcond: Union[str, List[str]]) -> str:
> +def docgen_ifcond(ifcond: Union[str, Dict[str, Any]]) -> str:
> if not ifcond:
> return ''
> - return '(' + ') && ('.join(ifcond) + ')'
> + if isinstance(ifcond, str):
> + return ifcond
>
> + oper, operands = next(iter(ifcond.items()))
> + oper = {'all': ' and '}[oper]
> + operands = [docgen_ifcond(o) for o in operands]
> + return '(' + oper.join(operands) + ')'
>
> -def docgen_ifcond(ifcond: Union[str, List[str]]) -> str:
> +
> +def cgen_ifcond(ifcond: Union[str, Dict[str, Any]]) -> str:
> if not ifcond:
> return ''
> - return ' and '.join(ifcond)
> + if isinstance(ifcond, str):
> + return ifcond
> +
> + oper, operands = next(iter(ifcond.items()))
> + oper = {'all': '&&'}[oper]
> + operands = [cgen_ifcond(o) for o in operands]
> + return '(' + (') ' + oper + ' (').join(operands) + ')'
>
>
> def gen_if(cond: str) -> str:
> diff --git a/scripts/qapi/expr.py b/scripts/qapi/expr.py
> index cf98923fa6..b5187bfbca 100644
> --- a/scripts/qapi/expr.py
> +++ b/scripts/qapi/expr.py
> @@ -259,14 +259,12 @@ def check_flags(expr: _JSONObject, info:
> QAPISourceInfo) -> None:
>
> def check_if(expr: _JSONObject, info: QAPISourceInfo, source: str) -> None:
> """
> - Normalize and validate the ``if`` member of an object.
> + Validate the ``if`` member of an object.
>
> - The ``if`` member may be either a ``str`` or a ``List[str]``.
> - A ``str`` value will be normalized to ``List[str]``.
> + The ``if`` member may be either a ``str`` or a dict.
>
> :forms:
> - :sugared: ``Union[str, List[str]]``
> - :canonical: ``List[str]``
> + :canonical: ``Union[str, dict]``
>
> :param expr: The expression containing the ``if`` member to validate.
> :param info: QAPI schema source file information.
> @@ -275,31 +273,45 @@ def check_if(expr: _JSONObject, info: QAPISourceInfo,
> source: str) -> None:
> :raise QAPISemError:
> When the "if" member fails validation, or when there are no
> non-empty conditions.
> - :return: None, ``expr`` is normalized in-place as needed.
> + :return: None
> """
> ifcond = expr.get('if')
> if ifcond is None:
> return
>
> - if isinstance(ifcond, list):
> - if not ifcond:
> - raise QAPISemError(
> - info, "'if' condition [] of %s is useless" % source)
> - else:
> - # Normalize to a list
> - ifcond = expr['if'] = [ifcond]
> + def _check_if(cond: Union[str, object]) -> None:
> + if isinstance(cond, str):
> + if not cond.strip():
> + raise QAPISemError(
> + info,
> + "'if' condition '%s' of %s makes no sense"
> + % (cond, source))
> + return
>
> - for elt in ifcond:
> - if not isinstance(elt, str):
> + if not isinstance(cond, dict):
> raise QAPISemError(
> info,
> - "'if' condition of %s must be a string or a list of strings"
> - % source)
> - if not elt.strip():
> + "'if' condition of %s must be a string or a dict" % source)
s/a dict/an object/, since we're talking about JSON, not Python.
The existing error messages don't get this right 100% either.
> + if len(cond) != 1:
> raise QAPISemError(
> info,
> - "'if' condition '%s' of %s makes no sense"
> - % (elt, source))
> + "'if' condition dict of %s must have one key: "
> + "'all'" % source)
> + check_keys(cond, info, "'if' condition", [],
> + ["all"])
> +
> + oper, operands = next(iter(cond.items()))
> + if not operands:
> + raise QAPISemError(
> + info, "'if' condition [] of %s is useless" % source)
> +
> + if oper in ("all") and not isinstance(operands, list):
> + raise QAPISemError(
> + info, "'%s' condition of %s must be a list" % (oper, source))
s/a list/an array/
Can do both in my tree.
> + for operand in operands:
> + _check_if(operand)
> +
> + _check_if(ifcond)
>
>
> def normalize_members(members: object) -> None:
> diff --git a/scripts/qapi/schema.py b/scripts/qapi/schema.py
> index ff9c4f0a17..627735a431 100644
> --- a/scripts/qapi/schema.py
> +++ b/scripts/qapi/schema.py
> @@ -32,7 +32,7 @@
>
> class QAPISchemaIfCond:
> def __init__(self, ifcond=None):
> - self.ifcond = ifcond or []
> + self.ifcond = ifcond or {}
>
> def cgen(self):
> return cgen_ifcond(self.ifcond)
> diff --git a/tests/qapi-schema/bad-if-all.err
> b/tests/qapi-schema/bad-if-all.err
> new file mode 100644
> index 0000000000..3d9edd8af9
> --- /dev/null
> +++ b/tests/qapi-schema/bad-if-all.err
> @@ -0,0 +1,2 @@
> +bad-if-all.json: In struct 'TestIfStruct':
> +bad-if-all.json:2: 'all' condition of struct must be a list
> diff --git a/tests/qapi-schema/bad-if-all.json
> b/tests/qapi-schema/bad-if-all.json
> new file mode 100644
> index 0000000000..44837d3981
> --- /dev/null
> +++ b/tests/qapi-schema/bad-if-all.json
> @@ -0,0 +1,3 @@
> +# check 'if all' is not a list
> +{ 'struct': 'TestIfStruct', 'data': { 'foo': 'int' },
> + 'if': { 'all': 'ALL' } }
> diff --git a/tests/qapi-schema/bad-if-all.out
> b/tests/qapi-schema/bad-if-all.out
> new file mode 100644
> index 0000000000..e69de29bb2
> diff --git a/tests/qapi-schema/bad-if-empty-list.json
> b/tests/qapi-schema/bad-if-empty-list.json
> index 94f2eb8670..b62b5671df 100644
> --- a/tests/qapi-schema/bad-if-empty-list.json
> +++ b/tests/qapi-schema/bad-if-empty-list.json
> @@ -1,3 +1,3 @@
> # check empty 'if' list
> { 'struct': 'TestIfStruct', 'data': { 'foo': 'int' },
> - 'if': [] }
> + 'if': { 'all': [] } }
Syntax changes, but the error message remains "'if' condition [] of
struct is useless". The new error message visible in bad-if-all.err
above refers to the same thing as "'all' condition of struct", which is
better.
Not worth a respin by itself. If improving it is trivial, I'll do it in
my tree.
> diff --git a/tests/qapi-schema/bad-if-key.err
> b/tests/qapi-schema/bad-if-key.err
> new file mode 100644
> index 0000000000..725d5abae5
> --- /dev/null
> +++ b/tests/qapi-schema/bad-if-key.err
> @@ -0,0 +1,3 @@
> +bad-if-key.json: In struct 'TestIfStruct':
> +bad-if-key.json:2: 'if' condition has unknown key 'value'
> +Valid keys are 'all'.
> diff --git a/tests/qapi-schema/bad-if-key.json
> b/tests/qapi-schema/bad-if-key.json
> new file mode 100644
> index 0000000000..64c74c13f2
> --- /dev/null
> +++ b/tests/qapi-schema/bad-if-key.json
> @@ -0,0 +1,3 @@
> +# check unknown 'if' dict key
> +{ 'struct': 'TestIfStruct', 'data': { 'foo': 'int' },
> + 'if': { 'value': 'defined(TEST_IF_STRUCT)' } }
> diff --git a/tests/qapi-schema/bad-if-key.out
> b/tests/qapi-schema/bad-if-key.out
> new file mode 100644
> index 0000000000..e69de29bb2
> diff --git a/tests/qapi-schema/bad-if-keys.err
> b/tests/qapi-schema/bad-if-keys.err
> new file mode 100644
> index 0000000000..b072db9a6f
> --- /dev/null
> +++ b/tests/qapi-schema/bad-if-keys.err
> @@ -0,0 +1,2 @@
> +bad-if-keys.json: In struct 'TestIfStruct':
> +bad-if-keys.json:2: 'if' condition dict of struct must have one key: 'all'
> diff --git a/tests/qapi-schema/bad-if-keys.json
> b/tests/qapi-schema/bad-if-keys.json
> new file mode 100644
> index 0000000000..9e2f39ae21
> --- /dev/null
> +++ b/tests/qapi-schema/bad-if-keys.json
> @@ -0,0 +1,3 @@
> +# check multiple 'if' keys
> +{ 'struct': 'TestIfStruct', 'data': { 'foo': 'int' },
> + 'if': { 'any': ['ANY'], 'all': ['ALL'] } }
> diff --git a/tests/qapi-schema/bad-if-keys.out
> b/tests/qapi-schema/bad-if-keys.out
> new file mode 100644
> index 0000000000..e69de29bb2
> diff --git a/tests/qapi-schema/bad-if-list.json
> b/tests/qapi-schema/bad-if-list.json
> index ea3d95bb6b..1fefef16a7 100644
> --- a/tests/qapi-schema/bad-if-list.json
> +++ b/tests/qapi-schema/bad-if-list.json
> @@ -1,3 +1,3 @@
> # check invalid 'if' content
> { 'struct': 'TestIfStruct', 'data': { 'foo': 'int' },
> - 'if': ['foo', ' '] }
> + 'if': { 'all': ['foo', ' '] } }
Likewise.
> diff --git a/tests/qapi-schema/bad-if.err b/tests/qapi-schema/bad-if.err
> index f83dee65da..7f8f57057a 100644
> --- a/tests/qapi-schema/bad-if.err
> +++ b/tests/qapi-schema/bad-if.err
> @@ -1,2 +1,2 @@
> bad-if.json: In struct 'TestIfStruct':
> -bad-if.json:2: 'if' condition of struct must be a string or a list of strings
> +bad-if.json:2: 'if' condition of struct must be a string or a dict
> diff --git a/tests/qapi-schema/bad-if.json b/tests/qapi-schema/bad-if.json
> index 3edd1a0bf2..fdc0c87bb3 100644
> --- a/tests/qapi-schema/bad-if.json
> +++ b/tests/qapi-schema/bad-if.json
> @@ -1,3 +1,3 @@
> # check invalid 'if' type
> { 'struct': 'TestIfStruct', 'data': { 'foo': 'int' },
> - 'if': { 'value': 'defined(TEST_IF_STRUCT)' } }
> + 'if': ['defined(TEST_IF_STRUCT)'] }
> diff --git a/tests/qapi-schema/doc-good.json b/tests/qapi-schema/doc-good.json
> index 423ea23e07..25b1053e8a 100644
> --- a/tests/qapi-schema/doc-good.json
> +++ b/tests/qapi-schema/doc-good.json
> @@ -70,7 +70,8 @@
> # @base1:
> # the first member
> ##
> -{ 'struct': 'Base', 'data': { 'base1': 'Enum' } }
> +{ 'struct': 'Base', 'data': { 'base1': 'Enum' },
> + 'if': { 'all': ['IFALL1', 'IFALL2'] } }
>
> ##
> # @Variant1:
> diff --git a/tests/qapi-schema/doc-good.out b/tests/qapi-schema/doc-good.out
> index 8f54ceff2e..689d084f3a 100644
> --- a/tests/qapi-schema/doc-good.out
> +++ b/tests/qapi-schema/doc-good.out
> @@ -12,15 +12,16 @@ enum QType
> module doc-good.json
> enum Enum
> member one
> - if ['defined(IFONE)']
> + if defined(IFONE)
> member two
> - if ['defined(IFCOND)']
> + if defined(IFCOND)
> feature enum-feat
> object Base
> member base1: Enum optional=False
> + if OrderedDict([('all', ['IFALL1', 'IFALL2'])])
This will change (for the better) when we drop OrderedDict in favor of
plain dict. Tolerable.
> object Variant1
> member var1: str optional=False
> - if ['defined(IFSTR)']
> + if defined(IFSTR)
> feature member-feat
> feature variant1-feat
> object Variant2
> @@ -29,7 +30,7 @@ object Object
> tag base1
> case one: Variant1
> case two: Variant2
> - if ['IFTWO']
> + if IFTWO
> feature union-feat1
> object q_obj_Variant1-wrapper
> member data: Variant1 optional=False
> @@ -38,13 +39,13 @@ object q_obj_Variant2-wrapper
> enum SugaredUnionKind
> member one
> member two
> - if ['IFTWO']
> + if IFTWO
> object SugaredUnion
> member type: SugaredUnionKind optional=False
> tag type
> case one: q_obj_Variant1-wrapper
> case two: q_obj_Variant2-wrapper
> - if ['IFTWO']
> + if IFTWO
> feature union-feat2
> alternate Alternate
> tag type
> diff --git a/tests/qapi-schema/doc-good.txt b/tests/qapi-schema/doc-good.txt
> index 726727af74..4490108cb7 100644
> --- a/tests/qapi-schema/doc-good.txt
> +++ b/tests/qapi-schema/doc-good.txt
> @@ -76,6 +76,12 @@ Members
> the first member
>
>
> +If
> +~~
> +
> +"(IFALL1 and IFALL2)"
> +
> +
> "Variant1" (Object)
> -------------------
>
> diff --git a/tests/qapi-schema/enum-if-invalid.err
> b/tests/qapi-schema/enum-if-invalid.err
> index 0556dc967b..df305cd79f 100644
> --- a/tests/qapi-schema/enum-if-invalid.err
> +++ b/tests/qapi-schema/enum-if-invalid.err
> @@ -1,2 +1,3 @@
> enum-if-invalid.json: In enum 'TestIfEnum':
> -enum-if-invalid.json:2: 'if' condition of 'data' member 'bar' must be a
> string or a list of strings
> +enum-if-invalid.json:2: 'if' condition has unknown key 'val'
> +Valid keys are 'all'.
> diff --git a/tests/qapi-schema/features-if-invalid.err
> b/tests/qapi-schema/features-if-invalid.err
> index f63b89535e..8b64318df6 100644
> --- a/tests/qapi-schema/features-if-invalid.err
> +++ b/tests/qapi-schema/features-if-invalid.err
> @@ -1,2 +1,2 @@
> features-if-invalid.json: In struct 'Stru':
> -features-if-invalid.json:2: 'if' condition of 'features' member 'f' must be
> a string or a list of strings
> +features-if-invalid.json:2: 'if' condition of 'features' member 'f' must be
> a string or a dict
> diff --git a/tests/qapi-schema/meson.build b/tests/qapi-schema/meson.build
> index b8de58116a..4697c070bc 100644
> --- a/tests/qapi-schema/meson.build
> +++ b/tests/qapi-schema/meson.build
> @@ -37,8 +37,11 @@ schemas = [
> 'bad-data.json',
> 'bad-ident.json',
> 'bad-if.json',
> + 'bad-if-all.json',
> 'bad-if-empty.json',
> 'bad-if-empty-list.json',
> + 'bad-if-key.json',
> + 'bad-if-keys.json',
> 'bad-if-list.json',
> 'bad-type-bool.json',
> 'bad-type-dict.json',
> diff --git a/tests/qapi-schema/qapi-schema-test.json
> b/tests/qapi-schema/qapi-schema-test.json
> index 84b9d41f15..f2e0fff51f 100644
> --- a/tests/qapi-schema/qapi-schema-test.json
> +++ b/tests/qapi-schema/qapi-schema-test.json
> @@ -231,8 +231,8 @@
>
> { 'union': 'TestIfUnion', 'data':
> { 'foo': 'TestStruct',
> - 'bar': { 'type': 'str', 'if': 'defined(TEST_IF_UNION_BAR)'} },
> - 'if': 'defined(TEST_IF_UNION) && defined(TEST_IF_STRUCT)' }
> + 'union-bar': { 'type': 'str', 'if': 'defined(TEST_IF_UNION_BAR)'} },
Any particular reason for renaming @bar to @union-bar?
> + 'if': { 'all': ['defined(TEST_IF_UNION)', 'defined(TEST_IF_STRUCT)'] } }
>
> { 'command': 'test-if-union-cmd',
> 'data': { 'union-cmd-arg': 'TestIfUnion' },
> @@ -241,25 +241,24 @@
> { 'alternate': 'TestIfAlternate', 'data':
> { 'foo': 'int',
> 'bar': { 'type': 'TestStruct', 'if': 'defined(TEST_IF_ALT_BAR)'} },
> - 'if': 'defined(TEST_IF_ALT) && defined(TEST_IF_STRUCT)' }
> + 'if': { 'all': ['defined(TEST_IF_ALT)', 'defined(TEST_IF_STRUCT)'] } }
>
> -{ 'command': 'test-if-alternate-cmd',
> - 'data': { 'alt-cmd-arg': 'TestIfAlternate' },
> - 'if': 'defined(TEST_IF_ALT)' }
> +{ 'command': 'test-if-alternate-cmd', 'data': { 'alt-cmd-arg':
> 'TestIfAlternate' },
The joining of lines looks accidental. Mind if I revert?
> + 'if': { 'all': ['defined(TEST_IF_ALT)'] } }
>
> { 'command': 'test-if-cmd',
> 'data': {
> 'foo': 'TestIfStruct',
> 'bar': { 'type': 'TestIfEnum', 'if': 'defined(TEST_IF_CMD_BAR)' } },
> 'returns': 'UserDefThree',
> - 'if': ['defined(TEST_IF_CMD)', 'defined(TEST_IF_STRUCT)'] }
> + 'if': { 'all': ['defined(TEST_IF_CMD)', 'defined(TEST_IF_STRUCT)'] } }
>
> { 'command': 'test-cmd-return-def-three', 'returns': 'UserDefThree' }
>
> { 'event': 'TEST_IF_EVENT', 'data':
> { 'foo': 'TestIfStruct',
> 'bar': { 'type': ['TestIfEnum'], 'if': 'defined(TEST_IF_EVT_BAR)' } },
> - 'if': 'defined(TEST_IF_EVT) && defined(TEST_IF_STRUCT)' }
> + 'if': { 'all': ['defined(TEST_IF_EVT)', 'defined(TEST_IF_STRUCT)'] } }
>
> # test 'features'
>
> @@ -288,8 +287,9 @@
> { 'name': 'feature2', 'if': 'defined(TEST_IF_FEATURE_2)'} ] }
> { 'struct': 'CondFeatureStruct3',
> 'data': { 'foo': 'int' },
> - 'features': [ { 'name': 'feature1', 'if': [ 'defined(TEST_IF_COND_1)',
> - 'defined(TEST_IF_COND_2)'] } ]
> }
> + 'features': [ { 'name': 'feature1',
> + 'if': { 'all': [ 'defined(TEST_IF_COND_1)',
> + 'defined(TEST_IF_COND_2)'] } } ] }
>
> { 'enum': 'FeatureEnum1',
> 'data': [ 'eins', 'zwei', 'drei' ],
> @@ -328,8 +328,9 @@
> 'features': [ { 'name': 'feature1', 'if': 'defined(TEST_IF_FEATURE_1)'},
> { 'name': 'feature2', 'if': 'defined(TEST_IF_FEATURE_2)'} ] }
> { 'command': 'test-command-cond-features3',
> - 'features': [ { 'name': 'feature1', 'if': [ 'defined(TEST_IF_COND_1)',
> - 'defined(TEST_IF_COND_2)'] } ]
> }
> + 'features': [ { 'name': 'feature1',
> + 'if': { 'all': [ 'defined(TEST_IF_COND_1)',
> + 'defined(TEST_IF_COND_2)'] } } ] }
>
> { 'event': 'TEST_EVENT_FEATURES0',
> 'data': 'FeatureStruct1' }
> diff --git a/tests/qapi-schema/qapi-schema-test.out
> b/tests/qapi-schema/qapi-schema-test.out
> index e0b8a5f0b6..6a1b3aa341 100644
> --- a/tests/qapi-schema/qapi-schema-test.out
> +++ b/tests/qapi-schema/qapi-schema-test.out
> @@ -298,65 +298,65 @@ command __org.qemu_x-command
> q_obj___org.qemu_x-command-arg -> __org.qemu_x-Unio
> object TestIfStruct
> member foo: int optional=False
> member bar: int optional=False
> - if ['defined(TEST_IF_STRUCT_BAR)']
> - if ['defined(TEST_IF_STRUCT)']
> + if defined(TEST_IF_STRUCT_BAR)
> + if defined(TEST_IF_STRUCT)
> enum TestIfEnum
> member foo
> member bar
> - if ['defined(TEST_IF_ENUM_BAR)']
> - if ['defined(TEST_IF_ENUM)']
> + if defined(TEST_IF_ENUM_BAR)
> + if defined(TEST_IF_ENUM)
> object q_obj_TestStruct-wrapper
> member data: TestStruct optional=False
> enum TestIfUnionKind
> member foo
> - member bar
> - if ['defined(TEST_IF_UNION_BAR)']
> - if ['defined(TEST_IF_UNION) && defined(TEST_IF_STRUCT)']
> + member union-bar
> + if defined(TEST_IF_UNION_BAR)
> + if OrderedDict([('all', ['defined(TEST_IF_UNION)',
> 'defined(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 ['defined(TEST_IF_UNION_BAR)']
> - if ['defined(TEST_IF_UNION) && defined(TEST_IF_STRUCT)']
> + case union-bar: q_obj_str-wrapper
> + if defined(TEST_IF_UNION_BAR)
> + if OrderedDict([('all', ['defined(TEST_IF_UNION)',
> 'defined(TEST_IF_STRUCT)'])])
> object q_obj_test-if-union-cmd-arg
> member union-cmd-arg: TestIfUnion optional=False
> - if ['defined(TEST_IF_UNION)']
> + if defined(TEST_IF_UNION)
> 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 ['defined(TEST_IF_UNION)']
> + if defined(TEST_IF_UNION)
> alternate TestIfAlternate
> tag type
> case foo: int
> case bar: TestStruct
> - if ['defined(TEST_IF_ALT_BAR)']
> - if ['defined(TEST_IF_ALT) && defined(TEST_IF_STRUCT)']
> + if defined(TEST_IF_ALT_BAR)
> + if OrderedDict([('all', ['defined(TEST_IF_ALT)',
> 'defined(TEST_IF_STRUCT)'])])
> object q_obj_test-if-alternate-cmd-arg
> member alt-cmd-arg: TestIfAlternate optional=False
> - if ['defined(TEST_IF_ALT)']
> + if OrderedDict([('all', ['defined(TEST_IF_ALT)'])])
> 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 ['defined(TEST_IF_ALT)']
> + if OrderedDict([('all', ['defined(TEST_IF_ALT)'])])
> object q_obj_test-if-cmd-arg
> member foo: TestIfStruct optional=False
> member bar: TestIfEnum optional=False
> - if ['defined(TEST_IF_CMD_BAR)']
> - if ['defined(TEST_IF_CMD)', 'defined(TEST_IF_STRUCT)']
> + if defined(TEST_IF_CMD_BAR)
> + if OrderedDict([('all', ['defined(TEST_IF_CMD)',
> 'defined(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 ['defined(TEST_IF_CMD)', 'defined(TEST_IF_STRUCT)']
> + if OrderedDict([('all', ['defined(TEST_IF_CMD)',
> 'defined(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
> - if ['defined(TEST_IF_ENUM)']
> + if defined(TEST_IF_ENUM)
> object q_obj_TEST_IF_EVENT-arg
> member foo: TestIfStruct optional=False
> member bar: TestIfEnumList optional=False
> - if ['defined(TEST_IF_EVT_BAR)']
> - if ['defined(TEST_IF_EVT) && defined(TEST_IF_STRUCT)']
> + if defined(TEST_IF_EVT_BAR)
> + if OrderedDict([('all', ['defined(TEST_IF_EVT)',
> 'defined(TEST_IF_STRUCT)'])])
> event TEST_IF_EVENT q_obj_TEST_IF_EVENT-arg
> boxed=False
> - if ['defined(TEST_IF_EVT) && defined(TEST_IF_STRUCT)']
> + if OrderedDict([('all', ['defined(TEST_IF_EVT)',
> 'defined(TEST_IF_STRUCT)'])])
> object FeatureStruct0
> member foo: int optional=False
> object FeatureStruct1
> @@ -379,17 +379,17 @@ object FeatureStruct4
> object CondFeatureStruct1
> member foo: int optional=False
> feature feature1
> - if ['defined(TEST_IF_FEATURE_1)']
> + if defined(TEST_IF_FEATURE_1)
> object CondFeatureStruct2
> member foo: int optional=False
> feature feature1
> - if ['defined(TEST_IF_FEATURE_1)']
> + if defined(TEST_IF_FEATURE_1)
> feature feature2
> - if ['defined(TEST_IF_FEATURE_2)']
> + if defined(TEST_IF_FEATURE_2)
> object CondFeatureStruct3
> member foo: int optional=False
> feature feature1
> - if ['defined(TEST_IF_COND_1)', 'defined(TEST_IF_COND_2)']
> + if OrderedDict([('all', ['defined(TEST_IF_COND_1)',
> 'defined(TEST_IF_COND_2)'])])
> enum FeatureEnum1
> member eins
> member zwei
> @@ -429,17 +429,17 @@ command test-command-features3 None -> None
> command test-command-cond-features1 None -> None
> gen=True success_response=True boxed=False oob=False preconfig=False
> feature feature1
> - if ['defined(TEST_IF_FEATURE_1)']
> + if defined(TEST_IF_FEATURE_1)
> command test-command-cond-features2 None -> None
> gen=True success_response=True boxed=False oob=False preconfig=False
> feature feature1
> - if ['defined(TEST_IF_FEATURE_1)']
> + if defined(TEST_IF_FEATURE_1)
> feature feature2
> - if ['defined(TEST_IF_FEATURE_2)']
> + if defined(TEST_IF_FEATURE_2)
> command test-command-cond-features3 None -> None
> gen=True success_response=True boxed=False oob=False preconfig=False
> feature feature1
> - if ['defined(TEST_IF_COND_1)', 'defined(TEST_IF_COND_2)']
> + if OrderedDict([('all', ['defined(TEST_IF_COND_1)',
> 'defined(TEST_IF_COND_2)'])])
> event TEST_EVENT_FEATURES0 FeatureStruct1
> boxed=False
> event TEST_EVENT_FEATURES1 None
> diff --git a/tests/qapi-schema/struct-member-if-invalid.err
> b/tests/qapi-schema/struct-member-if-invalid.err
> index 42e7fdae3c..eea4c62aaf 100644
> --- a/tests/qapi-schema/struct-member-if-invalid.err
> +++ b/tests/qapi-schema/struct-member-if-invalid.err
> @@ -1,2 +1,2 @@
> struct-member-if-invalid.json: In struct 'Stru':
> -struct-member-if-invalid.json:2: 'if' condition of 'data' member 'member'
> must be a string or a list of strings
> +struct-member-if-invalid.json:2: 'if' condition of 'data' member 'member'
> must be a string or a dict
> diff --git a/tests/qapi-schema/union-branch-if-invalid.json
> b/tests/qapi-schema/union-branch-if-invalid.json
> index 46d4239af6..c41633856f 100644
> --- a/tests/qapi-schema/union-branch-if-invalid.json
> +++ b/tests/qapi-schema/union-branch-if-invalid.json
> @@ -3,4 +3,4 @@
> { 'struct': 'Stru', 'data': { 'member': 'str' } }
> { 'union': 'Uni',
> 'base': { 'tag': 'Branches' }, 'discriminator': 'tag',
> - 'data': { 'branch1': { 'type': 'Stru', 'if': [''] } } }
> + 'data': { 'branch1': { 'type': 'Stru', 'if': { 'all': [''] } } } }
[PATCH v7 09/10] qapi: add 'not' condition operation, marcandre . lureau, 2021/08/04
[PATCH v7 10/10] qapi: make 'if' condition strings simple identifiers, marcandre . lureau, 2021/08/04
Re: [PATCH v7 00/10] qapi: untie 'if' conditions from C preprocessor, Markus Armbruster, 2021/08/05