aboutsummaryrefslogtreecommitdiff
path: root/qapi/qmp-input-visitor.c
diff options
context:
space:
mode:
Diffstat (limited to 'qapi/qmp-input-visitor.c')
-rw-r--r--qapi/qmp-input-visitor.c40
1 files changed, 21 insertions, 19 deletions
diff --git a/qapi/qmp-input-visitor.c b/qapi/qmp-input-visitor.c
index 90b9df11c4..aea90a1378 100644
--- a/qapi/qmp-input-visitor.c
+++ b/qapi/qmp-input-visitor.c
@@ -29,7 +29,6 @@ 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
@@ -81,7 +80,6 @@ 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);
@@ -97,7 +95,8 @@ static void qdict_add_key(const char *key, QObject *obj, void *opaque)
g_hash_table_insert(h, (gpointer) key, NULL);
}
-static void qmp_input_push(QmpInputVisitor *qiv, QObject *obj, Error **errp)
+static const QListEntry *qmp_input_push(QmpInputVisitor *qiv, QObject *obj,
+ Error **errp)
{
GHashTable *h;
StackObject *tos = &qiv->stack[qiv->nb_stack];
@@ -105,7 +104,7 @@ static void qmp_input_push(QmpInputVisitor *qiv, QObject *obj, Error **errp)
assert(obj);
if (qiv->nb_stack >= QIV_STACK_SIZE) {
error_setg(errp, "An internal buffer overran");
- return;
+ return NULL;
}
tos->obj = obj;
@@ -118,10 +117,10 @@ static void qmp_input_push(QmpInputVisitor *qiv, QObject *obj, Error **errp)
tos->h = h;
} else if (qobject_type(obj) == QTYPE_QLIST) {
tos->entry = qlist_first(qobject_to_qlist(obj));
- tos->first = true;
}
qiv->nb_stack++;
+ return tos->entry;
}
@@ -192,40 +191,43 @@ static void qmp_input_start_struct(Visitor *v, const char *name, void **obj,
}
-static void qmp_input_start_list(Visitor *v, const char *name, Error **errp)
+static void qmp_input_start_list(Visitor *v, const char *name,
+ GenericList **list, size_t size, Error **errp)
{
QmpInputVisitor *qiv = to_qiv(v);
QObject *qobj = qmp_input_get_object(qiv, name, true);
+ const QListEntry *entry;
if (!qobj || qobject_type(qobj) != QTYPE_QLIST) {
+ if (list) {
+ *list = NULL;
+ }
error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null",
"list");
return;
}
- qmp_input_push(qiv, qobj, errp);
+ entry = qmp_input_push(qiv, qobj, errp);
+ if (list) {
+ if (entry) {
+ *list = g_malloc0(size);
+ } else {
+ *list = NULL;
+ }
+ }
}
-static GenericList *qmp_input_next_list(Visitor *v, GenericList **list,
+static GenericList *qmp_input_next_list(Visitor *v, GenericList *tail,
size_t size)
{
QmpInputVisitor *qiv = to_qiv(v);
- GenericList *entry;
StackObject *so = &qiv->stack[qiv->nb_stack - 1];
if (!so->entry) {
return NULL;
}
-
- entry = g_malloc0(size);
- if (so->first) {
- *list = entry;
- so->first = false;
- } else {
- (*list)->next = entry;
- }
-
- return entry;
+ tail->next = g_malloc0(size);
+ return tail->next;
}