summaryrefslogtreecommitdiffstats
path: root/qapi/qmp-input-visitor.c
diff options
context:
space:
mode:
authorPeter Maydell2016-07-20 15:34:08 +0200
committerPeter Maydell2016-07-20 15:34:08 +0200
commit3b2e6798ffdc69a7bd630657651c778d95250b76 (patch)
tree3967cfab2e6893ce6c90ec453a6308cc21b757cf /qapi/qmp-input-visitor.c
parentMerge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20160719'... (diff)
parentnet: Use correct type for bool flag (diff)
downloadqemu-3b2e6798ffdc69a7bd630657651c778d95250b76.tar.gz
qemu-3b2e6798ffdc69a7bd630657651c778d95250b76.tar.xz
qemu-3b2e6798ffdc69a7bd630657651c778d95250b76.zip
Merge remote-tracking branch 'remotes/armbru/tags/pull-qapi-2016-07-19' into staging
QAPI patches for 2016-07-19 # gpg: Signature made Tue 19 Jul 2016 19:35:27 BST # gpg: using RSA key 0x3870B400EB918653 # gpg: Good signature from "Markus Armbruster <armbru@redhat.com>" # gpg: aka "Markus Armbruster <armbru@pond.sub.org>" # Primary key fingerprint: 354B C8B3 D7EB 2A6B 6867 4E5F 3870 B400 EB91 8653 * remotes/armbru/tags/pull-qapi-2016-07-19: net: Use correct type for bool flag qapi: Change Netdev into a flat union block: Simplify drive-mirror block: Simplify block_set_io_throttle qapi: Implement boxed types for commands/events qapi: Plumb in 'boxed' to qapi generator lower levels qapi-event: Simplify visit of non-implicit data qapi: Drop useless gen_err_check() qapi: Add type.is_empty() helper qapi: Hide tag_name data member of variants qapi: Special case c_name() for empty type qapi: Require all branches of flat union enum to be covered net: use Netdev instead of NetClientOptions in client init qapi: change QmpInputVisitor to QSLIST qapi: change QmpOutputVisitor to QSLIST Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'qapi/qmp-input-visitor.c')
-rw-r--r--qapi/qmp-input-visitor.c59
1 files changed, 29 insertions, 30 deletions
diff --git a/qapi/qmp-input-visitor.c b/qapi/qmp-input-visitor.c
index 21edb3928e..64dd392e6f 100644
--- a/qapi/qmp-input-visitor.c
+++ b/qapi/qmp-input-visitor.c
@@ -30,6 +30,8 @@ typedef struct StackObject
GHashTable *h; /* If obj is dict: unvisited keys */
const QListEntry *entry; /* If obj is list: unvisited tail */
+
+ QSLIST_ENTRY(StackObject) node;
} StackObject;
struct QmpInputVisitor
@@ -41,8 +43,7 @@ struct QmpInputVisitor
/* Stack of objects being visited (all entries will be either
* QDict or QList). */
- StackObject stack[QIV_STACK_SIZE];
- int nb_stack;
+ QSLIST_HEAD(, StackObject) stack;
/* True to reject parse in visit_end_struct() if unvisited keys remain. */
bool strict;
@@ -61,13 +62,13 @@ static QObject *qmp_input_get_object(QmpInputVisitor *qiv,
QObject *qobj;
QObject *ret;
- if (!qiv->nb_stack) {
+ if (QSLIST_EMPTY(&qiv->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];
+ tos = QSLIST_FIRST(&qiv->stack);
qobj = tos->obj;
assert(qobj);
@@ -100,18 +101,11 @@ static const QListEntry *qmp_input_push(QmpInputVisitor *qiv, QObject *obj,
void *qapi, Error **errp)
{
GHashTable *h;
- StackObject *tos = &qiv->stack[qiv->nb_stack];
+ StackObject *tos = g_new0(StackObject, 1);
assert(obj);
- if (qiv->nb_stack >= QIV_STACK_SIZE) {
- error_setg(errp, "An internal buffer overran");
- return NULL;
- }
-
tos->obj = obj;
tos->qapi = qapi;
- 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);
@@ -121,7 +115,7 @@ static const QListEntry *qmp_input_push(QmpInputVisitor *qiv, QObject *obj,
tos->entry = qlist_first(qobject_to_qlist(obj));
}
- qiv->nb_stack++;
+ QSLIST_INSERT_HEAD(&qiv->stack, tos, node);
return tos->entry;
}
@@ -129,10 +123,9 @@ static const QListEntry *qmp_input_push(QmpInputVisitor *qiv, QObject *obj,
static void qmp_input_check_struct(Visitor *v, Error **errp)
{
QmpInputVisitor *qiv = to_qiv(v);
- StackObject *tos = &qiv->stack[qiv->nb_stack - 1];
-
- assert(qiv->nb_stack > 0);
+ StackObject *tos = QSLIST_FIRST(&qiv->stack);
+ assert(tos && !tos->entry);
if (qiv->strict) {
GHashTable *const top_ht = tos->h;
if (top_ht) {
@@ -147,23 +140,23 @@ static void qmp_input_check_struct(Visitor *v, Error **errp)
}
}
-static void qmp_input_pop(Visitor *v, void **obj)
+static void qmp_input_stack_object_free(StackObject *tos)
{
- QmpInputVisitor *qiv = to_qiv(v);
- StackObject *tos = &qiv->stack[qiv->nb_stack - 1];
+ if (tos->h) {
+ g_hash_table_unref(tos->h);
+ }
- assert(qiv->nb_stack > 0);
- assert(tos->qapi == obj);
+ g_free(tos);
+}
- if (qiv->strict) {
- GHashTable * const top_ht = qiv->stack[qiv->nb_stack - 1].h;
- if (top_ht) {
- g_hash_table_unref(top_ht);
- }
- tos->h = NULL;
- }
+static void qmp_input_pop(Visitor *v, void **obj)
+{
+ QmpInputVisitor *qiv = to_qiv(v);
+ StackObject *tos = QSLIST_FIRST(&qiv->stack);
- qiv->nb_stack--;
+ assert(tos && tos->qapi == obj);
+ QSLIST_REMOVE_HEAD(&qiv->stack, node);
+ qmp_input_stack_object_free(tos);
}
static void qmp_input_start_struct(Visitor *v, const char *name, void **obj,
@@ -224,7 +217,7 @@ static GenericList *qmp_input_next_list(Visitor *v, GenericList *tail,
size_t size)
{
QmpInputVisitor *qiv = to_qiv(v);
- StackObject *so = &qiv->stack[qiv->nb_stack - 1];
+ StackObject *so = QSLIST_FIRST(&qiv->stack);
if (!so->entry) {
return NULL;
@@ -376,6 +369,12 @@ static void qmp_input_optional(Visitor *v, const char *name, bool *present)
static void qmp_input_free(Visitor *v)
{
QmpInputVisitor *qiv = to_qiv(v);
+ while (!QSLIST_EMPTY(&qiv->stack)) {
+ StackObject *tos = QSLIST_FIRST(&qiv->stack);
+
+ QSLIST_REMOVE_HEAD(&qiv->stack, node);
+ qmp_input_stack_object_free(tos);
+ }
qobject_decref(qiv->root);
g_free(qiv);