From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-10.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,HTML_MESSAGE,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id EAD4AC4338F for ; Wed, 4 Aug 2021 08:25:40 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id 4A06860F22 for ; Wed, 4 Aug 2021 08:25:40 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 4A06860F22 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=nongnu.org Received: from localhost ([::1]:34396 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mBCDb-0001DE-GL for qemu-devel@archiver.kernel.org; Wed, 04 Aug 2021 04:25:39 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:33640) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mBCBR-00046y-QU for qemu-devel@nongnu.org; Wed, 04 Aug 2021 04:23:26 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]:31534) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mBCBN-00033p-5C for qemu-devel@nongnu.org; Wed, 04 Aug 2021 04:23:25 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1628065400; 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: in-reply-to:in-reply-to:references:references; bh=SZPwbbP8poxAsdY63lnKpxsinDGG2o7suB5/MC5OtDE=; b=V7be1J0hELHHQWwmCCUCPSY98xU6t/9wbhMKWkYkM/ES6qyTUZ0krf6QMOlAL0LwZGqAhj woRGLBr0asiVbfrbwXUtf//iC80eATsYjZ5glqW6E7WFK2w6Tpf3Yj19bkEnoXY5L77bx3 FAUq2Jgb53H7yoQnXEOMK2LjvKhu5O0= Received: from mail-pl1-f197.google.com (mail-pl1-f197.google.com [209.85.214.197]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-546-VACbtCXLP4KlVsj4pddfxA-1; Wed, 04 Aug 2021 04:23:14 -0400 X-MC-Unique: VACbtCXLP4KlVsj4pddfxA-1 Received: by mail-pl1-f197.google.com with SMTP id j5-20020a170902da85b029012c4287ea54so1547351plx.22 for ; Wed, 04 Aug 2021 01:23:14 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=SZPwbbP8poxAsdY63lnKpxsinDGG2o7suB5/MC5OtDE=; b=uVvuobFjxxftMRm3CUGHp5wpbHVWR16eEkWteNqQBqSaRel5UIao0e4hmkDxHc0MRT GqK5ElErsT3DW013W4bn0ePXivAkGtz7yFmznNamfN9jbsntXK/z2Pgb6wDIqzjRKSXb zZstX0CELHtEzA2QECR56BeAjzT0GcsZPMBU3UBe4NY851xoJhH0k8B+rIZ5Y3f5X3qa hC1vVJfHMem83EVishmoiW4NMP0v6JINdCI+viobIGxmWSU9sQY5N1W64N0HLJZK2RhC 5Pt3nJtOHhK7i2OzpJI0XaZ43sRuBE29ghMJlZ5KJ87BkHVrNmD1A3/JIRb4fdFpbG9M i9lg== X-Gm-Message-State: AOAM531esG+sIORSqGOFC9bVChVFZ4sdqCi4TlZg7xsMfattsbe+HCzv GHWNGc+nENC7f6tk6BO70Ov91zlidDujDtkhrEP6B9aIsFXkpCmCwwvL2TJ33UTCVThdXZuAhau 3HTtun0tSGFY3nfLK4is8ddr0nmGB7SE= X-Received: by 2002:a17:90a:e558:: with SMTP id ei24mr26214415pjb.97.1628065393360; Wed, 04 Aug 2021 01:23:13 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyNT3GzZnk0nA62dFnGbyUud8wzAc0HgGnsa2WUZTIvYAMV0w5wSAQo1PiVtNfxKksVctgj09taVUvqziQ6Ywg= X-Received: by 2002:a17:90a:e558:: with SMTP id ei24mr26214398pjb.97.1628065393187; Wed, 04 Aug 2021 01:23:13 -0700 (PDT) MIME-Version: 1.0 References: <20210618102507.3761128-1-marcandre.lureau@redhat.com> <20210618102507.3761128-6-marcandre.lureau@redhat.com> <87pmuvoqek.fsf@dusky.pond.sub.org> In-Reply-To: <87pmuvoqek.fsf@dusky.pond.sub.org> From: =?UTF-8?B?TWFyYy1BbmRyw6kgTHVyZWF1?= Date: Wed, 4 Aug 2021 12:23:01 +0400 Message-ID: Subject: Re: [PATCH v6 05/11] qapi: introduce QAPISchemaIfCond.cgen() To: Markus Armbruster Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=mlureau@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: multipart/alternative; boundary="0000000000006eb58505c8b78375" Received-SPF: pass client-ip=170.10.133.124; envelope-from=mlureau@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -34 X-Spam_score: -3.5 X-Spam_bar: --- X-Spam_report: (-3.5 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.699, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, HTML_MESSAGE=0.001, 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 , John Snow , qemu-devel , Stefan Hajnoczi Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" --0000000000006eb58505c8b78375 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Hi On Mon, Aug 2, 2021 at 6:46 PM Markus Armbruster wrote: > marcandre.lureau@redhat.com writes: > > > From: Marc-Andr=C3=A9 Lureau > > > > Instead of building prepocessor conditions from a list of string, use > > the result generated from QAPISchemaIfCond.cgen() and hide the > > implementation details. > > > > Signed-off-by: Marc-Andr=C3=A9 Lureau > > Please mention that the patch changes generated code. See below for > details. > I'll add Note: this patch introduces a minor regression, generating a redundant pair of parenthesis. This is fixed in a later patch in this series ("qapi: replace if condition list with dict [..]") > > --- > > scripts/qapi/common.py | 35 ++++++++++++++++++++++------------- > > scripts/qapi/gen.py | 4 ++-- > > scripts/qapi/introspect.py | 4 ++-- > > scripts/qapi/schema.py | 5 ++++- > > scripts/qapi/types.py | 20 ++++++++++---------- > > scripts/qapi/visit.py | 12 ++++++------ > > 6 files changed, 46 insertions(+), 34 deletions(-) > > > > diff --git a/scripts/qapi/common.py b/scripts/qapi/common.py > > index 6ad1eeb61d..ba9fe14e4b 100644 > > --- a/scripts/qapi/common.py > > +++ b/scripts/qapi/common.py > > @@ -12,7 +12,12 @@ > > # See the COPYING file in the top-level directory. > > > > import re > > -from typing import Match, Optional, Sequence > > +from typing import ( > > + List, > > + Match, > > + Optional, > > + Union, > > +) > > > > > > #: Magic string that gets removed along with all space to its right. > > @@ -194,22 +199,26 @@ def guardend(name: str) -> str: > > name=3Dc_fname(name).upper()) > > > > > > -def gen_if(ifcond: Sequence[str]) -> str: > > - ret =3D '' > > - for ifc in ifcond: > > - ret +=3D mcgen(''' > > +def cgen_ifcond(ifcond: Union[str, List[str]]) -> str: > > + if not ifcond: > > + return '' > > + return '(' + ') && ('.join(ifcond) + ')' > > + > > + > > +def gen_if(cond: str) -> str: > > + if not cond: > > + return '' > > + return mcgen(''' > > #if %(cond)s > > -''', cond=3Difc) > > - return ret > > +''', cond=3Dcond) > > > > > > -def gen_endif(ifcond: Sequence[str]) -> str: > > - ret =3D '' > > - for ifc in reversed(ifcond): > > - ret +=3D mcgen(''' > > +def gen_endif(cond: str) -> str: > > + if not cond: > > + return '' > > + return mcgen(''' > > #endif /* %(cond)s */ > > -''', cond=3Difc) > > - return ret > > +''', cond=3Dcond) > > > > > > This patch does three things: > > (1) Change gen_if(), gen_endif() to always generate a single #if, > #endif. This enables: > > (2) Factor cgen_ifcond() out of gen_if() and gen_endif() > > (3) Lift the call of cgen_ifcond() into into gen_if()'s, gen_endif()'s > callers. > > I'd split the patch. This is *not* a demand. > > The motivation for (3) is unclear. Is it so gen_if() doesn't depend on > QAPISchemaIfCond? > > Step (1) affects the generated code. When @ifcond is [COND1, COND2, ...]= , > gen_if()'s value changes from > > #if COND1 > #if COND2 > ... > > to > > #if (COND1) && (COND2) > > Example: in tests/test-qapi-introspect.c > > @@ -259,11 +257,9 @@ const QLitObject test_qmp_schema_qlit =3D > QLIT_QDICT(((QLitDictEntry[]) { > { "arg-type", QLIT_QSTR("1"), }, > { "features", QLIT_QLIST(((QLitObject[]) { > -#if defined(TEST_IF_COND_1) > -#if defined(TEST_IF_COND_2) > +#if (defined(TEST_IF_COND_1)) && (defined(TEST_IF_COND_2)) > QLIT_QSTR("feature1"), > -#endif /* defined(TEST_IF_COND_2) */ > -#endif /* defined(TEST_IF_COND_1) */ > +#endif /* (defined(TEST_IF_COND_1)) && (defined(TEST_IF_COND_2)) */ > {} > })), }, > { "meta-type", QLIT_QSTR("command"), }, > > The common case: when it's just [COND], the value changes from > > #if COND > > to > > #if (COND) > > which is a bit ugly. > > Example: in qapi-types-block-export.c > > @@ -76,7 +76,7 @@ const QEnumLookup FuseExportAllowOther_l > .size =3D FUSE_EXPORT_ALLOW_OTHER__MAX > }; > > -#if defined(CONFIG_FUSE) > +#if (defined(CONFIG_FUSE)) > void qapi_free_BlockExportOptionsFuse(BlockExportOptionsFuse *obj) > { > Visitor *v; > @@ -89,7 +89,7 @@ void qapi_free_BlockExportOptionsFuse(Bl > visit_type_BlockExportOptionsFuse(v, NULL, &obj, NULL); > visit_free(v); > } > -#endif /* defined(CONFIG_FUSE) */ > +#endif /* (defined(CONFIG_FUSE)) */ > > void qapi_free_NbdServerAddOptions(NbdServerAddOptions *obj) > { > > Avoiding the redundant pair of parenthesis takes another special case. > Let's do it. > > > 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] =3D=3D '\n': > > out +=3D '\n' > > added =3D added[1:] > > - out +=3D gen_if(ifcond.ifcond) > > + out +=3D gen_if(ifcond.cgen()) > > out +=3D added > > - out +=3D gen_endif(ifcond.ifcond) > > + out +=3D 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 +=3D indent(level) + f"/* {obj.comment} */\n" > > if obj.ifcond: > > - ret +=3D gen_if(obj.ifcond.ifcond) > > + ret +=3D gen_if(obj.ifcond.cgen()) > > ret +=3D _tree_to_qlit(obj.value, level) > > if obj.ifcond: > > - ret +=3D '\n' + gen_endif(obj.ifcond.ifcond) > > + ret +=3D '\n' + gen_endif(obj.ifcond.cgen()) > > return ret > > > > ret =3D '' > > diff --git a/scripts/qapi/schema.py b/scripts/qapi/schema.py > > index c35fa3bf51..70120f0dcc 100644 > > --- a/scripts/qapi/schema.py > > +++ b/scripts/qapi/schema.py > > @@ -19,7 +19,7 @@ > > import re > > from typing import Optional > > > > -from .common import POINTER_SUFFIX, c_name > > +from .common import POINTER_SUFFIX, c_name, cgen_ifcond > > from .error import QAPIError, QAPISemError, QAPISourceError > > from .expr import check_exprs > > from .parser import QAPISchemaParser > > @@ -29,6 +29,9 @@ class QAPISchemaIfCond: > > def __init__(self, ifcond=3DNone): > > self.ifcond =3D ifcond or [] > > > > + def cgen(self): > > + return cgen_ifcond(self.ifcond) > > + > > As far as I can tell, this is only ever used like > > gen_if(obj.ifcond.cgen()) > > and > > gen_endif(obj.ifcond.cgen()) > > Wouldn't > > obj.ifcond.gen_if() > > and > > obj.ifcond.gen_endif() > > be neater? > Yes > Not a demand, since we can get there on top if we want to. > > > def is_present(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=3Dc_name(name)) > > for memb in members: > > - ret +=3D gen_if(memb.ifcond.ifcond) > > + ret +=3D gen_if(memb.ifcond.cgen()) > > index =3D c_enum_const(name, memb.name, prefix) > > ret +=3D mcgen(''' > > [%(index)s] =3D "%(name)s", > > ''', > > index=3Dindex, name=3Dmemb.name) > > - ret +=3D gen_endif(memb.ifcond.ifcond) > > + ret +=3D gen_endif(memb.ifcond.cgen()) > > > > ret +=3D mcgen(''' > > }, > > @@ -81,12 +81,12 @@ def gen_enum(name: str, > > c_name=3Dc_name(name)) > > > > for memb in enum_members: > > - ret +=3D gen_if(memb.ifcond.ifcond) > > + ret +=3D gen_if(memb.ifcond.cgen()) > > ret +=3D mcgen(''' > > %(c_enum)s, > > ''', > > c_enum=3Dc_enum_const(name, memb.name, prefix)) > > - ret +=3D gen_endif(memb.ifcond.ifcond) > > + ret +=3D gen_endif(memb.ifcond.cgen()) > > > > ret +=3D 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 =3D '' > > for memb in members: > > - ret +=3D gen_if(memb.ifcond.ifcond) > > + ret +=3D gen_if(memb.ifcond.cgen()) > > if memb.optional: > > ret +=3D 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=3Dmemb.type.c_type(), c_name=3Dc_name(memb= .name > )) > > - ret +=3D gen_endif(memb.ifcond.ifcond) > > + ret +=3D gen_endif(memb.ifcond.cgen()) > > return ret > > > > > > @@ -159,7 +159,7 @@ def gen_object(name: str, ifcond: QAPISchemaIfCond, > > ret +=3D mcgen(''' > > > > ''') > > - ret +=3D gen_if(ifcond.ifcond) > > + ret +=3D gen_if(ifcond.cgen()) > > ret +=3D mcgen(''' > > struct %(c_name)s { > > ''', > > @@ -193,7 +193,7 @@ def gen_object(name: str, ifcond: QAPISchemaIfCond, > > ret +=3D mcgen(''' > > }; > > ''') > > - ret +=3D gen_endif(ifcond.ifcond) > > + ret +=3D 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 =3D=3D 'q_empty': > > continue > > - ret +=3D gen_if(var.ifcond.ifcond) > > + ret +=3D gen_if(var.ifcond.cgen()) > > ret +=3D mcgen(''' > > %(c_type)s %(c_name)s; > > ''', > > c_type=3Dvar.type.c_unboxed_type(), > > c_name=3Dc_name(var.name)) > > - ret +=3D gen_endif(var.ifcond.ifcond) > > + ret +=3D gen_endif(var.ifcond.cgen()) > > > > ret +=3D 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 =3D 'deprecated' in [f.name for f in memb.features] > > - ret +=3D gen_if(memb.ifcond.ifcond) > > + ret +=3D gen_if(memb.ifcond.cgen()) > > if memb.optional: > > ret +=3D mcgen(''' > > if (visit_optional(v, "%(name)s", &obj->has_%(c_name)s)) { > > @@ -112,7 +112,7 @@ def gen_visit_object_members(name: str, > > ret +=3D mcgen(''' > > } > > ''') > > - ret +=3D gen_endif(memb.ifcond.ifcond) > > + ret +=3D gen_endif(memb.ifcond.cgen()) > > > > if variants: > > tag_member =3D variants.tag_member > > @@ -126,7 +126,7 @@ def gen_visit_object_members(name: str, > > for var in variants.variants: > > case_str =3D c_enum_const(tag_member.type.name, var.name, > > tag_member.type.prefix) > > - ret +=3D gen_if(var.ifcond.ifcond) > > + ret +=3D gen_if(var.ifcond.cgen()) > > if var.type.name =3D=3D 'q_empty': > > # valid variant and nothing to do > > ret +=3D mcgen(''' > > @@ -142,7 +142,7 @@ def gen_visit_object_members(name: str, > > case=3Dcase_str, > > c_type=3Dvar.type.c_name(), c_name=3Dc_na= me( > var.name)) > > > > - ret +=3D gen_endif(var.ifcond.ifcond) > > + ret +=3D gen_endif(var.ifcond.cgen()) > > ret +=3D mcgen(''' > > default: > > abort(); > > @@ -228,7 +228,7 @@ def gen_visit_alternate(name: str, variants: > QAPISchemaVariants) -> str: > > c_name=3Dc_name(name)) > > > > for var in variants.variants: > > - ret +=3D gen_if(var.ifcond.ifcond) > > + ret +=3D gen_if(var.ifcond.cgen()) > > ret +=3D mcgen(''' > > case %(case)s: > > ''', > > @@ -254,7 +254,7 @@ def gen_visit_alternate(name: str, variants: > QAPISchemaVariants) -> str: > > ret +=3D mcgen(''' > > break; > > ''') > > - ret +=3D gen_endif(var.ifcond.ifcond) > > + ret +=3D gen_endif(var.ifcond.cgen()) > > > > ret +=3D mcgen(''' > > case QTYPE_NONE: > > --0000000000006eb58505c8b78375 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
Hi

On Mon, Aug 2, 2021 at 6:46 PM Mark= us Armbruster <ar= mbru@redhat.com> wrote:
marcandre.lureau@redhat.com writes:

> From: Marc-Andr=C3=A9 Lureau <marcandre.lureau@redhat.com>
>
> Instead of building prepocessor conditions from a list of string, use<= br> > the result generated from QAPISchemaIfCond.cgen() and hide the
> implementation details.
>
> Signed-off-by: Marc-Andr=C3=A9 Lureau <marcandre.lureau@redhat.com>
Please mention that the patch changes generated code.=C2=A0 See below for details.

I'll add
=C2=A0 = =C2=A0
=C2=A0 =C2=A0 Note: this patch introduces a minor regression, ge= nerating a redundant
=C2=A0 =C2=A0 pair of parenthesis. This is fixed in= a later patch in this
=C2=A0 =C2=A0 series ("qapi: replace if cond= ition list with dict [..]")


> ---
>=C2=A0 scripts/qapi/common.py=C2=A0 =C2=A0 =C2=A0| 35 +++++++++++++++++= +++++-------------
>=C2=A0 scripts/qapi/gen.py=C2=A0 =C2=A0 =C2=A0 =C2=A0 |=C2=A0 4 ++-- >=C2=A0 scripts/qapi/introspect.py |=C2=A0 4 ++--
>=C2=A0 scripts/qapi/schema.py=C2=A0 =C2=A0 =C2=A0|=C2=A0 5 ++++-
>=C2=A0 scripts/qapi/types.py=C2=A0 =C2=A0 =C2=A0 | 20 ++++++++++-------= ---
>=C2=A0 scripts/qapi/visit.py=C2=A0 =C2=A0 =C2=A0 | 12 ++++++------
>=C2=A0 6 files changed, 46 insertions(+), 34 deletions(-)
>
> diff --git a/scripts/qapi/common.py b/scripts/qapi/common.py
> index 6ad1eeb61d..ba9fe14e4b 100644
> --- a/scripts/qapi/common.py
> +++ b/scripts/qapi/common.py
> @@ -12,7 +12,12 @@
>=C2=A0 # See the COPYING file in the top-level directory.
>=C2=A0
>=C2=A0 import re
> -from typing import Match, Optional, Sequence
> +from typing import (
> +=C2=A0 =C2=A0 List,
> +=C2=A0 =C2=A0 Match,
> +=C2=A0 =C2=A0 Optional,
> +=C2=A0 =C2=A0 Union,
> +)
>=C2=A0
>=C2=A0
>=C2=A0 #: Magic string that gets removed along with all space to its ri= ght.
> @@ -194,22 +199,26 @@ def guardend(name: str) -> str:
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0na= me=3Dc_fname(name).upper())
>=C2=A0
>=C2=A0
> -def gen_if(ifcond: Sequence[str]) -> str:
> -=C2=A0 =C2=A0 ret =3D ''
> -=C2=A0 =C2=A0 for ifc in ifcond:
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 ret +=3D mcgen('''
> +def cgen_ifcond(ifcond: Union[str, List[str]]) -> str:
> +=C2=A0 =C2=A0 if not ifcond:
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 return ''
> +=C2=A0 =C2=A0 return '(' + ') && ('.join(ifco= nd) + ')'
> +
> +
> +def gen_if(cond: str) -> str:
> +=C2=A0 =C2=A0 if not cond:
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 return ''
> +=C2=A0 =C2=A0 return mcgen('''
>=C2=A0 #if %(cond)s
> -''', cond=3Difc)
> -=C2=A0 =C2=A0 return ret
> +''', cond=3Dcond)
>=C2=A0
>=C2=A0
> -def gen_endif(ifcond: Sequence[str]) -> str:
> -=C2=A0 =C2=A0 ret =3D ''
> -=C2=A0 =C2=A0 for ifc in reversed(ifcond):
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 ret +=3D mcgen('''
> +def gen_endif(cond: str) -> str:
> +=C2=A0 =C2=A0 if not cond:
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 return ''
> +=C2=A0 =C2=A0 return mcgen('''
>=C2=A0 #endif /* %(cond)s */
> -''', cond=3Difc)
> -=C2=A0 =C2=A0 return ret
> +''', cond=3Dcond)
>=C2=A0
>=C2=A0

This patch does three things:

(1) Change gen_if(), gen_endif() to always generate a single #if,
=C2=A0 =C2=A0 #endif.=C2=A0 This enables:

(2) Factor cgen_ifcond() out of gen_if() and gen_endif()

(3) Lift the call of cgen_ifcond() into into gen_if()'s, gen_endif()= 9;s
=C2=A0 =C2=A0 callers.

I'd split the patch.=C2=A0 This is *not* a demand.

The motivation for (3) is unclear.=C2=A0 Is it so gen_if() doesn't depe= nd on
QAPISchemaIfCond?

Step (1) affects the generated code.=C2=A0 When @ifcond is [COND1, COND2, .= ..],
gen_if()'s value changes from

=C2=A0 =C2=A0 #if COND1
=C2=A0 =C2=A0 #if COND2
=C2=A0 =C2=A0 ...

to

=C2=A0 =C2=A0 #if (COND1) && (COND2)

Example: in tests/test-qapi-introspect.c

=C2=A0 =C2=A0 @@ -259,11 +257,9 @@ const QLitObject test_qmp_schema_qlit = =3D
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0QLIT_QDICT(((QLitDictEntry[]) {
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0{ "arg-type", QLI= T_QSTR("1"), },
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0{ "features", QLI= T_QLIST(((QLitObject[]) {
=C2=A0 =C2=A0 -#if defined(TEST_IF_COND_1)
=C2=A0 =C2=A0 -#if defined(TEST_IF_COND_2)
=C2=A0 =C2=A0 +#if (defined(TEST_IF_COND_1)) && (defined(TEST_IF_CO= ND_2))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0QLIT_QSTR(&qu= ot;feature1"),
=C2=A0 =C2=A0 -#endif /* defined(TEST_IF_COND_2) */
=C2=A0 =C2=A0 -#endif /* defined(TEST_IF_COND_1) */
=C2=A0 =C2=A0 +#endif /* (defined(TEST_IF_COND_1)) && (defined(TEST= _IF_COND_2)) */
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0{}
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0})), },
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0{ "meta-type", QL= IT_QSTR("command"), },

The common case: when it's just [COND], the value changes from

=C2=A0 =C2=A0 #if COND

to

=C2=A0 =C2=A0 #if (COND)

which is a bit ugly.

Example: in qapi-types-block-export.c

=C2=A0 =C2=A0 @@ -76,7 +76,7 @@ const QEnumLookup FuseExportAllowOther_l =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0.size =3D FUSE_EXPORT_ALLOW_OTHER__MAX =C2=A0 =C2=A0 =C2=A0};

=C2=A0 =C2=A0 -#if defined(CONFIG_FUSE)
=C2=A0 =C2=A0 +#if (defined(CONFIG_FUSE))
=C2=A0 =C2=A0 =C2=A0void qapi_free_BlockExportOptionsFuse(BlockExportOption= sFuse *obj)
=C2=A0 =C2=A0 =C2=A0{
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0Visitor *v;
=C2=A0 =C2=A0 @@ -89,7 +89,7 @@ void qapi_free_BlockExportOptionsFuse(Bl =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0visit_type_BlockExportOptionsFuse(v, NULL= , &obj, NULL);
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0visit_free(v);
=C2=A0 =C2=A0 =C2=A0}
=C2=A0 =C2=A0 -#endif /* defined(CONFIG_FUSE) */
=C2=A0 =C2=A0 +#endif /* (defined(CONFIG_FUSE)) */

=C2=A0 =C2=A0 =C2=A0void qapi_free_NbdServerAddOptions(NbdServerAddOptions = *obj)
=C2=A0 =C2=A0 =C2=A0{

Avoiding the redundant pair of parenthesis takes another special case.
Let's do it.

>=C2=A0 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: s= tr, after: str) -> str:
>=C2=A0 =C2=A0 =C2=A0 if added[0] =3D=3D '\n':
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 out +=3D '\n'
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 added =3D added[1:]
> -=C2=A0 =C2=A0 out +=3D gen_if(ifcond.ifcond)
> +=C2=A0 =C2=A0 out +=3D gen_if(ifcond.cgen())
>=C2=A0 =C2=A0 =C2=A0 out +=3D added
> -=C2=A0 =C2=A0 out +=3D gen_endif(ifcond.ifcond)
> +=C2=A0 =C2=A0 out +=3D gen_endif(ifcond.cgen())
>=C2=A0 =C2=A0 =C2=A0 return out
>=C2=A0
>=C2=A0

> 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:
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if obj.comment:
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ret +=3D indent(level)= + f"/* {obj.comment} */\n"
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if obj.ifcond:
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ret +=3D gen_if(obj.ifcond.= ifcond)
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ret +=3D gen_if(obj.ifcond.= cgen())
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ret +=3D _tree_to_qlit(obj.value, le= vel)
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if obj.ifcond:
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ret +=3D '\n' + gen= _endif(obj.ifcond.ifcond)
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ret +=3D '\n' + gen= _endif(obj.ifcond.cgen())
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return ret
>=C2=A0
>=C2=A0 =C2=A0 =C2=A0 ret =3D ''
> diff --git a/scripts/qapi/schema.py b/scripts/qapi/schema.py
> index c35fa3bf51..70120f0dcc 100644
> --- a/scripts/qapi/schema.py
> +++ b/scripts/qapi/schema.py
> @@ -19,7 +19,7 @@
>=C2=A0 import re
>=C2=A0 from typing import Optional
>=C2=A0
> -from .common import POINTER_SUFFIX, c_name
> +from .common import POINTER_SUFFIX, c_name, cgen_ifcond
>=C2=A0 from .error import QAPIError, QAPISemError, QAPISourceError
>=C2=A0 from .expr import check_exprs
>=C2=A0 from .parser import QAPISchemaParser
> @@ -29,6 +29,9 @@ class QAPISchemaIfCond:
>=C2=A0 =C2=A0 =C2=A0 def __init__(self, ifcond=3DNone):
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 self.ifcond =3D ifcond or []
>=C2=A0
> +=C2=A0 =C2=A0 def cgen(self):
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 return cgen_ifcond(self.ifcond)
> +

As far as I can tell, this is only ever used like

=C2=A0 =C2=A0 =C2=A0 =C2=A0gen_if(obj.ifcond.cgen())

and

=C2=A0 =C2=A0 =C2=A0 =C2=A0gen_endif(obj.ifcond.cgen())

Wouldn't

=C2=A0 =C2=A0 =C2=A0 =C2=A0obj.ifcond.gen_if()

and

=C2=A0 =C2=A0 =C2=A0 =C2=A0obj.ifcond.gen_endif()

be neater?

Yes


Not a demand, since we can get there on top if we want to.

>=C2=A0 =C2=A0 =C2=A0 def is_present(self):
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return bool(self.ifcond)
>=C2=A0
> 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,
>=C2=A0 ''',
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 c_name= =3Dc_name(name))
>=C2=A0 =C2=A0 =C2=A0 for memb in members:
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 ret +=3D gen_if(memb.ifcond.ifcond)
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 ret +=3D gen_if(memb.ifcond.cgen())
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 index =3D c_enum_const(name, memb.name, p= refix)
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ret +=3D mcgen('''
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 [%(index)s] =3D "%(name)s"= ,
>=C2=A0 ''',
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0index=3Dindex, name=3Dmemb.name)
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 ret +=3D gen_endif(memb.ifcond.ifcond) > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 ret +=3D gen_endif(memb.ifcond.cgen()) >=C2=A0
>=C2=A0 =C2=A0 =C2=A0 ret +=3D mcgen('''
>=C2=A0 =C2=A0 =C2=A0 },
> @@ -81,12 +81,12 @@ def gen_enum(name: str,
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 c_name= =3Dc_name(name))
>=C2=A0
>=C2=A0 =C2=A0 =C2=A0 for memb in enum_members:
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 ret +=3D gen_if(memb.ifcond.ifcond)
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 ret +=3D gen_if(memb.ifcond.cgen())
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ret +=3D mcgen('''
>=C2=A0 =C2=A0 =C2=A0 %(c_enum)s,
>=C2=A0 ''',
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0c_enum=3Dc_enum_const(name, memb.name, prefix))
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 ret +=3D gen_endif(memb.ifcond.ifcond) > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 ret +=3D gen_endif(memb.ifcond.cgen()) >=C2=A0
>=C2=A0 =C2=A0 =C2=A0 ret +=3D mcgen('''
>=C2=A0 } %(c_name)s;
> @@ -126,7 +126,7 @@ def gen_array(name: str, element_type: QAPISchemaT= ype) -> str:
>=C2=A0 def gen_struct_members(members: List[QAPISchemaObjectTypeMember]= ) -> str:
>=C2=A0 =C2=A0 =C2=A0 ret =3D ''
>=C2=A0 =C2=A0 =C2=A0 for memb in members:
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 ret +=3D gen_if(memb.ifcond.ifcond)
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 ret +=3D gen_if(memb.ifcond.cgen())
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if memb.optional:
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ret +=3D mcgen('&#= 39;'
>=C2=A0 =C2=A0 =C2=A0 bool has_%(c_name)s;
> @@ -136,7 +136,7 @@ def gen_struct_members(members: List[QAPISchemaObj= ectTypeMember]) -> str:
>=C2=A0 =C2=A0 =C2=A0 %(c_type)s %(c_name)s;
>=C2=A0 ''',
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0c_type=3Dmemb.type.c_type(), c_name=3Dc_name(memb.name))
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 ret +=3D gen_endif(memb.ifcond.ifcond) > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 ret +=3D gen_endif(memb.ifcond.cgen()) >=C2=A0 =C2=A0 =C2=A0 return ret
>=C2=A0
>=C2=A0
> @@ -159,7 +159,7 @@ def gen_object(name: str, ifcond: QAPISchemaIfCond= ,
>=C2=A0 =C2=A0 =C2=A0 ret +=3D mcgen('''
>=C2=A0
>=C2=A0 ''')
> -=C2=A0 =C2=A0 ret +=3D gen_if(ifcond.ifcond)
> +=C2=A0 =C2=A0 ret +=3D gen_if(ifcond.cgen())
>=C2=A0 =C2=A0 =C2=A0 ret +=3D mcgen('''
>=C2=A0 struct %(c_name)s {
>=C2=A0 ''',
> @@ -193,7 +193,7 @@ def gen_object(name: str, ifcond: QAPISchemaIfCond= ,
>=C2=A0 =C2=A0 =C2=A0 ret +=3D mcgen('''
>=C2=A0 };
>=C2=A0 ''')
> -=C2=A0 =C2=A0 ret +=3D gen_endif(ifcond.ifcond)
> +=C2=A0 =C2=A0 ret +=3D gen_endif(ifcond.cgen())
>=C2=A0
>=C2=A0 =C2=A0 =C2=A0 return ret
>=C2=A0
> @@ -220,13 +220,13 @@ def gen_variants(variants: QAPISchemaVariants) -= > str:
>=C2=A0 =C2=A0 =C2=A0 for var in variants.variants:
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if var.type.name =3D=3D 'q_empty&= #39;:
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 continue
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 ret +=3D gen_if(var.ifcond.ifcond)
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 ret +=3D gen_if(var.ifcond.cgen())
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ret +=3D mcgen('''
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 %(c_type)s %(c_name)s;
>=C2=A0 ''',
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0c_type=3Dvar.type.c_unboxed_type(),
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0c_name=3Dc_name(var.name))
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 ret +=3D gen_endif(var.ifcond.ifcond)
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 ret +=3D gen_endif(var.ifcond.cgen())
>=C2=A0
>=C2=A0 =C2=A0 =C2=A0 ret +=3D mcgen('''
>=C2=A0 =C2=A0 =C2=A0 } 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,
>=C2=A0
>=C2=A0 =C2=A0 =C2=A0 for memb in members:
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 deprecated =3D 'deprecated' = in [f.name for f in memb.features]
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 ret +=3D gen_if(memb.ifcond.ifcond)
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 ret +=3D gen_if(memb.ifcond.cgen())
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if memb.optional:
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ret +=3D mcgen('&#= 39;'
>=C2=A0 =C2=A0 =C2=A0 if (visit_optional(v, "%(name)s", &o= bj->has_%(c_name)s)) {
> @@ -112,7 +112,7 @@ def gen_visit_object_members(name: str,
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ret +=3D mcgen('&#= 39;'
>=C2=A0 =C2=A0 =C2=A0 }
>=C2=A0 ''')
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 ret +=3D gen_endif(memb.ifcond.ifcond) > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 ret +=3D gen_endif(memb.ifcond.cgen()) >=C2=A0
>=C2=A0 =C2=A0 =C2=A0 if variants:
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 tag_member =3D variants.tag_member > @@ -126,7 +126,7 @@ def gen_visit_object_members(name: str,
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 for var in variants.variants:
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 case_str =3D c_enum_co= nst(
tag_member.type.name, var.name,
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 tag_member.t= ype.prefix)
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ret +=3D gen_if(var.ifcond.= ifcond)
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ret +=3D gen_if(var.ifcond.= cgen())
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if var.type.name =3D=3D= 'q_empty':
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 # valid = variant and nothing to do
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ret +=3D= mcgen('''
> @@ -142,7 +142,7 @@ def gen_visit_object_members(name: str,
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0case=3Dcase_str,
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0c_type=3Dvar.type.c_name(), c_name= =3Dc_name(= var.name))
>=C2=A0
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ret +=3D gen_endif(var.ifco= nd.ifcond)
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ret +=3D gen_endif(var.ifco= nd.cgen())
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ret +=3D mcgen('''
>=C2=A0 =C2=A0 =C2=A0 default:
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 abort();
> @@ -228,7 +228,7 @@ def gen_visit_alternate(name: str, variants: QAPIS= chemaVariants) -> str:
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 c_name= =3Dc_name(name))
>=C2=A0
>=C2=A0 =C2=A0 =C2=A0 for var in variants.variants:
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 ret +=3D gen_if(var.ifcond.ifcond)
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 ret +=3D gen_if(var.ifcond.cgen())
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ret +=3D mcgen('''
>=C2=A0 =C2=A0 =C2=A0 case %(case)s:
>=C2=A0 ''',
> @@ -254,7 +254,7 @@ def gen_visit_alternate(name: str, variants: QAPIS= chemaVariants) -> str:
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ret +=3D mcgen('''
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 break;
>=C2=A0 ''')
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 ret +=3D gen_endif(var.ifcond.ifcond)
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 ret +=3D gen_endif(var.ifcond.cgen())
>=C2=A0
>=C2=A0 =C2=A0 =C2=A0 ret +=3D mcgen('''
>=C2=A0 =C2=A0 =C2=A0 case QTYPE_NONE:

--0000000000006eb58505c8b78375--