[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PULL 11/23] qmp-input: Refactor when list is advanced
From: |
Markus Armbruster |
Subject: |
[Qemu-devel] [PULL 11/23] qmp-input: Refactor when list is advanced |
Date: |
Thu, 12 May 2016 09:58:58 +0200 |
From: Eric Blake <address@hidden>
In the QMP input visitor, visiting a list traverses two objects:
the QAPI GenericList of the caller (which gets advanced in
visit_next_list() regardless of this patch), and the QList input
that we are converting to QAPI. For consistency with QDict
visits, we want to consume elements from the input QList during
the visit_type_FOO() for the list element; that is, we want ALL
the code for consuming an input to live in qmp_input_get_object(),
rather than having it split according to whether we are visiting
a dict or a list. Making qmp_input_get_object() the common point
of consumption will make it easier for a later patch to refactor
visit_start_list() to cover the GenericList * head of a QAPI list,
and in turn will get rid of the 'first' flag (which lived in
qmp_input_next_list() pre-patch, and is hoisted to StackObject
by this patch).
This patch is therefore altering the post-condition use of 'entry',
while keeping what gets visited unchanged, from:
start_list next_list type_ELT ... next_list type_ELT next_list end_list
visits 1st elt last elt
entry NULL 1st elt 1st elt last elt last elt NULL gone
where type_ELT() returns (entry ? entry : 1st elt) and next_list() steps
entry
to this usage:
start_list next_list type_ELT ... next_list type_ELT next_list end_list
visits 1st elt last elt
entry 1st elt 1nd elt 2nd elt last elt NULL NULL gone
where type_ELT() steps entry and returns the old entry, and next_list()
leaves entry alone.
Signed-off-by: Eric Blake <address@hidden>
Message-Id: <address@hidden>
Signed-off-by: Markus Armbruster <address@hidden>
---
qapi/qmp-input-visitor.c | 30 ++++++++++++++++--------------
1 file changed, 16 insertions(+), 14 deletions(-)
diff --git a/qapi/qmp-input-visitor.c b/qapi/qmp-input-visitor.c
index f158d57..5159833 100644
--- a/qapi/qmp-input-visitor.c
+++ b/qapi/qmp-input-visitor.c
@@ -29,6 +29,7 @@ typedef struct StackObject
GHashTable *h; /* If obj is dict: unvisited keys */
const QListEntry *entry; /* If obj is list: unvisited tail */
+ bool first; /* If obj is list: next_list() not yet called? */
} StackObject;
struct QmpInputVisitor
@@ -80,7 +81,11 @@ static QObject *qmp_input_get_object(QmpInputVisitor *qiv,
} else {
assert(qobject_type(qobj) == QTYPE_QLIST);
assert(!name);
+ assert(!tos->first);
ret = qlist_entry_obj(tos->entry);
+ if (consume) {
+ tos->entry = qlist_next(tos->entry);
+ }
}
return ret;
@@ -104,13 +109,16 @@ static void qmp_input_push(QmpInputVisitor *qiv, QObject
*obj, Error **errp)
}
tos->obj = obj;
- tos->entry = NULL;
- tos->h = NULL;
+ assert(!tos->h);
+ assert(!tos->entry);
if (qiv->strict && qobject_type(obj) == QTYPE_QDICT) {
h = g_hash_table_new(g_str_hash, g_str_equal);
qdict_iter(qobject_to_qdict(obj), qdict_add_key, h);
tos->h = h;
+ } else if (qobject_type(obj) == QTYPE_QLIST) {
+ tos->entry = qlist_first(qobject_to_qlist(obj));
+ tos->first = true;
}
qiv->nb_stack++;
@@ -119,10 +127,11 @@ static void qmp_input_push(QmpInputVisitor *qiv, QObject
*obj, Error **errp)
static void qmp_input_pop(QmpInputVisitor *qiv, Error **errp)
{
+ StackObject *tos = &qiv->stack[qiv->nb_stack - 1];
assert(qiv->nb_stack > 0);
if (qiv->strict) {
- GHashTable * const top_ht = qiv->stack[qiv->nb_stack - 1].h;
+ GHashTable *const top_ht = tos->h;
if (top_ht) {
GHashTableIter iter;
const char *key;
@@ -133,6 +142,7 @@ static void qmp_input_pop(QmpInputVisitor *qiv, Error
**errp)
}
g_hash_table_unref(top_ht);
}
+ tos->h = NULL;
}
qiv->nb_stack--;
@@ -192,23 +202,15 @@ 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) {
+ if (!so->entry) {
return NULL;
}
entry = g_malloc0(size);
- if (first) {
+ if (so->first) {
*list = entry;
+ so->first = false;
} else {
(*list)->next = entry;
}
--
2.5.5
- [Qemu-devel] [PULL 18/23] qmp: Tighten output visitor rules, (continued)
- [Qemu-devel] [PULL 18/23] qmp: Tighten output visitor rules, Markus Armbruster, 2016/05/12
- [Qemu-devel] [PULL 05/23] qapi: Consolidate QMP input visitor creation, Markus Armbruster, 2016/05/12
- [Qemu-devel] [PULL 02/23] qapi: Guarantee NULL obj on input visitor callback error, Markus Armbruster, 2016/05/12
- [Qemu-devel] [PULL 21/23] qapi: Fix string input visitor handling of invalid list, Markus Armbruster, 2016/05/12
- [Qemu-devel] [PULL 20/23] tests/string-input-visitor: Add negative integer tests, Markus Armbruster, 2016/05/12
- [Qemu-devel] [PULL 14/23] qapi: Add visit_type_null() visitor, Markus Armbruster, 2016/05/12
- [Qemu-devel] [PULL 17/23] qmp: Don't reuse qmp visitor after grabbing output, Markus Armbruster, 2016/05/12
- [Qemu-devel] [PULL 13/23] tests: Add check-qnull, Markus Armbruster, 2016/05/12
- [Qemu-devel] [PULL 23/23] qapi: Change visit_type_FOO() to no longer return partial objects, Markus Armbruster, 2016/05/12
- [Qemu-devel] [PULL 04/23] qmp-input: Clean up stack handling, Markus Armbruster, 2016/05/12
- [Qemu-devel] [PULL 11/23] qmp-input: Refactor when list is advanced,
Markus Armbruster <=
- [Qemu-devel] [PULL 16/23] spapr_drc: Expose 'null' in qom-get when there is no fdt, Markus Armbruster, 2016/05/12
- [Qemu-devel] [PULL 22/23] qapi: Simplify semantics of visit_next_list(), Markus Armbruster, 2016/05/12
- [Qemu-devel] [PULL 08/23] qapi-commands: Wrap argument visit in visit_start_struct, Markus Armbruster, 2016/05/12
- [Qemu-devel] [PULL 15/23] qmp: Support explicit null during visits, Markus Armbruster, 2016/05/12
- [Qemu-devel] [PULL 12/23] qapi: Document visitor interfaces, add assertions, Markus Armbruster, 2016/05/12
- [Qemu-devel] [PULL 19/23] qapi: Split visit_end_struct() into pieces, Markus Armbruster, 2016/05/12
- Re: [Qemu-devel] [PULL 00/23] QAPI patches for 2016-05-12, Peter Maydell, 2016/05/12