From patchwork Mon Sep 5 15:16:38 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?q?Daniel_P=2E_Berrang=C3=A9?= X-Patchwork-Id: 9314269 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 816DE607D3 for ; Mon, 5 Sep 2016 15:36:55 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 6C4812891C for ; Mon, 5 Sep 2016 15:36:55 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 5C91928A38; Mon, 5 Sep 2016 15:36:55 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 66B332891C for ; Mon, 5 Sep 2016 15:36:52 +0000 (UTC) Received: from localhost ([::1]:55411 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bgvx5-0005oY-Us for patchwork-qemu-devel@patchwork.kernel.org; Mon, 05 Sep 2016 11:36:52 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:53873) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bgvsJ-0002AS-3I for qemu-devel@nongnu.org; Mon, 05 Sep 2016 11:32:00 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1bgvsE-0007UC-Lq for qemu-devel@nongnu.org; Mon, 05 Sep 2016 11:31:54 -0400 Received: from mx1.redhat.com ([209.132.183.28]:46554) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bgvsE-0007U3-At for qemu-devel@nongnu.org; Mon, 05 Sep 2016 11:31:50 -0400 Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id EA23264370; Mon, 5 Sep 2016 15:31:49 +0000 (UTC) Received: from t530wlan.home.berrange.com.com (vpn1-6-221.ams2.redhat.com [10.36.6.221]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id u85FVdSR021140; Mon, 5 Sep 2016 11:31:48 -0400 From: "Daniel P. Berrange" To: qemu-devel@nongnu.org Date: Mon, 5 Sep 2016 16:16:38 +0100 Message-Id: <1473088600-17930-5-git-send-email-berrange@redhat.com> In-Reply-To: <1473088600-17930-1-git-send-email-berrange@redhat.com> References: <1473088600-17930-1-git-send-email-berrange@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.27 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.39]); Mon, 05 Sep 2016 15:31:49 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH v11 4/6] qapi: rename QmpOutputVisitor to QObjectOutputVisitor X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Markus Armbruster , Max Reitz , =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= , Paolo Bonzini , =?UTF-8?q?Andreas=20F=C3=A4rber?= Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP 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 Reviewed-by: Eric Blake --- 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%) 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 - * - * 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 + * + * 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 (based on test-qmp-output-visitor) + * Paolo Bonzini (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"