mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-07-26 20:03:54 -06:00
qapi: Make input visitors detect unvisited list tails
Fix the design flaw demonstrated in the previous commit: new method check_list() lets input visitors report that unvisited input remains for a list, exactly like check_struct() lets them report that unvisited input remains for a struct or union. Implement the method for the qobject input visitor (straightforward), and the string input visitor (less so, due to the magic list syntax there). The opts visitor's list magic is even more impenetrable, and all I can do there today is a stub with a FIXME comment. No worse than before. Signed-off-by: Markus Armbruster <armbru@redhat.com> Message-Id: <1488544368-30622-26-git-send-email-armbru@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com>
This commit is contained in:
parent
86ca0dbe04
commit
a4a1c70dc7
12 changed files with 116 additions and 10 deletions
|
@ -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);
|
||||
|
||||
if (!so->entry) {
|
||||
assert(tos && tos->obj && qobject_type(tos->obj) == QTYPE_QLIST);
|
||||
|
||||
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;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue