aboutsummaryrefslogtreecommitdiff
path: root/qapi
diff options
context:
space:
mode:
Diffstat (limited to 'qapi')
-rw-r--r--qapi/qapi-visit-core.c8
-rw-r--r--qapi/qmp-output-visitor.c21
-rw-r--r--qapi/string-output-visitor.c22
3 files changed, 32 insertions, 19 deletions
diff --git a/qapi/qapi-visit-core.c b/qapi/qapi-visit-core.c
index 5f68c251d2..eb7dd7253c 100644
--- a/qapi/qapi-visit-core.c
+++ b/qapi/qapi-visit-core.c
@@ -20,6 +20,14 @@
#include "qapi/visitor.h"
#include "qapi/visitor-impl.h"
+void visit_complete(Visitor *v, void *opaque)
+{
+ assert(v->type != VISITOR_OUTPUT || v->complete);
+ if (v->complete) {
+ v->complete(v, opaque);
+ }
+}
+
void visit_free(Visitor *v)
{
if (v) {
diff --git a/qapi/qmp-output-visitor.c b/qapi/qmp-output-visitor.c
index 3d12623cf9..0452056d42 100644
--- a/qapi/qmp-output-visitor.c
+++ b/qapi/qmp-output-visitor.c
@@ -33,6 +33,7 @@ struct QmpOutputVisitor
Visitor visitor;
QStack stack; /* Stack of containers that haven't yet been finished */
QObject *root; /* Root of the output visit */
+ QObject **result; /* User's storage location for result */
};
#define qmp_output_add(qov, name, value) \
@@ -200,18 +201,17 @@ static void qmp_output_type_null(Visitor *v, const char *name, Error **errp)
/* Finish building, and return the root object.
* The root object is never null. The caller becomes the object's
* owner, and should use qobject_decref() when done with it. */
-QObject *qmp_output_get_qobject(QmpOutputVisitor *qov)
+static void qmp_output_complete(Visitor *v, void *opaque)
{
+ QmpOutputVisitor *qov = to_qov(v);
+
/* A visit must have occurred, with each start paired with end. */
assert(qov->root && QTAILQ_EMPTY(&qov->stack));
+ assert(opaque == qov->result);
qobject_incref(qov->root);
- return qov->root;
-}
-
-Visitor *qmp_output_get_visitor(QmpOutputVisitor *v)
-{
- return &v->visitor;
+ *qov->result = qov->root;
+ qov->result = NULL;
}
static void qmp_output_free(Visitor *v)
@@ -228,7 +228,7 @@ static void qmp_output_free(Visitor *v)
g_free(qov);
}
-QmpOutputVisitor *qmp_output_visitor_new(void)
+Visitor *qmp_output_visitor_new(QObject **result)
{
QmpOutputVisitor *v;
@@ -247,9 +247,12 @@ QmpOutputVisitor *qmp_output_visitor_new(void)
v->visitor.type_number = qmp_output_type_number;
v->visitor.type_any = qmp_output_type_any;
v->visitor.type_null = qmp_output_type_null;
+ v->visitor.complete = qmp_output_complete;
v->visitor.free = qmp_output_free;
QTAILQ_INIT(&v->stack);
+ *result = NULL;
+ v->result = result;
- return v;
+ return &v->visitor;
}
diff --git a/qapi/string-output-visitor.c b/qapi/string-output-visitor.c
index 78aab876e3..94ac8211d1 100644
--- a/qapi/string-output-visitor.c
+++ b/qapi/string-output-visitor.c
@@ -58,6 +58,7 @@ struct StringOutputVisitor
Visitor visitor;
bool human;
GString *string;
+ char **result;
ListMode list_mode;
union {
int64_t s;
@@ -305,16 +306,13 @@ static void end_list(Visitor *v, void **obj)
sov->list_mode = LM_NONE;
}
-char *string_output_get_string(StringOutputVisitor *sov)
+static void string_output_complete(Visitor *v, void *opaque)
{
- char *string = g_string_free(sov->string, false);
- sov->string = NULL;
- return string;
-}
+ StringOutputVisitor *sov = to_sov(v);
-Visitor *string_output_get_visitor(StringOutputVisitor *sov)
-{
- return &sov->visitor;
+ assert(opaque == sov->result);
+ *sov->result = g_string_free(sov->string, false);
+ sov->string = NULL;
}
static void free_range(void *range, void *dummy)
@@ -335,7 +333,7 @@ static void string_output_free(Visitor *v)
g_free(sov);
}
-StringOutputVisitor *string_output_visitor_new(bool human)
+Visitor *string_output_visitor_new(bool human, char **result)
{
StringOutputVisitor *v;
@@ -343,6 +341,9 @@ StringOutputVisitor *string_output_visitor_new(bool human)
v->string = g_string_new(NULL);
v->human = human;
+ v->result = result;
+ *result = NULL;
+
v->visitor.type = VISITOR_OUTPUT;
v->visitor.type_int64 = print_type_int64;
v->visitor.type_uint64 = print_type_uint64;
@@ -353,7 +354,8 @@ StringOutputVisitor *string_output_visitor_new(bool human)
v->visitor.start_list = start_list;
v->visitor.next_list = next_list;
v->visitor.end_list = end_list;
+ v->visitor.complete = string_output_complete;
v->visitor.free = string_output_free;
- return v;
+ return &v->visitor;
}