|
@@ -51,7 +51,8 @@ static QObjectInputVisitor *to_qiv(Visitor *v)
|
|
return container_of(v, QObjectInputVisitor, visitor);
|
|
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;
|
|
StackObject *so;
|
|
char buf[32];
|
|
char buf[32];
|
|
@@ -63,8 +64,10 @@ static const char *full_name(QObjectInputVisitor *qiv, const char *name)
|
|
}
|
|
}
|
|
|
|
|
|
QSLIST_FOREACH(so , &qiv->stack, node) {
|
|
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, '.');
|
|
g_string_prepend_c(qiv->errname, '.');
|
|
} else {
|
|
} else {
|
|
snprintf(buf, sizeof(buf), "[%u]", so->index);
|
|
snprintf(buf, sizeof(buf), "[%u]", so->index);
|
|
@@ -72,18 +75,24 @@ static const char *full_name(QObjectInputVisitor *qiv, const char *name)
|
|
}
|
|
}
|
|
name = so->name;
|
|
name = so->name;
|
|
}
|
|
}
|
|
|
|
+ assert(!n);
|
|
|
|
|
|
if (name) {
|
|
if (name) {
|
|
g_string_prepend(qiv->errname, name);
|
|
g_string_prepend(qiv->errname, name);
|
|
} else if (qiv->errname->str[0] == '.') {
|
|
} else if (qiv->errname->str[0] == '.') {
|
|
g_string_erase(qiv->errname, 0, 1);
|
|
g_string_erase(qiv->errname, 0, 1);
|
|
- } else {
|
|
|
|
|
|
+ } else if (!qiv->errname->str[0]) {
|
|
return "<anonymous>";
|
|
return "<anonymous>";
|
|
}
|
|
}
|
|
|
|
|
|
return qiv->errname->str;
|
|
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,
|
|
static QObject *qobject_input_try_get_object(QObjectInputVisitor *qiv,
|
|
const char *name,
|
|
const char *name,
|
|
bool consume)
|
|
bool consume)
|
|
@@ -260,15 +269,30 @@ static GenericList *qobject_input_next_list(Visitor *v, GenericList *tail,
|
|
size_t size)
|
|
size_t size)
|
|
{
|
|
{
|
|
QObjectInputVisitor *qiv = to_qiv(v);
|
|
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;
|
|
return NULL;
|
|
}
|
|
}
|
|
tail->next = g_malloc0(size);
|
|
tail->next = g_malloc0(size);
|
|
return tail->next;
|
|
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,
|
|
static void qobject_input_start_alternate(Visitor *v, const char *name,
|
|
GenericAlternate **obj, size_t size,
|
|
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.end_struct = qobject_input_pop;
|
|
v->visitor.start_list = qobject_input_start_list;
|
|
v->visitor.start_list = qobject_input_start_list;
|
|
v->visitor.next_list = qobject_input_next_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.end_list = qobject_input_pop;
|
|
v->visitor.start_alternate = qobject_input_start_alternate;
|
|
v->visitor.start_alternate = qobject_input_start_alternate;
|
|
v->visitor.type_int64 = qobject_input_type_int64;
|
|
v->visitor.type_int64 = qobject_input_type_int64;
|