aboutsummaryrefslogtreecommitdiff
path: root/qapi/qobject-input-visitor.c
diff options
context:
space:
mode:
Diffstat (limited to 'qapi/qobject-input-visitor.c')
-rw-r--r--qapi/qobject-input-visitor.c37
1 files changed, 31 insertions, 6 deletions
diff --git a/qapi/qobject-input-visitor.c b/qapi/qobject-input-visitor.c
index eafcdf4625..34065ba7dd 100644
--- a/qapi/qobject-input-visitor.c
+++ b/qapi/qobject-input-visitor.c
@@ -51,7 +51,8 @@ static QObjectInputVisitor *to_qiv(Visitor *v)
return container_of(v, QObjectInputVisitor, visitor);
}
-static const char *full_name(QObjectInputVisitor *qiv, const char *name)
+static const char *full_name_nth(QObjectInputVisitor *qiv, const char *name,
+ int n)
{
StackObject *so;
char buf[32];
@@ -63,8 +64,10 @@ static const char *full_name(QObjectInputVisitor *qiv, const char *name)
}
QSLIST_FOREACH(so , &qiv->stack, node) {
- if (qobject_type(so->obj) == QTYPE_QDICT) {
- g_string_prepend(qiv->errname, name);
+ if (n) {
+ n--;
+ } else if (qobject_type(so->obj) == QTYPE_QDICT) {
+ g_string_prepend(qiv->errname, name ?: "<anonymous>");
g_string_prepend_c(qiv->errname, '.');
} else {
snprintf(buf, sizeof(buf), "[%u]", so->index);
@@ -72,18 +75,24 @@ static const char *full_name(QObjectInputVisitor *qiv, const char *name)
}
name = so->name;
}
+ assert(!n);
if (name) {
g_string_prepend(qiv->errname, name);
} else if (qiv->errname->str[0] == '.') {
g_string_erase(qiv->errname, 0, 1);
- } else {
+ } else if (!qiv->errname->str[0]) {
return "<anonymous>";
}
return qiv->errname->str;
}
+static const char *full_name(QObjectInputVisitor *qiv, const char *name)
+{
+ return full_name_nth(qiv, name, 0);
+}
+
static QObject *qobject_input_try_get_object(QObjectInputVisitor *qiv,
const char *name,
bool consume)
@@ -260,15 +269,30 @@ static GenericList *qobject_input_next_list(Visitor *v, GenericList *tail,
size_t size)
{
QObjectInputVisitor *qiv = to_qiv(v);
- StackObject *so = QSLIST_FIRST(&qiv->stack);
+ StackObject *tos = QSLIST_FIRST(&qiv->stack);
+
+ assert(tos && tos->obj && qobject_type(tos->obj) == QTYPE_QLIST);
- if (!so->entry) {
+ if (!tos->entry) {
return NULL;
}
tail->next = g_malloc0(size);
return tail->next;
}
+static void qobject_input_check_list(Visitor *v, Error **errp)
+{
+ QObjectInputVisitor *qiv = to_qiv(v);
+ StackObject *tos = QSLIST_FIRST(&qiv->stack);
+
+ assert(tos && tos->obj && qobject_type(tos->obj) == QTYPE_QLIST);
+
+ if (tos->entry) {
+ error_setg(errp, "Only %u list elements expected in %s",
+ tos->index + 1, full_name_nth(qiv, NULL, 1));
+ }
+}
+
static void qobject_input_start_alternate(Visitor *v, const char *name,
GenericAlternate **obj, size_t size,
@@ -471,6 +495,7 @@ Visitor *qobject_input_visitor_new(QObject *obj)
v->visitor.end_struct = qobject_input_pop;
v->visitor.start_list = qobject_input_start_list;
v->visitor.next_list = qobject_input_next_list;
+ v->visitor.check_list = qobject_input_check_list;
v->visitor.end_list = qobject_input_pop;
v->visitor.start_alternate = qobject_input_start_alternate;
v->visitor.type_int64 = qobject_input_type_int64;