From patchwork Thu May 12 07:58:57 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Markus Armbruster X-Patchwork-Id: 9077241 Return-Path: X-Original-To: patchwork-qemu-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 645D99F372 for ; Thu, 12 May 2016 07:59:35 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id A9EF1201D3 for ; Thu, 12 May 2016 07:59:34 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id D027920155 for ; Thu, 12 May 2016 07:59:33 +0000 (UTC) Received: from localhost ([::1]:55837 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1b0lWu-0000xA-W8 for patchwork-qemu-devel@patchwork.kernel.org; Thu, 12 May 2016 03:59:33 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:54051) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1b0lWi-0000st-IM for qemu-devel@nongnu.org; Thu, 12 May 2016 03:59:23 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1b0lWe-0006KX-Lm for qemu-devel@nongnu.org; Thu, 12 May 2016 03:59:19 -0400 Received: from mx1.redhat.com ([209.132.183.28]:34379) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1b0lWe-0006Ji-Az for qemu-devel@nongnu.org; Thu, 12 May 2016 03:59:16 -0400 Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id C48AC47074 for ; Thu, 12 May 2016 07:59:15 +0000 (UTC) Received: from blackfin.pond.sub.org (ovpn-116-35.ams2.redhat.com [10.36.116.35]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id u4C7xDKQ028682 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Thu, 12 May 2016 03:59:14 -0400 Received: by blackfin.pond.sub.org (Postfix, from userid 1000) id 81E9A1142141; Thu, 12 May 2016 09:59:10 +0200 (CEST) From: Markus Armbruster To: qemu-devel@nongnu.org Date: Thu, 12 May 2016 09:58:57 +0200 Message-Id: <1463039950-4021-11-git-send-email-armbru@redhat.com> In-Reply-To: <1463039950-4021-1-git-send-email-armbru@redhat.com> References: <1463039950-4021-1-git-send-email-armbru@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.30]); Thu, 12 May 2016 07:59:15 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL 10/23] qmp-input: Require struct push to visit members of top dict 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: , Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Eric Blake Don't embed the root of the visit into the stack of current containers being visited. That way, we no longer get confused on whether the first visit of a dictionary is to the dictionary itself or to one of the members of the dictionary, based on whether the caller passed name=NULL; and makes the QMP Input visitor like other visitors where the value of 'name' is now ignored on the root visit. (We may someday want to revisit the rules on what 'name' should be on a top-level visit, rather than just ignoring it; but that would be the topic of another patch). An audit of all qmp_input_visitor_new() call sites shows that there were only two places where callers had previously been visiting to a QDict with a non-NULL name to bypass a call to visit_start_struct(), and those were fixed in prior patches. Signed-off-by: Eric Blake Message-Id: <1461879932-9020-11-git-send-email-eblake@redhat.com> Signed-off-by: Markus Armbruster --- qapi/qmp-input-visitor.c | 43 +++++++++++++++++++++++-------------------- 1 file changed, 23 insertions(+), 20 deletions(-) diff --git a/qapi/qmp-input-visitor.c b/qapi/qmp-input-visitor.c index cae6387..f158d57 100644 --- a/qapi/qmp-input-visitor.c +++ b/qapi/qmp-input-visitor.c @@ -35,9 +35,11 @@ struct QmpInputVisitor { Visitor visitor; - /* Stack of objects being visited. stack[0] is root of visit, - * stack[1..] records the nesting of start_struct()/end_struct() - * and start_list()/end_list() pairs. */ + /* Root of visit at visitor creation. */ + QObject *root; + + /* Stack of objects being visited (all entries will be either + * QDict or QList). */ StackObject stack[QIV_STACK_SIZE]; int nb_stack; @@ -54,33 +56,34 @@ static QObject *qmp_input_get_object(QmpInputVisitor *qiv, const char *name, bool consume) { - StackObject *tos = &qiv->stack[qiv->nb_stack - 1]; - QObject *qobj = tos->obj; + StackObject *tos; + QObject *qobj; QObject *ret; + if (!qiv->nb_stack) { + /* Starting at root, name is ignored. */ + return qiv->root; + } + + /* We are in a container; find the next element. */ + tos = &qiv->stack[qiv->nb_stack - 1]; + qobj = tos->obj; assert(qobj); - /* If we have a name, and we're in a dictionary, then return that - * value. */ - if (name && qobject_type(qobj) == QTYPE_QDICT) { + if (qobject_type(qobj) == QTYPE_QDICT) { + assert(name); ret = qdict_get(qobject_to_qdict(qobj), name); if (tos->h && consume && ret) { bool removed = g_hash_table_remove(tos->h, name); assert(removed); } - return ret; - } - - /* If we are in the middle of a list, then return the next element - * of the list. */ - if (tos->entry) { + } else { assert(qobject_type(qobj) == QTYPE_QLIST); - return qlist_entry_obj(tos->entry); + assert(!name); + ret = qlist_entry_obj(tos->entry); } - /* Otherwise, we are at the root of the visit or the start of a - * list, and return the object as-is. */ - return qobj; + return ret; } static void qdict_add_key(const char *key, QObject *obj, void *opaque) @@ -355,7 +358,7 @@ Visitor *qmp_input_get_visitor(QmpInputVisitor *v) void qmp_input_visitor_cleanup(QmpInputVisitor *v) { - qobject_decref(v->stack[0].obj); + qobject_decref(v->root); g_free(v); } @@ -381,7 +384,7 @@ QmpInputVisitor *qmp_input_visitor_new(QObject *obj, bool strict) v->visitor.optional = qmp_input_optional; v->strict = strict; - qmp_input_push(v, obj, NULL); + v->root = obj; qobject_incref(obj); return v;