diff mbox

[v11,4/6] qapi: rename QmpOutputVisitor to QObjectOutputVisitor

Message ID 1473088600-17930-5-git-send-email-berrange@redhat.com (mailing list archive)
State New, archived
Headers show

Commit Message

Daniel P. Berrangé Sept. 5, 2016, 3:16 p.m. UTC
The QmpOutputVisitor has no direct dependancy on QMP. It is
valid to use it anywhere that one wants a QObject. Rename it
to better reflect its functionality as a generic QAPI
to QObject convertor.

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
---
 block/qapi.c                                       |   4 +-
 blockdev.c                                         |   4 +-
 docs/qapi-code-gen.txt                             |   2 +-
 ...p-output-visitor.h => qobject-output-visitor.h} |  10 +-
 qapi/Makefile.objs                                 |   2 +-
 qapi/qapi-clone-visitor.c                          |   2 +-
 qapi/qmp-output-visitor.c                          | 256 ---------------------
 qapi/qobject-output-visitor.c                      | 254 ++++++++++++++++++++
 qemu-img.c                                         |   8 +-
 qom/object_interfaces.c                            |   2 +-
 qom/qom-qobject.c                                  |   4 +-
 scripts/qapi-commands.py                           |   4 +-
 scripts/qapi-event.py                              |   4 +-
 tests/.gitignore                                   |   2 +-
 tests/Makefile.include                             |   8 +-
 tests/check-qnull.c                                |   4 +-
 ...put-visitor.c => test-qobject-output-visitor.c} |   4 +-
 tests/test-string-output-visitor.c                 |   2 +-
 tests/test-visitor-serialization.c                 |   4 +-
 util/qemu-sockets.c                                |   2 +-
 20 files changed, 290 insertions(+), 292 deletions(-)
 rename include/qapi/{qmp-output-visitor.h => qobject-output-visitor.h} (66%)
 delete mode 100644 qapi/qmp-output-visitor.c
 create mode 100644 qapi/qobject-output-visitor.c
 rename tests/{test-qmp-output-visitor.c => test-qobject-output-visitor.c} (99%)

Comments

Markus Armbruster Sept. 12, 2016, 4:20 p.m. UTC | #1
"Daniel P. Berrange" <berrange@redhat.com> writes:

> The QmpOutputVisitor has no direct dependancy on QMP. It is
> valid to use it anywhere that one wants a QObject. Rename it
> to better reflect its functionality as a generic QAPI
> to QObject convertor.
>
> Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
> ---
>  block/qapi.c                                       |   4 +-
>  blockdev.c                                         |   4 +-
>  docs/qapi-code-gen.txt                             |   2 +-
>  ...p-output-visitor.h => qobject-output-visitor.h} |  10 +-
>  qapi/Makefile.objs                                 |   2 +-
>  qapi/qapi-clone-visitor.c                          |   2 +-
>  qapi/qmp-output-visitor.c                          | 256 ---------------------
>  qapi/qobject-output-visitor.c                      | 254 ++++++++++++++++++++
>  qemu-img.c                                         |   8 +-
>  qom/object_interfaces.c                            |   2 +-
>  qom/qom-qobject.c                                  |   4 +-
>  scripts/qapi-commands.py                           |   4 +-
>  scripts/qapi-event.py                              |   4 +-
>  tests/.gitignore                                   |   2 +-
>  tests/Makefile.include                             |   8 +-
>  tests/check-qnull.c                                |   4 +-
>  ...put-visitor.c => test-qobject-output-visitor.c} |   4 +-
>  tests/test-string-output-visitor.c                 |   2 +-
>  tests/test-visitor-serialization.c                 |   4 +-
>  util/qemu-sockets.c                                |   2 +-
>  20 files changed, 290 insertions(+), 292 deletions(-)
>  rename include/qapi/{qmp-output-visitor.h => qobject-output-visitor.h} (66%)
>  delete mode 100644 qapi/qmp-output-visitor.c
>  create mode 100644 qapi/qobject-output-visitor.c
>  rename tests/{test-qmp-output-visitor.c => test-qobject-output-visitor.c} (99%)

$ git-grep -Ei 'qmp.?output.*?vis'
tests/test-qobject-output-visitor.c: * QMP Output Visitor unit-tests.
Eric Blake Sept. 12, 2016, 6:24 p.m. UTC | #2
On 09/05/2016 10:16 AM, Daniel P. Berrange wrote:
> The QmpOutputVisitor has no direct dependancy on QMP. It is

s/dependancy/dependency/

> valid to use it anywhere that one wants a QObject. Rename it
> to better reflect its functionality as a generic QAPI
> to QObject convertor.

c/convertor/converter/

> 
> Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
> ---

Other than the last couple spots found by Markus' grep, both 3/6 and
this 4/6 are fairly mechanical and verified by the compiler, so on the
respin, you can add:
Reviewed-by: Eric Blake <eblake@redhat.com>
Daniel P. Berrangé Sept. 13, 2016, 10:25 a.m. UTC | #3
On Mon, Sep 12, 2016 at 06:20:36PM +0200, Markus Armbruster wrote:
> "Daniel P. Berrange" <berrange@redhat.com> writes:
> 
> > The QmpOutputVisitor has no direct dependancy on QMP. It is
> > valid to use it anywhere that one wants a QObject. Rename it
> > to better reflect its functionality as a generic QAPI
> > to QObject convertor.
> >
> > Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
> > ---
> >  block/qapi.c                                       |   4 +-
> >  blockdev.c                                         |   4 +-
> >  docs/qapi-code-gen.txt                             |   2 +-
> >  ...p-output-visitor.h => qobject-output-visitor.h} |  10 +-
> >  qapi/Makefile.objs                                 |   2 +-
> >  qapi/qapi-clone-visitor.c                          |   2 +-
> >  qapi/qmp-output-visitor.c                          | 256 ---------------------
> >  qapi/qobject-output-visitor.c                      | 254 ++++++++++++++++++++
> >  qemu-img.c                                         |   8 +-
> >  qom/object_interfaces.c                            |   2 +-
> >  qom/qom-qobject.c                                  |   4 +-
> >  scripts/qapi-commands.py                           |   4 +-
> >  scripts/qapi-event.py                              |   4 +-
> >  tests/.gitignore                                   |   2 +-
> >  tests/Makefile.include                             |   8 +-
> >  tests/check-qnull.c                                |   4 +-
> >  ...put-visitor.c => test-qobject-output-visitor.c} |   4 +-
> >  tests/test-string-output-visitor.c                 |   2 +-
> >  tests/test-visitor-serialization.c                 |   4 +-
> >  util/qemu-sockets.c                                |   2 +-
> >  20 files changed, 290 insertions(+), 292 deletions(-)
> >  rename include/qapi/{qmp-output-visitor.h => qobject-output-visitor.h} (66%)
> >  delete mode 100644 qapi/qmp-output-visitor.c
> >  create mode 100644 qapi/qobject-output-visitor.c
> >  rename tests/{test-qmp-output-visitor.c => test-qobject-output-visitor.c} (99%)
> 
> $ git-grep -Ei 'qmp.?output.*?vis'
> tests/test-qobject-output-visitor.c: * QMP Output Visitor unit-tests.

Yep, will fix that.

Regards,
Daniel
diff mbox

Patch

diff --git a/block/qapi.c b/block/qapi.c
index 6f947e3..f35c89f 100644
--- a/block/qapi.c
+++ b/block/qapi.c
@@ -29,7 +29,7 @@ 
 #include "block/write-threshold.h"
 #include "qmp-commands.h"
 #include "qapi-visit.h"
-#include "qapi/qmp-output-visitor.h"
+#include "qapi/qobject-output-visitor.h"
 #include "qapi/qmp/types.h"
 #include "sysemu/block-backend.h"
 #include "qemu/cutils.h"
@@ -691,7 +691,7 @@  void bdrv_image_info_specific_dump(fprintf_function func_fprintf, void *f,
                                    ImageInfoSpecific *info_spec)
 {
     QObject *obj, *data;
-    Visitor *v = qmp_output_visitor_new(&obj);
+    Visitor *v = qobject_output_visitor_new(&obj);
 
     visit_type_ImageInfoSpecific(v, NULL, &info_spec, &error_abort);
     visit_complete(v, &obj);
diff --git a/blockdev.c b/blockdev.c
index 2161400..2d388d6 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -43,7 +43,7 @@ 
 #include "qapi/qmp/types.h"
 #include "qapi-visit.h"
 #include "qapi/qmp/qerror.h"
-#include "qapi/qmp-output-visitor.h"
+#include "qapi/qobject-output-visitor.h"
 #include "qapi/util.h"
 #include "sysemu/sysemu.h"
 #include "block/block_int.h"
@@ -3907,7 +3907,7 @@  void qmp_blockdev_add(BlockdevOptions *options, Error **errp)
     BlockDriverState *bs;
     BlockBackend *blk = NULL;
     QObject *obj;
-    Visitor *v = qmp_output_visitor_new(&obj);
+    Visitor *v = qobject_output_visitor_new(&obj);
     QDict *qdict;
     Error *local_err = NULL;
 
diff --git a/docs/qapi-code-gen.txt b/docs/qapi-code-gen.txt
index a011872..dd19172 100644
--- a/docs/qapi-code-gen.txt
+++ b/docs/qapi-code-gen.txt
@@ -1005,7 +1005,7 @@  Example:
         Error *err = NULL;
         Visitor *v;
 
-        v = qmp_output_visitor_new(ret_out);
+        v = qobject_output_visitor_new(ret_out);
         visit_type_UserDefOne(v, "unused", &ret_in, &err);
         if (!err) {
             visit_complete(v, ret_out);
diff --git a/include/qapi/qmp-output-visitor.h b/include/qapi/qobject-output-visitor.h
similarity index 66%
rename from include/qapi/qmp-output-visitor.h
rename to include/qapi/qobject-output-visitor.h
index 040fdda..358c959 100644
--- a/include/qapi/qmp-output-visitor.h
+++ b/include/qapi/qobject-output-visitor.h
@@ -11,20 +11,20 @@ 
  *
  */
 
-#ifndef QMP_OUTPUT_VISITOR_H
-#define QMP_OUTPUT_VISITOR_H
+#ifndef QOBJECT_OUTPUT_VISITOR_H
+#define QOBJECT_OUTPUT_VISITOR_H
 
 #include "qapi/visitor.h"
 #include "qapi/qmp/qobject.h"
 
-typedef struct QmpOutputVisitor QmpOutputVisitor;
+typedef struct QObjectOutputVisitor QObjectOutputVisitor;
 
 /*
- * Create a new QMP output visitor.
+ * Create a new QOBJECT output visitor.
  *
  * If everything else succeeds, pass @result to visit_complete() to
  * collect the result of the visit.
  */
-Visitor *qmp_output_visitor_new(QObject **result);
+Visitor *qobject_output_visitor_new(QObject **result);
 
 #endif
diff --git a/qapi/Makefile.objs b/qapi/Makefile.objs
index 6ec7bdc..33906ff 100644
--- a/qapi/Makefile.objs
+++ b/qapi/Makefile.objs
@@ -1,5 +1,5 @@ 
 util-obj-y = qapi-visit-core.o qapi-dealloc-visitor.o qobject-input-visitor.o
-util-obj-y += qmp-output-visitor.o qmp-registry.o qmp-dispatch.o
+util-obj-y += qobject-output-visitor.o qmp-registry.o qmp-dispatch.o
 util-obj-y += string-input-visitor.o string-output-visitor.o
 util-obj-y += opts-visitor.o qapi-clone-visitor.o
 util-obj-y += qmp-event.o
diff --git a/qapi/qapi-clone-visitor.c b/qapi/qapi-clone-visitor.c
index 0bb8216..34086cb 100644
--- a/qapi/qapi-clone-visitor.c
+++ b/qapi/qapi-clone-visitor.c
@@ -110,7 +110,7 @@  static void qapi_clone_type_str(Visitor *v, const char *name, char **obj,
     assert(qcv->depth);
     /*
      * Pointer was already cloned by g_memdup; create fresh copy.
-     * Note that as long as qmp-output-visitor accepts NULL instead of
+     * Note that as long as qobject-output-visitor accepts NULL instead of
      * "", then we must do likewise. However, we want to obey the
      * input visitor semantics of never producing NULL when the empty
      * string is intended.
diff --git a/qapi/qmp-output-visitor.c b/qapi/qmp-output-visitor.c
deleted file mode 100644
index 9e3b67c..0000000
--- a/qapi/qmp-output-visitor.c
+++ /dev/null
@@ -1,256 +0,0 @@ 
-/*
- * Core Definitions for QAPI/QMP Command Registry
- *
- * Copyright (C) 2012-2016 Red Hat, Inc.
- * Copyright IBM, Corp. 2011
- *
- * Authors:
- *  Anthony Liguori   <aliguori@us.ibm.com>
- *
- * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
- * See the COPYING.LIB file in the top-level directory.
- *
- */
-
-#include "qemu/osdep.h"
-#include "qapi/qmp-output-visitor.h"
-#include "qapi/visitor-impl.h"
-#include "qemu/queue.h"
-#include "qemu-common.h"
-#include "qapi/qmp/types.h"
-
-typedef struct QStackEntry
-{
-    QObject *value;
-    void *qapi; /* sanity check that caller uses same pointer */
-    QSLIST_ENTRY(QStackEntry) node;
-} QStackEntry;
-
-struct QmpOutputVisitor
-{
-    Visitor visitor;
-    QSLIST_HEAD(, QStackEntry) stack; /* Stack of unfinished containers */
-    QObject *root; /* Root of the output visit */
-    QObject **result; /* User's storage location for result */
-};
-
-#define qmp_output_add(qov, name, value) \
-    qmp_output_add_obj(qov, name, QOBJECT(value))
-#define qmp_output_push(qov, value, qapi) \
-    qmp_output_push_obj(qov, QOBJECT(value), qapi)
-
-static QmpOutputVisitor *to_qov(Visitor *v)
-{
-    return container_of(v, QmpOutputVisitor, visitor);
-}
-
-/* Push @value onto the stack of current QObjects being built */
-static void qmp_output_push_obj(QmpOutputVisitor *qov, QObject *value,
-                                void *qapi)
-{
-    QStackEntry *e = g_malloc0(sizeof(*e));
-
-    assert(qov->root);
-    assert(value);
-    e->value = value;
-    e->qapi = qapi;
-    QSLIST_INSERT_HEAD(&qov->stack, e, node);
-}
-
-/* Pop a value off the stack of QObjects being built, and return it. */
-static QObject *qmp_output_pop(QmpOutputVisitor *qov, void *qapi)
-{
-    QStackEntry *e = QSLIST_FIRST(&qov->stack);
-    QObject *value;
-
-    assert(e);
-    assert(e->qapi == qapi);
-    QSLIST_REMOVE_HEAD(&qov->stack, node);
-    value = e->value;
-    assert(value);
-    g_free(e);
-    return value;
-}
-
-/* Add @value to the current QObject being built.
- * If the stack is visiting a dictionary or list, @value is now owned
- * by that container. Otherwise, @value is now the root.  */
-static void qmp_output_add_obj(QmpOutputVisitor *qov, const char *name,
-                               QObject *value)
-{
-    QStackEntry *e = QSLIST_FIRST(&qov->stack);
-    QObject *cur = e ? e->value : NULL;
-
-    if (!cur) {
-        /* Don't allow reuse of visitor on more than one root */
-        assert(!qov->root);
-        qov->root = value;
-    } else {
-        switch (qobject_type(cur)) {
-        case QTYPE_QDICT:
-            assert(name);
-            qdict_put_obj(qobject_to_qdict(cur), name, value);
-            break;
-        case QTYPE_QLIST:
-            assert(!name);
-            qlist_append_obj(qobject_to_qlist(cur), value);
-            break;
-        default:
-            g_assert_not_reached();
-        }
-    }
-}
-
-static void qmp_output_start_struct(Visitor *v, const char *name, void **obj,
-                                    size_t unused, Error **errp)
-{
-    QmpOutputVisitor *qov = to_qov(v);
-    QDict *dict = qdict_new();
-
-    qmp_output_add(qov, name, dict);
-    qmp_output_push(qov, dict, obj);
-}
-
-static void qmp_output_end_struct(Visitor *v, void **obj)
-{
-    QmpOutputVisitor *qov = to_qov(v);
-    QObject *value = qmp_output_pop(qov, obj);
-    assert(qobject_type(value) == QTYPE_QDICT);
-}
-
-static void qmp_output_start_list(Visitor *v, const char *name,
-                                  GenericList **listp, size_t size,
-                                  Error **errp)
-{
-    QmpOutputVisitor *qov = to_qov(v);
-    QList *list = qlist_new();
-
-    qmp_output_add(qov, name, list);
-    qmp_output_push(qov, list, listp);
-}
-
-static GenericList *qmp_output_next_list(Visitor *v, GenericList *tail,
-                                         size_t size)
-{
-    return tail->next;
-}
-
-static void qmp_output_end_list(Visitor *v, void **obj)
-{
-    QmpOutputVisitor *qov = to_qov(v);
-    QObject *value = qmp_output_pop(qov, obj);
-    assert(qobject_type(value) == QTYPE_QLIST);
-}
-
-static void qmp_output_type_int64(Visitor *v, const char *name, int64_t *obj,
-                                  Error **errp)
-{
-    QmpOutputVisitor *qov = to_qov(v);
-    qmp_output_add(qov, name, qint_from_int(*obj));
-}
-
-static void qmp_output_type_uint64(Visitor *v, const char *name, uint64_t *obj,
-                                   Error **errp)
-{
-    /* FIXME: QMP outputs values larger than INT64_MAX as negative */
-    QmpOutputVisitor *qov = to_qov(v);
-    qmp_output_add(qov, name, qint_from_int(*obj));
-}
-
-static void qmp_output_type_bool(Visitor *v, const char *name, bool *obj,
-                                 Error **errp)
-{
-    QmpOutputVisitor *qov = to_qov(v);
-    qmp_output_add(qov, name, qbool_from_bool(*obj));
-}
-
-static void qmp_output_type_str(Visitor *v, const char *name, char **obj,
-                                Error **errp)
-{
-    QmpOutputVisitor *qov = to_qov(v);
-    if (*obj) {
-        qmp_output_add(qov, name, qstring_from_str(*obj));
-    } else {
-        qmp_output_add(qov, name, qstring_from_str(""));
-    }
-}
-
-static void qmp_output_type_number(Visitor *v, const char *name, double *obj,
-                                   Error **errp)
-{
-    QmpOutputVisitor *qov = to_qov(v);
-    qmp_output_add(qov, name, qfloat_from_double(*obj));
-}
-
-static void qmp_output_type_any(Visitor *v, const char *name, QObject **obj,
-                                Error **errp)
-{
-    QmpOutputVisitor *qov = to_qov(v);
-    qobject_incref(*obj);
-    qmp_output_add_obj(qov, name, *obj);
-}
-
-static void qmp_output_type_null(Visitor *v, const char *name, Error **errp)
-{
-    QmpOutputVisitor *qov = to_qov(v);
-    qmp_output_add_obj(qov, name, qnull());
-}
-
-/* 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.  */
-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 && QSLIST_EMPTY(&qov->stack));
-    assert(opaque == qov->result);
-
-    qobject_incref(qov->root);
-    *qov->result = qov->root;
-    qov->result = NULL;
-}
-
-static void qmp_output_free(Visitor *v)
-{
-    QmpOutputVisitor *qov = to_qov(v);
-    QStackEntry *e;
-
-    while (!QSLIST_EMPTY(&qov->stack)) {
-        e = QSLIST_FIRST(&qov->stack);
-        QSLIST_REMOVE_HEAD(&qov->stack, node);
-        g_free(e);
-    }
-
-    qobject_decref(qov->root);
-    g_free(qov);
-}
-
-Visitor *qmp_output_visitor_new(QObject **result)
-{
-    QmpOutputVisitor *v;
-
-    v = g_malloc0(sizeof(*v));
-
-    v->visitor.type = VISITOR_OUTPUT;
-    v->visitor.start_struct = qmp_output_start_struct;
-    v->visitor.end_struct = qmp_output_end_struct;
-    v->visitor.start_list = qmp_output_start_list;
-    v->visitor.next_list = qmp_output_next_list;
-    v->visitor.end_list = qmp_output_end_list;
-    v->visitor.type_int64 = qmp_output_type_int64;
-    v->visitor.type_uint64 = qmp_output_type_uint64;
-    v->visitor.type_bool = qmp_output_type_bool;
-    v->visitor.type_str = qmp_output_type_str;
-    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;
-
-    *result = NULL;
-    v->result = result;
-
-    return &v->visitor;
-}
diff --git a/qapi/qobject-output-visitor.c b/qapi/qobject-output-visitor.c
new file mode 100644
index 0000000..df43cb8
--- /dev/null
+++ b/qapi/qobject-output-visitor.c
@@ -0,0 +1,254 @@ 
+/*
+ * Core Definitions for QAPI/QMP Command Registry
+ *
+ * Copyright (C) 2012-2016 Red Hat, Inc.
+ * Copyright IBM, Corp. 2011
+ *
+ * Authors:
+ *  Anthony Liguori   <aliguori@us.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ *
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/qobject-output-visitor.h"
+#include "qapi/visitor-impl.h"
+#include "qemu/queue.h"
+#include "qemu-common.h"
+#include "qapi/qmp/types.h"
+
+typedef struct QStackEntry {
+    QObject *value;
+    void *qapi; /* sanity check that caller uses same pointer */
+    QSLIST_ENTRY(QStackEntry) node;
+} QStackEntry;
+
+struct QObjectOutputVisitor {
+    Visitor visitor;
+    QSLIST_HEAD(, QStackEntry) stack; /* Stack of unfinished containers */
+    QObject *root; /* Root of the output visit */
+    QObject **result; /* User's storage location for result */
+};
+
+#define qobject_output_add(qov, name, value) \
+    qobject_output_add_obj(qov, name, QOBJECT(value))
+#define qobject_output_push(qov, value, qapi) \
+    qobject_output_push_obj(qov, QOBJECT(value), qapi)
+
+static QObjectOutputVisitor *to_qov(Visitor *v)
+{
+    return container_of(v, QObjectOutputVisitor, visitor);
+}
+
+/* Push @value onto the stack of current QObjects being built */
+static void qobject_output_push_obj(QObjectOutputVisitor *qov, QObject *value,
+                                    void *qapi)
+{
+    QStackEntry *e = g_malloc0(sizeof(*e));
+
+    assert(qov->root);
+    assert(value);
+    e->value = value;
+    e->qapi = qapi;
+    QSLIST_INSERT_HEAD(&qov->stack, e, node);
+}
+
+/* Pop a value off the stack of QObjects being built, and return it. */
+static QObject *qobject_output_pop(QObjectOutputVisitor *qov, void *qapi)
+{
+    QStackEntry *e = QSLIST_FIRST(&qov->stack);
+    QObject *value;
+
+    assert(e);
+    assert(e->qapi == qapi);
+    QSLIST_REMOVE_HEAD(&qov->stack, node);
+    value = e->value;
+    assert(value);
+    g_free(e);
+    return value;
+}
+
+/* Add @value to the current QObject being built.
+ * If the stack is visiting a dictionary or list, @value is now owned
+ * by that container. Otherwise, @value is now the root.  */
+static void qobject_output_add_obj(QObjectOutputVisitor *qov, const char *name,
+                                   QObject *value)
+{
+    QStackEntry *e = QSLIST_FIRST(&qov->stack);
+    QObject *cur = e ? e->value : NULL;
+
+    if (!cur) {
+        /* Don't allow reuse of visitor on more than one root */
+        assert(!qov->root);
+        qov->root = value;
+    } else {
+        switch (qobject_type(cur)) {
+        case QTYPE_QDICT:
+            assert(name);
+            qdict_put_obj(qobject_to_qdict(cur), name, value);
+            break;
+        case QTYPE_QLIST:
+            assert(!name);
+            qlist_append_obj(qobject_to_qlist(cur), value);
+            break;
+        default:
+            g_assert_not_reached();
+        }
+    }
+}
+
+static void qobject_output_start_struct(Visitor *v, const char *name,
+                                        void **obj, size_t unused, Error **errp)
+{
+    QObjectOutputVisitor *qov = to_qov(v);
+    QDict *dict = qdict_new();
+
+    qobject_output_add(qov, name, dict);
+    qobject_output_push(qov, dict, obj);
+}
+
+static void qobject_output_end_struct(Visitor *v, void **obj)
+{
+    QObjectOutputVisitor *qov = to_qov(v);
+    QObject *value = qobject_output_pop(qov, obj);
+    assert(qobject_type(value) == QTYPE_QDICT);
+}
+
+static void qobject_output_start_list(Visitor *v, const char *name,
+                                      GenericList **listp, size_t size,
+                                      Error **errp)
+{
+    QObjectOutputVisitor *qov = to_qov(v);
+    QList *list = qlist_new();
+
+    qobject_output_add(qov, name, list);
+    qobject_output_push(qov, list, listp);
+}
+
+static GenericList *qobject_output_next_list(Visitor *v, GenericList *tail,
+                                             size_t size)
+{
+    return tail->next;
+}
+
+static void qobject_output_end_list(Visitor *v, void **obj)
+{
+    QObjectOutputVisitor *qov = to_qov(v);
+    QObject *value = qobject_output_pop(qov, obj);
+    assert(qobject_type(value) == QTYPE_QLIST);
+}
+
+static void qobject_output_type_int64(Visitor *v, const char *name,
+                                      int64_t *obj, Error **errp)
+{
+    QObjectOutputVisitor *qov = to_qov(v);
+    qobject_output_add(qov, name, qint_from_int(*obj));
+}
+
+static void qobject_output_type_uint64(Visitor *v, const char *name,
+                                       uint64_t *obj, Error **errp)
+{
+    /* FIXME: QOBJECT outputs values larger than INT64_MAX as negative */
+    QObjectOutputVisitor *qov = to_qov(v);
+    qobject_output_add(qov, name, qint_from_int(*obj));
+}
+
+static void qobject_output_type_bool(Visitor *v, const char *name, bool *obj,
+                                     Error **errp)
+{
+    QObjectOutputVisitor *qov = to_qov(v);
+    qobject_output_add(qov, name, qbool_from_bool(*obj));
+}
+
+static void qobject_output_type_str(Visitor *v, const char *name, char **obj,
+                                    Error **errp)
+{
+    QObjectOutputVisitor *qov = to_qov(v);
+    if (*obj) {
+        qobject_output_add(qov, name, qstring_from_str(*obj));
+    } else {
+        qobject_output_add(qov, name, qstring_from_str(""));
+    }
+}
+
+static void qobject_output_type_number(Visitor *v, const char *name,
+                                       double *obj, Error **errp)
+{
+    QObjectOutputVisitor *qov = to_qov(v);
+    qobject_output_add(qov, name, qfloat_from_double(*obj));
+}
+
+static void qobject_output_type_any(Visitor *v, const char *name,
+                                    QObject **obj, Error **errp)
+{
+    QObjectOutputVisitor *qov = to_qov(v);
+    qobject_incref(*obj);
+    qobject_output_add_obj(qov, name, *obj);
+}
+
+static void qobject_output_type_null(Visitor *v, const char *name, Error **errp)
+{
+    QObjectOutputVisitor *qov = to_qov(v);
+    qobject_output_add_obj(qov, name, qnull());
+}
+
+/* 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.  */
+static void qobject_output_complete(Visitor *v, void *opaque)
+{
+    QObjectOutputVisitor *qov = to_qov(v);
+
+    /* A visit must have occurred, with each start paired with end.  */
+    assert(qov->root && QSLIST_EMPTY(&qov->stack));
+    assert(opaque == qov->result);
+
+    qobject_incref(qov->root);
+    *qov->result = qov->root;
+    qov->result = NULL;
+}
+
+static void qobject_output_free(Visitor *v)
+{
+    QObjectOutputVisitor *qov = to_qov(v);
+    QStackEntry *e;
+
+    while (!QSLIST_EMPTY(&qov->stack)) {
+        e = QSLIST_FIRST(&qov->stack);
+        QSLIST_REMOVE_HEAD(&qov->stack, node);
+        g_free(e);
+    }
+
+    qobject_decref(qov->root);
+    g_free(qov);
+}
+
+Visitor *qobject_output_visitor_new(QObject **result)
+{
+    QObjectOutputVisitor *v;
+
+    v = g_malloc0(sizeof(*v));
+
+    v->visitor.type = VISITOR_OUTPUT;
+    v->visitor.start_struct = qobject_output_start_struct;
+    v->visitor.end_struct = qobject_output_end_struct;
+    v->visitor.start_list = qobject_output_start_list;
+    v->visitor.next_list = qobject_output_next_list;
+    v->visitor.end_list = qobject_output_end_list;
+    v->visitor.type_int64 = qobject_output_type_int64;
+    v->visitor.type_uint64 = qobject_output_type_uint64;
+    v->visitor.type_bool = qobject_output_type_bool;
+    v->visitor.type_str = qobject_output_type_str;
+    v->visitor.type_number = qobject_output_type_number;
+    v->visitor.type_any = qobject_output_type_any;
+    v->visitor.type_null = qobject_output_type_null;
+    v->visitor.complete = qobject_output_complete;
+    v->visitor.free = qobject_output_free;
+
+    *result = NULL;
+    v->result = result;
+
+    return &v->visitor;
+}
diff --git a/qemu-img.c b/qemu-img.c
index f204d041..a6e9c1e 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -25,7 +25,7 @@ 
 #include "qemu-version.h"
 #include "qapi/error.h"
 #include "qapi-visit.h"
-#include "qapi/qmp-output-visitor.h"
+#include "qapi/qobject-output-visitor.h"
 #include "qapi/qmp/qerror.h"
 #include "qapi/qmp/qjson.h"
 #include "qemu/cutils.h"
@@ -492,7 +492,7 @@  static void dump_json_image_check(ImageCheck *check, bool quiet)
 {
     QString *str;
     QObject *obj;
-    Visitor *v = qmp_output_visitor_new(&obj);
+    Visitor *v = qobject_output_visitor_new(&obj);
 
     visit_type_ImageCheck(v, NULL, &check, &error_abort);
     visit_complete(v, &obj);
@@ -2183,7 +2183,7 @@  static void dump_json_image_info_list(ImageInfoList *list)
 {
     QString *str;
     QObject *obj;
-    Visitor *v = qmp_output_visitor_new(&obj);
+    Visitor *v = qobject_output_visitor_new(&obj);
 
     visit_type_ImageInfoList(v, NULL, &list, &error_abort);
     visit_complete(v, &obj);
@@ -2199,7 +2199,7 @@  static void dump_json_image_info(ImageInfo *info)
 {
     QString *str;
     QObject *obj;
-    Visitor *v = qmp_output_visitor_new(&obj);
+    Visitor *v = qobject_output_visitor_new(&obj);
 
     visit_type_ImageInfo(v, NULL, &info, &error_abort);
     visit_complete(v, &obj);
diff --git a/qom/object_interfaces.c b/qom/object_interfaces.c
index bf59846..ded4d84 100644
--- a/qom/object_interfaces.c
+++ b/qom/object_interfaces.c
@@ -3,7 +3,7 @@ 
 #include "qom/object_interfaces.h"
 #include "qemu/module.h"
 #include "qapi-visit.h"
-#include "qapi/qmp-output-visitor.h"
+#include "qapi/qobject-output-visitor.h"
 #include "qapi/opts-visitor.h"
 
 void user_creatable_complete(Object *obj, Error **errp)
diff --git a/qom/qom-qobject.c b/qom/qom-qobject.c
index 81959e0..447e4a0 100644
--- a/qom/qom-qobject.c
+++ b/qom/qom-qobject.c
@@ -16,7 +16,7 @@ 
 #include "qom/qom-qobject.h"
 #include "qapi/visitor.h"
 #include "qapi/qobject-input-visitor.h"
-#include "qapi/qmp-output-visitor.h"
+#include "qapi/qobject-output-visitor.h"
 
 void object_property_set_qobject(Object *obj, QObject *value,
                                  const char *name, Error **errp)
@@ -35,7 +35,7 @@  QObject *object_property_get_qobject(Object *obj, const char *name,
     Error *local_err = NULL;
     Visitor *v;
 
-    v = qmp_output_visitor_new(&ret);
+    v = qobject_output_visitor_new(&ret);
     object_property_get(obj, v, name, &local_err);
     if (!local_err) {
         visit_complete(v, &ret);
diff --git a/scripts/qapi-commands.py b/scripts/qapi-commands.py
index 3010163..bf8372f 100644
--- a/scripts/qapi-commands.py
+++ b/scripts/qapi-commands.py
@@ -68,7 +68,7 @@  static void qmp_marshal_output_%(c_name)s(%(c_type)s ret_in, QObject **ret_out,
     Error *err = NULL;
     Visitor *v;
 
-    v = qmp_output_visitor_new(ret_out);
+    v = qobject_output_visitor_new(ret_out);
     visit_type_%(c_name)s(v, "unused", &ret_in, &err);
     if (!err) {
         visit_complete(v, ret_out);
@@ -278,7 +278,7 @@  fdef.write(mcgen('''
 #include "qapi/qmp/types.h"
 #include "qapi/qmp/dispatch.h"
 #include "qapi/visitor.h"
-#include "qapi/qmp-output-visitor.h"
+#include "qapi/qobject-output-visitor.h"
 #include "qapi/qobject-input-visitor.h"
 #include "qapi/dealloc-visitor.h"
 #include "%(prefix)sqapi-types.h"
diff --git a/scripts/qapi-event.py b/scripts/qapi-event.py
index 38d8211..f4eb7f8 100644
--- a/scripts/qapi-event.py
+++ b/scripts/qapi-event.py
@@ -98,7 +98,7 @@  def gen_event_send(name, arg_type, boxed):
 
     if arg_type and not arg_type.is_empty():
         ret += mcgen('''
-    v = qmp_output_visitor_new(&obj);
+    v = qobject_output_visitor_new(&obj);
 ''')
         if not arg_type.is_implicit():
             ret += mcgen('''
@@ -209,7 +209,7 @@  fdef.write(mcgen('''
 #include "qemu-common.h"
 #include "%(prefix)sqapi-event.h"
 #include "%(prefix)sqapi-visit.h"
-#include "qapi/qmp-output-visitor.h"
+#include "qapi/qobject-output-visitor.h"
 #include "qapi/qmp-event.h"
 
 ''',
diff --git a/tests/.gitignore b/tests/.gitignore
index 4ec0a1a..576b87b 100644
--- a/tests/.gitignore
+++ b/tests/.gitignore
@@ -61,7 +61,7 @@  test-qobject-input-strict
 test-qobject-input-visitor
 test-qmp-introspect.[ch]
 test-qmp-marshal.c
-test-qmp-output-visitor
+test-qobject-output-visitor
 test-rcu-list
 test-rfifolock
 test-string-input-visitor
diff --git a/tests/Makefile.include b/tests/Makefile.include
index 5ac61b7..716fafd 100644
--- a/tests/Makefile.include
+++ b/tests/Makefile.include
@@ -20,8 +20,8 @@  check-unit-y += tests/check-qnull$(EXESUF)
 gcov-files-check-qnull-y = qobject/qnull.c
 check-unit-y += tests/check-qjson$(EXESUF)
 gcov-files-check-qjson-y = qobject/qjson.c
-check-unit-y += tests/test-qmp-output-visitor$(EXESUF)
-gcov-files-test-qmp-output-visitor-y = qapi/qmp-output-visitor.c
+check-unit-y += tests/test-qobject-output-visitor$(EXESUF)
+gcov-files-test-qobject-output-visitor-y = qapi/qobject-output-visitor.c
 check-unit-y += tests/test-clone-visitor$(EXESUF)
 gcov-files-test-clone-visitor-y = qapi/qapi-clone-visitor.c
 check-unit-y += tests/test-qobject-input-visitor$(EXESUF)
@@ -413,7 +413,7 @@  test-obj-y = tests/check-qint.o tests/check-qstring.o tests/check-qdict.o \
 	tests/check-qlist.o tests/check-qfloat.o tests/check-qnull.o \
 	tests/check-qjson.o \
 	tests/test-coroutine.o tests/test-string-output-visitor.o \
-	tests/test-string-input-visitor.o tests/test-qmp-output-visitor.o \
+	tests/test-string-input-visitor.o tests/test-qobject-output-visitor.o \
 	tests/test-clone-visitor.o \
 	tests/test-qobject-input-visitor.o tests/test-qobject-input-strict.o \
 	tests/test-qmp-commands.o tests/test-visitor-serialization.o \
@@ -512,7 +512,7 @@  $(SRC_PATH)/tests/qapi-schema/qapi-schema-test.json $(SRC_PATH)/scripts/qapi-int
 tests/test-string-output-visitor$(EXESUF): tests/test-string-output-visitor.o $(test-qapi-obj-y)
 tests/test-string-input-visitor$(EXESUF): tests/test-string-input-visitor.o $(test-qapi-obj-y)
 tests/test-qmp-event$(EXESUF): tests/test-qmp-event.o $(test-qapi-obj-y)
-tests/test-qmp-output-visitor$(EXESUF): tests/test-qmp-output-visitor.o $(test-qapi-obj-y)
+tests/test-qobject-output-visitor$(EXESUF): tests/test-qobject-output-visitor.o $(test-qapi-obj-y)
 tests/test-clone-visitor$(EXESUF): tests/test-clone-visitor.o $(test-qapi-obj-y)
 tests/test-qobject-input-visitor$(EXESUF): tests/test-qobject-input-visitor.o $(test-qapi-obj-y)
 tests/test-qobject-input-strict$(EXESUF): tests/test-qobject-input-strict.o $(test-qapi-obj-y)
diff --git a/tests/check-qnull.c b/tests/check-qnull.c
index eeb803a..b50bb8a 100644
--- a/tests/check-qnull.c
+++ b/tests/check-qnull.c
@@ -11,7 +11,7 @@ 
 #include "qapi/qmp/qobject.h"
 #include "qemu-common.h"
 #include "qapi/qobject-input-visitor.h"
-#include "qapi/qmp-output-visitor.h"
+#include "qapi/qobject-output-visitor.h"
 #include "qapi/error.h"
 
 /*
@@ -52,7 +52,7 @@  static void qnull_visit_test(void)
     visit_type_null(v, NULL, &error_abort);
     visit_free(v);
 
-    v = qmp_output_visitor_new(&obj);
+    v = qobject_output_visitor_new(&obj);
     visit_type_null(v, NULL, &error_abort);
     visit_complete(v, &obj);
     g_assert(obj == &qnull_);
diff --git a/tests/test-qmp-output-visitor.c b/tests/test-qobject-output-visitor.c
similarity index 99%
rename from tests/test-qmp-output-visitor.c
rename to tests/test-qobject-output-visitor.c
index 513d71f..8f46c71 100644
--- a/tests/test-qmp-output-visitor.c
+++ b/tests/test-qobject-output-visitor.c
@@ -14,7 +14,7 @@ 
 
 #include "qemu-common.h"
 #include "qapi/error.h"
-#include "qapi/qmp-output-visitor.h"
+#include "qapi/qobject-output-visitor.h"
 #include "test-qapi-types.h"
 #include "test-qapi-visit.h"
 #include "qapi/qmp/types.h"
@@ -28,7 +28,7 @@  typedef struct TestOutputVisitorData {
 static void visitor_output_setup(TestOutputVisitorData *data,
                                  const void *unused)
 {
-    data->ov = qmp_output_visitor_new(&data->obj);
+    data->ov = qobject_output_visitor_new(&data->obj);
     g_assert(data->ov);
 }
 
diff --git a/tests/test-string-output-visitor.c b/tests/test-string-output-visitor.c
index 444844a..e736db3 100644
--- a/tests/test-string-output-visitor.c
+++ b/tests/test-string-output-visitor.c
@@ -4,7 +4,7 @@ 
  * Copyright (C) 2012 Red Hat Inc.
  *
  * Authors:
- *  Paolo Bonzini <pbonzini@redhat.com> (based on test-qmp-output-visitor)
+ *  Paolo Bonzini <pbonzini@redhat.com> (based on test-qobject-output-visitor)
  *
  * This work is licensed under the terms of the GNU GPL, version 2 or later.
  * See the COPYING file in the top-level directory.
diff --git a/tests/test-visitor-serialization.c b/tests/test-visitor-serialization.c
index 51df428..66b2b1c 100644
--- a/tests/test-visitor-serialization.c
+++ b/tests/test-visitor-serialization.c
@@ -21,7 +21,7 @@ 
 #include "qapi/qmp/types.h"
 #include "qapi/qmp/qjson.h"
 #include "qapi/qobject-input-visitor.h"
-#include "qapi/qmp-output-visitor.h"
+#include "qapi/qobject-output-visitor.h"
 #include "qapi/string-input-visitor.h"
 #include "qapi/string-output-visitor.h"
 #include "qapi-types.h"
@@ -1022,7 +1022,7 @@  static void qmp_serialize(void *native_in, void **datap,
 {
     QmpSerializeData *d = g_malloc0(sizeof(*d));
 
-    d->qov = qmp_output_visitor_new(&d->obj);
+    d->qov = qobject_output_visitor_new(&d->obj);
     visit(d->qov, &native_in, errp);
     *datap = d;
 }
diff --git a/util/qemu-sockets.c b/util/qemu-sockets.c
index dd9ad44..3a11e43 100644
--- a/util/qemu-sockets.c
+++ b/util/qemu-sockets.c
@@ -22,7 +22,7 @@ 
 #include "qemu/sockets.h"
 #include "qemu/main-loop.h"
 #include "qapi/qobject-input-visitor.h"
-#include "qapi/qmp-output-visitor.h"
+#include "qapi/qobject-output-visitor.h"
 #include "qapi-visit.h"
 #include "qemu/cutils.h"