From patchwork Tue Jun 8 12:07:15 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= X-Patchwork-Id: 1489396 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=TMgFMKxx; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4Fzpws6zmxz9sW8 for ; Tue, 8 Jun 2021 22:10:53 +1000 (AEST) Received: from localhost ([::1]:54386 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lqaZH-0003r8-9c for incoming@patchwork.ozlabs.org; Tue, 08 Jun 2021 08:10:51 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:54760) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lqaWD-0005xq-Al for qemu-devel@nongnu.org; Tue, 08 Jun 2021 08:07:41 -0400 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:30693) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lqaWB-00017t-Lo for qemu-devel@nongnu.org; Tue, 08 Jun 2021 08:07:41 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1623154059; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=cSo2UlPSDm3tbuXW3tS2gDLoaigJ7cA0lYHNzW0Nv28=; b=TMgFMKxxOqP3CSxuYy/01JGkMZLoBNM8vj8m6nF58rtbMTIhn0ewreQHGAZndSllJBbPEI ocGkNThoQxzWXtm6PihGU/Ih1As+lnbNEH/sa4xSGttX8pa1Fxi3L9yI3fcybi/mNDT1sh Jc+6Mo69yuw1LfvnUQ61msiASSu5DSQ= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-541-11wQRjuZMHmPLgo9STlo1w-1; Tue, 08 Jun 2021 08:07:37 -0400 X-MC-Unique: 11wQRjuZMHmPLgo9STlo1w-1 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id C0A1A800D55 for ; Tue, 8 Jun 2021 12:07:36 +0000 (UTC) Received: from localhost (unknown [10.36.110.2]) by smtp.corp.redhat.com (Postfix) with ESMTP id C4ED95C1BB; Tue, 8 Jun 2021 12:07:32 +0000 (UTC) From: marcandre.lureau@redhat.com To: qemu-devel@nongnu.org Subject: [PATCH v5 1/9] docs: update the documentation about schema configuration Date: Tue, 8 Jun 2021 16:07:15 +0400 Message-Id: <20210608120723.2268181-2-marcandre.lureau@redhat.com> In-Reply-To: <20210608120723.2268181-1-marcandre.lureau@redhat.com> References: <20210608120723.2268181-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=marcandre.lureau@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Received-SPF: pass client-ip=216.205.24.124; envelope-from=marcandre.lureau@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -29 X-Spam_score: -3.0 X-Spam_bar: --- X-Spam_report: (-3.0 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.197, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Eric Blake , jsnow@redhat.com, Markus Armbruster , =?utf-8?q?Marc-Andr=C3=A9_Lureau?= Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Marc-André Lureau Update the documentation describing the changes in this series. Signed-off-by: Marc-André Lureau Reviewed-by: Stefan Hajnoczi Tested-by: John Snow --- docs/devel/qapi-code-gen.txt | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/docs/devel/qapi-code-gen.txt b/docs/devel/qapi-code-gen.txt index c1cb6f987d..0162b73119 100644 --- a/docs/devel/qapi-code-gen.txt +++ b/docs/devel/qapi-code-gen.txt @@ -781,25 +781,31 @@ downstream command __com.redhat_drive-mirror. Syntax: COND = STRING - | [ STRING, ... ] + | { 'all: [ COND, ... ] } + | { 'any: [ COND, ... ] } + | { 'not': COND } All definitions take an optional 'if' member. Its value must be a -string or a list of strings. A string is shorthand for a list -containing just that string. The code generated for the definition -will then be guarded by #if STRING for each STRING in the COND list. +string, or an object with a single member 'all', 'any' or 'not'. + +The C code generated for the definition will then be guarded by an #if +preprocessing directive generated from that condition: + + * STRING will generate #if defined(STRING) + * { 'all': [COND, ...] } will generate #if (COND && ...) + * { 'any': [COND, ...] } will generate #if (COND || ...) + * { 'not': COND } will generate #if !COND Example: a conditional struct { 'struct': 'IfStruct', 'data': { 'foo': 'int' }, - 'if': ['defined(CONFIG_FOO)', 'defined(HAVE_BAR)'] } + 'if': { 'all': [ 'CONFIG_FOO', 'HAVE_BAR' ] } } gets its generated code guarded like this: - #if defined(CONFIG_FOO) - #if defined(HAVE_BAR) + #if defined(CONFIG_FOO) && defined(HAVE_BAR) ... generated code ... - #endif /* defined(HAVE_BAR) */ - #endif /* defined(CONFIG_FOO) */ + #endif /* defined(HAVE_BAR) && defined(CONFIG_FOO) */ Individual members of complex types, commands arguments, and event-specific data can also be made conditional. This requires the @@ -810,7 +816,7 @@ member 'bar' { 'struct': 'IfStruct', 'data': { 'foo': 'int', - 'bar': { 'type': 'int', 'if': 'defined(IFCOND)'} } } + 'bar': { 'type': 'int', 'if': 'IFCOND'} } } A union's discriminator may not be conditional. @@ -822,7 +828,7 @@ value 'bar' { 'enum': 'IfEnum', 'data': [ 'foo', - { 'name' : 'bar', 'if': 'defined(IFCOND)' } ] } + { 'name' : 'bar', 'if': 'IFCOND' } ] } Likewise, features can be conditional. This requires the longhand form of FEATURE. @@ -832,7 +838,7 @@ Example: a struct with conditional feature 'allow-negative-numbers' { 'struct': 'TestType', 'data': { 'number': 'int' }, 'features': [ { 'name': 'allow-negative-numbers', - 'if': 'defined(IFCOND)' } ] } + 'if': 'IFCOND' } ] } Please note that you are responsible to ensure that the C code will compile with an arbitrary combination of conditions, since the From patchwork Tue Jun 8 12:07:16 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= X-Patchwork-Id: 1489392 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=XRxa9TeE; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4Fzpt50Dxsz9sSn for ; Tue, 8 Jun 2021 22:08:29 +1000 (AEST) Received: from localhost ([::1]:45474 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lqaWx-0006KD-0B for incoming@patchwork.ozlabs.org; Tue, 08 Jun 2021 08:08:27 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:54938) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lqaWQ-0006HK-WB for qemu-devel@nongnu.org; Tue, 08 Jun 2021 08:07:55 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]:47843) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lqaWK-0001Dv-Jz for qemu-devel@nongnu.org; Tue, 08 Jun 2021 08:07:53 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1623154067; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=szypnb0aKBCHS+5fm3km5evCasCtlB/6bd/9tjjtW7E=; b=XRxa9TeElnvi3qrcaJiKvVbtwOQA8ajeFkUI3+Zas2xtocQhnOKwY+S8dcFlFZto/tupZW fUAGVUKaT15nyP6c8MMF1i5C6uoeRubf3YQfKYGsytTdK0RGMuK6Zb1fAVNWC+sfBfyaUO g6J8G7eDwelfNEresJl5ME2/AsGRIzs= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-448-oeSUSlYIPEqsOA2dvOXkhA-1; Tue, 08 Jun 2021 08:07:45 -0400 X-MC-Unique: oeSUSlYIPEqsOA2dvOXkhA-1 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 74E461020C38 for ; Tue, 8 Jun 2021 12:07:44 +0000 (UTC) Received: from localhost (unknown [10.36.110.2]) by smtp.corp.redhat.com (Postfix) with ESMTP id 5E20460C16; Tue, 8 Jun 2021 12:07:40 +0000 (UTC) From: marcandre.lureau@redhat.com To: qemu-devel@nongnu.org Subject: [PATCH v5 2/9] qapi: replace List[str] by QAPISchemaIfCond Date: Tue, 8 Jun 2021 16:07:16 +0400 Message-Id: <20210608120723.2268181-3-marcandre.lureau@redhat.com> In-Reply-To: <20210608120723.2268181-1-marcandre.lureau@redhat.com> References: <20210608120723.2268181-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=marcandre.lureau@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Received-SPF: pass client-ip=170.10.133.124; envelope-from=marcandre.lureau@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -29 X-Spam_score: -3.0 X-Spam_bar: --- X-Spam_report: (-3.0 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.197, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Eric Blake , jsnow@redhat.com, Markus Armbruster , =?utf-8?q?Marc-Andr=C3=A9_Lureau?= Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Marc-André Lureau Wrap the 'if' condition in a higher-level object. Not only does this provide more type safety but it also enables further refactoring without too much churn. The following patches will change the syntax of the schema 'if' conditions to be predicate expressions, and will generate code for different target languages (C, and Rust in another series). Signed-off-by: Marc-André Lureau Reviewed-by: Stefan Hajnoczi Tested-by: John Snow --- docs/sphinx/qapidoc.py | 2 +- scripts/qapi/commands.py | 4 +- scripts/qapi/events.py | 5 ++- scripts/qapi/gen.py | 14 +++---- scripts/qapi/introspect.py | 26 ++++++------ scripts/qapi/schema.py | 74 +++++++++++++++++++++++----------- scripts/qapi/types.py | 33 +++++++-------- scripts/qapi/visit.py | 23 ++++++----- tests/qapi-schema/test-qapi.py | 2 +- 9 files changed, 106 insertions(+), 77 deletions(-) diff --git a/docs/sphinx/qapidoc.py b/docs/sphinx/qapidoc.py index 87c67ab23f..b737949007 100644 --- a/docs/sphinx/qapidoc.py +++ b/docs/sphinx/qapidoc.py @@ -116,7 +116,7 @@ def _nodes_for_ifcond(self, ifcond, with_if=True): the conditions are in literal-text and the commas are not. If with_if is False, we don't return the "(If: " and ")". """ - condlist = intersperse([nodes.literal('', c) for c in ifcond], + condlist = intersperse([nodes.literal('', c) for c in ifcond.ifcond], nodes.Text(', ')) if not with_if: return condlist diff --git a/scripts/qapi/commands.py b/scripts/qapi/commands.py index 0e13d51054..3654825968 100644 --- a/scripts/qapi/commands.py +++ b/scripts/qapi/commands.py @@ -17,7 +17,6 @@ Dict, List, Optional, - Sequence, Set, ) @@ -31,6 +30,7 @@ from .schema import ( QAPISchema, QAPISchemaFeature, + QAPISchemaIfCond, QAPISchemaObjectType, QAPISchemaType, ) @@ -301,7 +301,7 @@ def visit_end(self) -> None: def visit_command(self, name: str, info: Optional[QAPISourceInfo], - ifcond: Sequence[str], + ifcond: QAPISchemaIfCond, features: List[QAPISchemaFeature], arg_type: Optional[QAPISchemaObjectType], ret_type: Optional[QAPISchemaType], diff --git a/scripts/qapi/events.py b/scripts/qapi/events.py index fee8c671e7..82475e84ec 100644 --- a/scripts/qapi/events.py +++ b/scripts/qapi/events.py @@ -12,7 +12,7 @@ See the COPYING file in the top-level directory. """ -from typing import List, Optional, Sequence +from typing import List, Optional from .common import c_enum_const, c_name, mcgen from .gen import QAPISchemaModularCVisitor, build_params, ifcontext @@ -20,6 +20,7 @@ QAPISchema, QAPISchemaEnumMember, QAPISchemaFeature, + QAPISchemaIfCond, QAPISchemaObjectType, ) from .source import QAPISourceInfo @@ -227,7 +228,7 @@ def visit_end(self) -> None: def visit_event(self, name: str, info: Optional[QAPISourceInfo], - ifcond: Sequence[str], + ifcond: QAPISchemaIfCond, features: List[QAPISchemaFeature], arg_type: Optional[QAPISchemaObjectType], boxed: bool) -> None: diff --git a/scripts/qapi/gen.py b/scripts/qapi/gen.py index 1fa503bdbd..1c5b190276 100644 --- a/scripts/qapi/gen.py +++ b/scripts/qapi/gen.py @@ -18,7 +18,6 @@ Dict, Iterator, Optional, - Sequence, Tuple, ) @@ -32,6 +31,7 @@ mcgen, ) from .schema import ( + QAPISchemaIfCond, QAPISchemaModule, QAPISchemaObjectType, QAPISchemaVisitor, @@ -85,7 +85,7 @@ def write(self, output_dir: str) -> None: fp.write(text) -def _wrap_ifcond(ifcond: Sequence[str], before: str, after: str) -> str: +def _wrap_ifcond(ifcond: QAPISchemaIfCond, before: str, after: str) -> str: if before == after: return after # suppress empty #if ... #endif @@ -95,9 +95,9 @@ def _wrap_ifcond(ifcond: Sequence[str], before: str, after: str) -> str: if added[0] == '\n': out += '\n' added = added[1:] - out += gen_if(ifcond) + out += gen_if(ifcond.ifcond) out += added - out += gen_endif(ifcond) + out += gen_endif(ifcond.ifcond) return out @@ -127,9 +127,9 @@ def build_params(arg_type: Optional[QAPISchemaObjectType], class QAPIGenCCode(QAPIGen): def __init__(self, fname: str): super().__init__(fname) - self._start_if: Optional[Tuple[Sequence[str], str, str]] = None + self._start_if: Optional[Tuple[QAPISchemaIfCond, str, str]] = None - def start_if(self, ifcond: Sequence[str]) -> None: + def start_if(self, ifcond: QAPISchemaIfCond) -> None: assert self._start_if is None self._start_if = (ifcond, self._body, self._preamble) @@ -187,7 +187,7 @@ def _bottom(self) -> str: @contextmanager -def ifcontext(ifcond: Sequence[str], *args: QAPIGenCCode) -> Iterator[None]: +def ifcontext(ifcond: QAPISchemaIfCond, *args: QAPIGenCCode) -> Iterator[None]: """ A with-statement context manager that wraps with `start_if()` / `end_if()`. diff --git a/scripts/qapi/introspect.py b/scripts/qapi/introspect.py index 9a348ca2e5..77a8c33ad4 100644 --- a/scripts/qapi/introspect.py +++ b/scripts/qapi/introspect.py @@ -15,11 +15,9 @@ Any, Dict, Generic, - Iterable, List, Optional, Sequence, - Tuple, TypeVar, Union, ) @@ -38,6 +36,7 @@ QAPISchemaEntity, QAPISchemaEnumMember, QAPISchemaFeature, + QAPISchemaIfCond, QAPISchemaObjectType, QAPISchemaObjectTypeMember, QAPISchemaType, @@ -91,11 +90,11 @@ class Annotated(Generic[_ValueT]): """ # TODO: Remove after Python 3.7 adds @dataclass: # pylint: disable=too-few-public-methods - def __init__(self, value: _ValueT, ifcond: Iterable[str], + def __init__(self, value: _ValueT, ifcond: QAPISchemaIfCond, comment: Optional[str] = None): self.value = value self.comment: Optional[str] = comment - self.ifcond: Tuple[str, ...] = tuple(ifcond) + self.ifcond = ifcond def _tree_to_qlit(obj: JSONValue, @@ -125,10 +124,10 @@ def indent(level: int) -> str: if obj.comment: ret += indent(level) + f"/* {obj.comment} */\n" if obj.ifcond: - ret += gen_if(obj.ifcond) + ret += gen_if(obj.ifcond.ifcond) ret += _tree_to_qlit(obj.value, level) if obj.ifcond: - ret += '\n' + gen_endif(obj.ifcond) + ret += '\n' + gen_endif(obj.ifcond.ifcond) return ret ret = '' @@ -254,7 +253,7 @@ def _gen_features(features: Sequence[QAPISchemaFeature] return [Annotated(f.name, f.ifcond) for f in features] def _gen_tree(self, name: str, mtype: str, obj: Dict[str, object], - ifcond: Sequence[str] = (), + ifcond: QAPISchemaIfCond = QAPISchemaIfCond(), features: Sequence[QAPISchemaFeature] = ()) -> None: """ Build and append a SchemaInfo object to self._trees. @@ -305,7 +304,7 @@ def visit_builtin_type(self, name: str, info: Optional[QAPISourceInfo], self._gen_tree(name, 'builtin', {'json-type': json_type}) def visit_enum_type(self, name: str, info: Optional[QAPISourceInfo], - ifcond: Sequence[str], + ifcond: QAPISchemaIfCond, features: List[QAPISchemaFeature], members: List[QAPISchemaEnumMember], prefix: Optional[str]) -> None: @@ -316,14 +315,14 @@ def visit_enum_type(self, name: str, info: Optional[QAPISourceInfo], ) def visit_array_type(self, name: str, info: Optional[QAPISourceInfo], - ifcond: Sequence[str], + ifcond: QAPISchemaIfCond, element_type: QAPISchemaType) -> None: element = self._use_type(element_type) self._gen_tree('[' + element + ']', 'array', {'element-type': element}, ifcond) def visit_object_type_flat(self, name: str, info: Optional[QAPISourceInfo], - ifcond: Sequence[str], + ifcond: QAPISchemaIfCond, features: List[QAPISchemaFeature], members: List[QAPISchemaObjectTypeMember], variants: Optional[QAPISchemaVariants]) -> None: @@ -336,7 +335,7 @@ def visit_object_type_flat(self, name: str, info: Optional[QAPISourceInfo], self._gen_tree(name, 'object', obj, ifcond, features) def visit_alternate_type(self, name: str, info: Optional[QAPISourceInfo], - ifcond: Sequence[str], + ifcond: QAPISchemaIfCond, features: List[QAPISchemaFeature], variants: QAPISchemaVariants) -> None: self._gen_tree( @@ -348,7 +347,7 @@ def visit_alternate_type(self, name: str, info: Optional[QAPISourceInfo], ) def visit_command(self, name: str, info: Optional[QAPISourceInfo], - ifcond: Sequence[str], + ifcond: QAPISchemaIfCond, features: List[QAPISchemaFeature], arg_type: Optional[QAPISchemaObjectType], ret_type: Optional[QAPISchemaType], gen: bool, @@ -367,7 +366,8 @@ def visit_command(self, name: str, info: Optional[QAPISourceInfo], self._gen_tree(name, 'command', obj, ifcond, features) def visit_event(self, name: str, info: Optional[QAPISourceInfo], - ifcond: Sequence[str], features: List[QAPISchemaFeature], + ifcond: QAPISchemaIfCond, + features: List[QAPISchemaFeature], arg_type: Optional[QAPISchemaObjectType], boxed: bool) -> None: assert self._schema is not None diff --git a/scripts/qapi/schema.py b/scripts/qapi/schema.py index d1d27ff7ee..bc357ebbfa 100644 --- a/scripts/qapi/schema.py +++ b/scripts/qapi/schema.py @@ -25,6 +25,20 @@ from .parser import QAPISchemaParser +class QAPISchemaIfCond: + def __init__(self, ifcond=None): + self.ifcond = ifcond or [] + + # Returns true if the condition is not void + def __bool__(self): + return bool(self.ifcond) + + def __eq__(self, other): + if not isinstance(other, QAPISchemaIfCond): + return NotImplemented + return self.ifcond == other.ifcond + + class QAPISchemaEntity: meta: Optional[str] = None @@ -42,7 +56,7 @@ def __init__(self, name: str, info, doc, ifcond=None, features=None): # such place). self.info = info self.doc = doc - self._ifcond = ifcond or [] + self._ifcond = ifcond or QAPISchemaIfCond() self.features = features or [] self._checked = False @@ -77,7 +91,7 @@ def set_module(self, schema): @property def ifcond(self): - assert self._checked + assert self._checked and isinstance(self._ifcond, QAPISchemaIfCond) return self._ifcond def is_implicit(self): @@ -601,7 +615,7 @@ def check(self, schema, seen): else: # simple union assert isinstance(self.tag_member.type, QAPISchemaEnumType) assert not self.tag_member.optional - assert self.tag_member.ifcond == [] + assert not self.tag_member.ifcond if self._tag_name: # flat union # branches that are not explicitly covered get an empty type cases = {v.name for v in self.variants} @@ -646,7 +660,7 @@ def __init__(self, name, info, ifcond=None): assert isinstance(name, str) self.name = name self.info = info - self.ifcond = ifcond or [] + self.ifcond = ifcond or QAPISchemaIfCond() self.defined_in = None def set_defined_in(self, name): @@ -968,11 +982,13 @@ def _def_predefineds(self): def _make_features(self, features, info): if features is None: return [] - return [QAPISchemaFeature(f['name'], info, f.get('if')) + return [QAPISchemaFeature(f['name'], info, + QAPISchemaIfCond(f.get('if'))) for f in features] def _make_enum_members(self, values, info): - return [QAPISchemaEnumMember(v['name'], info, v.get('if')) + return [QAPISchemaEnumMember(v['name'], info, + QAPISchemaIfCond(v.get('if'))) for v in values] def _make_implicit_enum_type(self, name, info, ifcond, values): @@ -1008,7 +1024,7 @@ def _make_implicit_object_type(self, name, info, ifcond, role, members): # TODO kill simple unions or implement the disjunction # pylint: disable=protected-access - assert (ifcond or []) == typ._ifcond + assert ifcond == typ._ifcond else: self._def_entity(QAPISchemaObjectType( name, info, None, ifcond, None, None, members, None)) @@ -1018,7 +1034,7 @@ def _def_enum_type(self, expr, info, doc): name = expr['enum'] data = expr['data'] prefix = expr.get('prefix') - ifcond = expr.get('if') + ifcond = QAPISchemaIfCond(expr.get('if')) features = self._make_features(expr.get('features'), info) self._def_entity(QAPISchemaEnumType( name, info, doc, ifcond, features, @@ -1036,7 +1052,8 @@ def _make_member(self, name, typ, ifcond, features, info): self._make_features(features, info)) def _make_members(self, data, info): - return [self._make_member(key, value['type'], value.get('if'), + return [self._make_member(key, value['type'], + QAPISchemaIfCond(value.get('if')), value.get('features'), info) for (key, value) in data.items()] @@ -1044,7 +1061,7 @@ def _def_struct_type(self, expr, info, doc): name = expr['struct'] base = expr.get('base') data = expr['data'] - ifcond = expr.get('if') + ifcond = QAPISchemaIfCond(expr.get('if')) features = self._make_features(expr.get('features'), info) self._def_entity(QAPISchemaObjectType( name, info, doc, ifcond, features, base, @@ -1067,7 +1084,7 @@ def _def_union_type(self, expr, info, doc): name = expr['union'] data = expr['data'] base = expr.get('base') - ifcond = expr.get('if') + ifcond = QAPISchemaIfCond(expr.get('if')) features = self._make_features(expr.get('features'), info) tag_name = expr.get('discriminator') tag_member = None @@ -1076,15 +1093,21 @@ def _def_union_type(self, expr, info, doc): name, info, ifcond, 'base', self._make_members(base, info)) if tag_name: - variants = [self._make_variant(key, value['type'], - value.get('if'), info) - for (key, value) in data.items()] + variants = [ + self._make_variant(key, value['type'], + QAPISchemaIfCond(value.get('if')), + info) + for (key, value) in data.items() + ] members = [] else: - variants = [self._make_simple_variant(key, value['type'], - value.get('if'), info) - for (key, value) in data.items()] - enum = [{'name': v.name, 'if': v.ifcond} for v in variants] + variants = [ + self._make_simple_variant(key, value['type'], + QAPISchemaIfCond(value.get('if')), + info) + for (key, value) in data.items() + ] + enum = [{'name': v.name, 'if': v.ifcond.ifcond} for v in variants] typ = self._make_implicit_enum_type(name, info, ifcond, enum) tag_member = QAPISchemaObjectTypeMember('type', info, typ, False) members = [tag_member] @@ -1097,11 +1120,14 @@ def _def_union_type(self, expr, info, doc): def _def_alternate_type(self, expr, info, doc): name = expr['alternate'] data = expr['data'] - ifcond = expr.get('if') + ifcond = QAPISchemaIfCond(expr.get('if')) features = self._make_features(expr.get('features'), info) - variants = [self._make_variant(key, value['type'], value.get('if'), - info) - for (key, value) in data.items()] + variants = [ + self._make_variant(key, value['type'], + QAPISchemaIfCond(value.get('if')), + info) + for (key, value) in data.items() + ] tag_member = QAPISchemaObjectTypeMember('type', info, 'QType', False) self._def_entity( QAPISchemaAlternateType(name, info, doc, ifcond, features, @@ -1118,7 +1144,7 @@ def _def_command(self, expr, info, doc): allow_oob = expr.get('allow-oob', False) allow_preconfig = expr.get('allow-preconfig', False) coroutine = expr.get('coroutine', False) - ifcond = expr.get('if') + ifcond = QAPISchemaIfCond(expr.get('if')) features = self._make_features(expr.get('features'), info) if isinstance(data, OrderedDict): data = self._make_implicit_object_type( @@ -1137,7 +1163,7 @@ def _def_event(self, expr, info, doc): name = expr['event'] data = expr.get('data') boxed = expr.get('boxed', False) - ifcond = expr.get('if') + ifcond = QAPISchemaIfCond(expr.get('if')) features = self._make_features(expr.get('features'), info) if isinstance(data, OrderedDict): data = self._make_implicit_object_type( diff --git a/scripts/qapi/types.py b/scripts/qapi/types.py index 20d572a23a..3673cf0f49 100644 --- a/scripts/qapi/types.py +++ b/scripts/qapi/types.py @@ -13,7 +13,7 @@ # See the COPYING file in the top-level directory. """ -from typing import List, Optional, Sequence +from typing import List, Optional from .common import ( c_enum_const, @@ -27,6 +27,7 @@ QAPISchema, QAPISchemaEnumMember, QAPISchemaFeature, + QAPISchemaIfCond, QAPISchemaObjectType, QAPISchemaObjectTypeMember, QAPISchemaType, @@ -50,13 +51,13 @@ def gen_enum_lookup(name: str, ''', c_name=c_name(name)) for memb in members: - ret += gen_if(memb.ifcond) + ret += gen_if(memb.ifcond.ifcond) index = c_enum_const(name, memb.name, prefix) ret += mcgen(''' [%(index)s] = "%(name)s", ''', index=index, name=memb.name) - ret += gen_endif(memb.ifcond) + ret += gen_endif(memb.ifcond.ifcond) ret += mcgen(''' }, @@ -80,12 +81,12 @@ def gen_enum(name: str, c_name=c_name(name)) for memb in enum_members: - ret += gen_if(memb.ifcond) + ret += gen_if(memb.ifcond.ifcond) ret += mcgen(''' %(c_enum)s, ''', c_enum=c_enum_const(name, memb.name, prefix)) - ret += gen_endif(memb.ifcond) + ret += gen_endif(memb.ifcond.ifcond) ret += mcgen(''' } %(c_name)s; @@ -125,7 +126,7 @@ def gen_array(name: str, element_type: QAPISchemaType) -> str: def gen_struct_members(members: List[QAPISchemaObjectTypeMember]) -> str: ret = '' for memb in members: - ret += gen_if(memb.ifcond) + ret += gen_if(memb.ifcond.ifcond) if memb.optional: ret += mcgen(''' bool has_%(c_name)s; @@ -135,11 +136,11 @@ 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) + ret += gen_endif(memb.ifcond.ifcond) return ret -def gen_object(name: str, ifcond: Sequence[str], +def gen_object(name: str, ifcond: QAPISchemaIfCond, base: Optional[QAPISchemaObjectType], members: List[QAPISchemaObjectTypeMember], variants: Optional[QAPISchemaVariants]) -> str: @@ -158,7 +159,7 @@ def gen_object(name: str, ifcond: Sequence[str], ret += mcgen(''' ''') - ret += gen_if(ifcond) + ret += gen_if(ifcond.ifcond) ret += mcgen(''' struct %(c_name)s { ''', @@ -192,7 +193,7 @@ def gen_object(name: str, ifcond: Sequence[str], ret += mcgen(''' }; ''') - ret += gen_endif(ifcond) + ret += gen_endif(ifcond.ifcond) return ret @@ -219,13 +220,13 @@ def gen_variants(variants: QAPISchemaVariants) -> str: for var in variants.variants: if var.type.name == 'q_empty': continue - ret += gen_if(var.ifcond) + ret += gen_if(var.ifcond.ifcond) 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) + ret += gen_endif(var.ifcond.ifcond) ret += mcgen(''' } u; @@ -307,7 +308,7 @@ def _gen_type_cleanup(self, name: str) -> None: def visit_enum_type(self, name: str, info: Optional[QAPISourceInfo], - ifcond: Sequence[str], + ifcond: QAPISchemaIfCond, features: List[QAPISchemaFeature], members: List[QAPISchemaEnumMember], prefix: Optional[str]) -> None: @@ -318,7 +319,7 @@ def visit_enum_type(self, def visit_array_type(self, name: str, info: Optional[QAPISourceInfo], - ifcond: Sequence[str], + ifcond: QAPISchemaIfCond, element_type: QAPISchemaType) -> None: with ifcontext(ifcond, self._genh, self._genc): self._genh.preamble_add(gen_fwd_object_or_array(name)) @@ -328,7 +329,7 @@ def visit_array_type(self, def visit_object_type(self, name: str, info: Optional[QAPISourceInfo], - ifcond: Sequence[str], + ifcond: QAPISchemaIfCond, features: List[QAPISchemaFeature], base: Optional[QAPISchemaObjectType], members: List[QAPISchemaObjectTypeMember], @@ -351,7 +352,7 @@ def visit_object_type(self, def visit_alternate_type(self, name: str, info: Optional[QAPISourceInfo], - ifcond: Sequence[str], + ifcond: QAPISchemaIfCond, features: List[QAPISchemaFeature], variants: QAPISchemaVariants) -> None: with ifcontext(ifcond, self._genh): diff --git a/scripts/qapi/visit.py b/scripts/qapi/visit.py index 9e96f3c566..67721b2470 100644 --- a/scripts/qapi/visit.py +++ b/scripts/qapi/visit.py @@ -13,7 +13,7 @@ See the COPYING file in the top-level directory. """ -from typing import List, Optional, Sequence +from typing import List, Optional from .common import ( c_enum_const, @@ -29,6 +29,7 @@ QAPISchemaEnumMember, QAPISchemaEnumType, QAPISchemaFeature, + QAPISchemaIfCond, QAPISchemaObjectType, QAPISchemaObjectTypeMember, QAPISchemaType, @@ -78,7 +79,7 @@ def gen_visit_object_members(name: str, for memb in members: deprecated = 'deprecated' in [f.name for f in memb.features] - ret += gen_if(memb.ifcond) + ret += gen_if(memb.ifcond.ifcond) if memb.optional: ret += mcgen(''' if (visit_optional(v, "%(name)s", &obj->has_%(c_name)s)) { @@ -111,7 +112,7 @@ def gen_visit_object_members(name: str, ret += mcgen(''' } ''') - ret += gen_endif(memb.ifcond) + ret += gen_endif(memb.ifcond.ifcond) if variants: tag_member = variants.tag_member @@ -125,7 +126,7 @@ def gen_visit_object_members(name: str, 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) + ret += gen_if(var.ifcond.ifcond) if var.type.name == 'q_empty': # valid variant and nothing to do ret += mcgen(''' @@ -141,7 +142,7 @@ def gen_visit_object_members(name: str, case=case_str, c_type=var.type.c_name(), c_name=c_name(var.name)) - ret += gen_endif(var.ifcond) + ret += gen_endif(var.ifcond.ifcond) ret += mcgen(''' default: abort(); @@ -227,7 +228,7 @@ def gen_visit_alternate(name: str, variants: QAPISchemaVariants) -> str: c_name=c_name(name)) for var in variants.variants: - ret += gen_if(var.ifcond) + ret += gen_if(var.ifcond.ifcond) ret += mcgen(''' case %(case)s: ''', @@ -253,7 +254,7 @@ def gen_visit_alternate(name: str, variants: QAPISchemaVariants) -> str: ret += mcgen(''' break; ''') - ret += gen_endif(var.ifcond) + ret += gen_endif(var.ifcond.ifcond) ret += mcgen(''' case QTYPE_NONE: @@ -352,7 +353,7 @@ def _begin_user_module(self, name: str) -> None: def visit_enum_type(self, name: str, info: Optional[QAPISourceInfo], - ifcond: Sequence[str], + ifcond: QAPISchemaIfCond, features: List[QAPISchemaFeature], members: List[QAPISchemaEnumMember], prefix: Optional[str]) -> None: @@ -363,7 +364,7 @@ def visit_enum_type(self, def visit_array_type(self, name: str, info: Optional[QAPISourceInfo], - ifcond: Sequence[str], + ifcond: QAPISchemaIfCond, element_type: QAPISchemaType) -> None: with ifcontext(ifcond, self._genh, self._genc): self._genh.add(gen_visit_decl(name)) @@ -372,7 +373,7 @@ def visit_array_type(self, def visit_object_type(self, name: str, info: Optional[QAPISourceInfo], - ifcond: Sequence[str], + ifcond: QAPISchemaIfCond, features: List[QAPISchemaFeature], base: Optional[QAPISchemaObjectType], members: List[QAPISchemaObjectTypeMember], @@ -394,7 +395,7 @@ def visit_object_type(self, def visit_alternate_type(self, name: str, info: Optional[QAPISourceInfo], - ifcond: Sequence[str], + ifcond: QAPISchemaIfCond, features: List[QAPISchemaFeature], variants: QAPISchemaVariants) -> None: with ifcontext(ifcond, self._genh, self._genc): diff --git a/tests/qapi-schema/test-qapi.py b/tests/qapi-schema/test-qapi.py index f1c4deb9a5..2ec328b22e 100755 --- a/tests/qapi-schema/test-qapi.py +++ b/tests/qapi-schema/test-qapi.py @@ -95,7 +95,7 @@ def _print_variants(variants): @staticmethod def _print_if(ifcond, indent=4): if ifcond: - print('%sif %s' % (' ' * indent, ifcond)) + print('%sif %s' % (' ' * indent, ifcond.ifcond)) @classmethod def _print_features(cls, features, indent=4): From patchwork Tue Jun 8 12:07:17 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= X-Patchwork-Id: 1489393 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=Hl/O8mNY; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4Fzpt66qYpz9sW8 for ; Tue, 8 Jun 2021 22:08:30 +1000 (AEST) Received: from localhost ([::1]:45646 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lqaWy-0006Sd-Tq for incoming@patchwork.ozlabs.org; Tue, 08 Jun 2021 08:08:28 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:54978) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lqaWW-0006Oe-BX for qemu-devel@nongnu.org; Tue, 08 Jun 2021 08:08:00 -0400 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:28094) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lqaWT-0001JI-UC for qemu-devel@nongnu.org; Tue, 08 Jun 2021 08:08:00 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1623154077; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=hsOmP1hUYUI1oK1o9o7Og47poQa7lx76Iub8n0k9/Cc=; b=Hl/O8mNYm2my3Ge4mrlrBfidKLS63Ulfh2hpQMJG/Mo7rmg0RLM747KNoido8gxPO7hQ63 tKNNRuB0CUlkYELi/PDjqjuS5kZvgwX4vD/Kaw+pXMWd6P71dy2VOfhahVYSaTtUwuIa2a XLd95UNd3H1JCtB2BYqymcrEcdFsdSw= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-597-uDtBN3y1Ot2PjXHV-HBRLA-1; Tue, 08 Jun 2021 08:07:54 -0400 X-MC-Unique: uDtBN3y1Ot2PjXHV-HBRLA-1 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id C1FE2803620 for ; Tue, 8 Jun 2021 12:07:53 +0000 (UTC) Received: from localhost (unknown [10.36.110.2]) by smtp.corp.redhat.com (Postfix) with ESMTP id 6817B620DE; Tue, 8 Jun 2021 12:07:48 +0000 (UTC) From: marcandre.lureau@redhat.com To: qemu-devel@nongnu.org Subject: [PATCH v5 3/9] qapi: make gen_if/gen_endif take a simple string Date: Tue, 8 Jun 2021 16:07:17 +0400 Message-Id: <20210608120723.2268181-4-marcandre.lureau@redhat.com> In-Reply-To: <20210608120723.2268181-1-marcandre.lureau@redhat.com> References: <20210608120723.2268181-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=marcandre.lureau@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Received-SPF: pass client-ip=216.205.24.124; envelope-from=marcandre.lureau@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -29 X-Spam_score: -3.0 X-Spam_bar: --- X-Spam_report: (-3.0 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.197, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Eric Blake , jsnow@redhat.com, Markus Armbruster , =?utf-8?q?Marc-Andr=C3=A9_Lureau?= Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Marc-André Lureau Instead of building prepocessor conditions from a list of string, use the result generated from QAPISchemaIfCond.cgen(). Signed-off-by: Marc-André Lureau --- scripts/qapi/common.py | 24 +++++++++++------------- scripts/qapi/gen.py | 4 ++-- scripts/qapi/introspect.py | 4 ++-- scripts/qapi/schema.py | 3 +++ scripts/qapi/types.py | 20 ++++++++++---------- scripts/qapi/visit.py | 12 ++++++------ 6 files changed, 34 insertions(+), 33 deletions(-) diff --git a/scripts/qapi/common.py b/scripts/qapi/common.py index 6ad1eeb61d..c305aaf2f1 100644 --- a/scripts/qapi/common.py +++ b/scripts/qapi/common.py @@ -12,7 +12,7 @@ # See the COPYING file in the top-level directory. import re -from typing import Match, Optional, Sequence +from typing import Match, Optional #: Magic string that gets removed along with all space to its right. @@ -194,22 +194,20 @@ def guardend(name: str) -> str: name=c_fname(name).upper()) -def gen_if(ifcond: Sequence[str]) -> str: - ret = '' - for ifc in ifcond: - ret += mcgen(''' +def gen_if(cond: str) -> str: + if not cond: + return '' + return mcgen(''' #if %(cond)s -''', cond=ifc) - return ret +''', cond=cond) -def gen_endif(ifcond: Sequence[str]) -> str: - ret = '' - for ifc in reversed(ifcond): - ret += mcgen(''' +def gen_endif(cond: str) -> str: + if not cond: + return '' + return mcgen(''' #endif /* %(cond)s */ -''', cond=ifc) - return ret +''', cond=cond) def must_match(pattern: str, string: str) -> Match[str]: diff --git a/scripts/qapi/gen.py b/scripts/qapi/gen.py index 1c5b190276..51a597a025 100644 --- a/scripts/qapi/gen.py +++ b/scripts/qapi/gen.py @@ -95,9 +95,9 @@ def _wrap_ifcond(ifcond: QAPISchemaIfCond, before: str, after: str) -> str: if added[0] == '\n': out += '\n' added = added[1:] - out += gen_if(ifcond.ifcond) + out += gen_if(ifcond.cgen()) out += added - out += gen_endif(ifcond.ifcond) + out += gen_endif(ifcond.cgen()) return out diff --git a/scripts/qapi/introspect.py b/scripts/qapi/introspect.py index 77a8c33ad4..474b08fd4d 100644 --- a/scripts/qapi/introspect.py +++ b/scripts/qapi/introspect.py @@ -124,10 +124,10 @@ def indent(level: int) -> str: if obj.comment: ret += indent(level) + f"/* {obj.comment} */\n" if obj.ifcond: - ret += gen_if(obj.ifcond.ifcond) + ret += gen_if(obj.ifcond.cgen()) ret += _tree_to_qlit(obj.value, level) if obj.ifcond: - ret += '\n' + gen_endif(obj.ifcond.ifcond) + ret += '\n' + gen_endif(obj.ifcond.cgen()) return ret ret = '' diff --git a/scripts/qapi/schema.py b/scripts/qapi/schema.py index bc357ebbfa..aa4715c519 100644 --- a/scripts/qapi/schema.py +++ b/scripts/qapi/schema.py @@ -29,6 +29,9 @@ class QAPISchemaIfCond: def __init__(self, ifcond=None): self.ifcond = ifcond or [] + def cgen(self): + return ' && '.join(self.ifcond) + # Returns true if the condition is not void def __bool__(self): return bool(self.ifcond) diff --git a/scripts/qapi/types.py b/scripts/qapi/types.py index 3673cf0f49..db9ff95bd1 100644 --- a/scripts/qapi/types.py +++ b/scripts/qapi/types.py @@ -51,13 +51,13 @@ def gen_enum_lookup(name: str, ''', c_name=c_name(name)) for memb in members: - ret += gen_if(memb.ifcond.ifcond) + ret += gen_if(memb.ifcond.cgen()) index = c_enum_const(name, memb.name, prefix) ret += mcgen(''' [%(index)s] = "%(name)s", ''', index=index, name=memb.name) - ret += gen_endif(memb.ifcond.ifcond) + ret += gen_endif(memb.ifcond.cgen()) ret += mcgen(''' }, @@ -81,12 +81,12 @@ def gen_enum(name: str, c_name=c_name(name)) for memb in enum_members: - ret += gen_if(memb.ifcond.ifcond) + ret += gen_if(memb.ifcond.cgen()) ret += mcgen(''' %(c_enum)s, ''', c_enum=c_enum_const(name, memb.name, prefix)) - ret += gen_endif(memb.ifcond.ifcond) + ret += gen_endif(memb.ifcond.cgen()) ret += mcgen(''' } %(c_name)s; @@ -126,7 +126,7 @@ def gen_array(name: str, element_type: QAPISchemaType) -> str: def gen_struct_members(members: List[QAPISchemaObjectTypeMember]) -> str: ret = '' for memb in members: - ret += gen_if(memb.ifcond.ifcond) + ret += gen_if(memb.ifcond.cgen()) if memb.optional: ret += mcgen(''' bool has_%(c_name)s; @@ -136,7 +136,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.ifcond) + ret += gen_endif(memb.ifcond.cgen()) return ret @@ -159,7 +159,7 @@ def gen_object(name: str, ifcond: QAPISchemaIfCond, ret += mcgen(''' ''') - ret += gen_if(ifcond.ifcond) + ret += gen_if(ifcond.cgen()) ret += mcgen(''' struct %(c_name)s { ''', @@ -193,7 +193,7 @@ def gen_object(name: str, ifcond: QAPISchemaIfCond, ret += mcgen(''' }; ''') - ret += gen_endif(ifcond.ifcond) + ret += gen_endif(ifcond.cgen()) return ret @@ -220,13 +220,13 @@ def gen_variants(variants: QAPISchemaVariants) -> str: for var in variants.variants: if var.type.name == 'q_empty': continue - ret += gen_if(var.ifcond.ifcond) + ret += gen_if(var.ifcond.cgen()) 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.ifcond) + ret += gen_endif(var.ifcond.cgen()) ret += mcgen(''' } u; diff --git a/scripts/qapi/visit.py b/scripts/qapi/visit.py index 67721b2470..56ea516399 100644 --- a/scripts/qapi/visit.py +++ b/scripts/qapi/visit.py @@ -79,7 +79,7 @@ def gen_visit_object_members(name: str, for memb in members: deprecated = 'deprecated' in [f.name for f in memb.features] - ret += gen_if(memb.ifcond.ifcond) + ret += gen_if(memb.ifcond.cgen()) if memb.optional: ret += mcgen(''' if (visit_optional(v, "%(name)s", &obj->has_%(c_name)s)) { @@ -112,7 +112,7 @@ def gen_visit_object_members(name: str, ret += mcgen(''' } ''') - ret += gen_endif(memb.ifcond.ifcond) + ret += gen_endif(memb.ifcond.cgen()) if variants: tag_member = variants.tag_member @@ -126,7 +126,7 @@ def gen_visit_object_members(name: str, 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.ifcond) + ret += gen_if(var.ifcond.cgen()) if var.type.name == 'q_empty': # valid variant and nothing to do ret += mcgen(''' @@ -142,7 +142,7 @@ def gen_visit_object_members(name: str, case=case_str, c_type=var.type.c_name(), c_name=c_name(var.name)) - ret += gen_endif(var.ifcond.ifcond) + ret += gen_endif(var.ifcond.cgen()) ret += mcgen(''' default: abort(); @@ -228,7 +228,7 @@ def gen_visit_alternate(name: str, variants: QAPISchemaVariants) -> str: c_name=c_name(name)) for var in variants.variants: - ret += gen_if(var.ifcond.ifcond) + ret += gen_if(var.ifcond.cgen()) ret += mcgen(''' case %(case)s: ''', @@ -254,7 +254,7 @@ def gen_visit_alternate(name: str, variants: QAPISchemaVariants) -> str: ret += mcgen(''' break; ''') - ret += gen_endif(var.ifcond.ifcond) + ret += gen_endif(var.ifcond.cgen()) ret += mcgen(''' case QTYPE_NONE: From patchwork Tue Jun 8 12:07:18 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= X-Patchwork-Id: 1489395 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=EjpLD+ik; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4Fzpwf54kGz9sXM for ; Tue, 8 Jun 2021 22:10:41 +1000 (AEST) Received: from localhost ([::1]:53920 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lqaZ5-0003Xb-BB for incoming@patchwork.ozlabs.org; Tue, 08 Jun 2021 08:10:39 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:55056) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lqaWh-0006lP-0V for qemu-devel@nongnu.org; Tue, 08 Jun 2021 08:08:11 -0400 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:27918) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lqaWe-0001R8-FA for qemu-devel@nongnu.org; Tue, 08 Jun 2021 08:08:10 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1623154087; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=CkzVQBbrGw5qk0dO6uQoe8xO8t0IOOKUd88hnVuog8I=; b=EjpLD+ikVsSmTUW1IjWwCV3fQCROnmDimQbwX/mF2QNLGvgGWqorCyFeU7lg/Y25kPIJ+e ivRq7FxcvvTkaCAbULL1NHrBNdJgKlYY2MOpVENS5uK6ro1ezg9WLIEzfLYmXXtCXZI5od 3qLbNt+T/Ud3peRP/x6n8UHMeCcd68o= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-423-2ivxY8JkNeaKbMXA_ynVZA-1; Tue, 08 Jun 2021 08:08:03 -0400 X-MC-Unique: 2ivxY8JkNeaKbMXA_ynVZA-1 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 613C21020C33 for ; Tue, 8 Jun 2021 12:08:02 +0000 (UTC) Received: from localhost (unknown [10.36.110.2]) by smtp.corp.redhat.com (Postfix) with ESMTP id 82B43100F49F; Tue, 8 Jun 2021 12:07:57 +0000 (UTC) From: marcandre.lureau@redhat.com To: qemu-devel@nongnu.org Subject: [PATCH v5 4/9] qapi: start building an 'if' predicate tree Date: Tue, 8 Jun 2021 16:07:18 +0400 Message-Id: <20210608120723.2268181-5-marcandre.lureau@redhat.com> In-Reply-To: <20210608120723.2268181-1-marcandre.lureau@redhat.com> References: <20210608120723.2268181-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=marcandre.lureau@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Received-SPF: pass client-ip=216.205.24.124; envelope-from=marcandre.lureau@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -29 X-Spam_score: -3.0 X-Spam_bar: --- X-Spam_report: (-3.0 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.197, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Eric Blake , jsnow@redhat.com, Markus Armbruster , =?utf-8?q?Marc-Andr=C3=A9_Lureau?= Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Marc-André Lureau The following patches are going to express schema 'if' conditions in a target language agnostic way. For that, let's start building a predicate tree of the configuration options. This intermediary steps still uses C-preprocessor expressions as the predicates: "if: [STR, ..]" is translated to a "IfCond -> IfAll -> [IfOption, ..]" tree, which will generate "#if STR && .." C code. Once the boolean operation tree nodes are introduced, the 'if' expressions will be converted to replace the C syntax (no more !defined(), &&, ...) and based only on option identifiers. For now, the condition tree will be less expressive than a full C macro expression as it will only support these operations: 'all', 'any' and 'not', the only ones needed so far. Signed-off-by: Marc-André Lureau Reviewed-by: Stefan Hajnoczi Tested-by: John Snow --- docs/sphinx/qapidoc.py | 6 +-- scripts/qapi/common.py | 53 ++++++++++++++++++++++- scripts/qapi/schema.py | 17 ++++++-- tests/qapi-schema/doc-good.out | 12 +++--- tests/qapi-schema/qapi-schema-test.out | 58 +++++++++++++------------- tests/qapi-schema/test-qapi.py | 2 +- 6 files changed, 103 insertions(+), 45 deletions(-) diff --git a/docs/sphinx/qapidoc.py b/docs/sphinx/qapidoc.py index b737949007..0f87fb16ce 100644 --- a/docs/sphinx/qapidoc.py +++ b/docs/sphinx/qapidoc.py @@ -112,12 +112,10 @@ def _make_section(self, title): def _nodes_for_ifcond(self, ifcond, with_if=True): """Return list of Text, literal nodes for the ifcond - Return a list which gives text like ' (If: cond1, cond2, cond3)', where - the conditions are in literal-text and the commas are not. + Return a list which gives text like ' (If: condition)'. If with_if is False, we don't return the "(If: " and ")". """ - condlist = intersperse([nodes.literal('', c) for c in ifcond.ifcond], - nodes.Text(', ')) + condlist = [nodes.literal('', ifcond.docgen())] if not with_if: return condlist diff --git a/scripts/qapi/common.py b/scripts/qapi/common.py index c305aaf2f1..01e3203545 100644 --- a/scripts/qapi/common.py +++ b/scripts/qapi/common.py @@ -12,7 +12,7 @@ # See the COPYING file in the top-level directory. import re -from typing import Match, Optional +from typing import Match, Optional, Sequence #: Magic string that gets removed along with all space to its right. @@ -214,3 +214,54 @@ def must_match(pattern: str, string: str) -> Match[str]: match = re.match(pattern, string) assert match is not None return match + + +class IfPredicate: + """An 'if' condition predicate""" + + def cgen(self) -> str: + raise NotImplementedError() + + def docgen(self) -> str: + raise NotImplementedError() + + +class IfOption(IfPredicate): + def __init__(self, option: str): + self.option = option + + def cgen(self) -> str: + return self.option + + def docgen(self) -> str: + return self.option + + def __repr__(self) -> str: + return f"{type(self).__name__}({self.option!r})" + + def __eq__(self, other: object) -> bool: + if not isinstance(other, IfOption): + return NotImplemented + return self.option == other.option + + +class IfAll(IfPredicate): + def __init__(self, pred_list: Sequence[IfPredicate]): + self.pred_list = pred_list + + def cgen(self) -> str: + return " && ".join([p.cgen() for p in self.pred_list]) + + def docgen(self) -> str: + return " and ".join([p.docgen() for p in self.pred_list]) + + def __bool__(self) -> bool: + return bool(self.pred_list) + + def __repr__(self) -> str: + return f"{type(self).__name__}({self.pred_list!r})" + + def __eq__(self, other: object) -> bool: + if not isinstance(other, IfAll): + return NotImplemented + return self.pred_list == other.pred_list diff --git a/scripts/qapi/schema.py b/scripts/qapi/schema.py index aa4715c519..f52caaeecc 100644 --- a/scripts/qapi/schema.py +++ b/scripts/qapi/schema.py @@ -19,7 +19,12 @@ import re from typing import Optional -from .common import POINTER_SUFFIX, c_name +from .common import ( + POINTER_SUFFIX, + IfAll, + IfOption, + c_name, +) from .error import QAPIError, QAPISemError, QAPISourceError from .expr import check_exprs from .parser import QAPISchemaParser @@ -28,18 +33,22 @@ class QAPISchemaIfCond: def __init__(self, ifcond=None): self.ifcond = ifcond or [] + self.pred = IfAll([IfOption(opt) for opt in self.ifcond]) + + def docgen(self): + return self.pred.docgen() def cgen(self): - return ' && '.join(self.ifcond) + return self.pred.cgen() # Returns true if the condition is not void def __bool__(self): - return bool(self.ifcond) + return bool(self.pred) def __eq__(self, other): if not isinstance(other, QAPISchemaIfCond): return NotImplemented - return self.ifcond == other.ifcond + return self.pred == other.pred class QAPISchemaEntity: diff --git a/tests/qapi-schema/doc-good.out b/tests/qapi-schema/doc-good.out index 8f54ceff2e..db1d23c6bf 100644 --- a/tests/qapi-schema/doc-good.out +++ b/tests/qapi-schema/doc-good.out @@ -12,15 +12,15 @@ enum QType module doc-good.json enum Enum member one - if ['defined(IFONE)'] + if IfAll([IfOption('defined(IFONE)')]) member two - if ['defined(IFCOND)'] + if IfAll([IfOption('defined(IFCOND)')]) feature enum-feat object Base member base1: Enum optional=False object Variant1 member var1: str optional=False - if ['defined(IFSTR)'] + if IfAll([IfOption('defined(IFSTR)')]) feature member-feat feature variant1-feat object Variant2 @@ -29,7 +29,7 @@ object Object tag base1 case one: Variant1 case two: Variant2 - if ['IFTWO'] + if IfAll([IfOption('IFTWO')]) feature union-feat1 object q_obj_Variant1-wrapper member data: Variant1 optional=False @@ -38,13 +38,13 @@ object q_obj_Variant2-wrapper enum SugaredUnionKind member one member two - if ['IFTWO'] + if IfAll([IfOption('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 IfAll([IfOption('IFTWO')]) feature union-feat2 alternate Alternate tag type diff --git a/tests/qapi-schema/qapi-schema-test.out b/tests/qapi-schema/qapi-schema-test.out index e0b8a5f0b6..e4e0fb173a 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 IfAll([IfOption('defined(TEST_IF_STRUCT_BAR)')]) + if IfAll([IfOption('defined(TEST_IF_STRUCT)')]) enum TestIfEnum member foo member bar - if ['defined(TEST_IF_ENUM_BAR)'] - if ['defined(TEST_IF_ENUM)'] + if IfAll([IfOption('defined(TEST_IF_ENUM_BAR)')]) + if IfAll([IfOption('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)'] + if IfAll([IfOption('defined(TEST_IF_UNION_BAR)')]) + if IfAll([IfOption('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)'] + if IfAll([IfOption('defined(TEST_IF_UNION_BAR)')]) + if IfAll([IfOption('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 IfAll([IfOption('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 IfAll([IfOption('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 IfAll([IfOption('defined(TEST_IF_ALT_BAR)')]) + if IfAll([IfOption('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 IfAll([IfOption('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 IfAll([IfOption('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 IfAll([IfOption('defined(TEST_IF_CMD_BAR)')]) + if IfAll([IfOption('defined(TEST_IF_CMD)'), IfOption('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 IfAll([IfOption('defined(TEST_IF_CMD)'), IfOption('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 IfAll([IfOption('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 IfAll([IfOption('defined(TEST_IF_EVT_BAR)')]) + if IfAll([IfOption('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 IfAll([IfOption('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 IfAll([IfOption('defined(TEST_IF_FEATURE_1)')]) object CondFeatureStruct2 member foo: int optional=False feature feature1 - if ['defined(TEST_IF_FEATURE_1)'] + if IfAll([IfOption('defined(TEST_IF_FEATURE_1)')]) feature feature2 - if ['defined(TEST_IF_FEATURE_2)'] + if IfAll([IfOption('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 IfAll([IfOption('defined(TEST_IF_COND_1)'), IfOption('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 IfAll([IfOption('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 IfAll([IfOption('defined(TEST_IF_FEATURE_1)')]) feature feature2 - if ['defined(TEST_IF_FEATURE_2)'] + if IfAll([IfOption('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 IfAll([IfOption('defined(TEST_IF_COND_1)'), IfOption('defined(TEST_IF_COND_2)')]) event TEST_EVENT_FEATURES0 FeatureStruct1 boxed=False event TEST_EVENT_FEATURES1 None diff --git a/tests/qapi-schema/test-qapi.py b/tests/qapi-schema/test-qapi.py index 2ec328b22e..631e255fba 100755 --- a/tests/qapi-schema/test-qapi.py +++ b/tests/qapi-schema/test-qapi.py @@ -95,7 +95,7 @@ def _print_variants(variants): @staticmethod def _print_if(ifcond, indent=4): if ifcond: - print('%sif %s' % (' ' * indent, ifcond.ifcond)) + print('%sif %s' % (' ' * indent, ifcond.pred)) @classmethod def _print_features(cls, features, indent=4): From patchwork Tue Jun 8 12:07:19 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= X-Patchwork-Id: 1489394 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=F8XvfSP+; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4FzptK2619z9sSn for ; Tue, 8 Jun 2021 22:08:41 +1000 (AEST) Received: from localhost ([::1]:46418 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lqaX9-0006xw-7a for incoming@patchwork.ozlabs.org; Tue, 08 Jun 2021 08:08:39 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:55082) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lqaWj-0006ry-2m for qemu-devel@nongnu.org; Tue, 08 Jun 2021 08:08:13 -0400 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:23116) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lqaWh-0001Tj-Ci for qemu-devel@nongnu.org; Tue, 08 Jun 2021 08:08:12 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1623154090; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=bfdUWFWXW6jf2/9KyMsuMG7uUpq43nznvRfgpEIIcjc=; b=F8XvfSP+IPhrPeOsWXwCFVKKIijD59ETAxk0blwpOyulLCRo2qq2Y0ZLchAA+KxKsQqD1Y s6mJeIO3HyV4rO3iHMLVL6PZ6Yfs7CaRtyru2dN1A248njEW4v2g7j2kNa+gcMJ0O3OYCw DmsVxSK7uR67YFCQDe3IosAKvALcbmE= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-211-vwHko3tON6mcoZw9zQebXw-1; Tue, 08 Jun 2021 08:08:09 -0400 X-MC-Unique: vwHko3tON6mcoZw9zQebXw-1 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id EC8F4803624 for ; Tue, 8 Jun 2021 12:08:07 +0000 (UTC) Received: from localhost (unknown [10.36.110.2]) by smtp.corp.redhat.com (Postfix) with ESMTP id F061A620DE; Tue, 8 Jun 2021 12:08:06 +0000 (UTC) From: marcandre.lureau@redhat.com To: qemu-devel@nongnu.org Subject: [PATCH v5 5/9] qapi: introduce IfPredicateList and IfAny Date: Tue, 8 Jun 2021 16:07:19 +0400 Message-Id: <20210608120723.2268181-6-marcandre.lureau@redhat.com> In-Reply-To: <20210608120723.2268181-1-marcandre.lureau@redhat.com> References: <20210608120723.2268181-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=marcandre.lureau@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Received-SPF: pass client-ip=216.205.24.124; envelope-from=marcandre.lureau@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -29 X-Spam_score: -3.0 X-Spam_bar: --- X-Spam_report: (-3.0 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.197, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Eric Blake , jsnow@redhat.com, Markus Armbruster , =?utf-8?q?Marc-Andr=C3=A9_Lureau?= Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Marc-André Lureau Refactor IfAll class, to introduce a base class IfPredicateList and add IfAny for the 'any' conditions. Signed-off-by: Marc-André Lureau Reviewed-by: Stefan Hajnoczi Tested-by: John Snow --- scripts/qapi/common.py | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/scripts/qapi/common.py b/scripts/qapi/common.py index 01e3203545..a4a41c23bc 100644 --- a/scripts/qapi/common.py +++ b/scripts/qapi/common.py @@ -245,15 +245,26 @@ def __eq__(self, other: object) -> bool: return self.option == other.option -class IfAll(IfPredicate): +class IfPredicateList(IfPredicate): + C_SEP = "" + DOC_SEP = "" + def __init__(self, pred_list: Sequence[IfPredicate]): self.pred_list = pred_list def cgen(self) -> str: - return " && ".join([p.cgen() for p in self.pred_list]) + sep = " " + self.C_SEP + " " + gen = sep.join([p.cgen() for p in self.pred_list]) + if len(self.pred_list) <= 1: + return gen + return "(%s)" % gen def docgen(self) -> str: - return " and ".join([p.docgen() for p in self.pred_list]) + sep = " " + self.DOC_SEP + " " + gen = sep.join([p.docgen() for p in self.pred_list]) + if len(self.pred_list) <= 1: + return gen + return "(%s)" % gen def __bool__(self) -> bool: return bool(self.pred_list) @@ -262,6 +273,16 @@ def __repr__(self) -> str: return f"{type(self).__name__}({self.pred_list!r})" def __eq__(self, other: object) -> bool: - if not isinstance(other, IfAll): + if not isinstance(other, type(self)): return NotImplemented return self.pred_list == other.pred_list + + +class IfAll(IfPredicateList): + C_SEP = "&&" + DOC_SEP = "and" + + +class IfAny(IfPredicateList): + C_SEP = "||" + DOC_SEP = "or" From patchwork Tue Jun 8 12:07:20 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= X-Patchwork-Id: 1489399 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=Dt7yrHTl; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4FzpxG5wVHz9sj1 for ; Tue, 8 Jun 2021 22:11:11 +1000 (AEST) Received: from localhost ([::1]:56098 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lqaZZ-0004zo-O4 for incoming@patchwork.ozlabs.org; Tue, 08 Jun 2021 08:11:09 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:55128) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lqaWr-0007Nv-6t for qemu-devel@nongnu.org; Tue, 08 Jun 2021 08:08:21 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]:30198) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lqaWp-0001Zq-F6 for qemu-devel@nongnu.org; Tue, 08 Jun 2021 08:08:20 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1623154098; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=lLjQcoatoJtqcdHrfqd6C+qc/pjhRo8VRkVG0JUTRVE=; b=Dt7yrHTlBOsnQJyHTqMNKSIO1e54WVbMvZxscu2dPs3P11yXwBryFZ7rOexuyt1jgux7MZ DYrlilWeYVEL0wPokObBRVjYpezinDDRmiqlWgXonbTg9U2htKb9mWQD9AWz7zvQHiFPQu b7ErQM4/4iJ5VjFfPnbGvjMVzUfmspM= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-516-Gx-Nxau4NHSoKOxs1F0NzA-1; Tue, 08 Jun 2021 08:08:16 -0400 X-MC-Unique: Gx-Nxau4NHSoKOxs1F0NzA-1 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id AC519800D62 for ; Tue, 8 Jun 2021 12:08:15 +0000 (UTC) Received: from localhost (unknown [10.36.110.2]) by smtp.corp.redhat.com (Postfix) with ESMTP id 9A9B0179E6; Tue, 8 Jun 2021 12:08:11 +0000 (UTC) From: marcandre.lureau@redhat.com To: qemu-devel@nongnu.org Subject: [PATCH v5 6/9] qapi: add IfNot Date: Tue, 8 Jun 2021 16:07:20 +0400 Message-Id: <20210608120723.2268181-7-marcandre.lureau@redhat.com> In-Reply-To: <20210608120723.2268181-1-marcandre.lureau@redhat.com> References: <20210608120723.2268181-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=marcandre.lureau@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Received-SPF: pass client-ip=170.10.133.124; envelope-from=marcandre.lureau@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -29 X-Spam_score: -3.0 X-Spam_bar: --- X-Spam_report: (-3.0 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.197, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Eric Blake , jsnow@redhat.com, Markus Armbruster , =?utf-8?q?Marc-Andr=C3=A9_Lureau?= Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Marc-André Lureau Introduce IfNot predicate class, for 'not' condition expressions. Signed-off-by: Marc-André Lureau Reviewed-by: Stefan Hajnoczi Tested-by: John Snow --- scripts/qapi/common.py | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/scripts/qapi/common.py b/scripts/qapi/common.py index a4a41c23bc..1d929cbeec 100644 --- a/scripts/qapi/common.py +++ b/scripts/qapi/common.py @@ -245,6 +245,28 @@ def __eq__(self, other: object) -> bool: return self.option == other.option +class IfNot(IfPredicate): + def __init__(self, pred: IfPredicate): + self.pred = pred + + def cgen(self) -> str: + return "!" + self.pred.cgen() + + def docgen(self) -> str: + return "not " + self.pred.docgen() + + def __bool__(self) -> bool: + return bool(self.pred) + + def __repr__(self) -> str: + return f"IfNot({self.pred!r})" + + def __eq__(self, other: object) -> bool: + if not isinstance(other, type(self)): + return False + return self.pred == other.pred + + class IfPredicateList(IfPredicate): C_SEP = "" DOC_SEP = "" From patchwork Tue Jun 8 12:07:21 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= X-Patchwork-Id: 1489400 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=KRPw37jk; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4Fzpyx4QYhz9sWD for ; Tue, 8 Jun 2021 22:12:41 +1000 (AEST) Received: from localhost ([::1]:34356 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lqab1-0000vn-Ja for incoming@patchwork.ozlabs.org; Tue, 08 Jun 2021 08:12:39 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:55176) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lqaX3-00089r-8R for qemu-devel@nongnu.org; Tue, 08 Jun 2021 08:08:33 -0400 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:56945) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lqaWy-0001fd-9U for qemu-devel@nongnu.org; Tue, 08 Jun 2021 08:08:33 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1623154107; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=KhCEU/qcGQ8bLCl3B9mDbCk1T4XTL0DIIo6oBXKeqvE=; b=KRPw37jka57u6u1cQAQXgznX5EiDl8Dy5iQpLiKcs2UqQQdurrke6gEIEdT3FGZIAzISDu Ro14k2WhY82UTLmp6twQssPcBEI7BeSnZfKpcReWjOQDhqgXBNa1wSBYvsPEZ6xDhmWAkS 2RzUSlXINTpWr28y8p/ZMZmAWC7GcrU= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-467-xc9Z35CVPbqw7o2ynGF6jw-1; Tue, 08 Jun 2021 08:08:26 -0400 X-MC-Unique: xc9Z35CVPbqw7o2ynGF6jw-1 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 3C5EC1020C2E for ; Tue, 8 Jun 2021 12:08:25 +0000 (UTC) Received: from localhost (unknown [10.36.110.2]) by smtp.corp.redhat.com (Postfix) with ESMTP id B27F21001281; Tue, 8 Jun 2021 12:08:19 +0000 (UTC) From: marcandre.lureau@redhat.com To: qemu-devel@nongnu.org Subject: [PATCH v5 7/9] qapi: normalize 'if' condition to IfPredicate tree Date: Tue, 8 Jun 2021 16:07:21 +0400 Message-Id: <20210608120723.2268181-8-marcandre.lureau@redhat.com> In-Reply-To: <20210608120723.2268181-1-marcandre.lureau@redhat.com> References: <20210608120723.2268181-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=marcandre.lureau@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Received-SPF: pass client-ip=216.205.24.124; envelope-from=marcandre.lureau@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -29 X-Spam_score: -3.0 X-Spam_bar: --- X-Spam_report: (-3.0 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.197, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Eric Blake , jsnow@redhat.com, Markus Armbruster , =?utf-8?q?Marc-Andr=C3=A9_Lureau?= Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Marc-André Lureau Modify check_if() to normalize the condition tree. Add _make_if() to build a QAPISchemaIfCond tree. Signed-off-by: Marc-André Lureau Reviewed-by: Stefan Hajnoczi Tested-by: John Snow --- tests/unit/test-qmp-cmds.c | 1 + scripts/qapi/expr.py | 51 +++++++++------ scripts/qapi/schema.py | 62 +++++++++++++------ tests/qapi-schema/bad-if-empty-list.json | 2 +- tests/qapi-schema/bad-if-list.json | 2 +- tests/qapi-schema/bad-if.err | 3 +- tests/qapi-schema/doc-good.out | 12 ++-- tests/qapi-schema/enum-if-invalid.err | 3 +- tests/qapi-schema/features-if-invalid.err | 2 +- tests/qapi-schema/qapi-schema-test.json | 32 ++++++---- tests/qapi-schema/qapi-schema-test.out | 59 ++++++++++-------- .../qapi-schema/struct-member-if-invalid.err | 2 +- .../qapi-schema/union-branch-if-invalid.json | 2 +- 13 files changed, 143 insertions(+), 90 deletions(-) diff --git a/tests/unit/test-qmp-cmds.c b/tests/unit/test-qmp-cmds.c index 1b0b7d99df..83efa39720 100644 --- a/tests/unit/test-qmp-cmds.c +++ b/tests/unit/test-qmp-cmds.c @@ -51,6 +51,7 @@ FeatureStruct1 *qmp_test_features0(bool has_fs0, FeatureStruct0 *fs0, bool has_cfs1, CondFeatureStruct1 *cfs1, bool has_cfs2, CondFeatureStruct2 *cfs2, bool has_cfs3, CondFeatureStruct3 *cfs3, + bool has_cfs4, CondFeatureStruct4 *cfs4, Error **errp) { return g_new0(FeatureStruct1, 1); diff --git a/scripts/qapi/expr.py b/scripts/qapi/expr.py index 496f7e0333..60ffe9ef03 100644 --- a/scripts/qapi/expr.py +++ b/scripts/qapi/expr.py @@ -261,12 +261,12 @@ def check_if(expr: _JSONObject, info: QAPISourceInfo, source: str) -> None: """ Normalize and 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`` field may be either a ``str`` or a dict. + A ``str`` element will be normalized to ``{'all': List[str]}``. :forms: - :sugared: ``Union[str, List[str]]`` - :canonical: ``List[str]`` + :sugared: ``Union[str, dict]`` + :canonical: ``Union[str, dict]`` :param expr: The expression containing the ``if`` member to validate. :param info: QAPI schema source file information. @@ -281,25 +281,38 @@ def check_if(expr: _JSONObject, info: QAPISourceInfo, source: str) -> None: 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] - - for elt in ifcond: - if not isinstance(elt, str): + def normalize(cond: Union[str, object]) -> Union[str, object]: + if isinstance(cond, str): + if not cond.strip(): + raise QAPISemError( + info, + "'if' condition '%s' of %s makes no sense" + % (cond, source)) + return cond + 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) + 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', 'any' or 'not'" % source) + check_keys(cond, info, "'if' condition", [], + ["all", "any", "not"]) + oper, operands = next(iter(cond.items())) + if not operands: + raise QAPISemError( + info, "'if' condition [] of %s is useless" % source) + if oper == "not": + return {oper: normalize(operands)} + if oper in ("all", "any") and not isinstance(operands, list): + raise QAPISemError( + info, "'%s' condition of %s must be a list" % (oper, source)) + operands = [normalize(o) for o in operands] + return {oper: operands} + + expr['if'] = normalize(ifcond) def normalize_members(members: object) -> None: diff --git a/scripts/qapi/schema.py b/scripts/qapi/schema.py index f52caaeecc..9864e49c54 100644 --- a/scripts/qapi/schema.py +++ b/scripts/qapi/schema.py @@ -22,6 +22,8 @@ from .common import ( POINTER_SUFFIX, IfAll, + IfAny, + IfNot, IfOption, c_name, ) @@ -31,15 +33,14 @@ class QAPISchemaIfCond: - def __init__(self, ifcond=None): - self.ifcond = ifcond or [] - self.pred = IfAll([IfOption(opt) for opt in self.ifcond]) + def __init__(self, pred=None): + self.pred = pred def docgen(self): - return self.pred.docgen() + return self and self.pred.docgen() def cgen(self): - return self.pred.cgen() + return self and self.pred.cgen() # Returns true if the condition is not void def __bool__(self): @@ -991,16 +992,41 @@ def _def_predefineds(self): self._def_entity(QAPISchemaEnumType('QType', None, None, None, None, qtype_values, 'QTYPE')) + def _make_if(self, cond): + if isinstance(cond, QAPISchemaIfCond): + return cond + if cond is None: + return QAPISchemaIfCond() + + def make_pred(node): + if isinstance(node, str): + return IfOption(node) + oper, operands = next(iter(node.items())) + op2cls = { + 'all': IfAll, + 'any': IfAny, + 'not': IfNot, + } + + if isinstance(operands, list): + operands = [make_pred(o) for o in operands] + else: + operands = make_pred(operands) + + return op2cls[oper](operands) + + return QAPISchemaIfCond(make_pred(cond)) + def _make_features(self, features, info): if features is None: return [] return [QAPISchemaFeature(f['name'], info, - QAPISchemaIfCond(f.get('if'))) + self._make_if(f.get('if'))) for f in features] def _make_enum_members(self, values, info): return [QAPISchemaEnumMember(v['name'], info, - QAPISchemaIfCond(v.get('if'))) + self._make_if(v.get('if'))) for v in values] def _make_implicit_enum_type(self, name, info, ifcond, values): @@ -1046,7 +1072,7 @@ def _def_enum_type(self, expr, info, doc): name = expr['enum'] data = expr['data'] prefix = expr.get('prefix') - ifcond = QAPISchemaIfCond(expr.get('if')) + ifcond = self._make_if(expr.get('if')) features = self._make_features(expr.get('features'), info) self._def_entity(QAPISchemaEnumType( name, info, doc, ifcond, features, @@ -1065,7 +1091,7 @@ def _make_member(self, name, typ, ifcond, features, info): def _make_members(self, data, info): return [self._make_member(key, value['type'], - QAPISchemaIfCond(value.get('if')), + self._make_if(value.get('if')), value.get('features'), info) for (key, value) in data.items()] @@ -1073,7 +1099,7 @@ def _def_struct_type(self, expr, info, doc): name = expr['struct'] base = expr.get('base') data = expr['data'] - ifcond = QAPISchemaIfCond(expr.get('if')) + ifcond = self._make_if(expr.get('if')) features = self._make_features(expr.get('features'), info) self._def_entity(QAPISchemaObjectType( name, info, doc, ifcond, features, base, @@ -1096,7 +1122,7 @@ def _def_union_type(self, expr, info, doc): name = expr['union'] data = expr['data'] base = expr.get('base') - ifcond = QAPISchemaIfCond(expr.get('if')) + ifcond = self._make_if(expr.get('if')) features = self._make_features(expr.get('features'), info) tag_name = expr.get('discriminator') tag_member = None @@ -1107,7 +1133,7 @@ def _def_union_type(self, expr, info, doc): if tag_name: variants = [ self._make_variant(key, value['type'], - QAPISchemaIfCond(value.get('if')), + self._make_if(value.get('if')), info) for (key, value) in data.items() ] @@ -1115,11 +1141,11 @@ def _def_union_type(self, expr, info, doc): else: variants = [ self._make_simple_variant(key, value['type'], - QAPISchemaIfCond(value.get('if')), + self._make_if(value.get('if')), info) for (key, value) in data.items() ] - enum = [{'name': v.name, 'if': v.ifcond.ifcond} for v in variants] + enum = [{'name': v.name, 'if': v.ifcond} for v in variants] typ = self._make_implicit_enum_type(name, info, ifcond, enum) tag_member = QAPISchemaObjectTypeMember('type', info, typ, False) members = [tag_member] @@ -1132,11 +1158,11 @@ def _def_union_type(self, expr, info, doc): def _def_alternate_type(self, expr, info, doc): name = expr['alternate'] data = expr['data'] - ifcond = QAPISchemaIfCond(expr.get('if')) + ifcond = self._make_if(expr.get('if')) features = self._make_features(expr.get('features'), info) variants = [ self._make_variant(key, value['type'], - QAPISchemaIfCond(value.get('if')), + self._make_if(value.get('if')), info) for (key, value) in data.items() ] @@ -1156,7 +1182,7 @@ def _def_command(self, expr, info, doc): allow_oob = expr.get('allow-oob', False) allow_preconfig = expr.get('allow-preconfig', False) coroutine = expr.get('coroutine', False) - ifcond = QAPISchemaIfCond(expr.get('if')) + ifcond = self._make_if(expr.get('if')) features = self._make_features(expr.get('features'), info) if isinstance(data, OrderedDict): data = self._make_implicit_object_type( @@ -1175,7 +1201,7 @@ def _def_event(self, expr, info, doc): name = expr['event'] data = expr.get('data') boxed = expr.get('boxed', False) - ifcond = QAPISchemaIfCond(expr.get('if')) + ifcond = self._make_if(expr.get('if')) features = self._make_features(expr.get('features'), info) if isinstance(data, OrderedDict): data = self._make_implicit_object_type( 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': [] } } 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', ' '] } } diff --git a/tests/qapi-schema/bad-if.err b/tests/qapi-schema/bad-if.err index f83dee65da..454fbae387 100644 --- a/tests/qapi-schema/bad-if.err +++ b/tests/qapi-schema/bad-if.err @@ -1,2 +1,3 @@ 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 has unknown key 'value' +Valid keys are 'all', 'any', 'not'. diff --git a/tests/qapi-schema/doc-good.out b/tests/qapi-schema/doc-good.out index db1d23c6bf..4d951f97ee 100644 --- a/tests/qapi-schema/doc-good.out +++ b/tests/qapi-schema/doc-good.out @@ -12,15 +12,15 @@ enum QType module doc-good.json enum Enum member one - if IfAll([IfOption('defined(IFONE)')]) + if IfOption('defined(IFONE)') member two - if IfAll([IfOption('defined(IFCOND)')]) + if IfOption('defined(IFCOND)') feature enum-feat object Base member base1: Enum optional=False object Variant1 member var1: str optional=False - if IfAll([IfOption('defined(IFSTR)')]) + if IfOption('defined(IFSTR)') feature member-feat feature variant1-feat object Variant2 @@ -29,7 +29,7 @@ object Object tag base1 case one: Variant1 case two: Variant2 - if IfAll([IfOption('IFTWO')]) + if IfOption('IFTWO') feature union-feat1 object q_obj_Variant1-wrapper member data: Variant1 optional=False @@ -38,13 +38,13 @@ object q_obj_Variant2-wrapper enum SugaredUnionKind member one member two - if IfAll([IfOption('IFTWO')]) + if IfOption('IFTWO') object SugaredUnion member type: SugaredUnionKind optional=False tag type case one: q_obj_Variant1-wrapper case two: q_obj_Variant2-wrapper - if IfAll([IfOption('IFTWO')]) + if IfOption('IFTWO') feature union-feat2 alternate Alternate tag type diff --git a/tests/qapi-schema/enum-if-invalid.err b/tests/qapi-schema/enum-if-invalid.err index 0556dc967b..3bb84075a9 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', 'any', 'not'. 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/qapi-schema-test.json b/tests/qapi-schema/qapi-schema-test.json index 84b9d41f15..a0f09b277e 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)'} }, + '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' }, + 'if': { 'all': ['defined(TEST_IF_ALT)', {'not': 'defined(TEST_IF_NOT_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,13 @@ { '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)'] } } ] } +{ 'struct': 'CondFeatureStruct4', + 'data': { 'foo': 'int' }, + 'features': [ { 'name': 'feature1', 'if': {'any': ['defined(TEST_IF_COND_1)', + 'defined(TEST_IF_COND_2)'] } } ] } { 'enum': 'FeatureEnum1', 'data': [ 'eins', 'zwei', 'drei' ], @@ -313,7 +317,8 @@ '*fs4': 'FeatureStruct4', '*cfs1': 'CondFeatureStruct1', '*cfs2': 'CondFeatureStruct2', - '*cfs3': 'CondFeatureStruct3' }, + '*cfs3': 'CondFeatureStruct3', + '*cfs4': 'CondFeatureStruct4' }, 'returns': 'FeatureStruct1', 'features': [] } @@ -328,8 +333,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 e4e0fb173a..dd2f83fbae 100644 --- a/tests/qapi-schema/qapi-schema-test.out +++ b/tests/qapi-schema/qapi-schema-test.out @@ -298,49 +298,49 @@ 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 IfAll([IfOption('defined(TEST_IF_STRUCT_BAR)')]) - if IfAll([IfOption('defined(TEST_IF_STRUCT)')]) + if IfOption('defined(TEST_IF_STRUCT_BAR)') + if IfOption('defined(TEST_IF_STRUCT)') enum TestIfEnum member foo member bar - if IfAll([IfOption('defined(TEST_IF_ENUM_BAR)')]) - if IfAll([IfOption('defined(TEST_IF_ENUM)')]) + if IfOption('defined(TEST_IF_ENUM_BAR)') + if IfOption('defined(TEST_IF_ENUM)') object q_obj_TestStruct-wrapper member data: TestStruct optional=False enum TestIfUnionKind member foo - member bar - if IfAll([IfOption('defined(TEST_IF_UNION_BAR)')]) - if IfAll([IfOption('defined(TEST_IF_UNION) && defined(TEST_IF_STRUCT)')]) + member union-bar + if IfOption('defined(TEST_IF_UNION_BAR)') + if IfAll([IfOption('defined(TEST_IF_UNION)'), IfOption('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 IfAll([IfOption('defined(TEST_IF_UNION_BAR)')]) - if IfAll([IfOption('defined(TEST_IF_UNION) && defined(TEST_IF_STRUCT)')]) + case union-bar: q_obj_str-wrapper + if IfOption('defined(TEST_IF_UNION_BAR)') + if IfAll([IfOption('defined(TEST_IF_UNION)'), IfOption('defined(TEST_IF_STRUCT)')]) object q_obj_test-if-union-cmd-arg member union-cmd-arg: TestIfUnion optional=False - if IfAll([IfOption('defined(TEST_IF_UNION)')]) + if IfOption('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 IfAll([IfOption('defined(TEST_IF_UNION)')]) + if IfOption('defined(TEST_IF_UNION)') alternate TestIfAlternate tag type case foo: int case bar: TestStruct - if IfAll([IfOption('defined(TEST_IF_ALT_BAR)')]) - if IfAll([IfOption('defined(TEST_IF_ALT) && defined(TEST_IF_STRUCT)')]) + if IfOption('defined(TEST_IF_ALT_BAR)') + if IfAll([IfOption('defined(TEST_IF_ALT)'), IfOption('defined(TEST_IF_STRUCT)')]) object q_obj_test-if-alternate-cmd-arg member alt-cmd-arg: TestIfAlternate optional=False - if IfAll([IfOption('defined(TEST_IF_ALT)')]) + if IfAll([IfOption('defined(TEST_IF_ALT)'), IfNot(IfOption('defined(TEST_IF_NOT_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 IfAll([IfOption('defined(TEST_IF_ALT)')]) + if IfAll([IfOption('defined(TEST_IF_ALT)'), IfNot(IfOption('defined(TEST_IF_NOT_ALT)'))]) object q_obj_test-if-cmd-arg member foo: TestIfStruct optional=False member bar: TestIfEnum optional=False - if IfAll([IfOption('defined(TEST_IF_CMD_BAR)')]) + if IfOption('defined(TEST_IF_CMD_BAR)') if IfAll([IfOption('defined(TEST_IF_CMD)'), IfOption('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 @@ -348,15 +348,15 @@ command test-if-cmd q_obj_test-if-cmd-arg -> UserDefThree command test-cmd-return-def-three None -> UserDefThree gen=True success_response=True boxed=False oob=False preconfig=False array TestIfEnumList TestIfEnum - if IfAll([IfOption('defined(TEST_IF_ENUM)')]) + if IfOption('defined(TEST_IF_ENUM)') object q_obj_TEST_IF_EVENT-arg member foo: TestIfStruct optional=False member bar: TestIfEnumList optional=False - if IfAll([IfOption('defined(TEST_IF_EVT_BAR)')]) - if IfAll([IfOption('defined(TEST_IF_EVT) && defined(TEST_IF_STRUCT)')]) + if IfOption('defined(TEST_IF_EVT_BAR)') + if IfAll([IfOption('defined(TEST_IF_EVT)'), IfOption('defined(TEST_IF_STRUCT)')]) event TEST_IF_EVENT q_obj_TEST_IF_EVENT-arg boxed=False - if IfAll([IfOption('defined(TEST_IF_EVT) && defined(TEST_IF_STRUCT)')]) + if IfAll([IfOption('defined(TEST_IF_EVT)'), IfOption('defined(TEST_IF_STRUCT)')]) object FeatureStruct0 member foo: int optional=False object FeatureStruct1 @@ -379,17 +379,21 @@ object FeatureStruct4 object CondFeatureStruct1 member foo: int optional=False feature feature1 - if IfAll([IfOption('defined(TEST_IF_FEATURE_1)')]) + if IfOption('defined(TEST_IF_FEATURE_1)') object CondFeatureStruct2 member foo: int optional=False feature feature1 - if IfAll([IfOption('defined(TEST_IF_FEATURE_1)')]) + if IfOption('defined(TEST_IF_FEATURE_1)') feature feature2 - if IfAll([IfOption('defined(TEST_IF_FEATURE_2)')]) + if IfOption('defined(TEST_IF_FEATURE_2)') object CondFeatureStruct3 member foo: int optional=False feature feature1 if IfAll([IfOption('defined(TEST_IF_COND_1)'), IfOption('defined(TEST_IF_COND_2)')]) +object CondFeatureStruct4 + member foo: int optional=False + feature feature1 + if IfAny([IfOption('defined(TEST_IF_COND_1)'), IfOption('defined(TEST_IF_COND_2)')]) enum FeatureEnum1 member eins member zwei @@ -417,6 +421,7 @@ object q_obj_test-features0-arg member cfs1: CondFeatureStruct1 optional=True member cfs2: CondFeatureStruct2 optional=True member cfs3: CondFeatureStruct3 optional=True + member cfs4: CondFeatureStruct4 optional=True command test-features0 q_obj_test-features0-arg -> FeatureStruct1 gen=True success_response=True boxed=False oob=False preconfig=False command test-command-features1 None -> None @@ -429,13 +434,13 @@ 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 IfAll([IfOption('defined(TEST_IF_FEATURE_1)')]) + if IfOption('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 IfAll([IfOption('defined(TEST_IF_FEATURE_1)')]) + if IfOption('defined(TEST_IF_FEATURE_1)') feature feature2 - if IfAll([IfOption('defined(TEST_IF_FEATURE_2)')]) + if IfOption('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 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': [''] } } } } From patchwork Tue Jun 8 12:07:22 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= X-Patchwork-Id: 1489416 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=OSzNlhFQ; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4Fzq4d6f14z9sXS for ; Tue, 8 Jun 2021 22:17:37 +1000 (AEST) Received: from localhost ([::1]:55144 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lqafn-0006J7-TB for incoming@patchwork.ozlabs.org; Tue, 08 Jun 2021 08:17:35 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:55238) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lqaX9-00006j-Ku for qemu-devel@nongnu.org; Tue, 08 Jun 2021 08:08:39 -0400 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:30118) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lqaX7-0001li-IV for qemu-devel@nongnu.org; Tue, 08 Jun 2021 08:08:39 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1623154116; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=oyLF3ZRBHl6FM6hwf1O8w2xfS6mPxoW2gYxtucOrFr8=; b=OSzNlhFQ0M5hhsC6HVKK16V99XI2zEJ8pQCa4mobSc0N40SE5diDwotRMkEa9luo9CY0SR r2qDf/7DnnYUQjEqhy26LIXNpAKwdnMnZjQNwZp98jzfPbhqSFWxgyChla+n+q4Fzj5QYs +OwWXAICpGxKLqRM/dpla6/XAQqfP1M= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-37-OFF_xRwWNmeKjEcrWUnPFg-1; Tue, 08 Jun 2021 08:08:35 -0400 X-MC-Unique: OFF_xRwWNmeKjEcrWUnPFg-1 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 1349A107ACE8 for ; Tue, 8 Jun 2021 12:08:34 +0000 (UTC) Received: from localhost (unknown [10.36.110.2]) by smtp.corp.redhat.com (Postfix) with ESMTP id 707E15C1BB; Tue, 8 Jun 2021 12:08:29 +0000 (UTC) From: marcandre.lureau@redhat.com To: qemu-devel@nongnu.org Subject: [PATCH v5 8/9] qapi: convert 'if' C-expressions to the new syntax tree Date: Tue, 8 Jun 2021 16:07:22 +0400 Message-Id: <20210608120723.2268181-9-marcandre.lureau@redhat.com> In-Reply-To: <20210608120723.2268181-1-marcandre.lureau@redhat.com> References: <20210608120723.2268181-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=marcandre.lureau@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Received-SPF: pass client-ip=216.205.24.124; envelope-from=marcandre.lureau@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -29 X-Spam_score: -3.0 X-Spam_bar: --- X-Spam_report: (-3.0 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.197, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Eric Blake , jsnow@redhat.com, Markus Armbruster , =?utf-8?q?Marc-Andr=C3=A9_Lureau?= Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Marc-André Lureau Signed-off-by: Marc-André Lureau Reviewed-by: Stefan Hajnoczi Tested-by: John Snow --- qapi/machine-target.json | 20 ++++++++++++++++---- qapi/misc-target.json | 12 +++++++++++- 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/qapi/machine-target.json b/qapi/machine-target.json index e7811654b7..9b56b81bea 100644 --- a/qapi/machine-target.json +++ b/qapi/machine-target.json @@ -213,7 +213,9 @@ ## { 'struct': 'CpuModelExpansionInfo', 'data': { 'model': 'CpuModelInfo' }, - 'if': 'defined(TARGET_S390X) || defined(TARGET_I386) || defined(TARGET_ARM)' } + 'if': { 'any': [ 'defined(TARGET_S390X)', + 'defined(TARGET_I386)', + 'defined(TARGET_ARM)'] } } ## # @query-cpu-model-expansion: @@ -252,7 +254,9 @@ 'data': { 'type': 'CpuModelExpansionType', 'model': 'CpuModelInfo' }, 'returns': 'CpuModelExpansionInfo', - 'if': 'defined(TARGET_S390X) || defined(TARGET_I386) || defined(TARGET_ARM)' } + 'if': { 'any': [ 'defined(TARGET_S390X)', + 'defined(TARGET_I386)', + 'defined(TARGET_ARM)' ] } } ## # @CpuDefinitionInfo: @@ -316,7 +320,11 @@ 'typename': 'str', '*alias-of' : 'str', 'deprecated' : 'bool' }, - 'if': 'defined(TARGET_PPC) || defined(TARGET_ARM) || defined(TARGET_I386) || defined(TARGET_S390X) || defined(TARGET_MIPS)' } + 'if': { 'any': [ 'defined(TARGET_PPC)', + 'defined(TARGET_ARM)', + 'defined(TARGET_I386)', + 'defined(TARGET_S390X)', + 'defined(TARGET_MIPS)' ] } } ## # @query-cpu-definitions: @@ -328,4 +336,8 @@ # Since: 1.2 ## { 'command': 'query-cpu-definitions', 'returns': ['CpuDefinitionInfo'], - 'if': 'defined(TARGET_PPC) || defined(TARGET_ARM) || defined(TARGET_I386) || defined(TARGET_S390X) || defined(TARGET_MIPS)' } + 'if': { 'any': [ 'defined(TARGET_PPC)', + 'defined(TARGET_ARM)', + 'defined(TARGET_I386)', + 'defined(TARGET_S390X)', + 'defined(TARGET_MIPS)' ] } } diff --git a/qapi/misc-target.json b/qapi/misc-target.json index 5573dcf8f0..9e2ea4a04a 100644 --- a/qapi/misc-target.json +++ b/qapi/misc-target.json @@ -23,7 +23,17 @@ ## { 'event': 'RTC_CHANGE', 'data': { 'offset': 'int' }, - 'if': 'defined(TARGET_ALPHA) || defined(TARGET_ARM) || defined(TARGET_HPPA) || defined(TARGET_I386) || defined(TARGET_MIPS) || defined(TARGET_MIPS64) || defined(TARGET_PPC) || defined(TARGET_PPC64) || defined(TARGET_S390X) || defined(TARGET_SH4) || defined(TARGET_SPARC)' } + 'if': { 'any': [ 'defined(TARGET_ALPHA)', + 'defined(TARGET_ARM)', + 'defined(TARGET_HPPA)', + 'defined(TARGET_I386)', + 'defined(TARGET_MIPS)', + 'defined(TARGET_MIPS64)', + 'defined(TARGET_PPC)', + 'defined(TARGET_PPC64)', + 'defined(TARGET_S390X)', + 'defined(TARGET_SH4)', + 'defined(TARGET_SPARC)' ] } } ## # @rtc-reset-reinjection: From patchwork Tue Jun 8 12:07:23 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= X-Patchwork-Id: 1489414 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=abVFJxkb; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4Fzq3w49lwz9sXS for ; Tue, 8 Jun 2021 22:16:59 +1000 (AEST) Received: from localhost ([::1]:51928 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lqafB-00049v-RZ for incoming@patchwork.ozlabs.org; Tue, 08 Jun 2021 08:16:57 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:55378) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lqaXT-0000jp-VG for qemu-devel@nongnu.org; Tue, 08 Jun 2021 08:09:00 -0400 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:59308) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lqaXI-0001sC-Vp for qemu-devel@nongnu.org; Tue, 08 Jun 2021 08:08:57 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1623154127; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=ilIyUPMbJIDtjFOwVsIZDfs7nAvIe8GyfvGmKGRNodE=; b=abVFJxkbP0hPntzneumiA63TplNmzXftgJREt9YYVVVuJM8+HTJG0s0YGEyC2qbEjqPoCk iWRfqtHyE6t3qdsxz229DMqCjYVxeBoFoPnqAJtekDZYcR+9KwoogzZjmAE/sLixjHwiBG KVzp+PyGmzoU7RczlgEFoI4zxcyqwwo= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-55-PuK5zlQuMGmZ8Ce3HTL7hQ-1; Tue, 08 Jun 2021 08:08:44 -0400 X-MC-Unique: PuK5zlQuMGmZ8Ce3HTL7hQ-1 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 934111020C33 for ; Tue, 8 Jun 2021 12:08:43 +0000 (UTC) Received: from localhost (unknown [10.36.110.2]) by smtp.corp.redhat.com (Postfix) with ESMTP id DC1185B4A6; Tue, 8 Jun 2021 12:08:37 +0000 (UTC) From: marcandre.lureau@redhat.com To: qemu-devel@nongnu.org Subject: [PATCH v5 9/9] qapi: make 'if' condition strings simple identifiers Date: Tue, 8 Jun 2021 16:07:23 +0400 Message-Id: <20210608120723.2268181-10-marcandre.lureau@redhat.com> In-Reply-To: <20210608120723.2268181-1-marcandre.lureau@redhat.com> References: <20210608120723.2268181-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=marcandre.lureau@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Received-SPF: pass client-ip=216.205.24.124; envelope-from=marcandre.lureau@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -29 X-Spam_score: -3.0 X-Spam_bar: --- X-Spam_report: (-3.0 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.197, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Eric Blake , jsnow@redhat.com, Markus Armbruster , =?utf-8?q?Marc-Andr=C3=A9_Lureau?= Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Marc-André Lureau Change the 'if' condition strings to be C-agnostic and be simple identifiers. Signed-off-by: Marc-André Lureau Reviewed-by: Stefan Hajnoczi Tested-by: John Snow --- qapi/block-core.json | 16 ++--- qapi/block-export.json | 6 +- qapi/char.json | 12 ++-- qapi/machine-target.json | 40 ++++++------- qapi/migration.json | 10 ++-- qapi/misc-target.json | 50 ++++++++-------- qapi/qom.json | 10 ++-- qapi/sockets.json | 4 +- qapi/ui.json | 48 +++++++-------- qga/qapi-schema.json | 8 +-- scripts/qapi/common.py | 2 +- scripts/qapi/expr.py | 4 +- .../alternate-branch-if-invalid.err | 2 +- tests/qapi-schema/bad-if-empty.err | 2 +- tests/qapi-schema/bad-if-list.err | 2 +- tests/qapi-schema/bad-if.json | 2 +- tests/qapi-schema/doc-good.json | 6 +- tests/qapi-schema/doc-good.out | 6 +- tests/qapi-schema/doc-good.txt | 6 +- tests/qapi-schema/features-missing-name.json | 2 +- tests/qapi-schema/qapi-schema-test.json | 52 ++++++++-------- tests/qapi-schema/qapi-schema-test.out | 60 +++++++++---------- tests/qapi-schema/union-branch-if-invalid.err | 2 +- 23 files changed, 176 insertions(+), 176 deletions(-) diff --git a/qapi/block-core.json b/qapi/block-core.json index 2ea294129e..13fcdd6b91 100644 --- a/qapi/block-core.json +++ b/qapi/block-core.json @@ -2779,7 +2779,7 @@ ## { 'enum': 'BlockdevAioOptions', 'data': [ 'threads', 'native', - { 'name': 'io_uring', 'if': 'defined(CONFIG_LINUX_IO_URING)' } ] } + { 'name': 'io_uring', 'if': 'CONFIG_LINUX_IO_URING' } ] } ## # @BlockdevCacheOptions: @@ -2817,7 +2817,7 @@ 'gluster', 'host_cdrom', 'host_device', 'http', 'https', 'iscsi', 'luks', 'nbd', 'nfs', 'null-aio', 'null-co', 'nvme', 'parallels', 'preallocate', 'qcow', 'qcow2', 'qed', 'quorum', 'raw', 'rbd', - { 'name': 'replication', 'if': 'defined(CONFIG_REPLICATION)' }, + { 'name': 'replication', 'if': 'CONFIG_REPLICATION' }, 'ssh', 'throttle', 'vdi', 'vhdx', 'vmdk', 'vpc', 'vvfat' ] } ## @@ -2859,10 +2859,10 @@ '*locking': 'OnOffAuto', '*aio': 'BlockdevAioOptions', '*drop-cache': {'type': 'bool', - 'if': 'defined(CONFIG_LINUX)'}, + 'if': 'CONFIG_LINUX'}, '*x-check-cache-dropped': 'bool' }, 'features': [ { 'name': 'dynamic-auto-read-only', - 'if': 'defined(CONFIG_POSIX)' } ] } + 'if': 'CONFIG_POSIX' } ] } ## # @BlockdevOptionsNull: @@ -3662,7 +3662,7 @@ # Since: 2.9 ## { 'enum' : 'ReplicationMode', 'data' : [ 'primary', 'secondary' ], - 'if': 'defined(CONFIG_REPLICATION)' } + 'if': 'CONFIG_REPLICATION' } ## # @BlockdevOptionsReplication: @@ -3681,7 +3681,7 @@ 'base': 'BlockdevOptionsGenericFormat', 'data': { 'mode': 'ReplicationMode', '*top-id': 'str' }, - 'if': 'defined(CONFIG_REPLICATION)' } + 'if': 'CONFIG_REPLICATION' } ## # @NFSTransport: @@ -4015,7 +4015,7 @@ 'raw': 'BlockdevOptionsRaw', 'rbd': 'BlockdevOptionsRbd', 'replication': { 'type': 'BlockdevOptionsReplication', - 'if': 'defined(CONFIG_REPLICATION)' }, + 'if': 'CONFIG_REPLICATION' }, 'ssh': 'BlockdevOptionsSsh', 'throttle': 'BlockdevOptionsThrottle', 'vdi': 'BlockdevOptionsGenericFormat', @@ -4316,7 +4316,7 @@ # Since: 5.1 ## { 'enum': 'Qcow2CompressionType', - 'data': [ 'zlib', { 'name': 'zstd', 'if': 'defined(CONFIG_ZSTD)' } ] } + 'data': [ 'zlib', { 'name': 'zstd', 'if': 'CONFIG_ZSTD' } ] } ## # @BlockdevCreateOptionsQcow2: diff --git a/qapi/block-export.json b/qapi/block-export.json index e819e70cac..319992b1b0 100644 --- a/qapi/block-export.json +++ b/qapi/block-export.json @@ -137,7 +137,7 @@ { 'struct': 'BlockExportOptionsFuse', 'data': { 'mountpoint': 'str', '*growable': 'bool' }, - 'if': 'defined(CONFIG_FUSE)' } + 'if': 'CONFIG_FUSE' } ## # @NbdServerAddOptions: @@ -247,7 +247,7 @@ ## { 'enum': 'BlockExportType', 'data': [ 'nbd', 'vhost-user-blk', - { 'name': 'fuse', 'if': 'defined(CONFIG_FUSE)' } ] } + { 'name': 'fuse', 'if': 'CONFIG_FUSE' } ] } ## # @BlockExportOptions: @@ -290,7 +290,7 @@ 'nbd': 'BlockExportOptionsNbd', 'vhost-user-blk': 'BlockExportOptionsVhostUserBlk', 'fuse': { 'type': 'BlockExportOptionsFuse', - 'if': 'defined(CONFIG_FUSE)' } + 'if': 'CONFIG_FUSE' } } } ## diff --git a/qapi/char.json b/qapi/char.json index adf2685f68..9b18ee3305 100644 --- a/qapi/char.json +++ b/qapi/char.json @@ -342,7 +342,7 @@ { 'struct': 'ChardevSpiceChannel', 'data': { 'type': 'str' }, 'base': 'ChardevCommon', - 'if': 'defined(CONFIG_SPICE)' } + 'if': 'CONFIG_SPICE' } ## # @ChardevSpicePort: @@ -356,7 +356,7 @@ { 'struct': 'ChardevSpicePort', 'data': { 'fqdn': 'str' }, 'base': 'ChardevCommon', - 'if': 'defined(CONFIG_SPICE)' } + 'if': 'CONFIG_SPICE' } ## # @ChardevVC: @@ -405,7 +405,7 @@ 'data': { '*mouse': 'bool', '*clipboard': 'bool' }, 'base': 'ChardevCommon', - 'if': 'defined(CONFIG_SPICE_PROTOCOL)' } + 'if': 'CONFIG_SPICE_PROTOCOL' } ## # @ChardevBackend: @@ -431,11 +431,11 @@ 'stdio': 'ChardevStdio', 'console': 'ChardevCommon', 'spicevmc': { 'type': 'ChardevSpiceChannel', - 'if': 'defined(CONFIG_SPICE)' }, + 'if': 'CONFIG_SPICE' }, 'spiceport': { 'type': 'ChardevSpicePort', - 'if': 'defined(CONFIG_SPICE)' }, + 'if': 'CONFIG_SPICE' }, 'qemu-vdagent': { 'type': 'ChardevQemuVDAgent', - 'if': 'defined(CONFIG_SPICE_PROTOCOL)' }, + 'if': 'CONFIG_SPICE_PROTOCOL' }, 'vc': 'ChardevVC', 'ringbuf': 'ChardevRingbuf', # next one is just for compatibility diff --git a/qapi/machine-target.json b/qapi/machine-target.json index 9b56b81bea..f5ec4bc172 100644 --- a/qapi/machine-target.json +++ b/qapi/machine-target.json @@ -89,7 +89,7 @@ ## { 'struct': 'CpuModelBaselineInfo', 'data': { 'model': 'CpuModelInfo' }, - 'if': 'defined(TARGET_S390X)' } + 'if': 'TARGET_S390X' } ## # @CpuModelCompareInfo: @@ -112,7 +112,7 @@ { 'struct': 'CpuModelCompareInfo', 'data': { 'result': 'CpuModelCompareResult', 'responsible-properties': ['str'] }, - 'if': 'defined(TARGET_S390X)' } + 'if': 'TARGET_S390X' } ## # @query-cpu-model-comparison: @@ -156,7 +156,7 @@ { 'command': 'query-cpu-model-comparison', 'data': { 'modela': 'CpuModelInfo', 'modelb': 'CpuModelInfo' }, 'returns': 'CpuModelCompareInfo', - 'if': 'defined(TARGET_S390X)' } + 'if': 'TARGET_S390X' } ## # @query-cpu-model-baseline: @@ -200,7 +200,7 @@ 'data': { 'modela': 'CpuModelInfo', 'modelb': 'CpuModelInfo' }, 'returns': 'CpuModelBaselineInfo', - 'if': 'defined(TARGET_S390X)' } + 'if': 'TARGET_S390X' } ## # @CpuModelExpansionInfo: @@ -213,9 +213,9 @@ ## { 'struct': 'CpuModelExpansionInfo', 'data': { 'model': 'CpuModelInfo' }, - 'if': { 'any': [ 'defined(TARGET_S390X)', - 'defined(TARGET_I386)', - 'defined(TARGET_ARM)'] } } + 'if': { 'any': [ 'TARGET_S390X', + 'TARGET_I386', + 'TARGET_ARM' ] } } ## # @query-cpu-model-expansion: @@ -254,9 +254,9 @@ 'data': { 'type': 'CpuModelExpansionType', 'model': 'CpuModelInfo' }, 'returns': 'CpuModelExpansionInfo', - 'if': { 'any': [ 'defined(TARGET_S390X)', - 'defined(TARGET_I386)', - 'defined(TARGET_ARM)' ] } } + 'if': { 'any': [ 'TARGET_S390X', + 'TARGET_I386', + 'TARGET_ARM' ] } } ## # @CpuDefinitionInfo: @@ -320,11 +320,11 @@ 'typename': 'str', '*alias-of' : 'str', 'deprecated' : 'bool' }, - 'if': { 'any': [ 'defined(TARGET_PPC)', - 'defined(TARGET_ARM)', - 'defined(TARGET_I386)', - 'defined(TARGET_S390X)', - 'defined(TARGET_MIPS)' ] } } + 'if': { 'any': [ 'TARGET_PPC', + 'TARGET_ARM', + 'TARGET_I386', + 'TARGET_S390X', + 'TARGET_MIPS' ] } } ## # @query-cpu-definitions: @@ -336,8 +336,8 @@ # Since: 1.2 ## { 'command': 'query-cpu-definitions', 'returns': ['CpuDefinitionInfo'], - 'if': { 'any': [ 'defined(TARGET_PPC)', - 'defined(TARGET_ARM)', - 'defined(TARGET_I386)', - 'defined(TARGET_S390X)', - 'defined(TARGET_MIPS)' ] } } + 'if': { 'any': [ 'TARGET_PPC', + 'TARGET_ARM', + 'TARGET_I386', + 'TARGET_S390X', + 'TARGET_MIPS' ] } } diff --git a/qapi/migration.json b/qapi/migration.json index 7a5bdf9a0d..44d8c90405 100644 --- a/qapi/migration.json +++ b/qapi/migration.json @@ -533,7 +533,7 @@ ## { 'enum': 'MultiFDCompression', 'data': [ 'none', 'zlib', - { 'name': 'zstd', 'if': 'defined(CONFIG_ZSTD)' } ] } + { 'name': 'zstd', 'if': 'CONFIG_ZSTD' } ] } ## # @BitmapMigrationBitmapAliasTransform: @@ -1562,7 +1562,7 @@ ## { 'command': 'xen-set-replication', 'data': { 'enable': 'bool', 'primary': 'bool', '*failover' : 'bool' }, - 'if': 'defined(CONFIG_REPLICATION)' } + 'if': 'CONFIG_REPLICATION' } ## # @ReplicationStatus: @@ -1578,7 +1578,7 @@ ## { 'struct': 'ReplicationStatus', 'data': { 'error': 'bool', '*desc': 'str' }, - 'if': 'defined(CONFIG_REPLICATION)' } + 'if': 'CONFIG_REPLICATION' } ## # @query-xen-replication-status: @@ -1596,7 +1596,7 @@ ## { 'command': 'query-xen-replication-status', 'returns': 'ReplicationStatus', - 'if': 'defined(CONFIG_REPLICATION)' } + 'if': 'CONFIG_REPLICATION' } ## # @xen-colo-do-checkpoint: @@ -1613,7 +1613,7 @@ # Since: 2.9 ## { 'command': 'xen-colo-do-checkpoint', - 'if': 'defined(CONFIG_REPLICATION)' } + 'if': 'CONFIG_REPLICATION' } ## # @COLOStatus: diff --git a/qapi/misc-target.json b/qapi/misc-target.json index 9e2ea4a04a..3b05ad3dbf 100644 --- a/qapi/misc-target.json +++ b/qapi/misc-target.json @@ -23,17 +23,17 @@ ## { 'event': 'RTC_CHANGE', 'data': { 'offset': 'int' }, - 'if': { 'any': [ 'defined(TARGET_ALPHA)', - 'defined(TARGET_ARM)', - 'defined(TARGET_HPPA)', - 'defined(TARGET_I386)', - 'defined(TARGET_MIPS)', - 'defined(TARGET_MIPS64)', - 'defined(TARGET_PPC)', - 'defined(TARGET_PPC64)', - 'defined(TARGET_S390X)', - 'defined(TARGET_SH4)', - 'defined(TARGET_SPARC)' ] } } + 'if': { 'any': [ 'TARGET_ALPHA', + 'TARGET_ARM', + 'TARGET_HPPA', + 'TARGET_I386', + 'TARGET_MIPS', + 'TARGET_MIPS64', + 'TARGET_PPC', + 'TARGET_PPC64', + 'TARGET_S390X', + 'TARGET_SH4', + 'TARGET_SPARC' ] } } ## # @rtc-reset-reinjection: @@ -52,7 +52,7 @@ # ## { 'command': 'rtc-reset-reinjection', - 'if': 'defined(TARGET_I386)' } + 'if': 'TARGET_I386' } ## @@ -79,7 +79,7 @@ { 'enum': 'SevState', 'data': ['uninit', 'launch-update', 'launch-secret', 'running', 'send-update', 'receive-update' ], - 'if': 'defined(TARGET_I386)' } + 'if': 'TARGET_I386' } ## # @SevInfo: @@ -111,7 +111,7 @@ 'state' : 'SevState', 'handle' : 'uint32' }, - 'if': 'defined(TARGET_I386)' + 'if': 'TARGET_I386' } ## @@ -132,7 +132,7 @@ # ## { 'command': 'query-sev', 'returns': 'SevInfo', - 'if': 'defined(TARGET_I386)' } + 'if': 'TARGET_I386' } ## @@ -146,7 +146,7 @@ # ## { 'struct': 'SevLaunchMeasureInfo', 'data': {'data': 'str'}, - 'if': 'defined(TARGET_I386)' } + 'if': 'TARGET_I386' } ## # @query-sev-launch-measure: @@ -164,7 +164,7 @@ # ## { 'command': 'query-sev-launch-measure', 'returns': 'SevLaunchMeasureInfo', - 'if': 'defined(TARGET_I386)' } + 'if': 'TARGET_I386' } ## @@ -189,7 +189,7 @@ 'cert-chain': 'str', 'cbitpos': 'int', 'reduced-phys-bits': 'int'}, - 'if': 'defined(TARGET_I386)' } + 'if': 'TARGET_I386' } ## # @query-sev-capabilities: @@ -209,7 +209,7 @@ # ## { 'command': 'query-sev-capabilities', 'returns': 'SevCapability', - 'if': 'defined(TARGET_I386)' } + 'if': 'TARGET_I386' } ## # @sev-inject-launch-secret: @@ -227,7 +227,7 @@ ## { 'command': 'sev-inject-launch-secret', 'data': { 'packet-header': 'str', 'secret': 'str', '*gpa': 'uint64' }, - 'if': 'defined(TARGET_I386)' } + 'if': 'TARGET_I386' } ## # @dump-skeys: @@ -249,7 +249,7 @@ ## { 'command': 'dump-skeys', 'data': { 'filename': 'str' }, - 'if': 'defined(TARGET_S390X)' } + 'if': 'TARGET_S390X' } ## # @GICCapability: @@ -274,7 +274,7 @@ 'data': { 'version': 'int', 'emulated': 'bool', 'kernel': 'bool' }, - 'if': 'defined(TARGET_ARM)' } + 'if': 'TARGET_ARM' } ## # @query-gic-capabilities: @@ -294,7 +294,7 @@ # ## { 'command': 'query-gic-capabilities', 'returns': ['GICCapability'], - 'if': 'defined(TARGET_ARM)' } + 'if': 'TARGET_ARM' } ## @@ -310,7 +310,7 @@ ## { 'struct': 'SevAttestationReport', 'data': { 'data': 'str'}, - 'if': 'defined(TARGET_I386)' } + 'if': 'TARGET_I386' } ## # @query-sev-attestation-report: @@ -332,4 +332,4 @@ ## { 'command': 'query-sev-attestation-report', 'data': { 'mnonce': 'str' }, 'returns': 'SevAttestationReport', - 'if': 'defined(TARGET_I386)' } + 'if': 'TARGET_I386' } diff --git a/qapi/qom.json b/qapi/qom.json index f7ef30f940..5577fa4868 100644 --- a/qapi/qom.json +++ b/qapi/qom.json @@ -603,7 +603,7 @@ 'data': { '*align': 'size', '*discard-data': 'bool', 'mem-path': 'str', - '*pmem': { 'type': 'bool', 'if': 'defined(CONFIG_LIBPMEM)' }, + '*pmem': { 'type': 'bool', 'if': 'CONFIG_LIBPMEM' }, '*readonly': 'bool' } } ## @@ -767,7 +767,7 @@ 'cryptodev-backend', 'cryptodev-backend-builtin', { 'name': 'cryptodev-vhost-user', - 'if': 'defined(CONFIG_VHOST_CRYPTO)' }, + 'if': 'CONFIG_VHOST_CRYPTO' }, 'dbus-vmstate', 'filter-buffer', 'filter-dump', @@ -780,7 +780,7 @@ 'iothread', 'memory-backend-file', { 'name': 'memory-backend-memfd', - 'if': 'defined(CONFIG_LINUX)' }, + 'if': 'CONFIG_LINUX' }, 'memory-backend-ram', 'pef-guest', 'pr-manager-helper', @@ -825,7 +825,7 @@ 'cryptodev-backend': 'CryptodevBackendProperties', 'cryptodev-backend-builtin': 'CryptodevBackendProperties', 'cryptodev-vhost-user': { 'type': 'CryptodevVhostUserProperties', - 'if': 'defined(CONFIG_VHOST_CRYPTO)' }, + 'if': 'CONFIG_VHOST_CRYPTO' }, 'dbus-vmstate': 'DBusVMStateProperties', 'filter-buffer': 'FilterBufferProperties', 'filter-dump': 'FilterDumpProperties', @@ -838,7 +838,7 @@ 'iothread': 'IothreadProperties', 'memory-backend-file': 'MemoryBackendFileProperties', 'memory-backend-memfd': { 'type': 'MemoryBackendMemfdProperties', - 'if': 'defined(CONFIG_LINUX)' }, + 'if': 'CONFIG_LINUX' }, 'memory-backend-ram': 'MemoryBackendProperties', 'pr-manager-helper': 'PrManagerHelperProperties', 'qtest': 'QtestProperties', diff --git a/qapi/sockets.json b/qapi/sockets.json index 2e83452797..a0c08aa4ba 100644 --- a/qapi/sockets.json +++ b/qapi/sockets.json @@ -86,8 +86,8 @@ { 'struct': 'UnixSocketAddress', 'data': { 'path': 'str', - '*abstract': { 'type': 'bool', 'if': 'defined(CONFIG_LINUX)' }, - '*tight': { 'type': 'bool', 'if': 'defined(CONFIG_LINUX)' } } } + '*abstract': { 'type': 'bool', 'if': 'CONFIG_LINUX' }, + '*tight': { 'type': 'bool', 'if': 'CONFIG_LINUX' } } } ## # @VsockSocketAddress: diff --git a/qapi/ui.json b/qapi/ui.json index 1052ca9c38..ec29a66c9f 100644 --- a/qapi/ui.json +++ b/qapi/ui.json @@ -123,7 +123,7 @@ 'data': { 'host': 'str', 'port': 'str', 'family': 'NetworkAddressFamily' }, - 'if': 'defined(CONFIG_SPICE)' } + 'if': 'CONFIG_SPICE' } ## # @SpiceServerInfo: @@ -137,7 +137,7 @@ { 'struct': 'SpiceServerInfo', 'base': 'SpiceBasicInfo', 'data': { '*auth': 'str' }, - 'if': 'defined(CONFIG_SPICE)' } + 'if': 'CONFIG_SPICE' } ## # @SpiceChannel: @@ -163,7 +163,7 @@ 'base': 'SpiceBasicInfo', 'data': {'connection-id': 'int', 'channel-type': 'int', 'channel-id': 'int', 'tls': 'bool'}, - 'if': 'defined(CONFIG_SPICE)' } + 'if': 'CONFIG_SPICE' } ## # @SpiceQueryMouseMode: @@ -183,7 +183,7 @@ ## { 'enum': 'SpiceQueryMouseMode', 'data': [ 'client', 'server', 'unknown' ], - 'if': 'defined(CONFIG_SPICE)' } + 'if': 'CONFIG_SPICE' } ## # @SpiceInfo: @@ -222,7 +222,7 @@ 'data': {'enabled': 'bool', 'migrated': 'bool', '*host': 'str', '*port': 'int', '*tls-port': 'int', '*auth': 'str', '*compiled-version': 'str', 'mouse-mode': 'SpiceQueryMouseMode', '*channels': ['SpiceChannel']}, - 'if': 'defined(CONFIG_SPICE)' } + 'if': 'CONFIG_SPICE' } ## # @query-spice: @@ -268,7 +268,7 @@ # ## { 'command': 'query-spice', 'returns': 'SpiceInfo', - 'if': 'defined(CONFIG_SPICE)' } + 'if': 'CONFIG_SPICE' } ## # @SPICE_CONNECTED: @@ -294,7 +294,7 @@ { 'event': 'SPICE_CONNECTED', 'data': { 'server': 'SpiceBasicInfo', 'client': 'SpiceBasicInfo' }, - 'if': 'defined(CONFIG_SPICE)' } + 'if': 'CONFIG_SPICE' } ## # @SPICE_INITIALIZED: @@ -323,7 +323,7 @@ { 'event': 'SPICE_INITIALIZED', 'data': { 'server': 'SpiceServerInfo', 'client': 'SpiceChannel' }, - 'if': 'defined(CONFIG_SPICE)' } + 'if': 'CONFIG_SPICE' } ## # @SPICE_DISCONNECTED: @@ -349,7 +349,7 @@ { 'event': 'SPICE_DISCONNECTED', 'data': { 'server': 'SpiceBasicInfo', 'client': 'SpiceBasicInfo' }, - 'if': 'defined(CONFIG_SPICE)' } + 'if': 'CONFIG_SPICE' } ## # @SPICE_MIGRATE_COMPLETED: @@ -365,7 +365,7 @@ # ## { 'event': 'SPICE_MIGRATE_COMPLETED', - 'if': 'defined(CONFIG_SPICE)' } + 'if': 'CONFIG_SPICE' } ## # == VNC @@ -393,7 +393,7 @@ 'service': 'str', 'family': 'NetworkAddressFamily', 'websocket': 'bool' }, - 'if': 'defined(CONFIG_VNC)' } + 'if': 'CONFIG_VNC' } ## # @VncServerInfo: @@ -408,7 +408,7 @@ { 'struct': 'VncServerInfo', 'base': 'VncBasicInfo', 'data': { '*auth': 'str' }, - 'if': 'defined(CONFIG_VNC)' } + 'if': 'CONFIG_VNC' } ## # @VncClientInfo: @@ -426,7 +426,7 @@ { 'struct': 'VncClientInfo', 'base': 'VncBasicInfo', 'data': { '*x509_dname': 'str', '*sasl_username': 'str' }, - 'if': 'defined(CONFIG_VNC)' } + 'if': 'CONFIG_VNC' } ## # @VncInfo: @@ -469,7 +469,7 @@ 'data': {'enabled': 'bool', '*host': 'str', '*family': 'NetworkAddressFamily', '*service': 'str', '*auth': 'str', '*clients': ['VncClientInfo']}, - 'if': 'defined(CONFIG_VNC)' } + 'if': 'CONFIG_VNC' } ## # @VncPrimaryAuth: @@ -481,7 +481,7 @@ { 'enum': 'VncPrimaryAuth', 'data': [ 'none', 'vnc', 'ra2', 'ra2ne', 'tight', 'ultra', 'tls', 'vencrypt', 'sasl' ], - 'if': 'defined(CONFIG_VNC)' } + 'if': 'CONFIG_VNC' } ## # @VncVencryptSubAuth: @@ -496,7 +496,7 @@ 'tls-vnc', 'x509-vnc', 'tls-plain', 'x509-plain', 'tls-sasl', 'x509-sasl' ], - 'if': 'defined(CONFIG_VNC)' } + 'if': 'CONFIG_VNC' } ## # @VncServerInfo2: @@ -514,7 +514,7 @@ 'base': 'VncBasicInfo', 'data': { 'auth' : 'VncPrimaryAuth', '*vencrypt' : 'VncVencryptSubAuth' }, - 'if': 'defined(CONFIG_VNC)' } + 'if': 'CONFIG_VNC' } ## # @VncInfo2: @@ -547,7 +547,7 @@ 'auth' : 'VncPrimaryAuth', '*vencrypt' : 'VncVencryptSubAuth', '*display' : 'str' }, - 'if': 'defined(CONFIG_VNC)' } + 'if': 'CONFIG_VNC' } ## # @query-vnc: @@ -579,7 +579,7 @@ # ## { 'command': 'query-vnc', 'returns': 'VncInfo', - 'if': 'defined(CONFIG_VNC)' } + 'if': 'CONFIG_VNC' } ## # @query-vnc-servers: # @@ -590,7 +590,7 @@ # Since: 2.3 ## { 'command': 'query-vnc-servers', 'returns': ['VncInfo2'], - 'if': 'defined(CONFIG_VNC)' } + 'if': 'CONFIG_VNC' } ## # @change-vnc-password: @@ -606,7 +606,7 @@ ## { 'command': 'change-vnc-password', 'data': { 'password': 'str' }, - 'if': 'defined(CONFIG_VNC)' } + 'if': 'CONFIG_VNC' } ## # @VNC_CONNECTED: @@ -636,7 +636,7 @@ { 'event': 'VNC_CONNECTED', 'data': { 'server': 'VncServerInfo', 'client': 'VncBasicInfo' }, - 'if': 'defined(CONFIG_VNC)' } + 'if': 'CONFIG_VNC' } ## # @VNC_INITIALIZED: @@ -664,7 +664,7 @@ { 'event': 'VNC_INITIALIZED', 'data': { 'server': 'VncServerInfo', 'client': 'VncClientInfo' }, - 'if': 'defined(CONFIG_VNC)' } + 'if': 'CONFIG_VNC' } ## # @VNC_DISCONNECTED: @@ -691,7 +691,7 @@ { 'event': 'VNC_DISCONNECTED', 'data': { 'server': 'VncServerInfo', 'client': 'VncClientInfo' }, - 'if': 'defined(CONFIG_VNC)' } + 'if': 'CONFIG_VNC' } ## # = Input diff --git a/qga/qapi-schema.json b/qga/qapi-schema.json index fb17eebde3..c60f5e669d 100644 --- a/qga/qapi-schema.json +++ b/qga/qapi-schema.json @@ -1380,7 +1380,7 @@ 'data': { 'keys': ['str'] }, - 'if': 'defined(CONFIG_POSIX)' } + 'if': 'CONFIG_POSIX' } ## @@ -1398,7 +1398,7 @@ { 'command': 'guest-ssh-get-authorized-keys', 'data': { 'username': 'str' }, 'returns': 'GuestAuthorizedKeys', - 'if': 'defined(CONFIG_POSIX)' } + 'if': 'CONFIG_POSIX' } ## # @guest-ssh-add-authorized-keys: @@ -1416,7 +1416,7 @@ ## { 'command': 'guest-ssh-add-authorized-keys', 'data': { 'username': 'str', 'keys': ['str'], '*reset': 'bool' }, - 'if': 'defined(CONFIG_POSIX)' } + 'if': 'CONFIG_POSIX' } ## # @guest-ssh-remove-authorized-keys: @@ -1434,4 +1434,4 @@ ## { 'command': 'guest-ssh-remove-authorized-keys', 'data': { 'username': 'str', 'keys': ['str'] }, - 'if': 'defined(CONFIG_POSIX)' } + 'if': 'CONFIG_POSIX' } diff --git a/scripts/qapi/common.py b/scripts/qapi/common.py index 1d929cbeec..e6422b1e22 100644 --- a/scripts/qapi/common.py +++ b/scripts/qapi/common.py @@ -231,7 +231,7 @@ def __init__(self, option: str): self.option = option def cgen(self) -> str: - return self.option + return f"defined({self.option})" def docgen(self) -> str: return self.option diff --git a/scripts/qapi/expr.py b/scripts/qapi/expr.py index 60ffe9ef03..31adbe045b 100644 --- a/scripts/qapi/expr.py +++ b/scripts/qapi/expr.py @@ -283,10 +283,10 @@ def check_if(expr: _JSONObject, info: QAPISourceInfo, source: str) -> None: def normalize(cond: Union[str, object]) -> Union[str, object]: if isinstance(cond, str): - if not cond.strip(): + if not cond.isidentifier(): raise QAPISemError( info, - "'if' condition '%s' of %s makes no sense" + "'if' condition '%s' of %s is not a valid identifier" % (cond, source)) return cond if not isinstance(cond, dict): diff --git a/tests/qapi-schema/alternate-branch-if-invalid.err b/tests/qapi-schema/alternate-branch-if-invalid.err index d384929c51..03bad877a3 100644 --- a/tests/qapi-schema/alternate-branch-if-invalid.err +++ b/tests/qapi-schema/alternate-branch-if-invalid.err @@ -1,2 +1,2 @@ alternate-branch-if-invalid.json: In alternate 'Alt': -alternate-branch-if-invalid.json:2: 'if' condition ' ' of 'data' member 'branch' makes no sense +alternate-branch-if-invalid.json:2: 'if' condition ' ' of 'data' member 'branch' is not a valid identifier diff --git a/tests/qapi-schema/bad-if-empty.err b/tests/qapi-schema/bad-if-empty.err index a0f3effefb..5208f543ce 100644 --- a/tests/qapi-schema/bad-if-empty.err +++ b/tests/qapi-schema/bad-if-empty.err @@ -1,2 +1,2 @@ bad-if-empty.json: In struct 'TestIfStruct': -bad-if-empty.json:2: 'if' condition '' of struct makes no sense +bad-if-empty.json:2: 'if' condition '' of struct is not a valid identifier diff --git a/tests/qapi-schema/bad-if-list.err b/tests/qapi-schema/bad-if-list.err index c462f11b90..fa01894d03 100644 --- a/tests/qapi-schema/bad-if-list.err +++ b/tests/qapi-schema/bad-if-list.err @@ -1,2 +1,2 @@ bad-if-list.json: In struct 'TestIfStruct': -bad-if-list.json:2: 'if' condition ' ' of struct makes no sense +bad-if-list.json:2: 'if' condition ' ' of struct is not a valid identifier diff --git a/tests/qapi-schema/bad-if.json b/tests/qapi-schema/bad-if.json index 3edd1a0bf2..67818888de 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': { 'value': 'TEST_IF_STRUCT' } } diff --git a/tests/qapi-schema/doc-good.json b/tests/qapi-schema/doc-good.json index 423ea23e07..ae531e89b5 100644 --- a/tests/qapi-schema/doc-good.json +++ b/tests/qapi-schema/doc-good.json @@ -61,9 +61,9 @@ # @two is undocumented ## { 'enum': 'Enum', 'data': - [ { 'name': 'one', 'if': 'defined(IFONE)' }, 'two' ], + [ { 'name': 'one', 'if': 'IFONE' }, 'two' ], 'features': [ 'enum-feat' ], - 'if': 'defined(IFCOND)' } + 'if': 'IFCOND' } ## # @Base: @@ -86,7 +86,7 @@ 'features': [ 'variant1-feat' ], 'data': { 'var1': { 'type': 'str', 'features': [ 'member-feat' ], - 'if': 'defined(IFSTR)' } } } + 'if': 'IFSTR' } } } ## # @Variant2: diff --git a/tests/qapi-schema/doc-good.out b/tests/qapi-schema/doc-good.out index 4d951f97ee..53e5981028 100644 --- a/tests/qapi-schema/doc-good.out +++ b/tests/qapi-schema/doc-good.out @@ -12,15 +12,15 @@ enum QType module doc-good.json enum Enum member one - if IfOption('defined(IFONE)') + if IfOption('IFONE') member two - if IfOption('defined(IFCOND)') + if IfOption('IFCOND') feature enum-feat object Base member base1: Enum optional=False object Variant1 member var1: str optional=False - if IfOption('defined(IFSTR)') + if IfOption('IFSTR') feature member-feat feature variant1-feat object Variant2 diff --git a/tests/qapi-schema/doc-good.txt b/tests/qapi-schema/doc-good.txt index 726727af74..27b7ce8799 100644 --- a/tests/qapi-schema/doc-good.txt +++ b/tests/qapi-schema/doc-good.txt @@ -43,7 +43,7 @@ Example: Values ~~~~~~ -"one" (**If: **"defined(IFONE)") +"one" (**If: **"IFONE") The _one_ {and only} "two" @@ -62,7 +62,7 @@ Features If ~~ -"defined(IFCOND)" +"IFCOND" "Base" (Object) @@ -87,7 +87,7 @@ Another paragraph (but no "var": line) Members ~~~~~~~ -"var1": "string" (**If: **"defined(IFSTR)") +"var1": "string" (**If: **"IFSTR") Not documented diff --git a/tests/qapi-schema/features-missing-name.json b/tests/qapi-schema/features-missing-name.json index 2314f97c00..8772c8f7b3 100644 --- a/tests/qapi-schema/features-missing-name.json +++ b/tests/qapi-schema/features-missing-name.json @@ -1,3 +1,3 @@ { 'struct': 'FeatureStruct0', 'data': { 'foo': 'int' }, - 'features': [ { 'if': 'defined(NAMELESS_FEATURES)' } ] } + 'features': [ { 'if': 'NAMELESS_FEATURES' } ] } diff --git a/tests/qapi-schema/qapi-schema-test.json b/tests/qapi-schema/qapi-schema-test.json index a0f09b277e..38b2b29d47 100644 --- a/tests/qapi-schema/qapi-schema-test.json +++ b/tests/qapi-schema/qapi-schema-test.json @@ -222,43 +222,43 @@ { 'struct': 'TestIfStruct', 'data': { 'foo': 'int', - 'bar': { 'type': 'int', 'if': 'defined(TEST_IF_STRUCT_BAR)'} }, - 'if': 'defined(TEST_IF_STRUCT)' } + 'bar': { 'type': 'int', 'if': 'TEST_IF_STRUCT_BAR'} }, + 'if': 'TEST_IF_STRUCT' } { 'enum': 'TestIfEnum', 'data': - [ 'foo', { 'name' : 'bar', 'if': 'defined(TEST_IF_ENUM_BAR)' } ], - 'if': 'defined(TEST_IF_ENUM)' } + [ 'foo', { 'name' : 'bar', 'if': 'TEST_IF_ENUM_BAR' } ], + 'if': 'TEST_IF_ENUM' } { 'union': 'TestIfUnion', 'data': { 'foo': 'TestStruct', - 'union-bar': { 'type': 'str', 'if': 'defined(TEST_IF_UNION_BAR)'} }, - 'if': { 'all': ['defined(TEST_IF_UNION)', 'defined(TEST_IF_STRUCT)'] } } + 'union-bar': { 'type': 'str', 'if': 'TEST_IF_UNION_BAR'} }, + 'if': { 'all': ['TEST_IF_UNION', 'TEST_IF_STRUCT'] } } { 'command': 'test-if-union-cmd', 'data': { 'union-cmd-arg': 'TestIfUnion' }, - 'if': 'defined(TEST_IF_UNION)' } + 'if': 'TEST_IF_UNION' } { 'alternate': 'TestIfAlternate', 'data': { 'foo': 'int', - 'bar': { 'type': 'TestStruct', 'if': 'defined(TEST_IF_ALT_BAR)'} }, - 'if': { 'all': ['defined(TEST_IF_ALT)', 'defined(TEST_IF_STRUCT)'] } } + 'bar': { 'type': 'TestStruct', 'if': 'TEST_IF_ALT_BAR'} }, + 'if': { 'all': ['TEST_IF_ALT', 'TEST_IF_STRUCT'] } } { 'command': 'test-if-alternate-cmd', 'data': { 'alt-cmd-arg': 'TestIfAlternate' }, - 'if': { 'all': ['defined(TEST_IF_ALT)', {'not': 'defined(TEST_IF_NOT_ALT)'}] } } + 'if': { 'all': ['TEST_IF_ALT', {'not': 'TEST_IF_NOT_ALT'}] } } { 'command': 'test-if-cmd', 'data': { 'foo': 'TestIfStruct', - 'bar': { 'type': 'TestIfEnum', 'if': 'defined(TEST_IF_CMD_BAR)' } }, + 'bar': { 'type': 'TestIfEnum', 'if': 'TEST_IF_CMD_BAR' } }, 'returns': 'UserDefThree', - 'if': { 'all': ['defined(TEST_IF_CMD)', 'defined(TEST_IF_STRUCT)'] } } + 'if': { 'all': ['TEST_IF_CMD', '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': { 'all': ['defined(TEST_IF_EVT)', 'defined(TEST_IF_STRUCT)'] } } + 'bar': { 'type': ['TestIfEnum'], 'if': 'TEST_IF_EVT_BAR' } }, + 'if': { 'all': ['TEST_IF_EVT', 'TEST_IF_STRUCT'] } } # test 'features' @@ -280,20 +280,20 @@ { 'struct': 'CondFeatureStruct1', 'data': { 'foo': 'int' }, - 'features': [ { 'name': 'feature1', 'if': 'defined(TEST_IF_FEATURE_1)'} ] } + 'features': [ { 'name': 'feature1', 'if': 'TEST_IF_FEATURE_1'} ] } { 'struct': 'CondFeatureStruct2', 'data': { 'foo': 'int' }, - 'features': [ { 'name': 'feature1', 'if': 'defined(TEST_IF_FEATURE_1)'}, - { 'name': 'feature2', 'if': 'defined(TEST_IF_FEATURE_2)'} ] } + 'features': [ { 'name': 'feature1', 'if': 'TEST_IF_FEATURE_1'}, + { 'name': 'feature2', 'if': 'TEST_IF_FEATURE_2'} ] } { 'struct': 'CondFeatureStruct3', 'data': { 'foo': 'int' }, 'features': [ { 'name': 'feature1', - 'if': { 'all': [ 'defined(TEST_IF_COND_1)', - 'defined(TEST_IF_COND_2)'] } } ] } + 'if': { 'all': [ 'TEST_IF_COND_1', + 'TEST_IF_COND_2'] } } ] } { 'struct': 'CondFeatureStruct4', 'data': { 'foo': 'int' }, - 'features': [ { 'name': 'feature1', 'if': {'any': ['defined(TEST_IF_COND_1)', - 'defined(TEST_IF_COND_2)'] } } ] } + 'features': [ { 'name': 'feature1', 'if': {'any': ['TEST_IF_COND_1', + 'TEST_IF_COND_2'] } } ] } { 'enum': 'FeatureEnum1', 'data': [ 'eins', 'zwei', 'drei' ], @@ -328,14 +328,14 @@ 'features': [ 'feature1', 'feature2' ] } { 'command': 'test-command-cond-features1', - 'features': [ { 'name': 'feature1', 'if': 'defined(TEST_IF_FEATURE_1)'} ] } + 'features': [ { 'name': 'feature1', 'if': 'TEST_IF_FEATURE_1'} ] } { 'command': 'test-command-cond-features2', - 'features': [ { 'name': 'feature1', 'if': 'defined(TEST_IF_FEATURE_1)'}, - { 'name': 'feature2', 'if': 'defined(TEST_IF_FEATURE_2)'} ] } + 'features': [ { 'name': 'feature1', 'if': 'TEST_IF_FEATURE_1'}, + { 'name': 'feature2', 'if': 'TEST_IF_FEATURE_2'} ] } { 'command': 'test-command-cond-features3', 'features': [ { 'name': 'feature1', - 'if': { 'all': [ 'defined(TEST_IF_COND_1)', - 'defined(TEST_IF_COND_2)'] } } ] } + 'if': { 'all': [ 'TEST_IF_COND_1', + '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 dd2f83fbae..52737debad 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 IfOption('defined(TEST_IF_STRUCT_BAR)') - if IfOption('defined(TEST_IF_STRUCT)') + if IfOption('TEST_IF_STRUCT_BAR') + if IfOption('TEST_IF_STRUCT') enum TestIfEnum member foo member bar - if IfOption('defined(TEST_IF_ENUM_BAR)') - if IfOption('defined(TEST_IF_ENUM)') + if IfOption('TEST_IF_ENUM_BAR') + if IfOption('TEST_IF_ENUM') object q_obj_TestStruct-wrapper member data: TestStruct optional=False enum TestIfUnionKind member foo member union-bar - if IfOption('defined(TEST_IF_UNION_BAR)') - if IfAll([IfOption('defined(TEST_IF_UNION)'), IfOption('defined(TEST_IF_STRUCT)')]) + if IfOption('TEST_IF_UNION_BAR') + if IfAll([IfOption('TEST_IF_UNION'), IfOption('TEST_IF_STRUCT')]) object TestIfUnion member type: TestIfUnionKind optional=False tag type case foo: q_obj_TestStruct-wrapper case union-bar: q_obj_str-wrapper - if IfOption('defined(TEST_IF_UNION_BAR)') - if IfAll([IfOption('defined(TEST_IF_UNION)'), IfOption('defined(TEST_IF_STRUCT)')]) + if IfOption('TEST_IF_UNION_BAR') + if IfAll([IfOption('TEST_IF_UNION'), IfOption('TEST_IF_STRUCT')]) object q_obj_test-if-union-cmd-arg member union-cmd-arg: TestIfUnion optional=False - if IfOption('defined(TEST_IF_UNION)') + if IfOption('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 IfOption('defined(TEST_IF_UNION)') + if IfOption('TEST_IF_UNION') alternate TestIfAlternate tag type case foo: int case bar: TestStruct - if IfOption('defined(TEST_IF_ALT_BAR)') - if IfAll([IfOption('defined(TEST_IF_ALT)'), IfOption('defined(TEST_IF_STRUCT)')]) + if IfOption('TEST_IF_ALT_BAR') + if IfAll([IfOption('TEST_IF_ALT'), IfOption('TEST_IF_STRUCT')]) object q_obj_test-if-alternate-cmd-arg member alt-cmd-arg: TestIfAlternate optional=False - if IfAll([IfOption('defined(TEST_IF_ALT)'), IfNot(IfOption('defined(TEST_IF_NOT_ALT)'))]) + if IfAll([IfOption('TEST_IF_ALT'), IfNot(IfOption('TEST_IF_NOT_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 IfAll([IfOption('defined(TEST_IF_ALT)'), IfNot(IfOption('defined(TEST_IF_NOT_ALT)'))]) + if IfAll([IfOption('TEST_IF_ALT'), IfNot(IfOption('TEST_IF_NOT_ALT'))]) object q_obj_test-if-cmd-arg member foo: TestIfStruct optional=False member bar: TestIfEnum optional=False - if IfOption('defined(TEST_IF_CMD_BAR)') - if IfAll([IfOption('defined(TEST_IF_CMD)'), IfOption('defined(TEST_IF_STRUCT)')]) + if IfOption('TEST_IF_CMD_BAR') + if IfAll([IfOption('TEST_IF_CMD'), IfOption('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 IfAll([IfOption('defined(TEST_IF_CMD)'), IfOption('defined(TEST_IF_STRUCT)')]) + if IfAll([IfOption('TEST_IF_CMD'), IfOption('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 IfOption('defined(TEST_IF_ENUM)') + if IfOption('TEST_IF_ENUM') object q_obj_TEST_IF_EVENT-arg member foo: TestIfStruct optional=False member bar: TestIfEnumList optional=False - if IfOption('defined(TEST_IF_EVT_BAR)') - if IfAll([IfOption('defined(TEST_IF_EVT)'), IfOption('defined(TEST_IF_STRUCT)')]) + if IfOption('TEST_IF_EVT_BAR') + if IfAll([IfOption('TEST_IF_EVT'), IfOption('TEST_IF_STRUCT')]) event TEST_IF_EVENT q_obj_TEST_IF_EVENT-arg boxed=False - if IfAll([IfOption('defined(TEST_IF_EVT)'), IfOption('defined(TEST_IF_STRUCT)')]) + if IfAll([IfOption('TEST_IF_EVT'), IfOption('TEST_IF_STRUCT')]) object FeatureStruct0 member foo: int optional=False object FeatureStruct1 @@ -379,21 +379,21 @@ object FeatureStruct4 object CondFeatureStruct1 member foo: int optional=False feature feature1 - if IfOption('defined(TEST_IF_FEATURE_1)') + if IfOption('TEST_IF_FEATURE_1') object CondFeatureStruct2 member foo: int optional=False feature feature1 - if IfOption('defined(TEST_IF_FEATURE_1)') + if IfOption('TEST_IF_FEATURE_1') feature feature2 - if IfOption('defined(TEST_IF_FEATURE_2)') + if IfOption('TEST_IF_FEATURE_2') object CondFeatureStruct3 member foo: int optional=False feature feature1 - if IfAll([IfOption('defined(TEST_IF_COND_1)'), IfOption('defined(TEST_IF_COND_2)')]) + if IfAll([IfOption('TEST_IF_COND_1'), IfOption('TEST_IF_COND_2')]) object CondFeatureStruct4 member foo: int optional=False feature feature1 - if IfAny([IfOption('defined(TEST_IF_COND_1)'), IfOption('defined(TEST_IF_COND_2)')]) + if IfAny([IfOption('TEST_IF_COND_1'), IfOption('TEST_IF_COND_2')]) enum FeatureEnum1 member eins member zwei @@ -434,17 +434,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 IfOption('defined(TEST_IF_FEATURE_1)') + if IfOption('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 IfOption('defined(TEST_IF_FEATURE_1)') + if IfOption('TEST_IF_FEATURE_1') feature feature2 - if IfOption('defined(TEST_IF_FEATURE_2)') + if IfOption('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 IfAll([IfOption('defined(TEST_IF_COND_1)'), IfOption('defined(TEST_IF_COND_2)')]) + if IfAll([IfOption('TEST_IF_COND_1'), IfOption('TEST_IF_COND_2')]) event TEST_EVENT_FEATURES0 FeatureStruct1 boxed=False event TEST_EVENT_FEATURES1 None diff --git a/tests/qapi-schema/union-branch-if-invalid.err b/tests/qapi-schema/union-branch-if-invalid.err index dd4518233e..046187a5b9 100644 --- a/tests/qapi-schema/union-branch-if-invalid.err +++ b/tests/qapi-schema/union-branch-if-invalid.err @@ -1,2 +1,2 @@ union-branch-if-invalid.json: In union 'Uni': -union-branch-if-invalid.json:4: 'if' condition '' of 'data' member 'branch1' makes no sense +union-branch-if-invalid.json:4: 'if' condition '' of 'data' member 'branch1' is not a valid identifier