From nobody Thu Apr 25 02:29:19 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of redhat.com designates 170.10.133.124 as permitted sender) client-ip=170.10.133.124; envelope-from=libvir-list-bounces@redhat.com; helo=us-smtp-delivery-124.mimecast.com; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of redhat.com designates 170.10.133.124 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1633781443; cv=none; d=zohomail.com; s=zohoarc; b=doGWZFU9k0pp5h9Pv0gWsJDWvK6FVdmmIsMkBG7DwzpQtRq15iyCajB3VMNz+aMCpl4UxlpaSpeFae4SWuhHVKs5UU+JhcKLvRG+gTVLSnctAiqN57esx0bd05tU3zcxIbnrjR/svBwds6Ph/XlKPsvY6b0lVTcVqxvTAYsqhiA= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1633781443; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=JDJVDKML8cwkNFZpoP9eXaiNHz/9pMM7hSz57ZlvH00=; b=PuhST7DBOFrFQg9m0T5UmceL9MnJ7oPAnaWU+mRNSu87odkP0nNOr8LDUKB6bviWGf7ngHW+dOXJej0d0NVAkTzD0Xjfkmqrk7fZIcQ+u1KCl1H+gJreKGbeBr32pl0XKpMB0tJY4va7luAeSCnV6iOFNoOzGjR0ddbb920+3CM= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of redhat.com designates 170.10.133.124 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by mx.zohomail.com with SMTPS id 1633781443067836.5621956635856; Sat, 9 Oct 2021 05:10:43 -0700 (PDT) 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-584-56x8CVv8OAufkUjR74mRJA-1; Sat, 09 Oct 2021 08:10:40 -0400 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 EB79910A8E00; Sat, 9 Oct 2021 12:10:35 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by smtp.corp.redhat.com (Postfix) with ESMTPS id C6ADE6091B; Sat, 9 Oct 2021 12:10:35 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 982585A0C7; Sat, 9 Oct 2021 12:10:35 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id 199CACiU030723 for ; Sat, 9 Oct 2021 08:10:12 -0400 Received: by smtp.corp.redhat.com (Postfix) id 8554F60C17; Sat, 9 Oct 2021 12:10:12 +0000 (UTC) Received: from blackfin.pond.sub.org (ovpn-112-14.ams2.redhat.com [10.36.112.14]) by smtp.corp.redhat.com (Postfix) with ESMTPS id BD0B260C05; Sat, 9 Oct 2021 12:09:45 +0000 (UTC) Received: by blackfin.pond.sub.org (Postfix, from userid 1000) id 4719111385C1; Sat, 9 Oct 2021 14:09:44 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1633781442; h=from:from:sender:sender: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:list-id:list-help: list-unsubscribe:list-subscribe:list-post; bh=JDJVDKML8cwkNFZpoP9eXaiNHz/9pMM7hSz57ZlvH00=; b=JhsJQR/ClPztwC6C/2BCJ1qiKoHbAV9qfpdEMgTuGWneILQyzpa5hxwCnhBdCTLLzAnn0q vKywHfIVrpFsDsdKjKkXS8jlLEiydVa3JJ2Ht3FaknWCVHmymNPmfuG9QOVbbp5ZS0byjU 3MH69Mv4ZJ5tc2C1YPgLkoC2Q+4y04c= X-MC-Unique: 56x8CVv8OAufkUjR74mRJA-1 From: Markus Armbruster To: qemu-devel@nongnu.org Subject: [PATCH v2 2/5] qapi: Add feature flags to enum members Date: Sat, 9 Oct 2021 14:09:41 +0200 Message-Id: <20211009120944.2858887-3-armbru@redhat.com> In-Reply-To: <20211009120944.2858887-1-armbru@redhat.com> References: <20211009120944.2858887-1-armbru@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-loop: libvir-list@redhat.com Cc: kwolf@redhat.com, vsementsov@virtuozzo.com, libvir-list@redhat.com, eblake@redhat.com, pkrempa@redhat.com, marcandre.lureau@redhat.com, jsnow@redhat.com, libguestfs@redhat.com X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=libvir-list-bounces@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1633781443579100001 Content-Type: text/plain; charset="utf-8" This is quite similar to commit 84ab008687 "qapi: Add feature flags to struct members", only for enums instead of structs. Special feature flag 'deprecated' is silently ignored there. This is okay only because it will be implemented shortly. Signed-off-by: Markus Armbruster Reviewed-by: Eric Blake --- docs/devel/qapi-code-gen.rst | 4 +++- qapi/compat.json | 2 ++ qapi/introspect.json | 5 ++++- scripts/qapi/expr.py | 3 ++- scripts/qapi/introspect.py | 5 +++-- scripts/qapi/schema.py | 22 +++++++++++++++++-- tests/qapi-schema/doc-good.json | 5 ++++- tests/qapi-schema/doc-good.out | 3 +++ tests/qapi-schema/doc-good.txt | 3 +++ .../qapi-schema/enum-dict-member-unknown.err | 2 +- tests/qapi-schema/qapi-schema-test.json | 3 ++- tests/qapi-schema/qapi-schema-test.out | 1 + tests/qapi-schema/test-qapi.py | 1 + 13 files changed, 49 insertions(+), 10 deletions(-) diff --git a/docs/devel/qapi-code-gen.rst b/docs/devel/qapi-code-gen.rst index b2569de486..00334e9fb8 100644 --- a/docs/devel/qapi-code-gen.rst +++ b/docs/devel/qapi-code-gen.rst @@ -200,7 +200,9 @@ Syntax:: '*if': COND, '*features': FEATURES } ENUM-VALUE =3D STRING - | { 'name': STRING, '*if': COND } + | { 'name': STRING, + '*if': COND, + '*features': FEATURES } =20 Member 'enum' names the enum type. =20 diff --git a/qapi/compat.json b/qapi/compat.json index ae3afc22df..1d2b76f00c 100644 --- a/qapi/compat.json +++ b/qapi/compat.json @@ -42,6 +42,8 @@ # with feature 'deprecated'. We may want to extend it to cover # semantic aspects, CLI, and experimental features. # +# Limitation: not implemented for deprecated enumeration values. +# # @deprecated-input: how to handle deprecated input (default 'accept') # @deprecated-output: how to handle deprecated output (default 'accept') # diff --git a/qapi/introspect.json b/qapi/introspect.json index f806bd7281..4a3b76464e 100644 --- a/qapi/introspect.json +++ b/qapi/introspect.json @@ -163,10 +163,13 @@ # # @name: the member's name, as defined in the QAPI schema. # +# @features: names of features associated with the member, in no +# particular order. +# # Since: 6.2 ## { 'struct': 'SchemaInfoEnumMember', - 'data': { 'name': 'str' } } + 'data': { 'name': 'str', '*features': [ 'str' ] } } =20 ## # @SchemaInfoArray: diff --git a/scripts/qapi/expr.py b/scripts/qapi/expr.py index 819ea6ad97..3cb389e875 100644 --- a/scripts/qapi/expr.py +++ b/scripts/qapi/expr.py @@ -472,7 +472,7 @@ def check_enum(expr: _JSONObject, info: QAPISourceInfo)= -> None: for m in members] for member in members: source =3D "'data' member" - check_keys(member, info, source, ['name'], ['if']) + check_keys(member, info, source, ['name'], ['if', 'features']) member_name =3D member['name'] check_name_is_str(member_name, info, source) source =3D "%s '%s'" % (source, member_name) @@ -483,6 +483,7 @@ def check_enum(expr: _JSONObject, info: QAPISourceInfo)= -> None: permit_upper=3Dpermissive, permit_underscore=3Dpermissive) check_if(member, info, source) + check_features(member.get('features'), info) =20 =20 def check_struct(expr: _JSONObject, info: QAPISourceInfo) -> None: diff --git a/scripts/qapi/introspect.py b/scripts/qapi/introspect.py index 6334546363..67c7d89aae 100644 --- a/scripts/qapi/introspect.py +++ b/scripts/qapi/introspect.py @@ -275,12 +275,13 @@ def _gen_tree(self, name: str, mtype: str, obj: Dict[= str, object], obj['features'] =3D self._gen_features(features) self._trees.append(Annotated(obj, ifcond, comment)) =20 - @staticmethod - def _gen_enum_member(member: QAPISchemaEnumMember + def _gen_enum_member(self, member: QAPISchemaEnumMember ) -> Annotated[SchemaInfoEnumMember]: obj: SchemaInfoEnumMember =3D { 'name': member.name, } + if member.features: + obj['features'] =3D self._gen_features(member.features) return Annotated(obj, member.ifcond) =20 def _gen_object_member(self, member: QAPISchemaObjectTypeMember diff --git a/scripts/qapi/schema.py b/scripts/qapi/schema.py index 004d7095ff..6d5f46509a 100644 --- a/scripts/qapi/schema.py +++ b/scripts/qapi/schema.py @@ -708,6 +708,19 @@ def describe(self, info): class QAPISchemaEnumMember(QAPISchemaMember): role =3D 'value' =20 + def __init__(self, name, info, ifcond=3DNone, features=3DNone): + super().__init__(name, info, ifcond) + for f in features or []: + assert isinstance(f, QAPISchemaFeature) + f.set_defined_in(name) + self.features =3D features or [] + + def connect_doc(self, doc): + super().connect_doc(doc) + if doc: + for f in self.features: + doc.connect_feature(f) + =20 class QAPISchemaFeature(QAPISchemaMember): role =3D 'feature' @@ -980,9 +993,14 @@ def _make_features(self, features, info): QAPISchemaIfCond(f.get('if'))) for f in features] =20 + def _make_enum_member(self, name, ifcond, features, info): + return QAPISchemaEnumMember(name, info, + QAPISchemaIfCond(ifcond), + self._make_features(features, info)) + def _make_enum_members(self, values, info): - return [QAPISchemaEnumMember(v['name'], info, - QAPISchemaIfCond(v.get('if'))) + return [self._make_enum_member(v['name'], v.get('if'), + v.get('features'), info) for v in values] =20 def _make_array_type(self, element_type, info): diff --git a/tests/qapi-schema/doc-good.json b/tests/qapi-schema/doc-good.j= son index 86dc25d2bd..74745fb405 100644 --- a/tests/qapi-schema/doc-good.json +++ b/tests/qapi-schema/doc-good.json @@ -58,11 +58,14 @@ # # Features: # @enum-feat: Also _one_ {and only} +# @enum-member-feat: a member feature # # @two is undocumented ## { 'enum': 'Enum', - 'data': [ { 'name': 'one', 'if': 'IFONE' }, 'two' ], + 'data': [ { 'name': 'one', 'if': 'IFONE', + 'features': [ 'enum-member-feat' ] }, + 'two' ], 'features': [ 'enum-feat' ], 'if': 'IFCOND' } =20 diff --git a/tests/qapi-schema/doc-good.out b/tests/qapi-schema/doc-good.out index 5a324e2627..9dd65b9d92 100644 --- a/tests/qapi-schema/doc-good.out +++ b/tests/qapi-schema/doc-good.out @@ -13,6 +13,7 @@ module doc-good.json enum Enum member one if IFONE + feature enum-member-feat member two if IFCOND feature enum-feat @@ -108,6 +109,8 @@ The _one_ {and only} =20 feature=3Denum-feat Also _one_ {and only} + feature=3Denum-member-feat +a member feature section=3DNone @two is undocumented doc symbol=3DBase diff --git a/tests/qapi-schema/doc-good.txt b/tests/qapi-schema/doc-good.txt index 701402ee5e..b3b76bd43f 100644 --- a/tests/qapi-schema/doc-good.txt +++ b/tests/qapi-schema/doc-good.txt @@ -56,6 +56,9 @@ Features "enum-feat" Also _one_ {and only} =20 +"enum-member-feat" + a member feature + "two" is undocumented =20 =20 diff --git a/tests/qapi-schema/enum-dict-member-unknown.err b/tests/qapi-sc= hema/enum-dict-member-unknown.err index f8617ea179..235cde0c49 100644 --- a/tests/qapi-schema/enum-dict-member-unknown.err +++ b/tests/qapi-schema/enum-dict-member-unknown.err @@ -1,3 +1,3 @@ enum-dict-member-unknown.json: In enum 'MyEnum': enum-dict-member-unknown.json:2: 'data' member has unknown key 'bad-key' -Valid keys are 'if', 'name'. +Valid keys are 'features', 'if', 'name'. diff --git a/tests/qapi-schema/qapi-schema-test.json b/tests/qapi-schema/qa= pi-schema-test.json index 2ec50109cb..b677ab861d 100644 --- a/tests/qapi-schema/qapi-schema-test.json +++ b/tests/qapi-schema/qapi-schema-test.json @@ -301,7 +301,8 @@ 'TEST_IF_COND_2'] } } ] } =20 { 'enum': 'FeatureEnum1', - 'data': [ 'eins', 'zwei', 'drei' ], + 'data': [ 'eins', 'zwei', + { 'name': 'drei', 'features': [ 'deprecated' ] } ], 'features': [ 'feature1' ] } =20 { 'union': 'FeatureUnion1', diff --git a/tests/qapi-schema/qapi-schema-test.out b/tests/qapi-schema/qap= i-schema-test.out index 9337adc9ea..16846dbeb8 100644 --- a/tests/qapi-schema/qapi-schema-test.out +++ b/tests/qapi-schema/qapi-schema-test.out @@ -341,6 +341,7 @@ enum FeatureEnum1 member eins member zwei member drei + feature deprecated feature feature1 object q_obj_FeatureUnion1-base member tag: FeatureEnum1 optional=3DFalse diff --git a/tests/qapi-schema/test-qapi.py b/tests/qapi-schema/test-qapi.py index c717a7a90b..2160cef082 100755 --- a/tests/qapi-schema/test-qapi.py +++ b/tests/qapi-schema/test-qapi.py @@ -37,6 +37,7 @@ def visit_enum_type(self, name, info, ifcond, features, m= embers, prefix): for m in members: print(' member %s' % m.name) self._print_if(m.ifcond, indent=3D8) + self._print_features(m.features, indent=3D8) self._print_if(ifcond) self._print_features(features) =20 --=20 2.31.1