From e46c930cdd68a3911ec16bd89379891c5473dd06 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Tue, 31 Aug 2021 14:37:59 +0200 Subject: qapi: Simplify how QAPISchemaIfCond represents "no condition" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit None works fine, there is no need to replace it by {} in .__init__(). Signed-off-by: Markus Armbruster Message-Id: <20210831123809.1107782-3-armbru@redhat.com> Reviewed-by: Marc-André Lureau --- scripts/qapi/common.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'scripts/qapi/common.py') diff --git a/scripts/qapi/common.py b/scripts/qapi/common.py index 1724ac32db..1c1dc87ccb 100644 --- a/scripts/qapi/common.py +++ b/scripts/qapi/common.py @@ -200,7 +200,7 @@ def guardend(name: str) -> str: name=c_fname(name).upper()) -def cgen_ifcond(ifcond: Union[str, Dict[str, Any]]) -> str: +def cgen_ifcond(ifcond: Optional[Union[str, Dict[str, Any]]]) -> str: if not ifcond: return '' if isinstance(ifcond, str): @@ -214,7 +214,7 @@ def cgen_ifcond(ifcond: Union[str, Dict[str, Any]]) -> str: return '(' + (') ' + oper + ' (').join(operands) + ')' -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 '' -- cgit 1.4.1 From 82ca72c023b42ee4061e092fd9d4750c756c0475 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Tue, 31 Aug 2021 14:38:02 +0200 Subject: qapi: Fix C code generation for 'if' MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When commit 5d83b9a130 "qapi: replace if condition list with dict {'all': [...]}" made cgen_ifcond() and docgen_ifcond() recursive, it messed up parenthesises in the former, and got them right in the latter, as the previous commit demonstrates. To fix, adopt the latter's working code for the former. This generates the correct code from the previous commit's commit message. Fixes: 5d83b9a130690f879d5f33e991beabe69cb88bc8 Signed-off-by: Markus Armbruster Message-Id: <20210831123809.1107782-6-armbru@redhat.com> Reviewed-by: Marc-André Lureau --- scripts/qapi/common.py | 4 ++-- tests/qapi-schema/qapi-schema-test.json | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) (limited to 'scripts/qapi/common.py') diff --git a/scripts/qapi/common.py b/scripts/qapi/common.py index 1c1dc87ccb..f31e077d7b 100644 --- a/scripts/qapi/common.py +++ b/scripts/qapi/common.py @@ -209,9 +209,9 @@ def cgen_ifcond(ifcond: Optional[Union[str, Dict[str, Any]]]) -> str: oper, operands = next(iter(ifcond.items())) if oper == 'not': return '!' + cgen_ifcond(operands) - oper = {'all': '&&', 'any': '||'}[oper] + oper = {'all': ' && ', 'any': ' || '}[oper] operands = [cgen_ifcond(o) for o in operands] - return '(' + (') ' + oper + ' (').join(operands) + ')' + return '(' + oper.join(operands) + ')' def docgen_ifcond(ifcond: Optional[Union[str, Dict[str, Any]]]) -> str: diff --git a/tests/qapi-schema/qapi-schema-test.json b/tests/qapi-schema/qapi-schema-test.json index 6e37758280..b6c36a9eee 100644 --- a/tests/qapi-schema/qapi-schema-test.json +++ b/tests/qapi-schema/qapi-schema-test.json @@ -262,7 +262,6 @@ 'if': { 'all': ['TEST_IF_EVT', 'TEST_IF_STRUCT'] } } { 'event': 'TEST_IF_EVENT2', 'data': {}, - # FIXME C #if generated for this conditional is wrong 'if': { 'not': { 'any': [ { 'not': 'TEST_IF_EVT' }, { 'not': 'TEST_IF_STRUCT' } ] } } } -- cgit 1.4.1 From ccea6a8637a08585433aa04ce2a25480f205afff Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Tue, 31 Aug 2021 14:38:03 +0200 Subject: qapi: Factor common recursion out of cgen_ifcond(), docgen_ifcond() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Markus Armbruster Message-Id: <20210831123809.1107782-7-armbru@redhat.com> Reviewed-by: Marc-André Lureau --- scripts/qapi/common.py | 45 +++++++++++++++++++++++++-------------------- 1 file changed, 25 insertions(+), 20 deletions(-) (limited to 'scripts/qapi/common.py') diff --git a/scripts/qapi/common.py b/scripts/qapi/common.py index f31e077d7b..df92cff852 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,37 @@ def guardend(name: str) -> str: name=c_fname(name).upper()) -def cgen_ifcond(ifcond: Optional[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]]): + 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']) + if 'all' in ifcond: + gen = gen_infix(all_operator, ifcond['all']) + else: + gen = gen_infix(any_operator, ifcond['any']) + return gen + + def gen_infix(operator: str, operands: Sequence[Any]) -> str: + return '(' + operator.join([do_gen(o) for o in operands]) + ')' + if not ifcond: return '' - if isinstance(ifcond, str): - return 'defined(' + ifcond + ')' + return do_gen(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) + ')' + +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', '!%s', ' and ', ' or ') def gen_if(cond: str) -> str: -- cgit 1.4.1 From a7987799d1373d2408565d09823946ec28df4521 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Tue, 31 Aug 2021 14:38:04 +0200 Subject: qapi: Avoid redundant parens in code generated for conditionals MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit 6cc2e4817f "qapi: introduce QAPISchemaIfCond.cgen()" caused a minor regression: redundant parenthesis. Subsequent commits eliminated of many of them, but not all. Get rid of the rest now. Signed-off-by: Markus Armbruster Message-Id: <20210831123809.1107782-8-armbru@redhat.com> Reviewed-by: Marc-André Lureau --- scripts/qapi/common.py | 10 ++++++---- tests/qapi-schema/doc-good.txt | 6 +++--- 2 files changed, 9 insertions(+), 7 deletions(-) (limited to 'scripts/qapi/common.py') diff --git a/scripts/qapi/common.py b/scripts/qapi/common.py index df92cff852..c7ccc7cec7 100644 --- a/scripts/qapi/common.py +++ b/scripts/qapi/common.py @@ -205,24 +205,26 @@ 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]]): + 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']) + 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) for o in operands]) + ')' + return operator.join([do_gen(o, True) for o in operands]) if not ifcond: return '' - return do_gen(ifcond) + return do_gen(ifcond, False) def cgen_ifcond(ifcond: Optional[Union[str, Dict[str, Any]]]) -> str: diff --git a/tests/qapi-schema/doc-good.txt b/tests/qapi-schema/doc-good.txt index 85a370831f..75f51a6fc1 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 ~~~~~~~~ -- cgit 1.4.1 From d0830ee443f2e27b62c40c9ac2d20b19c399ca4b Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Tue, 31 Aug 2021 14:38:05 +0200 Subject: qapi: Use "not COND" instead of "!COND" for generated documentation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Generated documentation uses operators "and", "or", and "!". Change the latter to "not". Signed-off-by: Markus Armbruster Message-Id: <20210831123809.1107782-9-armbru@redhat.com> Reviewed-by: Marc-André Lureau --- scripts/qapi/common.py | 2 +- tests/qapi-schema/doc-good.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'scripts/qapi/common.py') diff --git a/scripts/qapi/common.py b/scripts/qapi/common.py index c7ccc7cec7..5f8f76e5b2 100644 --- a/scripts/qapi/common.py +++ b/scripts/qapi/common.py @@ -233,7 +233,7 @@ def cgen_ifcond(ifcond: Optional[Union[str, Dict[str, Any]]]) -> str: def docgen_ifcond(ifcond: Optional[Union[str, Dict[str, Any]]]) -> str: # TODO Doc generated for conditions needs polish - return gen_ifcond(ifcond, '%s', '!%s', ' and ', ' or ') + return gen_ifcond(ifcond, '%s', 'not %s', ' and ', ' or ') def gen_if(cond: str) -> str: diff --git a/tests/qapi-schema/doc-good.txt b/tests/qapi-schema/doc-good.txt index 75f51a6fc1..0c59d75964 100644 --- a/tests/qapi-schema/doc-good.txt +++ b/tests/qapi-schema/doc-good.txt @@ -174,7 +174,7 @@ Features If ~~ -"!(IFONE or IFTWO)" +"not (IFONE or IFTWO)" Another subsection -- cgit 1.4.1