From patchwork Sat Dec 8 11:15:55 2018 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: 1009786 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 43BnBH5hCVz9s8r for ; Sat, 8 Dec 2018 22:27:34 +1100 (AEDT) Received: from localhost ([::1]:50391 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gVale-0007O0-Su for incoming@patchwork.ozlabs.org; Sat, 08 Dec 2018 06:27:30 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:60019) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gVace-00059Y-RZ for qemu-devel@nongnu.org; Sat, 08 Dec 2018 06:18:13 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gVacd-0004F6-TR for qemu-devel@nongnu.org; Sat, 08 Dec 2018 06:18:12 -0500 Received: from mx1.redhat.com ([209.132.183.28]:36506) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gVacd-0004Ey-Jq for qemu-devel@nongnu.org; Sat, 08 Dec 2018 06:18:11 -0500 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id EE881307CDFF; Sat, 8 Dec 2018 11:18:10 +0000 (UTC) Received: from localhost (unknown [10.36.112.11]) by smtp.corp.redhat.com (Postfix) with ESMTP id 5DC4980F6; Sat, 8 Dec 2018 11:18:07 +0000 (UTC) From: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= To: qemu-devel@nongnu.org Date: Sat, 8 Dec 2018 15:15:55 +0400 Message-Id: <20181208111606.8505-17-marcandre.lureau@redhat.com> In-Reply-To: <20181208111606.8505-1-marcandre.lureau@redhat.com> References: <20181208111606.8505-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.49]); Sat, 08 Dec 2018 11:18:11 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH for-4.0 v7 16/27] qapi: add 'if' to union members X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , armbru@redhat.com, Michael Roth Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Add 'if' key to union members: { 'union': 'TestIfUnion', 'data': 'mem': { 'type': 'str', 'if': 'COND'} } The generated code remains unconditional for now. Later patches generate the conditionals. Signed-off-by: Marc-André Lureau Reviewed-by: Markus Armbruster --- scripts/qapi/common.py | 17 +++++++++-------- docs/devel/qapi-code-gen.txt | 2 +- tests/qapi-schema/qapi-schema-test.json | 4 +++- tests/qapi-schema/qapi-schema-test.out | 4 ++++ tests/qapi-schema/test-qapi.py | 1 + 5 files changed, 18 insertions(+), 10 deletions(-) diff --git a/scripts/qapi/common.py b/scripts/qapi/common.py index f79b3fad54..fd622313cb 100644 --- a/scripts/qapi/common.py +++ b/scripts/qapi/common.py @@ -823,7 +823,7 @@ def check_union(expr, info): check_name(info, "Member of union '%s'" % name, key) if isinstance(value, dict): check_known_keys(info, "member '%s' of union '%s'" % (key, name), - value, ['type'], []) + value, ['type'], ['if']) typ = value['type'] else: typ = value @@ -1513,8 +1513,8 @@ class QAPISchemaObjectTypeVariants(object): class QAPISchemaObjectTypeVariant(QAPISchemaObjectTypeMember): role = 'branch' - def __init__(self, name, typ): - QAPISchemaObjectTypeMember.__init__(self, name, typ, False) + def __init__(self, name, typ, ifcond=None): + QAPISchemaObjectTypeMember.__init__(self, name, typ, False, ifcond) class QAPISchemaAlternateType(QAPISchemaType): @@ -1796,14 +1796,14 @@ class QAPISchema(object): def _make_variant(self, case, typ): return QAPISchemaObjectTypeVariant(case, typ) - def _make_simple_variant(self, case, typ, info): + def _make_simple_variant(self, case, typ, ifcond, info): if isinstance(typ, list): assert len(typ) == 1 typ = self._make_array_type(typ[0], info) typ = self._make_implicit_object_type( typ, info, None, self.lookup_type(typ), 'wrapper', [self._make_member('data', typ, None, info)]) - return QAPISchemaObjectTypeVariant(case, typ) + return QAPISchemaObjectTypeVariant(case, typ, ifcond) def _def_union_type(self, expr, info, doc): name = expr['union'] @@ -1821,10 +1821,11 @@ class QAPISchema(object): for (key, value) in data.items()] members = [] else: - variants = [self._make_simple_variant(key, value['type'], info) + variants = [self._make_simple_variant(key, value['type'], + value.get('if'), info) for (key, value) in data.items()] - typ = self._make_implicit_enum_type(name, info, ifcond, - [v.name 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', typ, False) members = [tag_member] self._def_entity( diff --git a/docs/devel/qapi-code-gen.txt b/docs/devel/qapi-code-gen.txt index e6fff32241..6f2457a2e0 100644 --- a/docs/devel/qapi-code-gen.txt +++ b/docs/devel/qapi-code-gen.txt @@ -754,7 +754,7 @@ gets its generated code guarded like this: Where a member can be defined with a single string value for its type, it is also possible to supply a dictionary instead with both 'type' -and 'if' keys. (TODO: union and alternate) +and 'if' keys. (TODO: alternate) Example: a conditional 'bar' member diff --git a/tests/qapi-schema/qapi-schema-test.json b/tests/qapi-schema/qapi-schema-test.json index b8565a3913..6e9e4e14d9 100644 --- a/tests/qapi-schema/qapi-schema-test.json +++ b/tests/qapi-schema/qapi-schema-test.json @@ -210,7 +210,9 @@ [ 'foo', { 'name' : 'bar', 'if': 'defined(TEST_IF_ENUM_BAR)' } ], 'if': 'defined(TEST_IF_ENUM)' } -{ 'union': 'TestIfUnion', 'data': { 'foo': 'TestStruct' }, +{ 'union': 'TestIfUnion', 'data': + { 'foo': 'TestStruct', + 'union_bar': { 'type': 'str', 'if': 'defined(TEST_IF_UNION_BAR)'} }, 'if': 'defined(TEST_IF_UNION) && defined(TEST_IF_STRUCT)' } { 'alternate': 'TestIfAlternate', 'data': { 'foo': 'int', 'bar': 'TestStruct' }, diff --git a/tests/qapi-schema/qapi-schema-test.out b/tests/qapi-schema/qapi-schema-test.out index 23fb078b85..a342ecfc55 100644 --- a/tests/qapi-schema/qapi-schema-test.out +++ b/tests/qapi-schema/qapi-schema-test.out @@ -280,11 +280,15 @@ object q_obj_TestStruct-wrapper member data: TestStruct optional=False enum TestIfUnionKind member foo + member union_bar + if ['defined(TEST_IF_UNION_BAR)'] if ['defined(TEST_IF_UNION) && defined(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 ['defined(TEST_IF_UNION_BAR)'] if ['defined(TEST_IF_UNION) && defined(TEST_IF_STRUCT)'] alternate TestIfAlternate tag type diff --git a/tests/qapi-schema/test-qapi.py b/tests/qapi-schema/test-qapi.py index 27081cb50c..d592854601 100644 --- a/tests/qapi-schema/test-qapi.py +++ b/tests/qapi-schema/test-qapi.py @@ -68,6 +68,7 @@ class QAPISchemaTestVisitor(QAPISchemaVisitor): print(' tag %s' % variants.tag_member.name) for v in variants.variants: print(' case %s: %s' % (v.name, v.type.name)) + QAPISchemaTestVisitor._print_if(v.ifcond, indent=8) @staticmethod def _print_if(ifcond, indent=4):