[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 08/13] qapi: untangle next_list
From: |
Luiz Capitulino |
Subject: |
[Qemu-devel] [PATCH 08/13] qapi: untangle next_list |
Date: |
Tue, 27 Mar 2012 09:20:46 -0300 |
From: Paolo Bonzini <address@hidden>
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 <address@hidden>
Reviewed-by: Michael Roth <address@hidden>
Signed-off-by: Luiz Capitulino <address@hidden>
---
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 31d50a6..8d4e94a 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.2.384.g4a92a
- [Qemu-devel] [PULL 00/13]: QMP queue, Luiz Capitulino, 2012/03/27
- [Qemu-devel] [PATCH 02/13] qapi: add struct-errors test case to test-qmp-output-visitor, Luiz Capitulino, 2012/03/27
- [Qemu-devel] [PATCH 01/13] qapi: fix double free in qmp_output_visitor_cleanup(), Luiz Capitulino, 2012/03/27
- [Qemu-devel] [PATCH 03/13] qapi: add a test case for type errors, Luiz Capitulino, 2012/03/27
- [Qemu-devel] [PATCH 05/13] qapi: fix memory leak on error, Luiz Capitulino, 2012/03/27
- [Qemu-devel] [PATCH 06/13] qapi: shortcut visits on errors, Luiz Capitulino, 2012/03/27
- [Qemu-devel] [PATCH 08/13] qapi: untangle next_list,
Luiz Capitulino <=
- [Qemu-devel] [PATCH 04/13] qapi: fail hard on stack imbalance, Luiz Capitulino, 2012/03/27
- [Qemu-devel] [PATCH 07/13] qapi: allow freeing partially-allocated objects, Luiz Capitulino, 2012/03/27
- [Qemu-devel] [PATCH 12/13] qmp: parse commands in strict mode, Luiz Capitulino, 2012/03/27
- [Qemu-devel] [PATCH 09/13] qapi: place outermost object on qiv stack, Luiz Capitulino, 2012/03/27
- [Qemu-devel] [PATCH 11/13] qmp: add and use q type specifier, Luiz Capitulino, 2012/03/27
- [Qemu-devel] [PATCH 13/13] qmp: document strict parsing, Luiz Capitulino, 2012/03/27
- [Qemu-devel] [PATCH 10/13] qapi: add strict mode to input visitor, Luiz Capitulino, 2012/03/27
- Re: [Qemu-devel] [PULL 00/13]: QMP queue, Anthony Liguori, 2012/03/30