From patchwork Thu Oct 8 02:00:50 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Blake X-Patchwork-Id: 527572 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from eggs.gnu.org (eggs.gnu.org [IPv6:2001:4830:134:3::10]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 7A18B140D72 for ; Thu, 8 Oct 2015 14:53:18 +1100 (AEDT) Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Zk2GY-0003SX-Va for incoming@patchwork.ozlabs.org; Wed, 07 Oct 2015 23:53:16 -0400 X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on eggs.gnu.org X-Spam-Level: X-Spam-Status: No, score=-0.0 required=5.0 tests=BAYES_40 autolearn=disabled version=3.3.2 Received: from lists.gnu.org ([2001:4830:134:3::11]:50307) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Zk0mp-0006uS-Sx for incoming@patchwork.ozlabs.org; Wed, 07 Oct 2015 22:18:28 -0400 Received: from localhost ([::1]:60310 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Zk0jj-00020q-OI for incoming@patchwork.ozlabs.org; Wed, 07 Oct 2015 22:15:15 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:54352) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Zk0W1-0004z9-Lb for qemu-devel@nongnu.org; Wed, 07 Oct 2015 22:01:54 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Zk0Vw-00038L-25 for qemu-devel@nongnu.org; Wed, 07 Oct 2015 22:01:05 -0400 Received: from mx1.redhat.com ([209.132.183.28]:47224) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Zk0Vv-00038F-OS for qemu-devel@nongnu.org; Wed, 07 Oct 2015 22:00:59 -0400 Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by mx1.redhat.com (Postfix) with ESMTPS id 59941C0BD892; Thu, 8 Oct 2015 02:00:59 +0000 (UTC) Received: from red.redhat.com (ovpn-113-202.phx2.redhat.com [10.3.113.202]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9820pM4024184; Wed, 7 Oct 2015 22:00:59 -0400 From: Eric Blake To: qemu-devel@nongnu.org Date: Wed, 7 Oct 2015 20:00:50 -0600 Message-Id: <1444269650-4117-16-git-send-email-eblake@redhat.com> In-Reply-To: <1444269650-4117-1-git-send-email-eblake@redhat.com> References: <1444269650-4117-1-git-send-email-eblake@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.22 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x Cc: armbru@redhat.com, Michael Roth Subject: [Qemu-devel] [PATCH v6 15/15] qapi: Simplify visits of optional fields X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-Received-From: 2001:4830:134:3::11 None of the visitor callbacks would set an error when testing if an optional field was present; make this part of the interface contract by eliminating the errp argument. Then, for less code, reflect the determined boolean value back to the caller instead of making the caller read the boolean after the fact. The resulting generated code has a nice diff: |- visit_optional(v, &has_fdset_id, "fdset-id", &err); |- if (err) { |- goto out; |- } |- if (has_fdset_id) { |+ if (visit_optional(v, &has_fdset_id, "fdset-id")) { | visit_type_int(v, &fdset_id, "fdset-id", &err); | if (err) { | goto out; | } | } Signed-off-by: Eric Blake --- v6: rebase onto earlier testsuite and gen_err_check() improvements --- include/qapi/visitor-impl.h | 5 ++--- include/qapi/visitor.h | 10 ++++++++-- qapi/opts-visitor.c | 2 +- qapi/qapi-visit-core.c | 6 +++--- qapi/qmp-input-visitor.c | 3 +-- qapi/string-input-visitor.c | 3 +-- scripts/qapi.py | 9 ++------- 7 files changed, 18 insertions(+), 20 deletions(-) diff --git a/include/qapi/visitor-impl.h b/include/qapi/visitor-impl.h index 370935a..fd2e905 100644 --- a/include/qapi/visitor-impl.h +++ b/include/qapi/visitor-impl.h @@ -44,9 +44,8 @@ struct Visitor void (*type_any)(Visitor *v, QObject **obj, const char *name, Error **errp); - /* May be NULL */ - void (*optional)(Visitor *v, bool *present, const char *name, - Error **errp); + /* May be NULL; most useful for input visitors. */ + void (*optional)(Visitor *v, bool *present, const char *name); bool (*start_union)(Visitor *v, bool data_present, Error **errp); void (*end_union)(Visitor *v, bool data_present, Error **errp); diff --git a/include/qapi/visitor.h b/include/qapi/visitor.h index 67ddd83..e52ad39 100644 --- a/include/qapi/visitor.h +++ b/include/qapi/visitor.h @@ -36,8 +36,14 @@ void visit_end_implicit_struct(Visitor *v, Error **errp); void visit_start_list(Visitor *v, const char *name, Error **errp); GenericList *visit_next_list(Visitor *v, GenericList **list, Error **errp); void visit_end_list(Visitor *v, Error **errp); -void visit_optional(Visitor *v, bool *present, const char *name, - Error **errp); + +/** + * Check if an optional member @name of an object needs visiting. + * For input visitors, set *@present according to whether the + * corresponding visit_type_*() needs calling; for other visitors, + * leave *@present unchanged. Return *@present for convenience. + */ +bool visit_optional(Visitor *v, bool *present, const char *name); /** * Determine the qtype of the item @name in the current object visit. diff --git a/qapi/opts-visitor.c b/qapi/opts-visitor.c index cd10392..ef5fb8b 100644 --- a/qapi/opts-visitor.c +++ b/qapi/opts-visitor.c @@ -488,7 +488,7 @@ opts_type_size(Visitor *v, uint64_t *obj, const char *name, Error **errp) static void -opts_optional(Visitor *v, bool *present, const char *name, Error **errp) +opts_optional(Visitor *v, bool *present, const char *name) { OptsVisitor *ov = DO_UPCAST(OptsVisitor, visitor, v); diff --git a/qapi/qapi-visit-core.c b/qapi/qapi-visit-core.c index cbf7780..2594147 100644 --- a/qapi/qapi-visit-core.c +++ b/qapi/qapi-visit-core.c @@ -73,12 +73,12 @@ void visit_end_union(Visitor *v, bool data_present, Error **errp) } } -void visit_optional(Visitor *v, bool *present, const char *name, - Error **errp) +bool visit_optional(Visitor *v, bool *present, const char *name) { if (v->optional) { - v->optional(v, present, name, errp); + v->optional(v, present, name); } + return *present; } void visit_get_next_type(Visitor *v, qtype_code *type, bool promote_int, diff --git a/qapi/qmp-input-visitor.c b/qapi/qmp-input-visitor.c index 5310db5..f714dfc 100644 --- a/qapi/qmp-input-visitor.c +++ b/qapi/qmp-input-visitor.c @@ -300,8 +300,7 @@ static void qmp_input_type_any(Visitor *v, QObject **obj, const char *name, *obj = qobj; } -static void qmp_input_optional(Visitor *v, bool *present, const char *name, - Error **errp) +static void qmp_input_optional(Visitor *v, bool *present, const char *name) { QmpInputVisitor *qiv = to_qiv(v); QObject *qobj = qmp_input_get_object(qiv, name, true); diff --git a/qapi/string-input-visitor.c b/qapi/string-input-visitor.c index bbd6a54..dee780a 100644 --- a/qapi/string-input-visitor.c +++ b/qapi/string-input-visitor.c @@ -299,8 +299,7 @@ static void parse_type_number(Visitor *v, double *obj, const char *name, *obj = val; } -static void parse_optional(Visitor *v, bool *present, const char *name, - Error **errp) +static void parse_optional(Visitor *v, bool *present, const char *name) { StringInputVisitor *siv = DO_UPCAST(StringInputVisitor, visitor, v); diff --git a/scripts/qapi.py b/scripts/qapi.py index 430c4bc..de76078 100644 --- a/scripts/qapi.py +++ b/scripts/qapi.py @@ -1648,15 +1648,10 @@ def gen_visit_fields(members, prefix='', need_cast=False, skiperr=False): for memb in members: if memb.optional: ret += mcgen(''' - visit_optional(v, &%(prefix)shas_%(c_name)s, "%(name)s", %(errp)s); + if (visit_optional(v, &%(prefix)shas_%(c_name)s, "%(name)s")) { ''', prefix=prefix, c_name=memb.c_name(), - name=memb.name, errp=errparg) - ret += gen_err_check(skiperr=skiperr) - ret += mcgen(''' - if (%(prefix)shas_%(c_name)s) { -''', - prefix=prefix, c_name=memb.c_name()) + name=memb.name) push_indent() # Ugly: sometimes we need to cast away const