All of lore.kernel.org
 help / color / mirror / Atom feed
From: Paolo Bonzini <pbonzini@redhat.com>
To: qemu-devel@nongnu.org
Cc: eblake@redhat.com, mdroth@linux.vnet.ibm.com,
	anthony@codemonkey.ws, lcapitulino@redhat.com
Subject: [Qemu-devel] [PATCH v2 06/10] qapi: untangle next_list
Date: Thu, 22 Mar 2012 22:38:40 +0100	[thread overview]
Message-ID: <1332452320-21956-1-git-send-email-pbonzini@redhat.com> (raw)
In-Reply-To: <4F6B9874.4020108@redhat.com>

Right now, the semantics of next_list are complicated.  The caller must:

* call start_list

* call next_list for each element *including the first*

* on the first call to next_list, the second argument should point to
NULL and the result is the head of the list.  On subsequent calls,
the second argument should point to the last node (last result of
next_list) and next_list itself tacks the element at the tail of the
list.

This works for both input and output visitor, but having the visitor
write memory when it is only reading the list is ugly.  Plus, relying
on *list to detect the first call is tricky and undocumented.

We can initialize so->entry in next_list instead of start_list, leaving
it NULL in start_list.  This way next_list sees clearly whether it is
on the first call---as a bonus, it discriminates the cases based on
internal state of the visitor rather than external state.  We can
also pull the assignment of the list head from generated code up to
next_list.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 docs/qapi-code-gen.txt   |    4 ++--
 qapi/qmp-input-visitor.c |   22 +++++++++++++---------
 scripts/qapi-visit.py    |    4 ++--
 3 files changed, 17 insertions(+), 13 deletions(-)

diff --git a/docs/qapi-code-gen.txt b/docs/qapi-code-gen.txt
index 5831e37..ad11767 100644
--- a/docs/qapi-code-gen.txt
+++ b/docs/qapi-code-gen.txt
@@ -194,11 +194,11 @@ Example:
 
     void visit_type_UserDefOneList(Visitor *m, UserDefOneList ** obj, const char *name, Error **errp)
     {
-        GenericList *i;
+        GenericList *i, **prev = (GenericList **)obj;
 
         visit_start_list(m, name, errp);
 
-        for (i = visit_next_list(m, (GenericList **)obj, errp); i; i = visit_next_list(m, &i, errp)) {
+        for (; (i = visit_next_list(m, prev, errp)) != NULL; prev = &i) {
             UserDefOneList *native_i = (UserDefOneList *)i;
             visit_type_UserDefOne(m, &native_i->value, NULL, errp);
         }
diff --git a/qapi/qmp-input-visitor.c b/qapi/qmp-input-visitor.c
index ef9288f..413e333 100644
--- a/qapi/qmp-input-visitor.c
+++ b/qapi/qmp-input-visitor.c
@@ -64,9 +64,7 @@ static const QObject *qmp_input_get_object(QmpInputVisitor *qiv,
 static void qmp_input_push(QmpInputVisitor *qiv, const QObject *obj, Error **errp)
 {
     qiv->stack[qiv->nb_stack].obj = obj;
-    if (qobject_type(obj) == QTYPE_QLIST) {
-        qiv->stack[qiv->nb_stack].entry = qlist_first(qobject_to_qlist(obj));
-    }
+    qiv->stack[qiv->nb_stack].entry = NULL;
     qiv->nb_stack++;
 
     if (qiv->nb_stack >= QIV_STACK_SIZE) {
@@ -132,18 +130,24 @@ static GenericList *qmp_input_next_list(Visitor *v, GenericList **list,
     QmpInputVisitor *qiv = to_qiv(v);
     GenericList *entry;
     StackObject *so = &qiv->stack[qiv->nb_stack - 1];
+    bool first;
+
+    if (so->entry == NULL) {
+        so->entry = qlist_first(qobject_to_qlist(so->obj));
+        first = true;
+    } else {
+        so->entry = qlist_next(so->entry);
+        first = false;
+    }
 
     if (so->entry == NULL) {
         return NULL;
     }
 
     entry = g_malloc0(sizeof(*entry));
-    if (*list) {
-        so->entry = qlist_next(so->entry);
-        if (so->entry == NULL) {
-            g_free(entry);
-            return NULL;
-        }
+    if (first) {
+        *list = entry;
+    } else {
         (*list)->next = entry;
     }
 
diff --git a/scripts/qapi-visit.py b/scripts/qapi-visit.py
index a85fb76..1ff81f4 100644
--- a/scripts/qapi-visit.py
+++ b/scripts/qapi-visit.py
@@ -86,14 +86,14 @@ def generate_visit_list(name, members):
 
 void visit_type_%(name)sList(Visitor *m, %(name)sList ** obj, const char *name, Error **errp)
 {
-    GenericList *i, **head = (GenericList **)obj;
+    GenericList *i, **prev = (GenericList **)obj;
 
     if (error_is_set(errp)) {
         return;
     }
     visit_start_list(m, name, errp);
 
-    for (*head = i = visit_next_list(m, head, errp); i; i = visit_next_list(m, &i, errp)) {
+    for (; (i = visit_next_list(m, prev, errp)) != NULL; prev = &i) {
         %(name)sList *native_i = (%(name)sList *)i;
         visit_type_%(name)s(m, &native_i->value, NULL, errp);
     }
-- 
1.7.9.1

  parent reply	other threads:[~2012-03-22 21:39 UTC|newest]

Thread overview: 31+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-03-22 11:51 [Qemu-devel] [PATCH 00/10] QAPI minor fixes and strict mode Paolo Bonzini
2012-03-22 11:51 ` [Qemu-devel] [PATCH 01/10] qapi: add a test case for type errors Paolo Bonzini
2012-03-22 20:17   ` Anthony Liguori
2012-03-22 11:51 ` [Qemu-devel] [PATCH 02/10] qapi: fail hard on stack imbalance Paolo Bonzini
2012-03-22 20:17   ` Anthony Liguori
2012-03-26 14:15   ` Luiz Capitulino
2012-03-26 15:06     ` Michael Roth
2012-03-22 11:51 ` [Qemu-devel] [PATCH 03/10] qapi: fix memory leak on error Paolo Bonzini
2012-03-22 20:17   ` Anthony Liguori
2012-03-22 11:51 ` [Qemu-devel] [PATCH 04/10] qapi: shortcut visits on errors Paolo Bonzini
2012-03-22 20:17   ` Anthony Liguori
2012-03-22 11:51 ` [Qemu-devel] [PATCH 05/10] qapi: allow freeing partially-allocated objects Paolo Bonzini
2012-03-22 20:18   ` Anthony Liguori
2012-03-22 11:51 ` [Qemu-devel] [PATCH 06/10] qapi: simplify qmp_input_next_list Paolo Bonzini
2012-03-22 20:22   ` Anthony Liguori
2012-03-22 21:24     ` Paolo Bonzini
2012-03-22 21:34       ` Anthony Liguori
2012-03-22 21:38       ` Paolo Bonzini [this message]
2012-03-23 16:42         ` [Qemu-devel] [PATCH v2 06/10] qapi: untangle next_list Michael Roth
2012-03-22 11:51 ` [Qemu-devel] [PATCH 07/10] qapi: place outermost object on qiv stack Paolo Bonzini
2012-03-22 20:25   ` Anthony Liguori
2012-03-22 11:51 ` [Qemu-devel] [PATCH 08/10] qapi: add strict mode to input visitor Paolo Bonzini
2012-03-22 20:25   ` Anthony Liguori
2012-04-02 10:34   ` Laurent Desnogues
2012-04-02 11:28     ` Paolo Bonzini
2012-03-22 11:51 ` [Qemu-devel] [PATCH 09/10] qmp: add and use q type specifier Paolo Bonzini
2012-03-22 20:27   ` Anthony Liguori
2012-03-22 11:51 ` [Qemu-devel] [PATCH 10/10] qmp: parse commands in strict mode Paolo Bonzini
2012-03-22 20:28   ` Anthony Liguori
2012-03-22 20:30     ` Luiz Capitulino
2012-03-22 21:39 ` [Qemu-devel] [PATCH 11/10] qmp: document strict parsing Paolo Bonzini

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1332452320-21956-1-git-send-email-pbonzini@redhat.com \
    --to=pbonzini@redhat.com \
    --cc=anthony@codemonkey.ws \
    --cc=eblake@redhat.com \
    --cc=lcapitulino@redhat.com \
    --cc=mdroth@linux.vnet.ibm.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.