* [Qemu-devel] [PATCH 00/36] Rip out dynamic JSON parsing
@ 2016-11-30 19:44 Eric Blake
2016-11-30 19:44 ` [Qemu-devel] [PATCH 01/36] pci: Use struct instead of QDict to pass back parameters Eric Blake
` (36 more replies)
0 siblings, 37 replies; 45+ messages in thread
From: Eric Blake @ 2016-11-30 19:44 UTC (permalink / raw)
To: qemu-devel; +Cc: armbru, pbonzini
Followup series to conversation about PRId64 and MacOS:
https://lists.gnu.org/archive/html/qemu-devel/2016-11/msg04226.html
We have relatively few users of dynamic JSON (the ability to pass
varargs plus a format string with % sequences embedded in the JSON,
to create a final QObject dynamically). Most of them live in the
testsuite. Converting ALL uses to hand-written QObjects would have
been too invasive, so I hope this series hits a nice compromise
of adjusting the few users that injected non-strings, while moving
the work of string injection out of the JSON parser proper and
instead into libqtest. Doing this means the testsuite is doing a
lot fewer string->QObject->string round-trips when computing what
to send over a QMP wire transaction.
I'm also pleased that this series has a net overall reduction in
lines of code, while still adding several new useful features (such
as qdict_put_str() in 2/36, QAPI_TO_QOBJECT() in 11/36, qmp_cmd() in
9/36) and fixing a couple of testsuite flaws (7/36, 8/36). Patch
2/36 may be a candidate for splitting into sub-patches, but the
series is already long enough that I wanted to post it for feedback
on the approaches taken here.
Partially overlaps with my earlier v6 posting of a qapi JSON visitor
(https://lists.gnu.org/archive/html/qemu-devel/2016-10/msg01915.html);
whichever series goes in first has two patches that the other
series will use as-is (28/36, 29/36).
Eric Blake (36):
pci: Use struct instead of QDict to pass back parameters
qdict: Add convenience helpers for wrapped puts
qlist: Add convenience helpers for wrapped appends
qmp-event: Avoid dynamic JSON
qmp-dispatch: Avoid dynamic JSON
qobject-input-visitor: Avoid dynamic JSON in tests
fdc-test: Avoid deprecated 'change' command
test-qga: Actually test 0xff sync bytes
qtest: Add a new helper qmp_cmd() and friends
qtest: Avoid dynamic JSON in libqtest
qapi: Add QAPI_TO_QOBJECT() convenience macro
nbd: Use simpler QAPI_TO_QOBJECT()
nfs: Use simpler QAPI_TO_QOBJECT()
qapi: Use simpler QAPI_TO_QOBJECT()
blockdev: Use simpler QAPI_TO_QOBJECT()
qapi: Promote blockdev-change-medium arguments to QAPI type
qtest: Avoid dynamic JSON in ahci-test
qtest: Avoid dynamic JSON in fdc-test
qtest: Change qmp_discard_response() to drop varargs
qtest: Avoid dynamic JSON in device-introspect-test
qtest: Avoid dynamic JSON in tmp105-test
qtest: Avoid dynamic JSON in pc-cpu-test
qtest: Avoid dynamic JSON in virtio-blk-test
qtest: Drop unused qmp_fdv()
qtest: Change qmp_fd_send() to drop varags
qtest: Drop unused qtest_qmp_async()
qtest: Avoid dynamic JSON in qmp_cmd()
qapi: Factor out JSON string escaping
qapi: Add qstring_append_printf()
qtest: Avoid dynamic JSON in qmp_fd_sendv()
qtest: Document calling conventions
qtest: Avoid dynamic JSON in qom-test
qtest: Avoid dynamic JSON in test-x86-cpuid-compat
qapi: Rip out dynamic JSON parser frontend
qapi: Rip out dynamic JSON parser escape sequence support
qapi: Rip out dynamic JSON parser backend
qapi/block-core.json | 11 ++-
include/qapi/qmp/json-lexer.h | 1 -
include/qapi/qmp/json-parser.h | 6 +-
include/qapi/qmp/qdict.h | 8 ++
include/qapi/qmp/qjson.h | 4 +-
include/qapi/qmp/qlist.h | 8 ++
include/qapi/qmp/qstring.h | 7 +-
include/qapi/qobject-output-visitor.h | 19 ++++
tests/libqtest.h | 78 +++++++--------
block.c | 59 +++++-------
block/archipelago.c | 4 +-
block/blkdebug.c | 6 +-
block/blkverify.c | 11 +--
block/curl.c | 2 +-
block/iscsi.c | 2 +-
block/nbd.c | 47 ++++-----
block/nfs.c | 49 ++++------
block/null.c | 2 +-
block/qapi.c | 6 +-
block/qcow2.c | 4 +-
block/quorum.c | 13 +--
block/raw-posix.c | 8 +-
block/raw-win32.c | 4 +-
block/ssh.c | 16 ++-
block/vvfat.c | 10 +-
blockdev.c | 42 +++-----
hw/block/xen_disk.c | 2 +-
hw/pci/pcie_aer.c | 36 ++++---
hw/usb/xen-usb.c | 12 +--
migration/qjson.c | 12 +--
monitor.c | 30 +++---
qapi/qmp-dispatch.c | 8 +-
qapi/qmp-event.c | 15 +--
qapi/qobject-output-visitor.c | 16 +++
qemu-img.c | 6 +-
qemu-io.c | 2 +-
qemu-nbd.c | 2 +-
qga/main.c | 2 +-
qobject/json-lexer.c | 40 --------
qobject/json-parser.c | 66 ++++---------
qobject/qdict.c | 2 +-
qobject/qjson.c | 177 ++++++++++++++--------------------
qobject/qstring.c | 26 ++++-
target-s390x/cpu_models.c | 4 +-
tests/ahci-test.c | 26 ++++-
tests/check-qdict.c | 142 +++++++++++++--------------
tests/check-qjson.c | 113 +---------------------
tests/check-qlist.c | 2 +-
tests/device-introspect-test.c | 15 +--
tests/fdc-test.c | 15 ++-
tests/libqtest.c | 147 ++++++++++++++--------------
tests/pc-cpu-test.c | 12 ++-
tests/qom-test.c | 15 +--
tests/test-qga.c | 12 ++-
tests/test-qmp-commands.c | 30 +++---
tests/test-qmp-event.c | 30 +++---
tests/test-qobject-input-strict.c | 37 +------
tests/test-qobject-input-visitor.c | 75 ++++++--------
tests/test-qobject-output-visitor.c | 6 +-
tests/test-x86-cpuid-compat.c | 14 ++-
tests/tmp105-test.c | 7 +-
tests/virtio-blk-test.c | 22 +++--
util/qemu-option.c | 6 +-
63 files changed, 726 insertions(+), 885 deletions(-)
--
2.7.4
^ permalink raw reply [flat|nested] 45+ messages in thread
* [Qemu-devel] [PATCH 01/36] pci: Use struct instead of QDict to pass back parameters
2016-11-30 19:44 [Qemu-devel] [PATCH 00/36] Rip out dynamic JSON parsing Eric Blake
@ 2016-11-30 19:44 ` Eric Blake
2016-11-30 21:15 ` Michael S. Tsirkin
2016-11-30 19:44 ` [Qemu-devel] [PATCH 02/36] qdict: Add convenience helpers for wrapped puts Eric Blake
` (35 subsequent siblings)
36 siblings, 1 reply; 45+ messages in thread
From: Eric Blake @ 2016-11-30 19:44 UTC (permalink / raw)
To: qemu-devel; +Cc: armbru, pbonzini, Michael S. Tsirkin, Marcel Apfelbaum
It's simpler to just use a C struct than it is to bundle things
into a QDict in one function just to pull them back out in the
caller. Plus, doing this gets rid of one more user of dynamic
JSON through qobject_from_jsonf().
Signed-off-by: Eric Blake <eblake@redhat.com>
---
hw/pci/pcie_aer.c | 36 +++++++++++++++++-------------------
1 file changed, 17 insertions(+), 19 deletions(-)
diff --git a/hw/pci/pcie_aer.c b/hw/pci/pcie_aer.c
index 048ce6a..0735796 100644
--- a/hw/pci/pcie_aer.c
+++ b/hw/pci/pcie_aer.c
@@ -43,6 +43,13 @@
#define PCI_ERR_SRC_COR_OFFS 0
#define PCI_ERR_SRC_UNCOR_OFFS 2
+typedef struct PCIEErrorInject {
+ const char *id;
+ const char *root_bus;
+ int bus;
+ int devfn;
+} PCIEErrorInject;
+
/* From 6.2.7 Error Listing and Rules. Table 6-2, 6-3 and 6-4 */
static uint32_t pcie_aer_uncor_default_severity(uint32_t status)
{
@@ -946,7 +953,8 @@ static int pcie_aer_parse_error_string(const char *error_name,
}
static int do_pcie_aer_inject_error(Monitor *mon,
- const QDict *qdict, QObject **ret_data)
+ const QDict *qdict,
+ PCIEErrorInject *ret_data)
{
const char *id = qdict_get_str(qdict, "id");
const char *error_name;
@@ -1007,34 +1015,24 @@ static int do_pcie_aer_inject_error(Monitor *mon,
err.prefix[2] = qdict_get_try_int(qdict, "prefix2", 0);
err.prefix[3] = qdict_get_try_int(qdict, "prefix3", 0);
- ret = pcie_aer_inject_error(dev, &err);
- *ret_data = qobject_from_jsonf("{'id': %s, "
- "'root_bus': %s, 'bus': %d, 'devfn': %d, "
- "'ret': %d}",
- id, pci_root_bus_path(dev),
- pci_bus_num(dev->bus), dev->devfn,
- ret);
- assert(*ret_data);
+ pcie_aer_inject_error(dev, &err);
+ ret_data->id = id;
+ ret_data->root_bus = pci_root_bus_path(dev);
+ ret_data->bus = pci_bus_num(dev->bus);
+ ret_data->devfn = dev->devfn;
return 0;
}
void hmp_pcie_aer_inject_error(Monitor *mon, const QDict *qdict)
{
- QObject *data;
- int devfn;
+ PCIEErrorInject data;
if (do_pcie_aer_inject_error(mon, qdict, &data) < 0) {
return;
}
- assert(qobject_type(data) == QTYPE_QDICT);
- qdict = qobject_to_qdict(data);
-
- devfn = (int)qdict_get_int(qdict, "devfn");
monitor_printf(mon, "OK id: %s root bus: %s, bus: %x devfn: %x.%x\n",
- qdict_get_str(qdict, "id"),
- qdict_get_str(qdict, "root_bus"),
- (int) qdict_get_int(qdict, "bus"),
- PCI_SLOT(devfn), PCI_FUNC(devfn));
+ data.id, data.root_bus, data.bus,
+ PCI_SLOT(data.devfn), PCI_FUNC(data.devfn));
}
--
2.7.4
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [Qemu-devel] [PATCH 02/36] qdict: Add convenience helpers for wrapped puts
2016-11-30 19:44 [Qemu-devel] [PATCH 00/36] Rip out dynamic JSON parsing Eric Blake
2016-11-30 19:44 ` [Qemu-devel] [PATCH 01/36] pci: Use struct instead of QDict to pass back parameters Eric Blake
@ 2016-11-30 19:44 ` Eric Blake
2016-12-09 14:06 ` Alberto Garcia
2016-11-30 19:44 ` [Qemu-devel] [PATCH 03/36] qlist: Add convenience helpers for wrapped appends Eric Blake
` (34 subsequent siblings)
36 siblings, 1 reply; 45+ messages in thread
From: Eric Blake @ 2016-11-30 19:44 UTC (permalink / raw)
To: qemu-devel
Cc: armbru, pbonzini, Kevin Wolf, Max Reitz, Chrysostomos Nanakos,
Jeff Cody, Stefan Hajnoczi, Ronnie Sahlberg, Peter Lieven,
Fam Zheng, Alberto Garcia, Stefan Weil, Richard W.M. Jones,
Stefano Stabellini, Anthony Perard, Gerd Hoffmann,
Dr. David Alan Gilbert, Michael Roth, Richard Henderson,
Alexander Graf, open list:Block layer core, open list:X86
Quite a few users of qdict_put() were manually wrapping a
non-QObject. We can make such call-sites shorter, by providing
common macros to do the tedious work. Also shorten nearby
qdict_put_obj(,,QOBJECT()) sequences.
Signed-off-by: Eric Blake <eblake@redhat.com>
---
I'm okay if you want me to break this patch into smaller pieces.
---
include/qapi/qmp/qdict.h | 8 +++
block.c | 59 +++++++---------
block/archipelago.c | 4 +-
block/blkdebug.c | 6 +-
block/blkverify.c | 11 ++-
block/curl.c | 2 +-
block/iscsi.c | 2 +-
block/nbd.c | 41 ++++++-----
block/nfs.c | 43 +++++-------
block/null.c | 2 +-
block/qcow2.c | 4 +-
block/quorum.c | 13 ++--
block/raw-posix.c | 8 +--
block/raw-win32.c | 4 +-
block/ssh.c | 16 ++---
block/vvfat.c | 10 +--
blockdev.c | 28 ++++----
hw/block/xen_disk.c | 2 +-
hw/usb/xen-usb.c | 12 ++--
monitor.c | 18 ++---
qapi/qmp-event.c | 2 +-
qemu-img.c | 6 +-
qemu-io.c | 2 +-
qemu-nbd.c | 2 +-
qobject/qdict.c | 2 +-
target-s390x/cpu_models.c | 4 +-
tests/check-qdict.c | 132 ++++++++++++++++++------------------
tests/test-qmp-commands.c | 30 ++++----
tests/test-qmp-event.c | 30 ++++----
tests/test-qobject-output-visitor.c | 6 +-
util/qemu-option.c | 6 +-
31 files changed, 245 insertions(+), 270 deletions(-)
diff --git a/include/qapi/qmp/qdict.h b/include/qapi/qmp/qdict.h
index fe9a4c5..9d9f9a3 100644
--- a/include/qapi/qmp/qdict.h
+++ b/include/qapi/qmp/qdict.h
@@ -52,6 +52,14 @@ void qdict_destroy_obj(QObject *obj);
#define qdict_put(qdict, key, obj) \
qdict_put_obj(qdict, key, QOBJECT(obj))
+/* Helpers for int, bool, and const char*. */
+#define qdict_put_int(qdict, key, value) \
+ qdict_put(qdict, key, qint_from_int(value))
+#define qdict_put_bool(qdict, key, value) \
+ qdict_put(qdict, key, qbool_from_bool(value))
+#define qdict_put_str(qdict, key, value) \
+ qdict_put(qdict, key, qstring_from_str(value))
+
/* High level helpers */
double qdict_get_double(const QDict *qdict, const char *key);
int64_t qdict_get_int(const QDict *qdict, const char *key);
diff --git a/block.c b/block.c
index 39ddea3..e816657 100644
--- a/block.c
+++ b/block.c
@@ -876,16 +876,16 @@ static void update_flags_from_options(int *flags, QemuOpts *opts)
static void update_options_from_flags(QDict *options, int flags)
{
if (!qdict_haskey(options, BDRV_OPT_CACHE_DIRECT)) {
- qdict_put(options, BDRV_OPT_CACHE_DIRECT,
- qbool_from_bool(flags & BDRV_O_NOCACHE));
+ qdict_put_bool(options, BDRV_OPT_CACHE_DIRECT,
+ flags & BDRV_O_NOCACHE);
}
if (!qdict_haskey(options, BDRV_OPT_CACHE_NO_FLUSH)) {
- qdict_put(options, BDRV_OPT_CACHE_NO_FLUSH,
- qbool_from_bool(flags & BDRV_O_NO_FLUSH));
+ qdict_put_bool(options, BDRV_OPT_CACHE_NO_FLUSH,
+ flags & BDRV_O_NO_FLUSH);
}
if (!qdict_haskey(options, BDRV_OPT_READ_ONLY)) {
- qdict_put(options, BDRV_OPT_READ_ONLY,
- qbool_from_bool(!(flags & BDRV_O_RDWR)));
+ qdict_put_bool(options, BDRV_OPT_READ_ONLY,
+ !(flags & BDRV_O_RDWR));
}
}
@@ -1244,7 +1244,7 @@ static int bdrv_fill_options(QDict **options, const char *filename,
/* Fetch the file name from the options QDict if necessary */
if (protocol && filename) {
if (!qdict_haskey(*options, "filename")) {
- qdict_put(*options, "filename", qstring_from_str(filename));
+ qdict_put_str(*options, "filename", filename);
parse_filename = true;
} else {
error_setg(errp, "Can't specify 'file' and 'filename' options at "
@@ -1264,7 +1264,7 @@ static int bdrv_fill_options(QDict **options, const char *filename,
}
drvname = drv->format_name;
- qdict_put(*options, "driver", qstring_from_str(drvname));
+ qdict_put_str(*options, "driver", drvname);
} else {
error_setg(errp, "Must specify either driver or file");
return -EINVAL;
@@ -1517,7 +1517,7 @@ int bdrv_open_backing_file(BlockDriverState *bs, QDict *parent_options,
}
if (bs->backing_format[0] != '\0' && !qdict_haskey(options, "driver")) {
- qdict_put(options, "driver", qstring_from_str(bs->backing_format));
+ qdict_put_str(options, "driver", bs->backing_format);
}
backing_hd = bdrv_open_inherit(*backing_filename ? backing_filename : NULL,
@@ -1607,7 +1607,7 @@ static BlockDriverState *bdrv_append_temp_snapshot(BlockDriverState *bs,
char *tmp_filename = g_malloc0(PATH_MAX + 1);
int64_t total_size;
QemuOpts *opts = NULL;
- BlockDriverState *bs_snapshot;
+ BlockDriverState *bs_snapshot = NULL;
int ret;
/* if snapshot, we create a temporary backing file and open it
@@ -1639,12 +1639,9 @@ static BlockDriverState *bdrv_append_temp_snapshot(BlockDriverState *bs,
}
/* Prepare options QDict for the temporary file */
- qdict_put(snapshot_options, "file.driver",
- qstring_from_str("file"));
- qdict_put(snapshot_options, "file.filename",
- qstring_from_str(tmp_filename));
- qdict_put(snapshot_options, "driver",
- qstring_from_str("qcow2"));
+ qdict_put_str(snapshot_options, "file.driver", "file");
+ qdict_put_str(snapshot_options, "file.filename", tmp_filename);
+ qdict_put_str(snapshot_options, "driver", "qcow2");
bs_snapshot = bdrv_open(NULL, NULL, snapshot_options, flags, errp);
snapshot_options = NULL;
@@ -1659,13 +1656,10 @@ static BlockDriverState *bdrv_append_temp_snapshot(BlockDriverState *bs,
bdrv_ref(bs_snapshot);
bdrv_append(bs_snapshot, bs);
+out:
+ QDECREF(snapshot_options);
g_free(tmp_filename);
return bs_snapshot;
-
-out:
- QDECREF(snapshot_options);
- g_free(tmp_filename);
- return NULL;
}
/*
@@ -1816,8 +1810,8 @@ static BlockDriverState *bdrv_open_inherit(const char *filename,
* sure to update both bs->options (which has the full effective
* options for bs) and options (which has file.* already removed).
*/
- qdict_put(bs->options, "driver", qstring_from_str(drv->format_name));
- qdict_put(options, "driver", qstring_from_str(drv->format_name));
+ qdict_put_str(bs->options, "driver", drv->format_name);
+ qdict_put_str(options, "driver", drv->format_name);
} else if (!drv) {
error_setg(errp, "Must specify either driver or file");
goto fail;
@@ -2191,12 +2185,12 @@ int bdrv_reopen_prepare(BDRVReopenState *reopen_state, BlockReopenQueue *queue,
* that they are checked at the end of this function. */
value = qemu_opt_get(opts, "node-name");
if (value) {
- qdict_put(reopen_state->options, "node-name", qstring_from_str(value));
+ qdict_put_str(reopen_state->options, "node-name", value);
}
value = qemu_opt_get(opts, "driver");
if (value) {
- qdict_put(reopen_state->options, "driver", qstring_from_str(value));
+ qdict_put_str(reopen_state->options, "driver", value);
}
/* if we are to stay read-only, do not allow permission change
@@ -3606,8 +3600,7 @@ void bdrv_img_create(const char *filename, const char *fmt,
if (backing_fmt) {
backing_options = qdict_new();
- qdict_put(backing_options, "driver",
- qstring_from_str(backing_fmt));
+ qdict_put_str(backing_options, "driver", backing_fmt);
}
bs = bdrv_open(full_backing, NULL, backing_options, back_flags,
@@ -3997,11 +3990,9 @@ void bdrv_refresh_filename(BlockDriverState *bs)
* contain a representation of the filename, therefore the following
* suffices without querying the (exact_)filename of this BDS. */
if (bs->file->bs->full_open_options) {
- qdict_put_obj(opts, "driver",
- QOBJECT(qstring_from_str(drv->format_name)));
+ qdict_put_str(opts, "driver", drv->format_name);
QINCREF(bs->file->bs->full_open_options);
- qdict_put_obj(opts, "file",
- QOBJECT(bs->file->bs->full_open_options));
+ qdict_put(opts, "file", bs->file->bs->full_open_options);
bs->full_open_options = opts;
} else {
@@ -4017,8 +4008,7 @@ void bdrv_refresh_filename(BlockDriverState *bs)
opts = qdict_new();
append_open_options(opts, bs);
- qdict_put_obj(opts, "driver",
- QOBJECT(qstring_from_str(drv->format_name)));
+ qdict_put_str(opts, "driver", drv->format_name);
if (bs->exact_filename[0]) {
/* This may not work for all block protocol drivers (some may
@@ -4028,8 +4018,7 @@ void bdrv_refresh_filename(BlockDriverState *bs)
* needs some special format of the options QDict, it needs to
* implement the driver-specific bdrv_refresh_filename() function.
*/
- qdict_put_obj(opts, "filename",
- QOBJECT(qstring_from_str(bs->exact_filename)));
+ qdict_put_str(opts, "filename", bs->exact_filename);
}
bs->full_open_options = opts;
diff --git a/block/archipelago.c b/block/archipelago.c
index 2449cfc..bf20c61 100644
--- a/block/archipelago.c
+++ b/block/archipelago.c
@@ -432,10 +432,10 @@ static void archipelago_parse_filename(const char *filename, QDict *options,
g_free(segment_name);
}
if (mport != NoPort) {
- qdict_put(options, ARCHIPELAGO_OPT_MPORT, qint_from_int(mport));
+ qdict_put_int(options, ARCHIPELAGO_OPT_MPORT, mport);
}
if (vport != NoPort) {
- qdict_put(options, ARCHIPELAGO_OPT_VPORT, qint_from_int(vport));
+ qdict_put_int(options, ARCHIPELAGO_OPT_VPORT, vport);
}
}
diff --git a/block/blkdebug.c b/block/blkdebug.c
index 4127571..f1fe03c 100644
--- a/block/blkdebug.c
+++ b/block/blkdebug.c
@@ -302,7 +302,7 @@ static void blkdebug_parse_filename(const char *filename, QDict *options,
if (!strstart(filename, "blkdebug:", &filename)) {
/* There was no prefix; therefore, all options have to be already
present in the QDict (except for the filename) */
- qdict_put(options, "x-image", qstring_from_str(filename));
+ qdict_put_str(options, "x-image", filename);
return;
}
@@ -321,7 +321,7 @@ static void blkdebug_parse_filename(const char *filename, QDict *options,
/* TODO Allow multi-level nesting and set file.filename here */
filename = c + 1;
- qdict_put(options, "x-image", qstring_from_str(filename));
+ qdict_put_str(options, "x-image", filename);
}
static QemuOptsList runtime_opts = {
@@ -708,7 +708,7 @@ static void blkdebug_refresh_filename(BlockDriverState *bs, QDict *options)
}
opts = qdict_new();
- qdict_put_obj(opts, "driver", QOBJECT(qstring_from_str("blkdebug")));
+ qdict_put_str(opts, "driver", "blkdebug");
QINCREF(bs->file->bs->full_open_options);
qdict_put_obj(opts, "image", QOBJECT(bs->file->bs->full_open_options));
diff --git a/block/blkverify.c b/block/blkverify.c
index 28f9af6..e87d5ea 100644
--- a/block/blkverify.c
+++ b/block/blkverify.c
@@ -69,7 +69,7 @@ static void blkverify_parse_filename(const char *filename, QDict *options,
if (!strstart(filename, "blkverify:", &filename)) {
/* There was no prefix; therefore, all options have to be already
present in the QDict (except for the filename) */
- qdict_put(options, "x-image", qstring_from_str(filename));
+ qdict_put_str(options, "x-image", filename);
return;
}
@@ -86,7 +86,7 @@ static void blkverify_parse_filename(const char *filename, QDict *options,
/* TODO Allow multi-level nesting and set file.filename here */
filename = c + 1;
- qdict_put(options, "x-image", qstring_from_str(filename));
+ qdict_put_str(options, "x-image", filename);
}
static QemuOptsList runtime_opts = {
@@ -300,13 +300,12 @@ static void blkverify_refresh_filename(BlockDriverState *bs, QDict *options)
&& s->test_file->bs->full_open_options)
{
QDict *opts = qdict_new();
- qdict_put_obj(opts, "driver", QOBJECT(qstring_from_str("blkverify")));
+ qdict_put_str(opts, "driver", "blkverify");
QINCREF(bs->file->bs->full_open_options);
- qdict_put_obj(opts, "raw", QOBJECT(bs->file->bs->full_open_options));
+ qdict_put(opts, "raw", bs->file->bs->full_open_options);
QINCREF(s->test_file->bs->full_open_options);
- qdict_put_obj(opts, "test",
- QOBJECT(s->test_file->bs->full_open_options));
+ qdict_put(opts, "test", s->test_file->bs->full_open_options);
bs->full_open_options = opts;
}
diff --git a/block/curl.c b/block/curl.c
index 0404c1b..6959d3c 100644
--- a/block/curl.c
+++ b/block/curl.c
@@ -531,7 +531,7 @@ static void curl_clean_state(CURLState *s)
static void curl_parse_filename(const char *filename, QDict *options,
Error **errp)
{
- qdict_put(options, CURL_BLOCK_OPT_URL, qstring_from_str(filename));
+ qdict_put_str(options, CURL_BLOCK_OPT_URL, filename);
}
static void curl_detach_aio_context(BlockDriverState *bs)
diff --git a/block/iscsi.c b/block/iscsi.c
index 0960929..1269188 100644
--- a/block/iscsi.c
+++ b/block/iscsi.c
@@ -1965,7 +1965,7 @@ static int iscsi_create(const char *filename, QemuOpts *opts, Error **errp)
iscsilun = bs->opaque;
bs_options = qdict_new();
- qdict_put(bs_options, "filename", qstring_from_str(filename));
+ qdict_put_str(bs_options, "filename", filename);
ret = iscsi_open(bs, bs_options, 0, NULL);
QDECREF(bs_options);
diff --git a/block/nbd.c b/block/nbd.c
index 35f24be..334748d 100644
--- a/block/nbd.c
+++ b/block/nbd.c
@@ -79,7 +79,7 @@ static int nbd_parse_uri(const char *filename, QDict *options)
p = uri->path ? uri->path : "/";
p += strspn(p, "/");
if (p[0]) {
- qdict_put(options, "export", qstring_from_str(p));
+ qdict_put_str(options, "export", p);
}
qp = query_params_parse(uri->query);
@@ -94,9 +94,8 @@ static int nbd_parse_uri(const char *filename, QDict *options)
ret = -EINVAL;
goto out;
}
- qdict_put(options, "server.type", qstring_from_str("unix"));
- qdict_put(options, "server.data.path",
- qstring_from_str(qp->p[0].value));
+ qdict_put_str(options, "server.type", "unix");
+ qdict_put_str(options, "server.data.path", qp->p[0].value);
} else {
QString *host;
char *port_str;
@@ -115,11 +114,11 @@ static int nbd_parse_uri(const char *filename, QDict *options)
host = qstring_from_str(uri->server);
}
- qdict_put(options, "server.type", qstring_from_str("inet"));
+ qdict_put_str(options, "server.type", "inet");
qdict_put(options, "server.data.host", host);
port_str = g_strdup_printf("%d", uri->port ?: NBD_DEFAULT_PORT);
- qdict_put(options, "server.data.port", qstring_from_str(port_str));
+ qdict_put_str(options, "server.data.port", port_str);
g_free(port_str);
}
@@ -181,7 +180,7 @@ static void nbd_parse_filename(const char *filename, QDict *options,
export_name[0] = 0; /* truncate 'file' */
export_name += strlen(EN_OPTSTR);
- qdict_put(options, "export", qstring_from_str(export_name));
+ qdict_put_str(options, "export", export_name);
}
/* extract the host_spec - fail if it's not nbd:... */
@@ -196,8 +195,8 @@ static void nbd_parse_filename(const char *filename, QDict *options,
/* are we a UNIX or TCP socket? */
if (strstart(host_spec, "unix:", &unixpath)) {
- qdict_put(options, "server.type", qstring_from_str("unix"));
- qdict_put(options, "server.data.path", qstring_from_str(unixpath));
+ qdict_put_str(options, "server.type", "unix");
+ qdict_put_str(options, "server.data.path", unixpath);
} else {
InetSocketAddress *addr = NULL;
@@ -206,9 +205,9 @@ static void nbd_parse_filename(const char *filename, QDict *options,
goto out;
}
- qdict_put(options, "server.type", qstring_from_str("inet"));
- qdict_put(options, "server.data.host", qstring_from_str(addr->host));
- qdict_put(options, "server.data.port", qstring_from_str(addr->port));
+ qdict_put_str(options, "server.type", "inet");
+ qdict_put_str(options, "server.data.host", addr->host);
+ qdict_put_str(options, "server.data.port", addr->port);
qapi_free_InetSocketAddress(addr);
}
@@ -247,13 +246,13 @@ static bool nbd_process_legacy_socket_options(QDict *output_options,
return false;
}
- qdict_put(output_options, "server.type", qstring_from_str("unix"));
- qdict_put(output_options, "server.data.path", qstring_from_str(path));
+ qdict_put_str(output_options, "server.type", "unix");
+ qdict_put_str(output_options, "server.data.path", path);
} else if (host) {
- qdict_put(output_options, "server.type", qstring_from_str("inet"));
- qdict_put(output_options, "server.data.host", qstring_from_str(host));
- qdict_put(output_options, "server.data.port",
- qstring_from_str(port ?: stringify(NBD_DEFAULT_PORT)));
+ qdict_put_str(output_options, "server.type", "inet");
+ qdict_put_str(output_options, "server.data.host", host);
+ qdict_put_str(output_options, "server.data.port",
+ port ?: stringify(NBD_DEFAULT_PORT));
}
return true;
@@ -517,7 +516,7 @@ static void nbd_refresh_filename(BlockDriverState *bs, QDict *options)
path = s->saddr->u.q_unix.data->path;
}
- qdict_put(opts, "driver", qstring_from_str("nbd"));
+ qdict_put_str(opts, "driver", "nbd");
if (path && s->export) {
snprintf(bs->exact_filename, sizeof(bs->exact_filename),
@@ -542,10 +541,10 @@ static void nbd_refresh_filename(BlockDriverState *bs, QDict *options)
qdict_put_obj(opts, "server", saddr_qdict);
if (s->export) {
- qdict_put(opts, "export", qstring_from_str(s->export));
+ qdict_put_str(opts, "export", s->export);
}
if (s->tlscredsid) {
- qdict_put(opts, "tls-creds", qstring_from_str(s->tlscredsid));
+ qdict_put_str(opts, "tls-creds", s->tlscredsid);
}
qdict_flatten(opts);
diff --git a/block/nfs.c b/block/nfs.c
index d082783..f8ba5cc 100644
--- a/block/nfs.c
+++ b/block/nfs.c
@@ -103,9 +103,9 @@ static int nfs_parse_uri(const char *filename, QDict *options, Error **errp)
goto out;
}
- qdict_put(options, "server.host", qstring_from_str(uri->server));
- qdict_put(options, "server.type", qstring_from_str("inet"));
- qdict_put(options, "path", qstring_from_str(uri->path));
+ qdict_put_str(options, "server.host", uri->server);
+ qdict_put_str(options, "server.type", "inet");
+ qdict_put_str(options, "path", uri->path);
for (i = 0; i < qp->n; i++) {
if (!qp->p[i].value) {
@@ -119,23 +119,17 @@ static int nfs_parse_uri(const char *filename, QDict *options, Error **errp)
goto out;
}
if (!strcmp(qp->p[i].name, "uid")) {
- qdict_put(options, "user",
- qstring_from_str(qp->p[i].value));
+ qdict_put_str(options, "user", qp->p[i].value);
} else if (!strcmp(qp->p[i].name, "gid")) {
- qdict_put(options, "group",
- qstring_from_str(qp->p[i].value));
+ qdict_put_str(options, "group", qp->p[i].value);
} else if (!strcmp(qp->p[i].name, "tcp-syncnt")) {
- qdict_put(options, "tcp-syn-count",
- qstring_from_str(qp->p[i].value));
+ qdict_put_str(options, "tcp-syn-count", qp->p[i].value);
} else if (!strcmp(qp->p[i].name, "readahead")) {
- qdict_put(options, "readahead-size",
- qstring_from_str(qp->p[i].value));
+ qdict_put_str(options, "readahead-size", qp->p[i].value);
} else if (!strcmp(qp->p[i].name, "pagecache")) {
- qdict_put(options, "page-cache-size",
- qstring_from_str(qp->p[i].value));
+ qdict_put_str(options, "page-cache-size", qp->p[i].value);
} else if (!strcmp(qp->p[i].name, "debug")) {
- qdict_put(options, "debug-level",
- qstring_from_str(qp->p[i].value));
+ qdict_put_str(options, "debug-level", qp->p[i].value);
} else {
error_setg(errp, "Unknown NFS parameter name: %s",
qp->p[i].name);
@@ -774,7 +768,7 @@ static void nfs_refresh_filename(BlockDriverState *bs, QDict *options)
QObject *server_qdict;
Visitor *ov;
- qdict_put(opts, "driver", qstring_from_str("nfs"));
+ qdict_put_str(opts, "driver", "nfs");
if (client->uid && !client->gid) {
snprintf(bs->exact_filename, sizeof(bs->exact_filename),
@@ -799,28 +793,25 @@ static void nfs_refresh_filename(BlockDriverState *bs, QDict *options)
assert(qobject_type(server_qdict) == QTYPE_QDICT);
qdict_put_obj(opts, "server", server_qdict);
- qdict_put(opts, "path", qstring_from_str(client->path));
+ qdict_put_str(opts, "path", client->path);
if (client->uid) {
- qdict_put(opts, "uid", qint_from_int(client->uid));
+ qdict_put_int(opts, "uid", client->uid);
}
if (client->gid) {
- qdict_put(opts, "gid", qint_from_int(client->gid));
+ qdict_put_int(opts, "gid", client->gid);
}
if (client->tcp_syncnt) {
- qdict_put(opts, "tcp-syncnt",
- qint_from_int(client->tcp_syncnt));
+ qdict_put_int(opts, "tcp-syncnt", client->tcp_syncnt);
}
if (client->readahead) {
- qdict_put(opts, "readahead",
- qint_from_int(client->readahead));
+ qdict_put_int(opts, "readahead", client->readahead);
}
if (client->pagecache) {
- qdict_put(opts, "pagecache",
- qint_from_int(client->pagecache));
+ qdict_put_int(opts, "pagecache", client->pagecache);
}
if (client->debug) {
- qdict_put(opts, "debug", qint_from_int(client->debug));
+ qdict_put_int(opts, "debug", client->debug);
}
visit_free(ov);
diff --git a/block/null.c b/block/null.c
index b300390..876f909 100644
--- a/block/null.c
+++ b/block/null.c
@@ -232,7 +232,7 @@ static void null_refresh_filename(BlockDriverState *bs, QDict *opts)
bs->drv->format_name);
}
- qdict_put(opts, "driver", qstring_from_str(bs->drv->format_name));
+ qdict_put_str(opts, "driver", bs->drv->format_name);
bs->full_open_options = opts;
}
diff --git a/block/qcow2.c b/block/qcow2.c
index ed9e0f3..f908577 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -2252,7 +2252,7 @@ static int qcow2_create2(const char *filename, int64_t total_size,
* table)
*/
options = qdict_new();
- qdict_put(options, "driver", qstring_from_str("qcow2"));
+ qdict_put_str(options, "driver", "qcow2");
blk = blk_new_open(filename, NULL, options,
BDRV_O_RDWR | BDRV_O_NO_FLUSH, &local_err);
if (blk == NULL) {
@@ -2313,7 +2313,7 @@ static int qcow2_create2(const char *filename, int64_t total_size,
/* Reopen the image without BDRV_O_NO_FLUSH to flush it before returning */
options = qdict_new();
- qdict_put(options, "driver", qstring_from_str("qcow2"));
+ qdict_put_str(options, "driver", "qcow2");
blk = blk_new_open(filename, NULL, options,
BDRV_O_RDWR | BDRV_O_NO_BACKING, &local_err);
if (blk == NULL) {
diff --git a/block/quorum.c b/block/quorum.c
index d122299..0aa16dd 100644
--- a/block/quorum.c
+++ b/block/quorum.c
@@ -1072,14 +1072,11 @@ static void quorum_refresh_filename(BlockDriverState *bs, QDict *options)
}
opts = qdict_new();
- qdict_put_obj(opts, "driver", QOBJECT(qstring_from_str("quorum")));
- qdict_put_obj(opts, QUORUM_OPT_VOTE_THRESHOLD,
- QOBJECT(qint_from_int(s->threshold)));
- qdict_put_obj(opts, QUORUM_OPT_BLKVERIFY,
- QOBJECT(qbool_from_bool(s->is_blkverify)));
- qdict_put_obj(opts, QUORUM_OPT_REWRITE,
- QOBJECT(qbool_from_bool(s->rewrite_corrupted)));
- qdict_put_obj(opts, "children", QOBJECT(children));
+ qdict_put_str(opts, "driver", "quorum");
+ qdict_put_int(opts, QUORUM_OPT_VOTE_THRESHOLD, s->threshold);
+ qdict_put_bool(opts, QUORUM_OPT_BLKVERIFY, s->is_blkverify);
+ qdict_put_bool(opts, QUORUM_OPT_REWRITE, s->rewrite_corrupted);
+ qdict_put(opts, "children", children);
bs->full_open_options = opts;
}
diff --git a/block/raw-posix.c b/block/raw-posix.c
index 28b47d9..38a009b 100644
--- a/block/raw-posix.c
+++ b/block/raw-posix.c
@@ -376,7 +376,7 @@ static void raw_parse_filename(const char *filename, QDict *options,
* function call can be ignored. */
strstart(filename, "file:", &filename);
- qdict_put_obj(options, "filename", QOBJECT(qstring_from_str(filename)));
+ qdict_put_str(options, "filename", filename);
}
static QemuOptsList raw_runtime_opts = {
@@ -2061,7 +2061,7 @@ static void hdev_parse_filename(const char *filename, QDict *options,
/* The prefix is optional, just as for "file". */
strstart(filename, "host_device:", &filename);
- qdict_put_obj(options, "filename", QOBJECT(qstring_from_str(filename)));
+ qdict_put_str(options, "filename", filename);
}
static bool hdev_is_sg(BlockDriverState *bs)
@@ -2144,7 +2144,7 @@ static int hdev_open(BlockDriverState *bs, QDict *options, int flags,
goto hdev_open_Mac_error;
}
- qdict_put(options, "filename", qstring_from_str(bsd_path));
+ qdict_put_str(options, "filename", bsd_path);
hdev_open_Mac_error:
g_free(mediaType);
@@ -2354,7 +2354,7 @@ static void cdrom_parse_filename(const char *filename, QDict *options,
/* The prefix is optional, just as for "file". */
strstart(filename, "host_cdrom:", &filename);
- qdict_put_obj(options, "filename", QOBJECT(qstring_from_str(filename)));
+ qdict_put_str(options, "filename", filename);
}
#endif
diff --git a/block/raw-win32.c b/block/raw-win32.c
index 800fabd..0d455d1 100644
--- a/block/raw-win32.c
+++ b/block/raw-win32.c
@@ -282,7 +282,7 @@ static void raw_parse_filename(const char *filename, QDict *options,
* function call can be ignored. */
strstart(filename, "file:", &filename);
- qdict_put_obj(options, "filename", QOBJECT(qstring_from_str(filename)));
+ qdict_put_str(options, "filename", filename);
}
static QemuOptsList raw_runtime_opts = {
@@ -669,7 +669,7 @@ static void hdev_parse_filename(const char *filename, QDict *options,
/* The prefix is optional, just as for "file". */
strstart(filename, "host_device:", &filename);
- qdict_put_obj(options, "filename", QOBJECT(qstring_from_str(filename)));
+ qdict_put_str(options, "filename", filename);
}
static int hdev_open(BlockDriverState *bs, QDict *options, int flags,
diff --git a/block/ssh.c b/block/ssh.c
index 15ed281..656153e 100644
--- a/block/ssh.c
+++ b/block/ssh.c
@@ -227,24 +227,23 @@ static int parse_uri(const char *filename, QDict *options, Error **errp)
}
if(uri->user && strcmp(uri->user, "") != 0) {
- qdict_put(options, "user", qstring_from_str(uri->user));
+ qdict_put_str(options, "user", uri->user);
}
- qdict_put(options, "server.host", qstring_from_str(uri->server));
+ qdict_put_str(options, "server.host", uri->server);
port_str = g_strdup_printf("%d", uri->port ?: 22);
- qdict_put(options, "server.port", qstring_from_str(port_str));
+ qdict_put_str(options, "server.port", port_str);
g_free(port_str);
- qdict_put(options, "path", qstring_from_str(uri->path));
+ qdict_put_str(options, "path", uri->path);
/* Pick out any query parameters that we understand, and ignore
* the rest.
*/
for (i = 0; i < qp->n; ++i) {
if (strcmp(qp->p[i].name, "host_key_check") == 0) {
- qdict_put(options, "host_key_check",
- qstring_from_str(qp->p[i].value));
+ qdict_put_str(options, "host_key_check", qp->p[i].value);
}
}
@@ -574,9 +573,8 @@ static bool ssh_process_legacy_socket_options(QDict *output_opts,
}
if (host) {
- qdict_put(output_opts, "server.host", qstring_from_str(host));
- qdict_put(output_opts, "server.port",
- qstring_from_str(port ?: stringify(22)));
+ qdict_put_str(output_opts, "server.host", host);
+ qdict_put_str(output_opts, "server.port", port ?: stringify(22));
}
return true;
diff --git a/block/vvfat.c b/block/vvfat.c
index ded2109..cf2e109 100644
--- a/block/vvfat.c
+++ b/block/vvfat.c
@@ -1057,10 +1057,10 @@ static void vvfat_parse_filename(const char *filename, QDict *options,
}
/* Fill in the options QDict */
- qdict_put(options, "dir", qstring_from_str(filename));
- qdict_put(options, "fat-type", qint_from_int(fat_type));
- qdict_put(options, "floppy", qbool_from_bool(floppy));
- qdict_put(options, "rw", qbool_from_bool(rw));
+ qdict_put_str(options, "dir", filename);
+ qdict_put_int(options, "fat-type", fat_type);
+ qdict_put_bool(options, "floppy", floppy);
+ qdict_put_bool(options, "rw", rw);
}
static int vvfat_open(BlockDriverState *bs, QDict *options, int flags,
@@ -3019,7 +3019,7 @@ static int enable_write_target(BlockDriverState *bs, Error **errp)
}
options = qdict_new();
- qdict_put(options, "write-target.driver", qstring_from_str("qcow"));
+ qdict_put_str(options, "write-target.driver", "qcow");
s->qcow = bdrv_open_child(s->qcow_filename, options, "write-target", bs,
&child_vvfat_qcow, false, errp);
QDECREF(options);
diff --git a/blockdev.c b/blockdev.c
index 245e1e1..2802cea 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -523,7 +523,7 @@ static BlockBackend *blockdev_init(const char *file, QDict *bs_opts,
error_setg(errp, "Cannot specify both 'driver' and 'format'");
goto early_err;
}
- qdict_put(bs_opts, "driver", qstring_from_str(buf));
+ qdict_put_str(bs_opts, "driver", buf);
}
on_write_error = BLOCKDEV_ON_ERROR_ENOSPC;
@@ -899,10 +899,8 @@ DriveInfo *drive_new(QemuOpts *all_opts, BlockInterfaceType block_default_type)
copy_on_read = false;
}
- qdict_put(bs_opts, BDRV_OPT_READ_ONLY,
- qstring_from_str(read_only ? "on" : "off"));
- qdict_put(bs_opts, "copy-on-read",
- qstring_from_str(copy_on_read ? "on" :"off"));
+ qdict_put_str(bs_opts, BDRV_OPT_READ_ONLY, read_only ? "on" : "off");
+ qdict_put_str(bs_opts, "copy-on-read", copy_on_read ? "on" : "off");
/* Controller type */
value = qemu_opt_get(legacy_opts, "if");
@@ -1063,7 +1061,7 @@ DriveInfo *drive_new(QemuOpts *all_opts, BlockInterfaceType block_default_type)
error_report("werror is not supported by this bus type");
goto fail;
}
- qdict_put(bs_opts, "werror", qstring_from_str(werror));
+ qdict_put_str(bs_opts, "werror", werror);
}
rerror = qemu_opt_get(legacy_opts, "rerror");
@@ -1073,7 +1071,7 @@ DriveInfo *drive_new(QemuOpts *all_opts, BlockInterfaceType block_default_type)
error_report("rerror is not supported by this bus type");
goto fail;
}
- qdict_put(bs_opts, "rerror", qstring_from_str(rerror));
+ qdict_put_str(bs_opts, "rerror", rerror);
}
/* Actual block device init: Functionality shared with blockdev-add */
@@ -1732,10 +1730,9 @@ static void external_snapshot_prepare(BlkActionState *common,
options = qdict_new();
if (s->has_snapshot_node_name) {
- qdict_put(options, "node-name",
- qstring_from_str(snapshot_node_name));
+ qdict_put_str(options, "node-name", snapshot_node_name);
}
- qdict_put(options, "driver", qstring_from_str(format));
+ qdict_put_str(options, "driver", format);
flags |= BDRV_O_NO_BACKING;
}
@@ -2544,11 +2541,10 @@ void qmp_blockdev_change_medium(bool has_device, const char *device,
options = qdict_new();
detect_zeroes = blk_get_detect_zeroes_from_root_state(blk);
- qdict_put(options, "detect-zeroes",
- qstring_from_str(detect_zeroes ? "on" : "off"));
+ qdict_put_str(options, "detect-zeroes", detect_zeroes ? "on" : "off");
if (has_format) {
- qdict_put(options, "driver", qstring_from_str(format));
+ qdict_put_str(options, "driver", format);
}
medium_bs = bdrv_open(filename, NULL, options, bdrv_flags, errp);
@@ -3204,7 +3200,7 @@ static BlockJob *do_drive_backup(DriveBackup *backup, BlockJobTxn *txn,
if (backup->format) {
options = qdict_new();
- qdict_put(options, "driver", qstring_from_str(backup->format));
+ qdict_put_str(options, "driver", backup->format);
}
target_bs = bdrv_open(backup->target, NULL, options, flags, errp);
@@ -3502,10 +3498,10 @@ void qmp_drive_mirror(DriveMirror *arg, Error **errp)
options = qdict_new();
if (arg->has_node_name) {
- qdict_put(options, "node-name", qstring_from_str(arg->node_name));
+ qdict_put_str(options, "node-name", arg->node_name);
}
if (format) {
- qdict_put(options, "driver", qstring_from_str(format));
+ qdict_put_str(options, "driver", format);
}
/* Mirroring takes care of copy-on-write using the source's backing
diff --git a/hw/block/xen_disk.c b/hw/block/xen_disk.c
index 456a2d5..47b2ca1 100644
--- a/hw/block/xen_disk.c
+++ b/hw/block/xen_disk.c
@@ -1082,7 +1082,7 @@ static int blk_connect(struct XenDevice *xendev)
if (strcmp(blkdev->fileproto, "<unset>")) {
options = qdict_new();
- qdict_put(options, "driver", qstring_from_str(blkdev->fileproto));
+ qdict_put_str(options, "driver", blkdev->fileproto);
}
/* setup via xenbus -> create new block driver instance */
diff --git a/hw/usb/xen-usb.c b/hw/usb/xen-usb.c
index 8e676e6..6659415 100644
--- a/hw/usb/xen-usb.c
+++ b/hw/usb/xen-usb.c
@@ -746,16 +746,16 @@ static void usbback_portid_add(struct usbback_info *usbif, unsigned port,
portname++;
qdict = qdict_new();
- qdict_put(qdict, "driver", qstring_from_str("usb-host"));
+ qdict_put_str(qdict, "driver", "usb-host");
tmp = g_strdup_printf("%s.0", usbif->xendev.qdev.id);
- qdict_put(qdict, "bus", qstring_from_str(tmp));
+ qdict_put_str(qdict, "bus", tmp);
g_free(tmp);
tmp = g_strdup_printf("%s-%u", usbif->xendev.qdev.id, port);
- qdict_put(qdict, "id", qstring_from_str(tmp));
+ qdict_put_str(qdict, "id", tmp);
g_free(tmp);
- qdict_put(qdict, "port", qint_from_int(port));
- qdict_put(qdict, "hostbus", qint_from_int(atoi(busid)));
- qdict_put(qdict, "hostport", qstring_from_str(portname));
+ qdict_put_int(qdict, "port", port);
+ qdict_put_int(qdict, "hostbus", atoi(busid));
+ qdict_put_str(qdict, "hostport", portname);
opts = qemu_opts_from_qdict(qemu_find_opts("device"), qdict, &local_err);
if (local_err) {
goto err;
diff --git a/monitor.c b/monitor.c
index 0841d43..2a877ef 100644
--- a/monitor.c
+++ b/monitor.c
@@ -2618,7 +2618,7 @@ static QDict *monitor_parse_arguments(Monitor *mon,
}
goto fail;
}
- qdict_put(qdict, key, qstring_from_str(buf));
+ qdict_put_str(qdict, key, buf);
}
break;
case 'O':
@@ -2720,9 +2720,9 @@ static QDict *monitor_parse_arguments(Monitor *mon,
size = -1;
}
}
- qdict_put(qdict, "count", qint_from_int(count));
- qdict_put(qdict, "format", qint_from_int(format));
- qdict_put(qdict, "size", qint_from_int(size));
+ qdict_put_int(qdict, "count", count);
+ qdict_put_int(qdict, "format", format);
+ qdict_put_int(qdict, "size", size);
}
break;
case 'i':
@@ -2765,7 +2765,7 @@ static QDict *monitor_parse_arguments(Monitor *mon,
}
val <<= 20;
}
- qdict_put(qdict, key, qint_from_int(val));
+ qdict_put_int(qdict, key, val);
}
break;
case 'o':
@@ -2787,7 +2787,7 @@ static QDict *monitor_parse_arguments(Monitor *mon,
monitor_printf(mon, "invalid size\n");
goto fail;
}
- qdict_put(qdict, key, qint_from_int(val));
+ qdict_put_int(qdict, key, val);
p = end;
}
break;
@@ -2843,7 +2843,7 @@ static QDict *monitor_parse_arguments(Monitor *mon,
monitor_printf(mon, "Expected 'on' or 'off'\n");
goto fail;
}
- qdict_put(qdict, key, qbool_from_bool(val));
+ qdict_put_bool(qdict, key, val);
}
break;
case '-':
@@ -2874,7 +2874,7 @@ static QDict *monitor_parse_arguments(Monitor *mon,
} else {
/* has option */
p++;
- qdict_put(qdict, key, qbool_from_bool(true));
+ qdict_put_bool(qdict, key, true);
}
}
}
@@ -2900,7 +2900,7 @@ static QDict *monitor_parse_arguments(Monitor *mon,
cmd->name);
goto fail;
}
- qdict_put(qdict, key, qstring_from_str(p));
+ qdict_put_str(qdict, key, p);
p += len;
}
break;
diff --git a/qapi/qmp-event.c b/qapi/qmp-event.c
index 802ede4..ba3029c 100644
--- a/qapi/qmp-event.c
+++ b/qapi/qmp-event.c
@@ -51,7 +51,7 @@ static void timestamp_put(QDict *qdict)
QDict *qmp_event_build_dict(const char *event_name)
{
QDict *dict = qdict_new();
- qdict_put(dict, "event", qstring_from_str(event_name));
+ qdict_put_str(dict, "event", event_name);
timestamp_put(dict);
return dict;
}
diff --git a/qemu-img.c b/qemu-img.c
index 6949b73..b58cdfa 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -298,7 +298,7 @@ static BlockBackend *img_open_file(const char *filename,
if (fmt) {
options = qdict_new();
- qdict_put(options, "driver", qstring_from_str(fmt));
+ qdict_put_str(options, "driver", fmt);
}
blk = blk_new_open(filename, NULL, options, flags, &local_err);
@@ -2953,7 +2953,7 @@ static int img_rebase(int argc, char **argv)
if (bs->backing_format[0] != '\0') {
options = qdict_new();
- qdict_put(options, "driver", qstring_from_str(bs->backing_format));
+ qdict_put_str(options, "driver", bs->backing_format);
}
bdrv_get_backing_filename(bs, backing_name, sizeof(backing_name));
@@ -2970,7 +2970,7 @@ static int img_rebase(int argc, char **argv)
if (out_baseimg[0]) {
if (out_basefmt) {
options = qdict_new();
- qdict_put(options, "driver", qstring_from_str(out_basefmt));
+ qdict_put_str(options, "driver", out_basefmt);
} else {
options = NULL;
}
diff --git a/qemu-io.c b/qemu-io.c
index 23a229f..97fe99d 100644
--- a/qemu-io.c
+++ b/qemu-io.c
@@ -599,7 +599,7 @@ int main(int argc, char **argv)
} else {
if (format) {
opts = qdict_new();
- qdict_put(opts, "driver", qstring_from_str(format));
+ qdict_put_str(opts, "driver", format);
}
openfile(argv[optind], flags, writethrough, opts);
}
diff --git a/qemu-nbd.c b/qemu-nbd.c
index c734f62..8f5ac8d 100644
--- a/qemu-nbd.c
+++ b/qemu-nbd.c
@@ -882,7 +882,7 @@ int main(int argc, char **argv)
} else {
if (fmt) {
options = qdict_new();
- qdict_put(options, "driver", qstring_from_str(fmt));
+ qdict_put_str(options, "driver", fmt);
}
blk = blk_new_open(srcpath, NULL, options, flags, &local_err);
}
diff --git a/qobject/qdict.c b/qobject/qdict.c
index 197b0fb..51f0ef6 100644
--- a/qobject/qdict.c
+++ b/qobject/qdict.c
@@ -487,7 +487,7 @@ void qdict_set_default_str(QDict *dst, const char *key, const char *val)
return;
}
- qdict_put(dst, key, qstring_from_str(val));
+ qdict_put_str(dst, key, val);
}
static void qdict_flatten_qdict(QDict *qdict, QDict *target,
diff --git a/target-s390x/cpu_models.c b/target-s390x/cpu_models.c
index c1e729d..cf631b2 100644
--- a/target-s390x/cpu_models.c
+++ b/target-s390x/cpu_models.c
@@ -375,12 +375,12 @@ static void cpu_model_from_info(S390CPUModel *model, const CpuModelInfo *info,
static void qdict_add_disabled_feat(const char *name, void *opaque)
{
- qdict_put((QDict *) opaque, name, qbool_from_bool(false));
+ qdict_put_bool((QDict *) opaque, name, false);
}
static void qdict_add_enabled_feat(const char *name, void *opaque)
{
- qdict_put((QDict *) opaque, name, qbool_from_bool(true));
+ qdict_put_bool((QDict *) opaque, name, true);
}
/* convert S390CPUDef into a static CpuModelInfo */
diff --git a/tests/check-qdict.c b/tests/check-qdict.c
index 07b1c79..d00b411 100644
--- a/tests/check-qdict.c
+++ b/tests/check-qdict.c
@@ -47,7 +47,7 @@ static void qdict_put_obj_test(void)
qdict = qdict_new();
// key "" will have tdb hash 12345
- qdict_put_obj(qdict, "", QOBJECT(qint_from_int(num)));
+ qdict_put_int(qdict, "", num);
g_assert(qdict_size(qdict) == 1);
ent = QLIST_FIRST(&qdict->table[12345 % QDICT_BUCKET_MAX]);
@@ -66,8 +66,8 @@ static void qdict_destroy_simple_test(void)
QDict *qdict;
qdict = qdict_new();
- qdict_put_obj(qdict, "num", QOBJECT(qint_from_int(0)));
- qdict_put_obj(qdict, "str", QOBJECT(qstring_from_str("foo")));
+ qdict_put_int(qdict, "num", 0);
+ qdict_put_str(qdict, "str", "foo");
QDECREF(qdict);
}
@@ -80,7 +80,7 @@ static void qdict_get_test(void)
const char *key = "test";
QDict *tests_dict = qdict_new();
- qdict_put(tests_dict, key, qint_from_int(value));
+ qdict_put_int(tests_dict, key, value);
obj = qdict_get(tests_dict, key);
g_assert(obj != NULL);
@@ -98,7 +98,7 @@ static void qdict_get_int_test(void)
const char *key = "int";
QDict *tests_dict = qdict_new();
- qdict_put(tests_dict, key, qint_from_int(value));
+ qdict_put_int(tests_dict, key, value);
ret = qdict_get_int(tests_dict, key);
g_assert(ret == value);
@@ -113,7 +113,7 @@ static void qdict_get_try_int_test(void)
const char *key = "int";
QDict *tests_dict = qdict_new();
- qdict_put(tests_dict, key, qint_from_int(value));
+ qdict_put_int(tests_dict, key, value);
ret = qdict_get_try_int(tests_dict, key, 0);
g_assert(ret == value);
@@ -128,7 +128,7 @@ static void qdict_get_str_test(void)
const char *str = "string";
QDict *tests_dict = qdict_new();
- qdict_put(tests_dict, key, qstring_from_str(str));
+ qdict_put_str(tests_dict, key, str);
p = qdict_get_str(tests_dict, key);
g_assert(p != NULL);
@@ -144,7 +144,7 @@ static void qdict_get_try_str_test(void)
const char *str = "string";
QDict *tests_dict = qdict_new();
- qdict_put(tests_dict, key, qstring_from_str(str));
+ qdict_put_str(tests_dict, key, str);
p = qdict_get_try_str(tests_dict, key);
g_assert(p != NULL);
@@ -188,7 +188,7 @@ static void qdict_haskey_test(void)
const char *key = "test";
QDict *tests_dict = qdict_new();
- qdict_put(tests_dict, key, qint_from_int(0));
+ qdict_put_int(tests_dict, key, 0);
g_assert(qdict_haskey(tests_dict, key) == 1);
QDECREF(tests_dict);
@@ -199,7 +199,7 @@ static void qdict_del_test(void)
const char *key = "key test";
QDict *tests_dict = qdict_new();
- qdict_put(tests_dict, key, qstring_from_str("foo"));
+ qdict_put_str(tests_dict, key, "foo");
g_assert(qdict_size(tests_dict) == 1);
qdict_del(tests_dict, key);
@@ -226,9 +226,9 @@ static void qdict_iterapi_test(void)
g_assert(qdict_first(tests_dict) == NULL);
- qdict_put(tests_dict, "key1", qint_from_int(1));
- qdict_put(tests_dict, "key2", qint_from_int(2));
- qdict_put(tests_dict, "key3", qint_from_int(3));
+ qdict_put_int(tests_dict, "key1", 1);
+ qdict_put_int(tests_dict, "key2", 2);
+ qdict_put_int(tests_dict, "key3", 3);
count = 0;
for (ent = qdict_first(tests_dict); ent; ent = qdict_next(tests_dict, ent)){
@@ -294,8 +294,8 @@ static void qdict_flatten_test(void)
* }
*/
- qdict_put(dict1, "a", qint_from_int(0));
- qdict_put(dict1, "b", qint_from_int(1));
+ qdict_put_int(dict1, "a", 0);
+ qdict_put_int(dict1, "b", 1);
qlist_append_obj(list1, QOBJECT(qint_from_int(23)));
qlist_append_obj(list1, QOBJECT(qint_from_int(66)));
@@ -303,11 +303,11 @@ static void qdict_flatten_test(void)
qlist_append_obj(list2, QOBJECT(qint_from_int(42)));
qlist_append_obj(list2, QOBJECT(list1));
- qdict_put(dict2, "c", qint_from_int(2));
- qdict_put(dict2, "d", qint_from_int(3));
- qdict_put_obj(dict3, "e", QOBJECT(list2));
- qdict_put_obj(dict3, "f", QOBJECT(dict2));
- qdict_put(dict3, "g", qint_from_int(4));
+ qdict_put_int(dict2, "c", 2);
+ qdict_put_int(dict2, "d", 3);
+ qdict_put(dict3, "e", list2);
+ qdict_put(dict3, "f", dict2);
+ qdict_put_int(dict3, "g", 4);
qdict_flatten(dict3);
@@ -369,12 +369,12 @@ static void qdict_array_split_test(void)
* This example is given in the comment of qdict_array_split().
*/
- qdict_put(test_dict, "1.x", qint_from_int(0));
- qdict_put(test_dict, "4.y", qint_from_int(1));
- qdict_put(test_dict, "0.a", qint_from_int(42));
- qdict_put(test_dict, "o.o", qint_from_int(7));
- qdict_put(test_dict, "0.b", qint_from_int(23));
- qdict_put(test_dict, "2", qint_from_int(66));
+ qdict_put_int(test_dict, "1.x", 0);
+ qdict_put_int(test_dict, "4.y", 1);
+ qdict_put_int(test_dict, "0.a", 42);
+ qdict_put_int(test_dict, "o.o", 7);
+ qdict_put_int(test_dict, "0.b", 23);
+ qdict_put_int(test_dict, "2", 66);
qdict_array_split(test_dict, &test_list);
@@ -441,9 +441,9 @@ static void qdict_array_split_test(void)
test_dict = qdict_new();
- qdict_put(test_dict, "0", qint_from_int(42));
- qdict_put(test_dict, "1", qint_from_int(23));
- qdict_put(test_dict, "1.x", qint_from_int(84));
+ qdict_put_int(test_dict, "0", 42);
+ qdict_put_int(test_dict, "1", 23);
+ qdict_put_int(test_dict, "1.x", 84);
qdict_array_split(test_dict, &test_list);
@@ -472,38 +472,38 @@ static void qdict_array_entries_test(void)
g_assert_cmpint(qdict_array_entries(dict, "foo."), ==, 0);
- qdict_put(dict, "bar", qint_from_int(0));
- qdict_put(dict, "baz.0", qint_from_int(0));
+ qdict_put_int(dict, "bar", 0);
+ qdict_put_int(dict, "baz.0", 0);
g_assert_cmpint(qdict_array_entries(dict, "foo."), ==, 0);
- qdict_put(dict, "foo.1", qint_from_int(0));
+ qdict_put_int(dict, "foo.1", 0);
g_assert_cmpint(qdict_array_entries(dict, "foo."), ==, -EINVAL);
- qdict_put(dict, "foo.0", qint_from_int(0));
+ qdict_put_int(dict, "foo.0", 0);
g_assert_cmpint(qdict_array_entries(dict, "foo."), ==, 2);
- qdict_put(dict, "foo.bar", qint_from_int(0));
+ qdict_put_int(dict, "foo.bar", 0);
g_assert_cmpint(qdict_array_entries(dict, "foo."), ==, -EINVAL);
qdict_del(dict, "foo.bar");
- qdict_put(dict, "foo.2.a", qint_from_int(0));
- qdict_put(dict, "foo.2.b", qint_from_int(0));
- qdict_put(dict, "foo.2.c", qint_from_int(0));
+ qdict_put_int(dict, "foo.2.a", 0);
+ qdict_put_int(dict, "foo.2.b", 0);
+ qdict_put_int(dict, "foo.2.c", 0);
g_assert_cmpint(qdict_array_entries(dict, "foo."), ==, 3);
g_assert_cmpint(qdict_array_entries(dict, ""), ==, -EINVAL);
QDECREF(dict);
dict = qdict_new();
- qdict_put(dict, "1", qint_from_int(0));
+ qdict_put_int(dict, "1", 0);
g_assert_cmpint(qdict_array_entries(dict, ""), ==, -EINVAL);
- qdict_put(dict, "0", qint_from_int(0));
+ qdict_put_int(dict, "0", 0);
g_assert_cmpint(qdict_array_entries(dict, ""), ==, 2);
- qdict_put(dict, "bar", qint_from_int(0));
+ qdict_put_int(dict, "bar", 0);
g_assert_cmpint(qdict_array_entries(dict, ""), ==, -EINVAL);
qdict_del(dict, "bar");
- qdict_put(dict, "2.a", qint_from_int(0));
- qdict_put(dict, "2.b", qint_from_int(0));
- qdict_put(dict, "2.c", qint_from_int(0));
+ qdict_put_int(dict, "2.a", 0);
+ qdict_put_int(dict, "2.b", 0);
+ qdict_put_int(dict, "2.c", 0);
g_assert_cmpint(qdict_array_entries(dict, ""), ==, 3);
QDECREF(dict);
@@ -529,7 +529,7 @@ static void qdict_join_test(void)
/* First iteration: Test movement */
/* Second iteration: Test empty source and non-empty destination */
- qdict_put(dict2, "foo", qint_from_int(42));
+ qdict_put_int(dict2, "foo", 42);
for (i = 0; i < 2; i++) {
qdict_join(dict1, dict2, overwrite);
@@ -541,7 +541,7 @@ static void qdict_join_test(void)
}
/* Test non-empty source and destination without conflict */
- qdict_put(dict2, "bar", qint_from_int(23));
+ qdict_put_int(dict2, "bar", 23);
qdict_join(dict1, dict2, overwrite);
@@ -552,7 +552,7 @@ static void qdict_join_test(void)
g_assert(qdict_get_int(dict1, "bar") == 23);
/* Test conflict */
- qdict_put(dict2, "foo", qint_from_int(84));
+ qdict_put_int(dict2, "foo", 84);
qdict_join(dict1, dict2, overwrite);
@@ -595,15 +595,15 @@ static void qdict_crumple_test_recursive(void)
QList *rules;
src = qdict_new();
- qdict_put(src, "vnc.listen.addr", qstring_from_str("127.0.0.1"));
- qdict_put(src, "vnc.listen.port", qstring_from_str("5901"));
- qdict_put(src, "vnc.acl.rules.0.match", qstring_from_str("fred"));
- qdict_put(src, "vnc.acl.rules.0.policy", qstring_from_str("allow"));
- qdict_put(src, "vnc.acl.rules.1.match", qstring_from_str("bob"));
- qdict_put(src, "vnc.acl.rules.1.policy", qstring_from_str("deny"));
- qdict_put(src, "vnc.acl.default", qstring_from_str("deny"));
- qdict_put(src, "vnc.acl..name", qstring_from_str("acl0"));
- qdict_put(src, "vnc.acl.rule..name", qstring_from_str("acl0"));
+ qdict_put_str(src, "vnc.listen.addr", "127.0.0.1");
+ qdict_put_str(src, "vnc.listen.port", "5901");
+ qdict_put_str(src, "vnc.acl.rules.0.match", "fred");
+ qdict_put_str(src, "vnc.acl.rules.0.policy", "allow");
+ qdict_put_str(src, "vnc.acl.rules.1.match", "bob");
+ qdict_put_str(src, "vnc.acl.rules.1.policy", "deny");
+ qdict_put_str(src, "vnc.acl.default", "deny");
+ qdict_put_str(src, "vnc.acl..name", "acl0");
+ qdict_put_str(src, "vnc.acl.rule..name", "acl0");
res = qdict_crumple(src, &error_abort);
@@ -676,8 +676,8 @@ static void qdict_crumple_test_bad_inputs(void)
src = qdict_new();
/* rule.0 can't be both a string and a dict */
- qdict_put(src, "rule.0", qstring_from_str("fred"));
- qdict_put(src, "rule.0.policy", qstring_from_str("allow"));
+ qdict_put_str(src, "rule.0", "fred");
+ qdict_put_str(src, "rule.0.policy", "allow");
g_assert(qdict_crumple(src, &error) == NULL);
g_assert(error != NULL);
@@ -687,8 +687,8 @@ static void qdict_crumple_test_bad_inputs(void)
src = qdict_new();
/* rule can't be both a list and a dict */
- qdict_put(src, "rule.0", qstring_from_str("fred"));
- qdict_put(src, "rule.a", qstring_from_str("allow"));
+ qdict_put_str(src, "rule.0", "fred");
+ qdict_put_str(src, "rule.a", "allow");
g_assert(qdict_crumple(src, &error) == NULL);
g_assert(error != NULL);
@@ -699,7 +699,7 @@ static void qdict_crumple_test_bad_inputs(void)
src = qdict_new();
/* The input should be flat, ie no dicts or lists */
qdict_put(src, "rule.a", qdict_new());
- qdict_put(src, "rule.b", qstring_from_str("allow"));
+ qdict_put_str(src, "rule.b", "allow");
g_assert(qdict_crumple(src, &error) == NULL);
g_assert(error != NULL);
@@ -709,8 +709,8 @@ static void qdict_crumple_test_bad_inputs(void)
src = qdict_new();
/* List indexes must not have gaps */
- qdict_put(src, "rule.0", qstring_from_str("deny"));
- qdict_put(src, "rule.3", qstring_from_str("allow"));
+ qdict_put_str(src, "rule.0", "deny");
+ qdict_put_str(src, "rule.3", "allow");
g_assert(qdict_crumple(src, &error) == NULL);
g_assert(error != NULL);
@@ -720,8 +720,8 @@ static void qdict_crumple_test_bad_inputs(void)
src = qdict_new();
/* List indexes must be in %zu format */
- qdict_put(src, "rule.0", qstring_from_str("deny"));
- qdict_put(src, "rule.+1", qstring_from_str("allow"));
+ qdict_put_str(src, "rule.0", "deny");
+ qdict_put_str(src, "rule.+1", "allow");
g_assert(qdict_crumple(src, &error) == NULL);
g_assert(error != NULL);
@@ -740,8 +740,8 @@ static void qdict_put_exists_test(void)
const char *key = "exists";
QDict *tests_dict = qdict_new();
- qdict_put(tests_dict, key, qint_from_int(1));
- qdict_put(tests_dict, key, qint_from_int(2));
+ qdict_put_int(tests_dict, key, 1);
+ qdict_put_int(tests_dict, key, 2);
value = qdict_get_int(tests_dict, key);
g_assert(value == 2);
diff --git a/tests/test-qmp-commands.c b/tests/test-qmp-commands.c
index ff94481..660a9e8 100644
--- a/tests/test-qmp-commands.c
+++ b/tests/test-qmp-commands.c
@@ -92,7 +92,7 @@ static void test_dispatch_cmd(void)
QDict *req = qdict_new();
QObject *resp;
- qdict_put_obj(req, "execute", QOBJECT(qstring_from_str("user_def_cmd")));
+ qdict_put_str(req, "execute", "user_def_cmd");
resp = qmp_dispatch(QOBJECT(req));
assert(resp != NULL);
@@ -109,7 +109,7 @@ static void test_dispatch_cmd_failure(void)
QDict *args = qdict_new();
QObject *resp;
- qdict_put_obj(req, "execute", QOBJECT(qstring_from_str("user_def_cmd2")));
+ qdict_put_str(req, "execute", "user_def_cmd2");
resp = qmp_dispatch(QOBJECT(req));
assert(resp != NULL);
@@ -120,10 +120,10 @@ static void test_dispatch_cmd_failure(void)
/* check that with extra arguments it throws an error */
req = qdict_new();
- qdict_put(args, "a", qint_from_int(66));
+ qdict_put_int(args, "a", 66);
qdict_put(req, "arguments", args);
- qdict_put_obj(req, "execute", QOBJECT(qstring_from_str("user_def_cmd")));
+ qdict_put_str(req, "execute", "user_def_cmd");
resp = qmp_dispatch(QOBJECT(req));
assert(resp != NULL);
@@ -162,14 +162,14 @@ static void test_dispatch_cmd_io(void)
QDict *ret_dict_dict2, *ret_dict_dict2_userdef;
QInt *ret3;
- qdict_put_obj(ud1a, "integer", QOBJECT(qint_from_int(42)));
- qdict_put_obj(ud1a, "string", QOBJECT(qstring_from_str("hello")));
- qdict_put_obj(ud1b, "integer", QOBJECT(qint_from_int(422)));
- qdict_put_obj(ud1b, "string", QOBJECT(qstring_from_str("hello2")));
- qdict_put_obj(args, "ud1a", QOBJECT(ud1a));
- qdict_put_obj(args, "ud1b", QOBJECT(ud1b));
- qdict_put_obj(req, "arguments", QOBJECT(args));
- qdict_put_obj(req, "execute", QOBJECT(qstring_from_str("user_def_cmd2")));
+ qdict_put_int(ud1a, "integer", 42);
+ qdict_put_str(ud1a, "string", "hello");
+ qdict_put_int(ud1b, "integer", 422);
+ qdict_put_str(ud1b, "string", "hello2");
+ qdict_put(args, "ud1a", ud1a);
+ qdict_put(args, "ud1b", ud1b);
+ qdict_put(req, "arguments", args);
+ qdict_put_str(req, "execute", "user_def_cmd2");
ret = qobject_to_qdict(test_qmp_dispatch(req));
@@ -188,9 +188,9 @@ static void test_dispatch_cmd_io(void)
assert(!strcmp(qdict_get_str(ret_dict_dict2, "string"), "blah4"));
QDECREF(ret);
- qdict_put(args3, "a", qint_from_int(66));
+ qdict_put_int(args3, "a", 66);
qdict_put(req, "arguments", args3);
- qdict_put(req, "execute", qstring_from_str("guest-get-time"));
+ qdict_put_str(req, "execute", "guest-get-time");
ret3 = qobject_to_qint(test_qmp_dispatch(req));
assert(qint_get_int(ret3) == 66);
@@ -242,7 +242,7 @@ static void test_dealloc_partial(void)
Visitor *v;
ud2_dict = qdict_new();
- qdict_put_obj(ud2_dict, "string0", QOBJECT(qstring_from_str(text)));
+ qdict_put_str(ud2_dict, "string0", text);
v = qobject_input_visitor_new(QOBJECT(ud2_dict), true);
visit_type_UserDefTwo(v, NULL, &ud2, &err);
diff --git a/tests/test-qmp-event.c b/tests/test-qmp-event.c
index 633dc87..cf58104 100644
--- a/tests/test-qmp-event.c
+++ b/tests/test-qmp-event.c
@@ -159,7 +159,7 @@ static void test_event_a(TestEventData *data,
{
QDict *d;
d = data->expect;
- qdict_put(d, "event", qstring_from_str("EVENT_A"));
+ qdict_put_str(d, "event", "EVENT_A");
qapi_event_send_event_a(&error_abort);
}
@@ -168,7 +168,7 @@ static void test_event_b(TestEventData *data,
{
QDict *d;
d = data->expect;
- qdict_put(d, "event", qstring_from_str("EVENT_B"));
+ qdict_put_str(d, "event", "EVENT_B");
qapi_event_send_event_b(&error_abort);
}
@@ -183,16 +183,16 @@ static void test_event_c(TestEventData *data,
b.has_enum1 = false;
d_b = qdict_new();
- qdict_put(d_b, "integer", qint_from_int(2));
- qdict_put(d_b, "string", qstring_from_str("test1"));
+ qdict_put_int(d_b, "integer", 2);
+ qdict_put_str(d_b, "string", "test1");
d_data = qdict_new();
- qdict_put(d_data, "a", qint_from_int(1));
+ qdict_put_int(d_data, "a", 1);
qdict_put(d_data, "b", d_b);
- qdict_put(d_data, "c", qstring_from_str("test2"));
+ qdict_put_str(d_data, "c", "test2");
d = data->expect;
- qdict_put(d, "event", qstring_from_str("EVENT_C"));
+ qdict_put_str(d, "event", "EVENT_C");
qdict_put(d, "data", d_data);
qapi_event_send_event_c(true, 1, true, &b, "test2", &error_abort);
@@ -219,22 +219,22 @@ static void test_event_d(TestEventData *data,
a.enum2 = ENUM_ONE_VALUE2;
d_struct1 = qdict_new();
- qdict_put(d_struct1, "integer", qint_from_int(2));
- qdict_put(d_struct1, "string", qstring_from_str("test1"));
- qdict_put(d_struct1, "enum1", qstring_from_str("value1"));
+ qdict_put_int(d_struct1, "integer", 2);
+ qdict_put_str(d_struct1, "string", "test1");
+ qdict_put_str(d_struct1, "enum1", "value1");
d_a = qdict_new();
qdict_put(d_a, "struct1", d_struct1);
- qdict_put(d_a, "string", qstring_from_str("test2"));
- qdict_put(d_a, "enum2", qstring_from_str("value2"));
+ qdict_put_str(d_a, "string", "test2");
+ qdict_put_str(d_a, "enum2", "value2");
d_data = qdict_new();
qdict_put(d_data, "a", d_a);
- qdict_put(d_data, "b", qstring_from_str("test3"));
- qdict_put(d_data, "enum3", qstring_from_str("value3"));
+ qdict_put_str(d_data, "b", "test3");
+ qdict_put_str(d_data, "enum3", "value3");
d = data->expect;
- qdict_put(d, "event", qstring_from_str("EVENT_D"));
+ qdict_put_str(d, "event", "EVENT_D");
qdict_put(d, "data", d_data);
qapi_event_send_event_d(&a, "test3", false, NULL, true, ENUM_ONE_VALUE3,
diff --git a/tests/test-qobject-output-visitor.c b/tests/test-qobject-output-visitor.c
index 4e2d79c..22d148a 100644
--- a/tests/test-qobject-output-visitor.c
+++ b/tests/test-qobject-output-visitor.c
@@ -356,9 +356,9 @@ static void test_visitor_out_any(TestOutputVisitorData *data,
visitor_reset(data);
qdict = qdict_new();
- qdict_put(qdict, "integer", qint_from_int(-42));
- qdict_put(qdict, "boolean", qbool_from_bool(true));
- qdict_put(qdict, "string", qstring_from_str("foo"));
+ qdict_put_int(qdict, "integer", -42);
+ qdict_put_bool(qdict, "boolean", true);
+ qdict_put_str(qdict, "string", "foo");
qobj = QOBJECT(qdict);
visit_type_any(data->ov, NULL, &qobj, &error_abort);
qobject_decref(qobj);
diff --git a/util/qemu-option.c b/util/qemu-option.c
index 3467dc2..b061fb0 100644
--- a/util/qemu-option.c
+++ b/util/qemu-option.c
@@ -1056,17 +1056,15 @@ void qemu_opts_absorb_qdict(QemuOpts *opts, QDict *qdict, Error **errp)
QDict *qemu_opts_to_qdict(QemuOpts *opts, QDict *qdict)
{
QemuOpt *opt;
- QObject *val;
if (!qdict) {
qdict = qdict_new();
}
if (opts->id) {
- qdict_put(qdict, "id", qstring_from_str(opts->id));
+ qdict_put_str(qdict, "id", opts->id);
}
QTAILQ_FOREACH(opt, &opts->head, next) {
- val = QOBJECT(qstring_from_str(opt->str));
- qdict_put_obj(qdict, opt->name, val);
+ qdict_put_str(qdict, opt->name, opt->str);
}
return qdict;
}
--
2.7.4
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [Qemu-devel] [PATCH 03/36] qlist: Add convenience helpers for wrapped appends
2016-11-30 19:44 [Qemu-devel] [PATCH 00/36] Rip out dynamic JSON parsing Eric Blake
2016-11-30 19:44 ` [Qemu-devel] [PATCH 01/36] pci: Use struct instead of QDict to pass back parameters Eric Blake
2016-11-30 19:44 ` [Qemu-devel] [PATCH 02/36] qdict: Add convenience helpers for wrapped puts Eric Blake
@ 2016-11-30 19:44 ` Eric Blake
2016-11-30 19:44 ` [Qemu-devel] [PATCH 04/36] qmp-event: Avoid dynamic JSON Eric Blake
` (33 subsequent siblings)
36 siblings, 0 replies; 45+ messages in thread
From: Eric Blake @ 2016-11-30 19:44 UTC (permalink / raw)
To: qemu-devel; +Cc: armbru, pbonzini
Similar to the qdict additions of the previous patch, although
this time there are not as many clients.
Signed-off-by: Eric Blake <eblake@redhat.com>
---
include/qapi/qmp/qlist.h | 8 ++++++++
tests/check-qdict.c | 10 +++++-----
tests/check-qlist.c | 2 +-
3 files changed, 14 insertions(+), 6 deletions(-)
diff --git a/include/qapi/qmp/qlist.h b/include/qapi/qmp/qlist.h
index a84117e..659325a 100644
--- a/include/qapi/qmp/qlist.h
+++ b/include/qapi/qmp/qlist.h
@@ -29,6 +29,14 @@ typedef struct QList {
#define qlist_append(qlist, obj) \
qlist_append_obj(qlist, QOBJECT(obj))
+/* Helpers for int, bool, and const char*. */
+#define qlist_append_int(qlist, value) \
+ qlist_append(qlist, qint_from_int(value))
+#define qlist_append_bool(qlist, value) \
+ qlist_append(qlist, qbool_from_bool(value))
+#define qlist_append_str(qlist, value) \
+ qlist_append(qlist, qstring_from_str(value))
+
#define QLIST_FOREACH_ENTRY(qlist, var) \
for ((var) = ((qlist)->head.tqh_first); \
(var); \
diff --git a/tests/check-qdict.c b/tests/check-qdict.c
index d00b411..6d4f8a7 100644
--- a/tests/check-qdict.c
+++ b/tests/check-qdict.c
@@ -297,11 +297,11 @@ static void qdict_flatten_test(void)
qdict_put_int(dict1, "a", 0);
qdict_put_int(dict1, "b", 1);
- qlist_append_obj(list1, QOBJECT(qint_from_int(23)));
- qlist_append_obj(list1, QOBJECT(qint_from_int(66)));
- qlist_append_obj(list1, QOBJECT(dict1));
- qlist_append_obj(list2, QOBJECT(qint_from_int(42)));
- qlist_append_obj(list2, QOBJECT(list1));
+ qlist_append_int(list1, 23);
+ qlist_append_int(list1, 66);
+ qlist_append(list1, dict1);
+ qlist_append_int(list2, 42);
+ qlist_append(list2, list1);
qdict_put_int(dict2, "c", 2);
qdict_put_int(dict2, "d", 3);
diff --git a/tests/check-qlist.c b/tests/check-qlist.c
index e16da5e..38463f1 100644
--- a/tests/check-qlist.c
+++ b/tests/check-qlist.c
@@ -74,7 +74,7 @@ static void qlist_destroy_test(void)
qlist = qlist_new();
for (i = 0; i < 42; i++)
- qlist_append(qlist, qint_from_int(i));
+ qlist_append_int(qlist, i);
QDECREF(qlist);
}
--
2.7.4
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [Qemu-devel] [PATCH 04/36] qmp-event: Avoid dynamic JSON
2016-11-30 19:44 [Qemu-devel] [PATCH 00/36] Rip out dynamic JSON parsing Eric Blake
` (2 preceding siblings ...)
2016-11-30 19:44 ` [Qemu-devel] [PATCH 03/36] qlist: Add convenience helpers for wrapped appends Eric Blake
@ 2016-11-30 19:44 ` Eric Blake
2016-11-30 19:44 ` [Qemu-devel] [PATCH 05/36] qmp-dispatch: " Eric Blake
` (32 subsequent siblings)
36 siblings, 0 replies; 45+ messages in thread
From: Eric Blake @ 2016-11-30 19:44 UTC (permalink / raw)
To: qemu-devel; +Cc: armbru, pbonzini, Michael Roth
The qobject_from_jsonf() function implements a pseudo-printf
language for creating a QObject through the extension of dynamic
JSON; however, it is hard-coded to only parse a subset of
formats understood by -Wformat and is not a straight synonym to
bare printf(). During a recent cleanup due to problems caused
by PRId64, it was questioned whether the maintenance burden of
keeping the dynamic JSON extension can be counterbalanced by
converting code to use alternative ways of describing QObject.
For this particular use of dynamic JSON, it is just as simple
to open-code the correct QObject creation.
Signed-off-by: Eric Blake <eblake@redhat.com>
---
qapi/qmp-event.c | 13 ++++++++-----
1 file changed, 8 insertions(+), 5 deletions(-)
diff --git a/qapi/qmp-event.c b/qapi/qmp-event.c
index ba3029c..57f54d9 100644
--- a/qapi/qmp-event.c
+++ b/qapi/qmp-event.c
@@ -15,6 +15,8 @@
#include "qemu-common.h"
#include "qapi/qmp-event.h"
+#include "qapi/qmp/qdict.h"
+#include "qapi/qmp/qint.h"
#include "qapi/qmp/qstring.h"
#include "qapi/qmp/qjson.h"
@@ -33,15 +35,16 @@ QMPEventFuncEmit qmp_event_get_func_emit(void)
static void timestamp_put(QDict *qdict)
{
int err;
- QObject *obj;
+ QDict *stamp = qdict_new();
qemu_timeval tv;
err = qemu_gettimeofday(&tv);
/* Put -1 to indicate failure of getting host time */
- obj = qobject_from_jsonf("{ 'seconds': %lld, 'microseconds': %lld }",
- err < 0 ? -1LL : (long long)tv.tv_sec,
- err < 0 ? -1LL : (long long)tv.tv_usec);
- qdict_put_obj(qdict, "timestamp", obj);
+ qdict_put_int(stamp, "seconds",
+ err < 0 ? -1LL : (long long)tv.tv_sec);
+ qdict_put_int(stamp, "microseconds",
+ err < 0 ? -1LL : (long long)tv.tv_usec);
+ qdict_put(qdict, "timestamp", stamp);
}
/*
--
2.7.4
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [Qemu-devel] [PATCH 05/36] qmp-dispatch: Avoid dynamic JSON
2016-11-30 19:44 [Qemu-devel] [PATCH 00/36] Rip out dynamic JSON parsing Eric Blake
` (3 preceding siblings ...)
2016-11-30 19:44 ` [Qemu-devel] [PATCH 04/36] qmp-event: Avoid dynamic JSON Eric Blake
@ 2016-11-30 19:44 ` Eric Blake
2016-11-30 19:44 ` [Qemu-devel] [PATCH 06/36] qobject-input-visitor: Avoid dynamic JSON in tests Eric Blake
` (31 subsequent siblings)
36 siblings, 0 replies; 45+ messages in thread
From: Eric Blake @ 2016-11-30 19:44 UTC (permalink / raw)
To: qemu-devel; +Cc: armbru, pbonzini, Dr. David Alan Gilbert, Michael Roth
The qobject_from_jsonf() function implements a pseudo-printf
language for creating a QObject through the extension of dynamic
JSON; however, it is hard-coded to only parse a subset of
formats understood by -Wformat and is not a straight synonym to
bare printf(). During a recent cleanup due to problems caused
by PRId64, it was questioned whether the maintenance burden of
keeping the dynamic JSON extension can be counterbalanced by
converting code to use alternative ways of describing QObject.
For these two conversions, the open-coded QObject creation is a
bit more verbose, but performs slightly faster than going through
a parse; futhermore, there is no correpsonding QAPI C type to
make for an easier representation than open-coding.
Signed-off-by: Eric Blake <eblake@redhat.com>
---
monitor.c | 10 +++++++---
qapi/qmp-dispatch.c | 8 +++++---
2 files changed, 12 insertions(+), 6 deletions(-)
diff --git a/monitor.c b/monitor.c
index 2a877ef..f86a855 100644
--- a/monitor.c
+++ b/monitor.c
@@ -3839,11 +3839,15 @@ void monitor_resume(Monitor *mon)
static QObject *get_qmp_greeting(void)
{
QObject *ver = NULL;
+ QDict *sub, *ret;
qmp_marshal_query_version(NULL, &ver, NULL);
-
- return qobject_from_jsonf("{'QMP': {'version': %p, 'capabilities': []}}",
- ver);
+ sub = qdict_new();
+ qdict_put_obj(sub, "version", ver);
+ qdict_put(sub, "capabilities", qlist_new());
+ ret = qdict_new();
+ qdict_put(ret, "QMP", sub);
+ return QOBJECT(ret);
}
static void monitor_qmp_event(void *opaque, int event)
diff --git a/qapi/qmp-dispatch.c b/qapi/qmp-dispatch.c
index 505eb41..483ea68 100644
--- a/qapi/qmp-dispatch.c
+++ b/qapi/qmp-dispatch.c
@@ -111,9 +111,11 @@ static QObject *do_qmp_dispatch(QObject *request, Error **errp)
QObject *qmp_build_error_object(Error *err)
{
- return qobject_from_jsonf("{ 'class': %s, 'desc': %s }",
- QapiErrorClass_lookup[error_get_class(err)],
- error_get_pretty(err));
+ QDict *ret = qdict_new();
+
+ qdict_put_str(ret, "class", QapiErrorClass_lookup[error_get_class(err)]);
+ qdict_put_str(ret, "desc", error_get_pretty(err));
+ return QOBJECT(ret);
}
QObject *qmp_dispatch(QObject *request)
--
2.7.4
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [Qemu-devel] [PATCH 06/36] qobject-input-visitor: Avoid dynamic JSON in tests
2016-11-30 19:44 [Qemu-devel] [PATCH 00/36] Rip out dynamic JSON parsing Eric Blake
` (4 preceding siblings ...)
2016-11-30 19:44 ` [Qemu-devel] [PATCH 05/36] qmp-dispatch: " Eric Blake
@ 2016-11-30 19:44 ` Eric Blake
2016-11-30 19:44 ` [Qemu-devel] [PATCH 07/36] fdc-test: Avoid deprecated 'change' command Eric Blake
` (30 subsequent siblings)
36 siblings, 0 replies; 45+ messages in thread
From: Eric Blake @ 2016-11-30 19:44 UTC (permalink / raw)
To: qemu-devel; +Cc: armbru, pbonzini, Michael Roth
As argued elsewhere, we want to get rid of the pseudo-printf
dynamic JSON parsing of qobject_from_jsonv(). In the qobject-input
visitor tests, it is trivial to convert to using the direct
qobject_from_json() or a hand-built QObject.
While at it, wrap some long lines noticed while auditing callers.
Signed-off-by: Eric Blake <eblake@redhat.com>
---
tests/test-qobject-input-strict.c | 37 +++----------------
tests/test-qobject-input-visitor.c | 75 ++++++++++++++++----------------------
2 files changed, 37 insertions(+), 75 deletions(-)
diff --git a/tests/test-qobject-input-strict.c b/tests/test-qobject-input-strict.c
index 4087ea3..8e6a74a 100644
--- a/tests/test-qobject-input-strict.c
+++ b/tests/test-qobject-input-strict.c
@@ -41,16 +41,15 @@ static void validate_teardown(TestInputVisitorData *data,
}
}
-/* The various test_init functions are provided instead of a test setup
+/* The test_init function is provided instead of a test setup
function so that the JSON string used by the tests are kept in the test
functions (and not in main()). */
-static Visitor *validate_test_init_internal(TestInputVisitorData *data,
- const char *json_string,
- va_list *ap)
+static Visitor *validate_test_init(TestInputVisitorData *data,
+ const char *json_string)
{
validate_teardown(data, NULL);
- data->obj = qobject_from_jsonv(json_string, ap);
+ data->obj = qobject_from_json(json_string);
g_assert(data->obj);
data->qiv = qobject_input_visitor_new(data->obj, true);
@@ -58,32 +57,6 @@ static Visitor *validate_test_init_internal(TestInputVisitorData *data,
return data->qiv;
}
-static GCC_FMT_ATTR(2, 3)
-Visitor *validate_test_init(TestInputVisitorData *data,
- const char *json_string, ...)
-{
- Visitor *v;
- va_list ap;
-
- va_start(ap, json_string);
- v = validate_test_init_internal(data, json_string, &ap);
- va_end(ap);
- return v;
-}
-
-/* similar to validate_test_init(), but does not expect a string
- * literal/format json_string argument and so can be used for
- * programatically generated strings (and we can't pass in programatically
- * generated strings via %s format parameters since qobject_from_jsonv()
- * will wrap those in double-quotes and treat the entire object as a
- * string)
- */
-static Visitor *validate_test_init_raw(TestInputVisitorData *data,
- const char *json_string)
-{
- return validate_test_init_internal(data, json_string, NULL);
-}
-
static void test_validate_struct(TestInputVisitorData *data,
const void *unused)
@@ -315,7 +288,7 @@ static void do_test_validate_qmp_introspect(TestInputVisitorData *data,
SchemaInfoList *schema = NULL;
Visitor *v;
- v = validate_test_init_raw(data, schema_json);
+ v = validate_test_init(data, schema_json);
visit_type_SchemaInfoList(v, NULL, &schema, &error_abort);
g_assert(schema);
diff --git a/tests/test-qobject-input-visitor.c b/tests/test-qobject-input-visitor.c
index 945404a..4c1436d 100644
--- a/tests/test-qobject-input-visitor.c
+++ b/tests/test-qobject-input-visitor.c
@@ -40,44 +40,24 @@ static void visitor_input_teardown(TestInputVisitorData *data,
/* The various test_init functions are provided instead of a test setup
function so that the JSON string used by the tests are kept in the test
functions (and not in main()). */
-static Visitor *visitor_input_test_init_internal(TestInputVisitorData *data,
- const char *json_string,
- va_list *ap)
+static Visitor *visitor_input_test_init_obj(TestInputVisitorData *data,
+ QObject *obj)
{
visitor_input_teardown(data, NULL);
- data->obj = qobject_from_jsonv(json_string, ap);
- g_assert(data->obj);
-
+ data->obj = obj;
data->qiv = qobject_input_visitor_new(data->obj, false);
g_assert(data->qiv);
return data->qiv;
}
-static GCC_FMT_ATTR(2, 3)
-Visitor *visitor_input_test_init(TestInputVisitorData *data,
- const char *json_string, ...)
-{
- Visitor *v;
- va_list ap;
-
- va_start(ap, json_string);
- v = visitor_input_test_init_internal(data, json_string, &ap);
- va_end(ap);
- return v;
-}
-
-/* similar to visitor_input_test_init(), but does not expect a string
- * literal/format json_string argument and so can be used for
- * programatically generated strings (and we can't pass in programatically
- * generated strings via %s format parameters since qobject_from_jsonv()
- * will wrap those in double-quotes and treat the entire object as a
- * string)
+/* similar to visitor_input_test_init_obj(), but takes input as a raw JSON
+ * string rather than a preformed QObject
*/
-static Visitor *visitor_input_test_init_raw(TestInputVisitorData *data,
- const char *json_string)
+static Visitor *visitor_input_test_init(TestInputVisitorData *data,
+ const char *json_string)
{
- return visitor_input_test_init_internal(data, json_string, NULL);
+ return visitor_input_test_init_obj(data, qobject_from_json(json_string));
}
static void test_visitor_in_int(TestInputVisitorData *data,
@@ -87,7 +67,7 @@ static void test_visitor_in_int(TestInputVisitorData *data,
int value = -42;
Visitor *v;
- v = visitor_input_test_init(data, "%d", value);
+ v = visitor_input_test_init_obj(data, QOBJECT(qint_from_int(value)));
visit_type_int(v, NULL, &res, &error_abort);
g_assert_cmpint(res, ==, value);
@@ -104,7 +84,8 @@ static void test_visitor_in_int_overflow(TestInputVisitorData *data,
* a QFloat/double field instead, leading to an error if we pass it
* to visit_type_int. confirm this.
*/
- v = visitor_input_test_init(data, "%f", DBL_MAX);
+ v = visitor_input_test_init_obj(data,
+ QOBJECT(qfloat_from_double(DBL_MAX)));
visit_type_int(v, NULL, &res, &err);
error_free_or_abort(&err);
@@ -116,7 +97,7 @@ static void test_visitor_in_bool(TestInputVisitorData *data,
bool res = false;
Visitor *v;
- v = visitor_input_test_init(data, "true");
+ v = visitor_input_test_init_obj(data, QOBJECT(qbool_from_bool(true)));
visit_type_bool(v, NULL, &res, &error_abort);
g_assert_cmpint(res, ==, true);
@@ -128,7 +109,7 @@ static void test_visitor_in_number(TestInputVisitorData *data,
double res = 0, value = 3.14;
Visitor *v;
- v = visitor_input_test_init(data, "%f", value);
+ v = visitor_input_test_init_obj(data, QOBJECT(qfloat_from_double(value)));
visit_type_number(v, NULL, &res, &error_abort);
g_assert_cmpfloat(res, ==, value);
@@ -140,7 +121,7 @@ static void test_visitor_in_string(TestInputVisitorData *data,
char *res = NULL, *value = (char *) "Q E M U";
Visitor *v;
- v = visitor_input_test_init(data, "%s", value);
+ v = visitor_input_test_init_obj(data, QOBJECT(qstring_from_str(value)));
visit_type_str(v, NULL, &res, &error_abort);
g_assert_cmpstr(res, ==, value);
@@ -156,8 +137,9 @@ static void test_visitor_in_enum(TestInputVisitorData *data,
for (i = 0; EnumOne_lookup[i]; i++) {
EnumOne res = -1;
+ QString *str = qstring_from_str(EnumOne_lookup[i]);
- v = visitor_input_test_init(data, "%s", EnumOne_lookup[i]);
+ v = visitor_input_test_init_obj(data, QOBJECT(str));
visit_type_EnumOne(v, NULL, &res, &error_abort);
g_assert_cmpint(i, ==, res);
@@ -171,7 +153,8 @@ static void test_visitor_in_struct(TestInputVisitorData *data,
TestStruct *p = NULL;
Visitor *v;
- v = visitor_input_test_init(data, "{ 'integer': -42, 'boolean': true, 'string': 'foo' }");
+ v = visitor_input_test_init(data, "{ 'integer': -42, 'boolean': true,"
+ " 'string': 'foo' }");
visit_type_TestStruct(v, NULL, &p, &error_abort);
g_assert_cmpint(p->integer, ==, -42);
@@ -191,7 +174,8 @@ static void test_visitor_in_struct_nested(TestInputVisitorData *data,
v = visitor_input_test_init(data, "{ 'string0': 'string0', "
"'dict1': { 'string1': 'string1', "
"'dict2': { 'userdef': { 'integer': 42, "
- "'string': 'string' }, 'string': 'string2'}}}");
+ "'string': 'string' }, "
+ "'string': 'string2'}}}");
visit_type_UserDefTwo(v, NULL, &udp, &error_abort);
@@ -212,7 +196,10 @@ static void test_visitor_in_list(TestInputVisitorData *data,
Visitor *v;
int i;
- v = visitor_input_test_init(data, "[ { 'string': 'string0', 'integer': 42 }, { 'string': 'string1', 'integer': 43 }, { 'string': 'string2', 'integer': 44 } ]");
+ v = visitor_input_test_init(data,
+ "[ { 'string': 'string0', 'integer': 42 },"
+ "{ 'string': 'string1', 'integer': 43 }, "
+ "{ 'string': 'string2', 'integer': 44 } ]");
visit_type_UserDefOneList(v, NULL, &head, &error_abort);
g_assert(head != NULL);
@@ -252,7 +239,8 @@ static void test_visitor_in_any(TestInputVisitorData *data,
g_assert_cmpint(qint_get_int(qint), ==, -42);
qobject_decref(res);
- v = visitor_input_test_init(data, "{ 'integer': -42, 'boolean': true, 'string': 'foo' }");
+ v = visitor_input_test_init(data, "{ 'integer': -42, 'boolean': true, "
+ "'string': 'foo' }");
visit_type_any(v, NULL, &res, &error_abort);
qdict = qobject_to_qdict(res);
g_assert(qdict && qdict_size(qdict) == 3);
@@ -375,7 +363,8 @@ static void test_visitor_in_alternate(TestInputVisitorData *data,
g_assert_cmpstr(wrap->alt->u.s, ==, "string");
qapi_free_WrapAlternate(wrap);
- v = visitor_input_test_init(data, "{ 'alt': {'integer':1, 'string':'str', "
+ v = visitor_input_test_init(data, "{ 'alt': {'integer':1, "
+ "'string':'str', "
"'enum1':'value1', 'boolean':true} }");
visit_type_WrapAlternate(v, NULL, &wrap, &error_abort);
g_assert_cmpint(wrap->alt->type, ==, QTYPE_QDICT);
@@ -492,7 +481,7 @@ static void test_native_list_integer_helper(TestInputVisitorData *data,
g_string_append_printf(gstr_union, "{ 'type': '%s', 'data': [ %s ] }",
UserDefNativeListUnionKind_lookup[kind],
gstr_list->str);
- v = visitor_input_test_init_raw(data, gstr_union->str);
+ v = visitor_input_test_init(data, gstr_union->str);
visit_type_UserDefNativeListUnion(v, NULL, &cvalue, &error_abort);
g_assert(cvalue != NULL);
@@ -654,7 +643,7 @@ static void test_visitor_in_native_list_bool(TestInputVisitorData *data,
}
g_string_append_printf(gstr_union, "{ 'type': 'boolean', 'data': [ %s ] }",
gstr_list->str);
- v = visitor_input_test_init_raw(data, gstr_union->str);
+ v = visitor_input_test_init(data, gstr_union->str);
visit_type_UserDefNativeListUnion(v, NULL, &cvalue, &error_abort);
g_assert(cvalue != NULL);
@@ -687,7 +676,7 @@ static void test_visitor_in_native_list_string(TestInputVisitorData *data,
}
g_string_append_printf(gstr_union, "{ 'type': 'string', 'data': [ %s ] }",
gstr_list->str);
- v = visitor_input_test_init_raw(data, gstr_union->str);
+ v = visitor_input_test_init(data, gstr_union->str);
visit_type_UserDefNativeListUnion(v, NULL, &cvalue, &error_abort);
g_assert(cvalue != NULL);
@@ -724,7 +713,7 @@ static void test_visitor_in_native_list_number(TestInputVisitorData *data,
}
g_string_append_printf(gstr_union, "{ 'type': 'number', 'data': [ %s ] }",
gstr_list->str);
- v = visitor_input_test_init_raw(data, gstr_union->str);
+ v = visitor_input_test_init(data, gstr_union->str);
visit_type_UserDefNativeListUnion(v, NULL, &cvalue, &error_abort);
g_assert(cvalue != NULL);
--
2.7.4
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [Qemu-devel] [PATCH 07/36] fdc-test: Avoid deprecated 'change' command
2016-11-30 19:44 [Qemu-devel] [PATCH 00/36] Rip out dynamic JSON parsing Eric Blake
` (5 preceding siblings ...)
2016-11-30 19:44 ` [Qemu-devel] [PATCH 06/36] qobject-input-visitor: Avoid dynamic JSON in tests Eric Blake
@ 2016-11-30 19:44 ` Eric Blake
2016-11-30 20:58 ` John Snow
2016-11-30 19:44 ` [Qemu-devel] [PATCH 08/36] test-qga: Actually test 0xff sync bytes Eric Blake
` (29 subsequent siblings)
36 siblings, 1 reply; 45+ messages in thread
From: Eric Blake @ 2016-11-30 19:44 UTC (permalink / raw)
To: qemu-devel; +Cc: armbru, pbonzini, John Snow, open list:Floppy
Use the preferred blockdev-change-medium command instead.
Signed-off-by: Eric Blake <eblake@redhat.com>
---
tests/fdc-test.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/tests/fdc-test.c b/tests/fdc-test.c
index 738c6b4..f5ff68d 100644
--- a/tests/fdc-test.c
+++ b/tests/fdc-test.c
@@ -298,8 +298,9 @@ static void test_media_insert(void)
/* Insert media in drive. DSKCHK should not be reset until a step pulse
* is sent. */
- qmp_discard_response("{'execute':'change', 'arguments':{"
- " 'device':'floppy0', 'target': %s, 'arg': 'raw' }}",
+ qmp_discard_response("{'execute':'blockdev-change-medium', 'arguments':{"
+ " 'device':'floppy0', 'filename': %s, "
+ "'format': 'raw' }}",
test_image);
dir = inb(FLOPPY_BASE + reg_dir);
--
2.7.4
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [Qemu-devel] [PATCH 08/36] test-qga: Actually test 0xff sync bytes
2016-11-30 19:44 [Qemu-devel] [PATCH 00/36] Rip out dynamic JSON parsing Eric Blake
` (6 preceding siblings ...)
2016-11-30 19:44 ` [Qemu-devel] [PATCH 07/36] fdc-test: Avoid deprecated 'change' command Eric Blake
@ 2016-11-30 19:44 ` Eric Blake
2016-11-30 19:44 ` [Qemu-devel] [PATCH 09/36] qtest: Add a new helper qmp_cmd() and friends Eric Blake
` (28 subsequent siblings)
36 siblings, 0 replies; 45+ messages in thread
From: Eric Blake @ 2016-11-30 19:44 UTC (permalink / raw)
To: qemu-devel; +Cc: armbru, pbonzini
Commit 62c39b3 introduced test-qga, and at face value, appears
to be testing the 'guest-sync' behavior that is recommended for
guests in sending 0xff to QGA to force the parser to reset. But
this aspect of the test has never actually done anything: the
qmp_fd() call chain converts its string argument into QObject,
then converts that QObject back to the actual string that is
sent over the wire - and the conversion process silently drops
the 0xff byte from the string sent to QGA, thus never resetting
the QGA parser.
An upcoming patch will get rid of the wasteful round trip
through QObject, at which point the string in test-qga will be
directly sent over the wire.
But fixing qmp_fd() to actually send 0xff over the wire is not
all we have to do - the actual QMP parser loudly complains that
0xff is not valid JSON, and sends an error message _prior_ to
actually parsing the 'guest-sync' or 'guest-sync-delimited'
command. With 'guest-sync', we cannot easily tell if this error
message is a result of our command - which is WHY we invented
the 'guest-sync-delimited' command. So for the testsuite, fix
things to only check 0xff behavior on 'guest-sync-delimited',
and to loop until we've consumed all garbage prior to the
requested delimiter, which matches the documented actions that
a real QGA client is supposed to do.
Ideally, we'd fix the QGA JSON parser to silently ignore 0xff
rather than sending an error message back, at which point we
could enhance this test for 'guest-sync' as well as for
'guest-sync-delimited'. But for the sake of this patch, our
testing of 'guest-sync' is no worse than it was pre-patch,
because we have never been sending 0xff over the wire in the
first place.
Signed-off-by: Eric Blake <eblake@redhat.com>
---
tests/libqtest.c | 8 ++++++++
tests/test-qga.c | 12 +++++++-----
2 files changed, 15 insertions(+), 5 deletions(-)
diff --git a/tests/libqtest.c b/tests/libqtest.c
index 6f69752..429aaec 100644
--- a/tests/libqtest.c
+++ b/tests/libqtest.c
@@ -430,6 +430,14 @@ void qmp_fd_sendv(int fd, const char *fmt, va_list ap)
va_list ap_copy;
QObject *qobj;
+ /* qobject_from_jsonv() silently eats leading 0xff as invalid
+ * JSON, but we want to test sending them over the wire to force
+ * resyncs */
+ if (*fmt == '\377') {
+ socket_send(fd, fmt, 1);
+ fmt++;
+ }
+
/* Going through qobject ensures we escape strings properly.
* This seemingly unnecessary copy is required in case va_list
* is an array type.
diff --git a/tests/test-qga.c b/tests/test-qga.c
index 868b02a..4b64630 100644
--- a/tests/test-qga.c
+++ b/tests/test-qga.c
@@ -151,9 +151,11 @@ static void test_qga_sync_delimited(gconstpointer fix)
qmp_fd_send(fixture->fd, cmd);
g_free(cmd);
- v = read(fixture->fd, &c, 1);
- g_assert_cmpint(v, ==, 1);
- g_assert_cmpint(c, ==, 0xff);
+ /* Read and ignore garbage until resynchronized */
+ do {
+ v = read(fixture->fd, &c, 1);
+ g_assert_cmpint(v, ==, 1);
+ } while (c != 0xff);
ret = qmp_fd_receive(fixture->fd);
g_assert_nonnull(ret);
@@ -172,8 +174,8 @@ static void test_qga_sync(gconstpointer fix)
QDict *ret;
gchar *cmd;
- cmd = g_strdup_printf("%c{'execute': 'guest-sync',"
- " 'arguments': {'id': %u } }", 0xff, r);
+ cmd = g_strdup_printf("{'execute': 'guest-sync',"
+ " 'arguments': {'id': %u } }", r);
ret = qmp_fd(fixture->fd, cmd);
g_free(cmd);
--
2.7.4
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [Qemu-devel] [PATCH 09/36] qtest: Add a new helper qmp_cmd() and friends
2016-11-30 19:44 [Qemu-devel] [PATCH 00/36] Rip out dynamic JSON parsing Eric Blake
` (7 preceding siblings ...)
2016-11-30 19:44 ` [Qemu-devel] [PATCH 08/36] test-qga: Actually test 0xff sync bytes Eric Blake
@ 2016-11-30 19:44 ` Eric Blake
2016-11-30 19:44 ` [Qemu-devel] [PATCH 10/36] qtest: Avoid dynamic JSON in libqtest Eric Blake
` (27 subsequent siblings)
36 siblings, 0 replies; 45+ messages in thread
From: Eric Blake @ 2016-11-30 19:44 UTC (permalink / raw)
To: qemu-devel; +Cc: armbru, pbonzini
The qobject_from_jsonv() function implements a pseudo-printf
language for creating a QObject through the extension of dynamic
JSON; however, it is hard-coded to only parse a subset of
formats understood by -Wformat and is not a straight synonym to
bare printf(). During a recent cleanup due to problems caused
by PRId64, it was questioned whether the maintenance burden of
keeping the dynamic JSON extension can be counterbalanced by
converting code to use alternative ways of describing QObject.
This particular patch just adds a couple of convenience methods,
based on the observation that most testsuite use of dynamic JSON
is nested within the arguments portion of a larger command
dictionary. Separating the task of generating the arguments
from the boilerplate of generating the outer dictionary reduces
the conversion effort needed in the various clients.
Because the hand-built QObject might contain '%' characters
embedded in strings, we can't directly convert the QObject to
string and pass that as a format argument. So for now, we just
use a hack of a format string of "%p" to pass the resulting
QObject through various varargs calls and into the dynamic
JSON parser, where it will then be regurgitated as the QObject
that gets converted into the final string to send over the wire.
A later patch will clean up libqtest to accept direct string
commands, at which point we can tweak qmp_cmd() to avoid the
extra no-op trip through the JSON parser.
Signed-off-by: Eric Blake <eblake@redhat.com>
---
tests/libqtest.h | 31 +++++++++++++++++++++++++++++++
tests/libqtest.c | 26 ++++++++++++++++++++++++++
2 files changed, 57 insertions(+)
diff --git a/tests/libqtest.h b/tests/libqtest.h
index 90f182e..07ddaa2 100644
--- a/tests/libqtest.h
+++ b/tests/libqtest.h
@@ -58,6 +58,17 @@ void qtest_qmp_discard_response(QTestState *s, const char *fmt, ...);
QDict *qtest_qmp(QTestState *s, const char *fmt, ...);
/**
+ * qtest_qmp_cmd:
+ * @s: #QTestState instance to operate on.
+ * @cmd: Command name to send
+ * @args: Arguments to transfer to the command, or NULL.
+ *
+ * Sends a QMP message to QEMU and returns the response. Calling this will
+ * reduce the reference count of @args.
+ */
+QDict *qtest_qmp_cmd(QTestState *s, const char *cmd, QDict *args);
+
+/**
* qtest_async_qmp:
* @s: #QTestState instance to operate on.
* @fmt...: QMP message to send to qemu
@@ -532,6 +543,16 @@ static inline void qtest_end(void)
QDict *qmp(const char *fmt, ...);
/**
+ * qmp_cmd:
+ * @cmd: Command name to send
+ * @args: Arguments to transfer to the command, or NULL.
+ *
+ * Sends a QMP message to QEMU and returns the response. Calling this will
+ * reduce the reference count of @args.
+ */
+QDict *qmp_cmd(const char *cmd, QDict *args);
+
+/**
* qmp_async:
* @fmt...: QMP message to send to qemu
*
@@ -548,6 +569,16 @@ void qmp_async(const char *fmt, ...);
void qmp_discard_response(const char *fmt, ...);
/**
+ * qmp_cmd_discard_response:
+ * @cmd: Command name to send
+ * @args: Arguments to transfer to the command, or NULL.
+ *
+ * Sends a QMP message to QEMU and consumes the response. Calling this will
+ * reduce the reference count of @args.
+ */
+void qmp_cmd_discard_response(const char *cmd, QDict *args);
+
+/**
* qmp_receive:
*
* Reads a QMP message from QEMU and returns the response.
diff --git a/tests/libqtest.c b/tests/libqtest.c
index 429aaec..0796bb0 100644
--- a/tests/libqtest.c
+++ b/tests/libqtest.c
@@ -515,6 +515,18 @@ QDict *qtest_qmp(QTestState *s, const char *fmt, ...)
return response;
}
+QDict *qtest_qmp_cmd(QTestState *s, const char *cmd, QDict *args)
+{
+ QDict *dict = qdict_new();
+
+ if (!args) {
+ args = qdict_new();
+ }
+ qdict_put_str(dict, "execute", cmd);
+ qdict_put(dict, "arguments", args);
+ return qtest_qmp(s, "%p", QOBJECT(dict));
+}
+
void qtest_async_qmp(QTestState *s, const char *fmt, ...)
{
va_list ap;
@@ -894,6 +906,11 @@ QDict *qmp(const char *fmt, ...)
return response;
}
+QDict *qmp_cmd(const char *cmd, QDict *args)
+{
+ return qtest_qmp_cmd(global_qtest, cmd, args);
+}
+
void qmp_async(const char *fmt, ...)
{
va_list ap;
@@ -911,6 +928,15 @@ void qmp_discard_response(const char *fmt, ...)
qtest_qmpv_discard_response(global_qtest, fmt, ap);
va_end(ap);
}
+
+void qmp_cmd_discard_response(const char *cmd, QDict *args)
+{
+ QDict *response;
+
+ response = qmp_cmd(cmd, args);
+ QDECREF(response);
+}
+
char *hmp(const char *fmt, ...)
{
va_list ap;
--
2.7.4
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [Qemu-devel] [PATCH 10/36] qtest: Avoid dynamic JSON in libqtest
2016-11-30 19:44 [Qemu-devel] [PATCH 00/36] Rip out dynamic JSON parsing Eric Blake
` (8 preceding siblings ...)
2016-11-30 19:44 ` [Qemu-devel] [PATCH 09/36] qtest: Add a new helper qmp_cmd() and friends Eric Blake
@ 2016-11-30 19:44 ` Eric Blake
2016-11-30 19:44 ` [Qemu-devel] [PATCH 11/36] qapi: Add QAPI_TO_QOBJECT() convenience macro Eric Blake
` (26 subsequent siblings)
36 siblings, 0 replies; 45+ messages in thread
From: Eric Blake @ 2016-11-30 19:44 UTC (permalink / raw)
To: qemu-devel; +Cc: armbru, pbonzini
The qobject_from_jsonf() function implements a pseudo-printf
language for creating a QObject through the extension of dynamic
JSON; however, it is hard-coded to only parse a subset of
formats understood by -Wformat and is not a straight synonym to
bare printf(). During a recent cleanup due to problems caused
by PRId64, it was questioned whether the maintenance burden of
keeping the dynamic JSON extension can be counterbalanced by
converting code to use alternative ways of describing QObject.
The only use of dynamic JSON in the testsuite glue code was
the creation of a human monitor command over QMP, and is a
relatively straightforward update.
Signed-off-by: Eric Blake <eblake@redhat.com>
---
tests/libqtest.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/tests/libqtest.c b/tests/libqtest.c
index 0796bb0..26c4beb 100644
--- a/tests/libqtest.c
+++ b/tests/libqtest.c
@@ -580,11 +580,11 @@ char *qtest_hmpv(QTestState *s, const char *fmt, va_list ap)
char *cmd;
QDict *resp;
char *ret;
+ QDict *args = qdict_new();
cmd = g_strdup_vprintf(fmt, ap);
- resp = qtest_qmp(s, "{'execute': 'human-monitor-command',"
- " 'arguments': {'command-line': %s}}",
- cmd);
+ qdict_put_str(args, "command-line", cmd);
+ resp = qtest_qmp_cmd(s, "human-monitor-command", args);
ret = g_strdup(qdict_get_try_str(resp, "return"));
g_assert(ret);
QDECREF(resp);
--
2.7.4
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [Qemu-devel] [PATCH 11/36] qapi: Add QAPI_TO_QOBJECT() convenience macro
2016-11-30 19:44 [Qemu-devel] [PATCH 00/36] Rip out dynamic JSON parsing Eric Blake
` (9 preceding siblings ...)
2016-11-30 19:44 ` [Qemu-devel] [PATCH 10/36] qtest: Avoid dynamic JSON in libqtest Eric Blake
@ 2016-11-30 19:44 ` Eric Blake
2016-11-30 19:44 ` [Qemu-devel] [PATCH 12/36] nbd: Use simpler QAPI_TO_QOBJECT() Eric Blake
` (25 subsequent siblings)
36 siblings, 0 replies; 45+ messages in thread
From: Eric Blake @ 2016-11-30 19:44 UTC (permalink / raw)
To: qemu-devel; +Cc: armbru, pbonzini, Michael Roth
We have several callers that want to convert a QAPI C type into
a QObject; right now all of them have to copy the same boilerplate
of creating a visitor. A convenience macro makes this paradigm
easier to type.
Signed-off-by: Eric Blake <eblake@redhat.com>
---
include/qapi/qobject-output-visitor.h | 19 +++++++++++++++++++
qapi/qobject-output-visitor.c | 16 ++++++++++++++++
2 files changed, 35 insertions(+)
diff --git a/include/qapi/qobject-output-visitor.h b/include/qapi/qobject-output-visitor.h
index 8241877..8ed5271 100644
--- a/include/qapi/qobject-output-visitor.h
+++ b/include/qapi/qobject-output-visitor.h
@@ -16,6 +16,8 @@
#include "qapi/visitor.h"
#include "qapi/qmp/qobject.h"
+#include "qapi/error.h"
+#include "qapi-visit.h"
typedef struct QObjectOutputVisitor QObjectOutputVisitor;
@@ -27,4 +29,21 @@ typedef struct QObjectOutputVisitor QObjectOutputVisitor;
*/
Visitor *qobject_output_visitor_new(QObject **result);
+QObject *qapi_to_qobject(const void *src,
+ void (*visit_type)(Visitor *, const char *,
+ void **, Error **),
+ Error **errp);
+
+/*
+ * Create a QObject from a QAPI object @src of the given @type.
+ *
+ * Not usable on QAPI scalars (integers, strings, enums), nor on a
+ * QAPI object that references the 'any' type. @src must not be NULL.
+ */
+#define QAPI_TO_QOBJECT(type, src, err) \
+ (qapi_to_qobject(1 ? src : (type *)NULL, \
+ (void (*)(Visitor *, const char *, void**, \
+ Error **))visit_type_ ## type, \
+ err))
+
#endif
diff --git a/qapi/qobject-output-visitor.c b/qapi/qobject-output-visitor.c
index 8711270..6d7783c 100644
--- a/qapi/qobject-output-visitor.c
+++ b/qapi/qobject-output-visitor.c
@@ -252,3 +252,19 @@ Visitor *qobject_output_visitor_new(QObject **result)
return &v->visitor;
}
+
+QObject *qapi_to_qobject(const void *src,
+ void (*visit_type)(Visitor *, const char *,
+ void **, Error **),
+ Error **errp)
+{
+ Visitor *v;
+ void *s = (void *) src; /* cast away const */
+ QObject *dst = NULL;
+
+ v = qobject_output_visitor_new(&dst);
+ visit_type(v, NULL, &s, &error_abort);
+ visit_complete(v, &dst);
+ visit_free(v);
+ return dst;
+}
--
2.7.4
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [Qemu-devel] [PATCH 12/36] nbd: Use simpler QAPI_TO_QOBJECT()
2016-11-30 19:44 [Qemu-devel] [PATCH 00/36] Rip out dynamic JSON parsing Eric Blake
` (10 preceding siblings ...)
2016-11-30 19:44 ` [Qemu-devel] [PATCH 11/36] qapi: Add QAPI_TO_QOBJECT() convenience macro Eric Blake
@ 2016-11-30 19:44 ` Eric Blake
2016-11-30 19:44 ` [Qemu-devel] [PATCH 13/36] nfs: " Eric Blake
` (24 subsequent siblings)
36 siblings, 0 replies; 45+ messages in thread
From: Eric Blake @ 2016-11-30 19:44 UTC (permalink / raw)
To: qemu-devel
Cc: armbru, pbonzini, Kevin Wolf, Max Reitz,
open list:Block layer core
Use the new macro to avoid some boilerplate.
Signed-off-by: Eric Blake <eblake@redhat.com>
---
block/nbd.c | 6 +-----
1 file changed, 1 insertion(+), 5 deletions(-)
diff --git a/block/nbd.c b/block/nbd.c
index 334748d..a1dfd86 100644
--- a/block/nbd.c
+++ b/block/nbd.c
@@ -503,7 +503,6 @@ static void nbd_refresh_filename(BlockDriverState *bs, QDict *options)
BDRVNBDState *s = bs->opaque;
QDict *opts = qdict_new();
QObject *saddr_qdict;
- Visitor *ov;
const char *host = NULL, *port = NULL, *path = NULL;
if (s->saddr->type == SOCKET_ADDRESS_KIND_INET) {
@@ -532,10 +531,7 @@ static void nbd_refresh_filename(BlockDriverState *bs, QDict *options)
"nbd://%s:%s", host, port);
}
- ov = qobject_output_visitor_new(&saddr_qdict);
- visit_type_SocketAddress(ov, NULL, &s->saddr, &error_abort);
- visit_complete(ov, &saddr_qdict);
- visit_free(ov);
+ saddr_qdict = QAPI_TO_QOBJECT(SocketAddress, s->saddr, &error_abort);
assert(qobject_type(saddr_qdict) == QTYPE_QDICT);
qdict_put_obj(opts, "server", saddr_qdict);
--
2.7.4
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [Qemu-devel] [PATCH 13/36] nfs: Use simpler QAPI_TO_QOBJECT()
2016-11-30 19:44 [Qemu-devel] [PATCH 00/36] Rip out dynamic JSON parsing Eric Blake
` (11 preceding siblings ...)
2016-11-30 19:44 ` [Qemu-devel] [PATCH 12/36] nbd: Use simpler QAPI_TO_QOBJECT() Eric Blake
@ 2016-11-30 19:44 ` Eric Blake
2016-11-30 19:44 ` [Qemu-devel] [PATCH 14/36] qapi: " Eric Blake
` (23 subsequent siblings)
36 siblings, 0 replies; 45+ messages in thread
From: Eric Blake @ 2016-11-30 19:44 UTC (permalink / raw)
To: qemu-devel
Cc: armbru, pbonzini, Jeff Cody, Peter Lieven, Kevin Wolf, Max Reitz,
open list:NFS
Use the new macro to avoid some boilerplate.
Signed-off-by: Eric Blake <eblake@redhat.com>
---
block/nfs.c | 6 +-----
1 file changed, 1 insertion(+), 5 deletions(-)
diff --git a/block/nfs.c b/block/nfs.c
index f8ba5cc..71cc746 100644
--- a/block/nfs.c
+++ b/block/nfs.c
@@ -766,7 +766,6 @@ static void nfs_refresh_filename(BlockDriverState *bs, QDict *options)
NFSClient *client = bs->opaque;
QDict *opts = qdict_new();
QObject *server_qdict;
- Visitor *ov;
qdict_put_str(opts, "driver", "nfs");
@@ -787,9 +786,7 @@ static void nfs_refresh_filename(BlockDriverState *bs, QDict *options)
"nfs://%s%s", client->server->host, client->path);
}
- ov = qobject_output_visitor_new(&server_qdict);
- visit_type_NFSServer(ov, NULL, &client->server, &error_abort);
- visit_complete(ov, &server_qdict);
+ server_qdict = QAPI_TO_QOBJECT(NFSServer, client->server, &error_abort);
assert(qobject_type(server_qdict) == QTYPE_QDICT);
qdict_put_obj(opts, "server", server_qdict);
@@ -814,7 +811,6 @@ static void nfs_refresh_filename(BlockDriverState *bs, QDict *options)
qdict_put_int(opts, "debug", client->debug);
}
- visit_free(ov);
qdict_flatten(opts);
bs->full_open_options = opts;
}
--
2.7.4
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [Qemu-devel] [PATCH 14/36] qapi: Use simpler QAPI_TO_QOBJECT()
2016-11-30 19:44 [Qemu-devel] [PATCH 00/36] Rip out dynamic JSON parsing Eric Blake
` (12 preceding siblings ...)
2016-11-30 19:44 ` [Qemu-devel] [PATCH 13/36] nfs: " Eric Blake
@ 2016-11-30 19:44 ` Eric Blake
2016-11-30 19:44 ` [Qemu-devel] [PATCH 15/36] blockdev: " Eric Blake
` (22 subsequent siblings)
36 siblings, 0 replies; 45+ messages in thread
From: Eric Blake @ 2016-11-30 19:44 UTC (permalink / raw)
To: qemu-devel
Cc: armbru, pbonzini, Kevin Wolf, Max Reitz,
open list:Block layer core
Use the new macro to avoid some boilerplate.
Signed-off-by: Eric Blake <eblake@redhat.com>
---
block/qapi.c | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/block/qapi.c b/block/qapi.c
index a62e862..802a372 100644
--- a/block/qapi.c
+++ b/block/qapi.c
@@ -691,15 +691,13 @@ void bdrv_image_info_specific_dump(fprintf_function func_fprintf, void *f,
ImageInfoSpecific *info_spec)
{
QObject *obj, *data;
- Visitor *v = qobject_output_visitor_new(&obj);
- visit_type_ImageInfoSpecific(v, NULL, &info_spec, &error_abort);
- visit_complete(v, &obj);
+ obj = QAPI_TO_QOBJECT(ImageInfoSpecific, info_spec, &error_abort);
+
assert(qobject_type(obj) == QTYPE_QDICT);
data = qdict_get(qobject_to_qdict(obj), "data");
dump_qobject(func_fprintf, f, 1, data);
qobject_decref(obj);
- visit_free(v);
}
void bdrv_image_info_dump(fprintf_function func_fprintf, void *f,
--
2.7.4
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [Qemu-devel] [PATCH 15/36] blockdev: Use simpler QAPI_TO_QOBJECT()
2016-11-30 19:44 [Qemu-devel] [PATCH 00/36] Rip out dynamic JSON parsing Eric Blake
` (13 preceding siblings ...)
2016-11-30 19:44 ` [Qemu-devel] [PATCH 14/36] qapi: " Eric Blake
@ 2016-11-30 19:44 ` Eric Blake
2016-11-30 19:44 ` [Qemu-devel] [PATCH 16/36] qapi: Promote blockdev-change-medium arguments to QAPI type Eric Blake
` (21 subsequent siblings)
36 siblings, 0 replies; 45+ messages in thread
From: Eric Blake @ 2016-11-30 19:44 UTC (permalink / raw)
To: qemu-devel
Cc: armbru, pbonzini, Kevin Wolf, Max Reitz,
open list:Block layer core
Use the new macro to avoid some boilerplate.
Signed-off-by: Eric Blake <eblake@redhat.com>
---
blockdev.c | 14 ++++----------
1 file changed, 4 insertions(+), 10 deletions(-)
diff --git a/blockdev.c b/blockdev.c
index 2802cea..18a3212 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -3801,29 +3801,27 @@ void qmp_blockdev_add(BlockdevOptions *options, Error **errp)
{
BlockDriverState *bs;
QObject *obj;
- Visitor *v = qobject_output_visitor_new(&obj);
QDict *qdict;
Error *local_err = NULL;
- visit_type_BlockdevOptions(v, NULL, &options, &local_err);
+ obj = QAPI_TO_QOBJECT(BlockdevOptions, options, &local_err);
if (local_err) {
error_propagate(errp, local_err);
- goto fail;
+ return;
}
- visit_complete(v, &obj);
qdict = qobject_to_qdict(obj);
qdict_flatten(qdict);
if (!qdict_get_try_str(qdict, "node-name")) {
error_setg(errp, "'node-name' must be specified for the root node");
- goto fail;
+ return;
}
bs = bds_tree_init(qdict, errp);
if (!bs) {
- goto fail;
+ return;
}
QTAILQ_INSERT_TAIL(&monitor_bdrv_states, bs, monitor_list);
@@ -3832,11 +3830,7 @@ void qmp_blockdev_add(BlockdevOptions *options, Error **errp)
QTAILQ_REMOVE(&monitor_bdrv_states, bs, monitor_list);
bdrv_unref(bs);
error_setg(errp, "blockdev-add doesn't support encrypted devices");
- goto fail;
}
-
-fail:
- visit_free(v);
}
void qmp_x_blockdev_del(const char *node_name, Error **errp)
--
2.7.4
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [Qemu-devel] [PATCH 16/36] qapi: Promote blockdev-change-medium arguments to QAPI type
2016-11-30 19:44 [Qemu-devel] [PATCH 00/36] Rip out dynamic JSON parsing Eric Blake
` (14 preceding siblings ...)
2016-11-30 19:44 ` [Qemu-devel] [PATCH 15/36] blockdev: " Eric Blake
@ 2016-11-30 19:44 ` Eric Blake
2016-11-30 19:44 ` [Qemu-devel] [PATCH 17/36] qtest: Avoid dynamic JSON in ahci-test Eric Blake
` (20 subsequent siblings)
36 siblings, 0 replies; 45+ messages in thread
From: Eric Blake @ 2016-11-30 19:44 UTC (permalink / raw)
To: qemu-devel; +Cc: armbru, pbonzini
Having a named rather than anonymous C type will make it easier
to improve the testsuite in a later patch. No semantic change,
to any of the existing code or to the introspection output.
Signed-off-by: Eric Blake <eblake@redhat.com>
---
qapi/block-core.json | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/qapi/block-core.json b/qapi/block-core.json
index ec1da2a..021a7e4 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -2592,6 +2592,15 @@
# combines blockdev-open-tray, x-blockdev-remove-medium,
# x-blockdev-insert-medium and blockdev-close-tray).
#
+# Since: 2.5
+##
+{ 'command': 'blockdev-change-medium',
+ 'data': 'BlockdevChangeMedium' }
+
+
+##
+# @BlockdevChangeMedium:
+#
# @device: #optional Block device name (deprecated, use @id instead)
#
# @id: #optional The name or QOM path of the guest device
@@ -2607,7 +2616,7 @@
#
# Since: 2.5
##
-{ 'command': 'blockdev-change-medium',
+{ 'struct': 'BlockdevChangeMedium',
'data': { '*device': 'str',
'*id': 'str',
'filename': 'str',
--
2.7.4
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [Qemu-devel] [PATCH 17/36] qtest: Avoid dynamic JSON in ahci-test
2016-11-30 19:44 [Qemu-devel] [PATCH 00/36] Rip out dynamic JSON parsing Eric Blake
` (15 preceding siblings ...)
2016-11-30 19:44 ` [Qemu-devel] [PATCH 16/36] qapi: Promote blockdev-change-medium arguments to QAPI type Eric Blake
@ 2016-11-30 19:44 ` Eric Blake
2016-11-30 21:02 ` John Snow
2016-11-30 19:44 ` [Qemu-devel] [PATCH 18/36] qtest: Avoid dynamic JSON in fdc-test Eric Blake
` (19 subsequent siblings)
36 siblings, 1 reply; 45+ messages in thread
From: Eric Blake @ 2016-11-30 19:44 UTC (permalink / raw)
To: qemu-devel; +Cc: armbru, pbonzini, John Snow, open list:IDE
As argued elsewhere, it's less code to maintain if we convert
from a dynamic string passed to qobject_from_jsonv() to instead
use a hand-built QDict.
Rather than build up a QDict by manual qdict_put*() calls, we
can let QAPI do the work for us. The result is more lines of
code to initialize the QAPI struct, but the result will force us
to track any changes to the qapi (whereas the dynamic JSON string
would not detect qapi changes until runtime).
Signed-off-by: Eric Blake <eblake@redhat.com>
---
tests/ahci-test.c | 26 +++++++++++++++++++++-----
1 file changed, 21 insertions(+), 5 deletions(-)
diff --git a/tests/ahci-test.c b/tests/ahci-test.c
index ef17629..dfa9c52 100644
--- a/tests/ahci-test.c
+++ b/tests/ahci-test.c
@@ -32,6 +32,8 @@
#include "qemu-common.h"
#include "qemu/host-utils.h"
+#include "qapi/qmp/qjson.h"
+#include "qapi/qobject-output-visitor.h"
#include "hw/pci/pci_ids.h"
#include "hw/pci/pci_regs.h"
@@ -1576,6 +1578,7 @@ static void test_atapi_tray(void)
uint8_t port, sense, asc;
uint64_t iso_size = ATAPI_SECTOR_SIZE;
QDict *rsp;
+ QObject *args;
fd = prepare_iso(iso_size, &tx, &iso);
ahci = ahci_boot_and_enable("-drive if=none,id=drive0,file=%s,format=raw "
@@ -1607,11 +1610,24 @@ static void test_atapi_tray(void)
atapi_wait_tray(true);
/* Re-insert media */
- qmp_discard_response("{'execute': 'blockdev-add', "
- "'arguments': {'node-name': 'node0', "
- "'driver': 'raw', "
- "'file': { 'driver': 'file', "
- "'filename': %s }}}", iso);
+ {
+ BlockdevRef ref = {
+ .type = QTYPE_QDICT,
+ .u.definition = {
+ .driver = BLOCKDEV_DRIVER_FILE,
+ .u.file.filename = iso,
+ },
+ };
+ BlockdevOptions opts = {
+ .has_node_name = true,
+ .node_name = (char *)"node0",
+ .driver = BLOCKDEV_DRIVER_RAW,
+ .u.raw.file = &ref,
+ };
+ args = QAPI_TO_QOBJECT(BlockdevOptions, &opts, &error_abort);
+ }
+
+ qmp_cmd_discard_response("blockdev-add", qobject_to_qdict(args));
qmp_discard_response("{'execute': 'x-blockdev-insert-medium',"
"'arguments': { 'device': 'drive0', "
"'node-name': 'node0' }}");
--
2.7.4
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [Qemu-devel] [PATCH 18/36] qtest: Avoid dynamic JSON in fdc-test
2016-11-30 19:44 [Qemu-devel] [PATCH 00/36] Rip out dynamic JSON parsing Eric Blake
` (16 preceding siblings ...)
2016-11-30 19:44 ` [Qemu-devel] [PATCH 17/36] qtest: Avoid dynamic JSON in ahci-test Eric Blake
@ 2016-11-30 19:44 ` Eric Blake
2016-11-30 21:14 ` John Snow
2016-11-30 19:44 ` [Qemu-devel] [PATCH 19/36] qtest: Change qmp_discard_response() to drop varargs Eric Blake
` (18 subsequent siblings)
36 siblings, 1 reply; 45+ messages in thread
From: Eric Blake @ 2016-11-30 19:44 UTC (permalink / raw)
To: qemu-devel; +Cc: armbru, pbonzini, John Snow, open list:Floppy
As argued elsewhere, it's less code to maintain if we convert
from a dynamic string passed to qobject_from_jsonv() to instead
use a hand-built QDict.
Rather than build up a QDict by manual qdict_put*() calls, we
can let QAPI do the work for us. The result is more lines of
code to initialize the QAPI struct, but the result will force us
to track any changes to the qapi (whereas the dynamic JSON string
would not detect qapi changes until runtime).
Signed-off-by: Eric Blake <eblake@redhat.com>
---
tests/fdc-test.c | 16 ++++++++++++----
1 file changed, 12 insertions(+), 4 deletions(-)
diff --git a/tests/fdc-test.c b/tests/fdc-test.c
index f5ff68d..ac75e87 100644
--- a/tests/fdc-test.c
+++ b/tests/fdc-test.c
@@ -27,6 +27,8 @@
#include "libqtest.h"
#include "qemu-common.h"
+#include "qapi/qmp/qjson.h"
+#include "qapi/qobject-output-visitor.h"
#define TEST_IMAGE_SIZE 1440 * 1024
@@ -295,13 +297,19 @@ static void test_read_without_media(void)
static void test_media_insert(void)
{
uint8_t dir;
+ QObject *args;
+ BlockdevChangeMedium bcm = {
+ .has_device = true,
+ .device = (char *)"floppy0",
+ .filename = test_image,
+ .has_format = true,
+ .format = (char *)"raw",
+ };
/* Insert media in drive. DSKCHK should not be reset until a step pulse
* is sent. */
- qmp_discard_response("{'execute':'blockdev-change-medium', 'arguments':{"
- " 'device':'floppy0', 'filename': %s, "
- "'format': 'raw' }}",
- test_image);
+ args = QAPI_TO_QOBJECT(BlockdevChangeMedium, &bcm, &error_abort);
+ qmp_cmd_discard_response("blockdev-change-medium", qobject_to_qdict(args));
dir = inb(FLOPPY_BASE + reg_dir);
assert_bit_set(dir, DSKCHG);
--
2.7.4
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [Qemu-devel] [PATCH 19/36] qtest: Change qmp_discard_response() to drop varargs
2016-11-30 19:44 [Qemu-devel] [PATCH 00/36] Rip out dynamic JSON parsing Eric Blake
` (17 preceding siblings ...)
2016-11-30 19:44 ` [Qemu-devel] [PATCH 18/36] qtest: Avoid dynamic JSON in fdc-test Eric Blake
@ 2016-11-30 19:44 ` Eric Blake
2016-11-30 19:44 ` [Qemu-devel] [PATCH 20/36] qtest: Avoid dynamic JSON in device-introspect-test Eric Blake
` (17 subsequent siblings)
36 siblings, 0 replies; 45+ messages in thread
From: Eric Blake @ 2016-11-30 19:44 UTC (permalink / raw)
To: qemu-devel; +Cc: armbru, pbonzini
Now that no more clients are passing variadic arguments, we can
update the contract to state that we will be using normal JSON
parsing rather than dynamic JSON for any client using this wrapper.
Signed-off-by: Eric Blake <eblake@redhat.com>
---
tests/libqtest.h | 18 ++++--------------
tests/libqtest.c | 22 +++++-----------------
2 files changed, 9 insertions(+), 31 deletions(-)
diff --git a/tests/libqtest.h b/tests/libqtest.h
index 07ddaa2..c89c075 100644
--- a/tests/libqtest.h
+++ b/tests/libqtest.h
@@ -42,11 +42,11 @@ void qtest_quit(QTestState *s);
/**
* qtest_qmp_discard_response:
* @s: #QTestState instance to operate on.
- * @fmt...: QMP message to send to qemu
+ * @json: QMP message to send to qemu
*
* Sends a QMP message to QEMU and consumes the response.
*/
-void qtest_qmp_discard_response(QTestState *s, const char *fmt, ...);
+void qtest_qmp_discard_response(QTestState *s, const char *json);
/**
* qtest_qmp:
@@ -78,16 +78,6 @@ QDict *qtest_qmp_cmd(QTestState *s, const char *cmd, QDict *args);
void qtest_async_qmp(QTestState *s, const char *fmt, ...);
/**
- * qtest_qmpv_discard_response:
- * @s: #QTestState instance to operate on.
- * @fmt: QMP message to send to QEMU
- * @ap: QMP message arguments
- *
- * Sends a QMP message to QEMU and consumes the response.
- */
-void qtest_qmpv_discard_response(QTestState *s, const char *fmt, va_list ap);
-
-/**
* qtest_qmpv:
* @s: #QTestState instance to operate on.
* @fmt: QMP message to send to QEMU
@@ -562,11 +552,11 @@ void qmp_async(const char *fmt, ...);
/**
* qmp_discard_response:
- * @fmt...: QMP message to send to qemu
+ * @json: QMP message to send to qemu
*
* Sends a QMP message to QEMU and consumes the response.
*/
-void qmp_discard_response(const char *fmt, ...);
+void qmp_discard_response(const char *json);
/**
* qmp_cmd_discard_response:
diff --git a/tests/libqtest.c b/tests/libqtest.c
index 26c4beb..1328bd9 100644
--- a/tests/libqtest.c
+++ b/tests/libqtest.c
@@ -536,20 +536,12 @@ void qtest_async_qmp(QTestState *s, const char *fmt, ...)
va_end(ap);
}
-void qtest_qmpv_discard_response(QTestState *s, const char *fmt, va_list ap)
+void qtest_qmp_discard_response(QTestState *s, const char *json)
{
- QDict *response = qtest_qmpv(s, fmt, ap);
- QDECREF(response);
-}
-
-void qtest_qmp_discard_response(QTestState *s, const char *fmt, ...)
-{
- va_list ap;
QDict *response;
- va_start(ap, fmt);
- response = qtest_qmpv(s, fmt, ap);
- va_end(ap);
+ assert(!strchr(json, '%'));
+ response = qtest_qmp(s, json);
QDECREF(response);
}
@@ -920,13 +912,9 @@ void qmp_async(const char *fmt, ...)
va_end(ap);
}
-void qmp_discard_response(const char *fmt, ...)
+void qmp_discard_response(const char *json)
{
- va_list ap;
-
- va_start(ap, fmt);
- qtest_qmpv_discard_response(global_qtest, fmt, ap);
- va_end(ap);
+ qtest_qmp_discard_response(global_qtest, json);
}
void qmp_cmd_discard_response(const char *cmd, QDict *args)
--
2.7.4
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [Qemu-devel] [PATCH 20/36] qtest: Avoid dynamic JSON in device-introspect-test
2016-11-30 19:44 [Qemu-devel] [PATCH 00/36] Rip out dynamic JSON parsing Eric Blake
` (18 preceding siblings ...)
2016-11-30 19:44 ` [Qemu-devel] [PATCH 19/36] qtest: Change qmp_discard_response() to drop varargs Eric Blake
@ 2016-11-30 19:44 ` Eric Blake
2016-11-30 19:44 ` [Qemu-devel] [PATCH 21/36] qtest: Avoid dynamic JSON in tmp105-test Eric Blake
` (16 subsequent siblings)
36 siblings, 0 replies; 45+ messages in thread
From: Eric Blake @ 2016-11-30 19:44 UTC (permalink / raw)
To: qemu-devel; +Cc: armbru, pbonzini
As argued elsewhere, it's less code to maintain if we convert
from a dynamic string passed to qobject_from_jsonv() to instead
use a hand-built QDict.
Signed-off-by: Eric Blake <eblake@redhat.com>
---
tests/device-introspect-test.c | 15 +++++++++------
1 file changed, 9 insertions(+), 6 deletions(-)
diff --git a/tests/device-introspect-test.c b/tests/device-introspect-test.c
index 37debc1..9655a49 100644
--- a/tests/device-introspect-test.c
+++ b/tests/device-introspect-test.c
@@ -19,6 +19,8 @@
#include "qemu/osdep.h"
#include "qemu-common.h"
+#include "qapi/qmp/qbool.h"
+#include "qapi/qmp/qdict.h"
#include "qapi/qmp/qstring.h"
#include "libqtest.h"
@@ -28,10 +30,11 @@ static QList *device_type_list(bool abstract)
{
QDict *resp;
QList *ret;
+ QDict *args = qdict_new();
- resp = qmp("{'execute': 'qom-list-types',"
- " 'arguments': {'implements': 'device', 'abstract': %i}}",
- abstract);
+ qdict_put_str(args, "implements", "device");
+ qdict_put_bool(args, "abstract", abstract);
+ resp = qmp_cmd("qom-list-types", args);
g_assert(qdict_haskey(resp, "return"));
ret = qdict_get_qlist(resp, "return");
QINCREF(ret);
@@ -43,10 +46,10 @@ static void test_one_device(const char *type)
{
QDict *resp;
char *help, *qom_tree;
+ QDict *args = qdict_new();
- resp = qmp("{'execute': 'device-list-properties',"
- " 'arguments': {'typename': %s}}",
- type);
+ qdict_put_str(args, "typename", type);
+ resp = qmp_cmd("device-list-properties", args);
QDECREF(resp);
help = hmp("device_add \"%s,help\"", type);
--
2.7.4
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [Qemu-devel] [PATCH 21/36] qtest: Avoid dynamic JSON in tmp105-test
2016-11-30 19:44 [Qemu-devel] [PATCH 00/36] Rip out dynamic JSON parsing Eric Blake
` (19 preceding siblings ...)
2016-11-30 19:44 ` [Qemu-devel] [PATCH 20/36] qtest: Avoid dynamic JSON in device-introspect-test Eric Blake
@ 2016-11-30 19:44 ` Eric Blake
2016-11-30 19:44 ` [Qemu-devel] [PATCH 22/36] qtest: Avoid dynamic JSON in pc-cpu-test Eric Blake
` (15 subsequent siblings)
36 siblings, 0 replies; 45+ messages in thread
From: Eric Blake @ 2016-11-30 19:44 UTC (permalink / raw)
To: qemu-devel; +Cc: armbru, pbonzini
As argued elsewhere, it's less code to maintain if we convert
from a dynamic string passed to qobject_from_jsonv() to instead
use a hand-built QDict.
Signed-off-by: Eric Blake <eblake@redhat.com>
---
tests/tmp105-test.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/tests/tmp105-test.c b/tests/tmp105-test.c
index a7940a4..7019445 100644
--- a/tests/tmp105-test.c
+++ b/tests/tmp105-test.c
@@ -80,9 +80,12 @@ static int qmp_tmp105_get_temperature(const char *id)
static void qmp_tmp105_set_temperature(const char *id, int value)
{
QDict *response;
+ QDict *args = qdict_new();
- response = qmp("{ 'execute': 'qom-set', 'arguments': { 'path': %s, "
- "'property': 'temperature', 'value': %d } }", id, value);
+ qdict_put_str(args, "path", id);
+ qdict_put_str(args, "property", "temperature");
+ qdict_put_int(args, "value", value);
+ response = qmp_cmd("qom-set", args);
g_assert(qdict_haskey(response, "return"));
QDECREF(response);
}
--
2.7.4
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [Qemu-devel] [PATCH 22/36] qtest: Avoid dynamic JSON in pc-cpu-test
2016-11-30 19:44 [Qemu-devel] [PATCH 00/36] Rip out dynamic JSON parsing Eric Blake
` (20 preceding siblings ...)
2016-11-30 19:44 ` [Qemu-devel] [PATCH 21/36] qtest: Avoid dynamic JSON in tmp105-test Eric Blake
@ 2016-11-30 19:44 ` Eric Blake
2016-11-30 19:44 ` [Qemu-devel] [PATCH 23/36] qtest: Avoid dynamic JSON in virtio-blk-test Eric Blake
` (14 subsequent siblings)
36 siblings, 0 replies; 45+ messages in thread
From: Eric Blake @ 2016-11-30 19:44 UTC (permalink / raw)
To: qemu-devel; +Cc: armbru, pbonzini
As argued elsewhere, it's less code to maintain if we convert
from a dynamic string passed to qobject_from_jsonv() to instead
use a hand-built QDict.
Signed-off-by: Eric Blake <eblake@redhat.com>
---
tests/pc-cpu-test.c | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/tests/pc-cpu-test.c b/tests/pc-cpu-test.c
index c3a2633..7df7c54 100644
--- a/tests/pc-cpu-test.c
+++ b/tests/pc-cpu-test.c
@@ -37,8 +37,10 @@ static void test_pc_with_cpu_add(gconstpointer data)
qtest_start(args);
for (i = s->sockets * s->cores * s->threads; i < s->maxcpus; i++) {
- response = qmp("{ 'execute': 'cpu-add',"
- " 'arguments': { 'id': %d } }", i);
+ QDict *id = qdict_new();
+
+ qdict_put_int(id, "id", i);
+ response = qmp_cmd("cpu-add", id);
g_assert(response);
g_assert(!qdict_haskey(response, "error"));
QDECREF(response);
@@ -53,6 +55,7 @@ static void test_pc_without_cpu_add(gconstpointer data)
const PCTestData *s = data;
char *args;
QDict *response;
+ QDict *id = qdict_new();
args = g_strdup_printf("-machine %s -cpu %s "
"-smp sockets=%u,cores=%u,threads=%u,maxcpus=%u",
@@ -60,9 +63,8 @@ static void test_pc_without_cpu_add(gconstpointer data)
s->sockets, s->cores, s->threads, s->maxcpus);
qtest_start(args);
- response = qmp("{ 'execute': 'cpu-add',"
- " 'arguments': { 'id': %d } }",
- s->sockets * s->cores * s->threads);
+ qdict_put_int(id, "id", s->sockets * s->cores * s->threads);
+ response = qmp_cmd("cpu-add", id);
g_assert(response);
g_assert(qdict_haskey(response, "error"));
QDECREF(response);
--
2.7.4
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [Qemu-devel] [PATCH 23/36] qtest: Avoid dynamic JSON in virtio-blk-test
2016-11-30 19:44 [Qemu-devel] [PATCH 00/36] Rip out dynamic JSON parsing Eric Blake
` (21 preceding siblings ...)
2016-11-30 19:44 ` [Qemu-devel] [PATCH 22/36] qtest: Avoid dynamic JSON in pc-cpu-test Eric Blake
@ 2016-11-30 19:44 ` Eric Blake
2016-11-30 19:44 ` [Qemu-devel] [PATCH 24/36] qtest: Drop unused qmp_fdv() Eric Blake
` (13 subsequent siblings)
36 siblings, 0 replies; 45+ messages in thread
From: Eric Blake @ 2016-11-30 19:44 UTC (permalink / raw)
To: qemu-devel; +Cc: armbru, pbonzini, Stefan Hajnoczi, open list:virtio-blk
As argued elsewhere, it's less code to maintain if we convert
from a dynamic string passed to qobject_from_jsonv() to instead
use a hand-built QDict.
Signed-off-by: Eric Blake <eblake@redhat.com>
---
tests/virtio-blk-test.c | 22 ++++++++++++++++------
1 file changed, 16 insertions(+), 6 deletions(-)
diff --git a/tests/virtio-blk-test.c b/tests/virtio-blk-test.c
index 0e32e41..57780aa 100644
--- a/tests/virtio-blk-test.c
+++ b/tests/virtio-blk-test.c
@@ -16,6 +16,9 @@
#include "libqos/virtio-pci.h"
#include "libqos/virtio-mmio.h"
#include "libqos/malloc-generic.h"
+#include "qapi/qmp/qdict.h"
+#include "qapi/qmp/qint.h"
+#include "qapi/qmp/qstring.h"
#include "qemu/bswap.h"
#include "standard-headers/linux/virtio_ids.h"
#include "standard-headers/linux/virtio_config.h"
@@ -399,6 +402,7 @@ static void pci_config(void)
QOSState *qs;
int n_size = TEST_IMAGE_SIZE / 2;
uint64_t capacity;
+ QDict *args = qdict_new();
qs = pci_test_start();
@@ -409,8 +413,10 @@ static void pci_config(void)
qvirtio_set_driver_ok(&dev->vdev);
- qmp("{ 'execute': 'block_resize', 'arguments': { 'device': 'drive0', "
- " 'size': %d } }", n_size);
+ qdict_put_str(args, "device", "drive0");
+ qdict_put_int(args, "size", n_size);
+ qmp_cmd("block_resize", args);
+
qvirtio_wait_config_isr(&dev->vdev, QVIRTIO_BLK_TIMEOUT_US);
capacity = qvirtio_config_readq(&dev->vdev, 0);
@@ -435,6 +441,7 @@ static void pci_msix(void)
uint32_t free_head;
uint8_t status;
char *data;
+ QDict *args = qdict_new();
qs = pci_test_start();
@@ -458,8 +465,9 @@ static void pci_msix(void)
qvirtio_set_driver_ok(&dev->vdev);
- qmp("{ 'execute': 'block_resize', 'arguments': { 'device': 'drive0', "
- " 'size': %d } }", n_size);
+ qdict_put_str(args, "device", "drive0");
+ qdict_put_int(args, "size", n_size);
+ qmp_cmd("block_resize", args);
qvirtio_wait_config_isr(&dev->vdev, QVIRTIO_BLK_TIMEOUT_US);
@@ -675,6 +683,7 @@ static void mmio_basic(void)
QGuestAllocator *alloc;
int n_size = TEST_IMAGE_SIZE / 2;
uint64_t capacity;
+ QDict *args = qdict_new();
arm_test_start();
@@ -691,8 +700,9 @@ static void mmio_basic(void)
test_basic(&dev->vdev, alloc, vq);
- qmp("{ 'execute': 'block_resize', 'arguments': { 'device': 'drive0', "
- " 'size': %d } }", n_size);
+ qdict_put_str(args, "device", "drive0");
+ qdict_put_int(args, "size", n_size);
+ qmp_cmd("block_resize", args);
qvirtio_wait_queue_isr(&dev->vdev, vq, QVIRTIO_BLK_TIMEOUT_US);
--
2.7.4
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [Qemu-devel] [PATCH 24/36] qtest: Drop unused qmp_fdv()
2016-11-30 19:44 [Qemu-devel] [PATCH 00/36] Rip out dynamic JSON parsing Eric Blake
` (22 preceding siblings ...)
2016-11-30 19:44 ` [Qemu-devel] [PATCH 23/36] qtest: Avoid dynamic JSON in virtio-blk-test Eric Blake
@ 2016-11-30 19:44 ` Eric Blake
2016-11-30 19:44 ` [Qemu-devel] [PATCH 25/36] qtest: Change qmp_fd_send() to drop varags Eric Blake
` (12 subsequent siblings)
36 siblings, 0 replies; 45+ messages in thread
From: Eric Blake @ 2016-11-30 19:44 UTC (permalink / raw)
To: qemu-devel; +Cc: armbru, pbonzini
Now that no more clients are passing variadic arguments, we can
simplify the testsuite by requiring that qmp_fd() be given the
final string to pass over the wire, rather than a dynamic JSON
string that has to be parsed into QObject and back out again.
Signed-off-by: Eric Blake <eblake@redhat.com>
---
tests/libqtest.h | 3 +--
tests/libqtest.c | 17 +++--------------
2 files changed, 4 insertions(+), 16 deletions(-)
diff --git a/tests/libqtest.h b/tests/libqtest.h
index c89c075..0adf880 100644
--- a/tests/libqtest.h
+++ b/tests/libqtest.h
@@ -927,7 +927,6 @@ static inline int64_t clock_set(int64_t val)
QDict *qmp_fd_receive(int fd);
void qmp_fd_sendv(int fd, const char *fmt, va_list ap);
void qmp_fd_send(int fd, const char *fmt, ...);
-QDict *qmp_fdv(int fd, const char *fmt, va_list ap);
-QDict *qmp_fd(int fd, const char *fmt, ...);
+QDict *qmp_fd(int fd, const char *msg);
#endif
diff --git a/tests/libqtest.c b/tests/libqtest.c
index 1328bd9..b5b9f01 100644
--- a/tests/libqtest.c
+++ b/tests/libqtest.c
@@ -469,13 +469,6 @@ void qtest_async_qmpv(QTestState *s, const char *fmt, va_list ap)
qmp_fd_sendv(s->qmp_fd, fmt, ap);
}
-QDict *qmp_fdv(int fd, const char *fmt, va_list ap)
-{
- qmp_fd_sendv(fd, fmt, ap);
-
- return qmp_fd_receive(fd);
-}
-
QDict *qtest_qmpv(QTestState *s, const char *fmt, va_list ap)
{
qtest_async_qmpv(s, fmt, ap);
@@ -484,15 +477,11 @@ QDict *qtest_qmpv(QTestState *s, const char *fmt, va_list ap)
return qtest_qmp_receive(s);
}
-QDict *qmp_fd(int fd, const char *fmt, ...)
+QDict *qmp_fd(int fd, const char *msg)
{
- va_list ap;
- QDict *response;
+ qmp_fd_send(fd, msg);
- va_start(ap, fmt);
- response = qmp_fdv(fd, fmt, ap);
- va_end(ap);
- return response;
+ return qmp_fd_receive(fd);
}
void qmp_fd_send(int fd, const char *fmt, ...)
--
2.7.4
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [Qemu-devel] [PATCH 25/36] qtest: Change qmp_fd_send() to drop varags
2016-11-30 19:44 [Qemu-devel] [PATCH 00/36] Rip out dynamic JSON parsing Eric Blake
` (23 preceding siblings ...)
2016-11-30 19:44 ` [Qemu-devel] [PATCH 24/36] qtest: Drop unused qmp_fdv() Eric Blake
@ 2016-11-30 19:44 ` Eric Blake
2016-11-30 19:44 ` [Qemu-devel] [PATCH 26/36] qtest: Drop unused qtest_qmp_async() Eric Blake
` (11 subsequent siblings)
36 siblings, 0 replies; 45+ messages in thread
From: Eric Blake @ 2016-11-30 19:44 UTC (permalink / raw)
To: qemu-devel; +Cc: armbru, pbonzini
No external clients were using qmp_fd_sendv(). Making it static
lets us refactor the public qmp_fd_send() to take the final string
to send over the wire, rather than a dynamic JSON string that has
to be parsed into QObject and back out again. Note that the
refactoring switches roles: previously, qmp_fd_send() called
qmp_fd_sendv(), now the dependence is in the opposite direction.
Also, we no longer need to cater to a leading 0xff byte: the only
client (test-qga) is already sending a direct string.
Signed-off-by: Eric Blake <eblake@redhat.com>
---
tests/libqtest.h | 3 +--
tests/libqtest.c | 33 ++++++++++++---------------------
2 files changed, 13 insertions(+), 23 deletions(-)
diff --git a/tests/libqtest.h b/tests/libqtest.h
index 0adf880..1f640c0 100644
--- a/tests/libqtest.h
+++ b/tests/libqtest.h
@@ -925,8 +925,7 @@ static inline int64_t clock_set(int64_t val)
}
QDict *qmp_fd_receive(int fd);
-void qmp_fd_sendv(int fd, const char *fmt, va_list ap);
-void qmp_fd_send(int fd, const char *fmt, ...);
+void qmp_fd_send(int fd, const char *msg);
QDict *qmp_fd(int fd, const char *msg);
#endif
diff --git a/tests/libqtest.c b/tests/libqtest.c
index b5b9f01..555d0c4 100644
--- a/tests/libqtest.c
+++ b/tests/libqtest.c
@@ -425,19 +425,11 @@ QDict *qtest_qmp_receive(QTestState *s)
* in the case that they choose to discard all replies up until
* a particular EVENT is received.
*/
-void qmp_fd_sendv(int fd, const char *fmt, va_list ap)
+static void qmp_fd_sendv(int fd, const char *fmt, va_list ap)
{
va_list ap_copy;
QObject *qobj;
- /* qobject_from_jsonv() silently eats leading 0xff as invalid
- * JSON, but we want to test sending them over the wire to force
- * resyncs */
- if (*fmt == '\377') {
- socket_send(fd, fmt, 1);
- fmt++;
- }
-
/* Going through qobject ensures we escape strings properly.
* This seemingly unnecessary copy is required in case va_list
* is an array type.
@@ -448,16 +440,10 @@ void qmp_fd_sendv(int fd, const char *fmt, va_list ap)
/* No need to send anything for an empty QObject. */
if (qobj) {
- int log = getenv("QTEST_LOG") != NULL;
QString *qstr = qobject_to_json(qobj);
const char *str = qstring_get_str(qstr);
- size_t size = qstring_get_length(qstr);
- if (log) {
- fprintf(stderr, "%s", str);
- }
- /* Send QMP request */
- socket_send(fd, str, size);
+ qmp_fd_send(fd, str);
QDECREF(qstr);
qobject_decref(qobj);
@@ -484,13 +470,18 @@ QDict *qmp_fd(int fd, const char *msg)
return qmp_fd_receive(fd);
}
-void qmp_fd_send(int fd, const char *fmt, ...)
+void qmp_fd_send(int fd, const char *msg)
{
- va_list ap;
+ /* No need to send anything for the empty message. */
+ if (*msg) {
+ int log = getenv("QTEST_LOG") != NULL;
- va_start(ap, fmt);
- qmp_fd_sendv(fd, fmt, ap);
- va_end(ap);
+ if (log) {
+ fprintf(stderr, "%s", msg);
+ }
+ /* Send QMP request */
+ socket_send(fd, msg, strlen(msg));
+ }
}
QDict *qtest_qmp(QTestState *s, const char *fmt, ...)
--
2.7.4
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [Qemu-devel] [PATCH 26/36] qtest: Drop unused qtest_qmp_async()
2016-11-30 19:44 [Qemu-devel] [PATCH 00/36] Rip out dynamic JSON parsing Eric Blake
` (24 preceding siblings ...)
2016-11-30 19:44 ` [Qemu-devel] [PATCH 25/36] qtest: Change qmp_fd_send() to drop varags Eric Blake
@ 2016-11-30 19:44 ` Eric Blake
2016-11-30 19:44 ` [Qemu-devel] [PATCH 27/36] qtest: Avoid dynamic JSON in qmp_cmd() Eric Blake
` (10 subsequent siblings)
36 siblings, 0 replies; 45+ messages in thread
From: Eric Blake @ 2016-11-30 19:44 UTC (permalink / raw)
To: qemu-devel; +Cc: armbru, pbonzini
There were no external clients of qtest_qmp_async(); delete
this wrapper for one less varargs call in the chain.
Signed-off-by: Eric Blake <eblake@redhat.com>
---
tests/libqtest.h | 19 -------------------
tests/libqtest.c | 18 ++----------------
2 files changed, 2 insertions(+), 35 deletions(-)
diff --git a/tests/libqtest.h b/tests/libqtest.h
index 1f640c0..bab8d95 100644
--- a/tests/libqtest.h
+++ b/tests/libqtest.h
@@ -69,15 +69,6 @@ QDict *qtest_qmp(QTestState *s, const char *fmt, ...);
QDict *qtest_qmp_cmd(QTestState *s, const char *cmd, QDict *args);
/**
- * qtest_async_qmp:
- * @s: #QTestState instance to operate on.
- * @fmt...: QMP message to send to qemu
- *
- * Sends a QMP message to QEMU and leaves the response in the stream.
- */
-void qtest_async_qmp(QTestState *s, const char *fmt, ...);
-
-/**
* qtest_qmpv:
* @s: #QTestState instance to operate on.
* @fmt: QMP message to send to QEMU
@@ -88,16 +79,6 @@ void qtest_async_qmp(QTestState *s, const char *fmt, ...);
QDict *qtest_qmpv(QTestState *s, const char *fmt, va_list ap);
/**
- * qtest_async_qmpv:
- * @s: #QTestState instance to operate on.
- * @fmt: QMP message to send to QEMU
- * @ap: QMP message arguments
- *
- * Sends a QMP message to QEMU and leaves the response in the stream.
- */
-void qtest_async_qmpv(QTestState *s, const char *fmt, va_list ap);
-
-/**
* qtest_receive:
* @s: #QTestState instance to operate on.
*
diff --git a/tests/libqtest.c b/tests/libqtest.c
index 555d0c4..ba329c0 100644
--- a/tests/libqtest.c
+++ b/tests/libqtest.c
@@ -450,14 +450,9 @@ static void qmp_fd_sendv(int fd, const char *fmt, va_list ap)
}
}
-void qtest_async_qmpv(QTestState *s, const char *fmt, va_list ap)
-{
- qmp_fd_sendv(s->qmp_fd, fmt, ap);
-}
-
QDict *qtest_qmpv(QTestState *s, const char *fmt, va_list ap)
{
- qtest_async_qmpv(s, fmt, ap);
+ qmp_fd_sendv(s->qmp_fd, fmt, ap);
/* Receive reply */
return qtest_qmp_receive(s);
@@ -507,15 +502,6 @@ QDict *qtest_qmp_cmd(QTestState *s, const char *cmd, QDict *args)
return qtest_qmp(s, "%p", QOBJECT(dict));
}
-void qtest_async_qmp(QTestState *s, const char *fmt, ...)
-{
- va_list ap;
-
- va_start(ap, fmt);
- qtest_async_qmpv(s, fmt, ap);
- va_end(ap);
-}
-
void qtest_qmp_discard_response(QTestState *s, const char *json)
{
QDict *response;
@@ -888,7 +874,7 @@ void qmp_async(const char *fmt, ...)
va_list ap;
va_start(ap, fmt);
- qtest_async_qmpv(global_qtest, fmt, ap);
+ qmp_fd_sendv(global_qtest->qmp_fd, fmt, ap);
va_end(ap);
}
--
2.7.4
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [Qemu-devel] [PATCH 27/36] qtest: Avoid dynamic JSON in qmp_cmd()
2016-11-30 19:44 [Qemu-devel] [PATCH 00/36] Rip out dynamic JSON parsing Eric Blake
` (25 preceding siblings ...)
2016-11-30 19:44 ` [Qemu-devel] [PATCH 26/36] qtest: Drop unused qtest_qmp_async() Eric Blake
@ 2016-11-30 19:44 ` Eric Blake
2016-11-30 19:44 ` [Qemu-devel] [PATCH 28/36] qapi: Factor out JSON string escaping Eric Blake
` (9 subsequent siblings)
36 siblings, 0 replies; 45+ messages in thread
From: Eric Blake @ 2016-11-30 19:44 UTC (permalink / raw)
To: qemu-devel; +Cc: armbru, pbonzini
When qmp_cmd() was first added, we used a shortcut of a format
string of "%p" to pass the QObject intact through the varargs.
But now that we have a way to directly invoke strings, we can
altogether avoid the no-op trip through the parser by just
flattening to a string ourselves.
Signed-off-by: Eric Blake <eblake@redhat.com>
---
tests/libqtest.c | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/tests/libqtest.c b/tests/libqtest.c
index ba329c0..22bf0ad 100644
--- a/tests/libqtest.c
+++ b/tests/libqtest.c
@@ -493,13 +493,22 @@ QDict *qtest_qmp(QTestState *s, const char *fmt, ...)
QDict *qtest_qmp_cmd(QTestState *s, const char *cmd, QDict *args)
{
QDict *dict = qdict_new();
+ QString *qstr;
+ QDict *result;
if (!args) {
args = qdict_new();
}
qdict_put_str(dict, "execute", cmd);
qdict_put(dict, "arguments", args);
- return qtest_qmp(s, "%p", QOBJECT(dict));
+ qstr = qobject_to_json(QOBJECT(dict));
+
+ qmp_fd_send(s->qmp_fd, qstring_get_str(qstr));
+ result = qtest_qmp_receive(s);
+
+ QDECREF(dict);
+ QDECREF(qstr);
+ return result;
}
void qtest_qmp_discard_response(QTestState *s, const char *json)
--
2.7.4
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [Qemu-devel] [PATCH 28/36] qapi: Factor out JSON string escaping
2016-11-30 19:44 [Qemu-devel] [PATCH 00/36] Rip out dynamic JSON parsing Eric Blake
` (26 preceding siblings ...)
2016-11-30 19:44 ` [Qemu-devel] [PATCH 27/36] qtest: Avoid dynamic JSON in qmp_cmd() Eric Blake
@ 2016-11-30 19:44 ` Eric Blake
2016-11-30 19:44 ` [Qemu-devel] [PATCH 29/36] qapi: Add qstring_append_printf() Eric Blake
` (8 subsequent siblings)
36 siblings, 0 replies; 45+ messages in thread
From: Eric Blake @ 2016-11-30 19:44 UTC (permalink / raw)
To: qemu-devel; +Cc: armbru, pbonzini, Juan Quintela, Amit Shah
Pull out a new qstring_append_json_string() helper, so that all
JSON output producers can use the same output escaping rules.
While it appears that vmstate's use of the simpler qjson.c
formatter is not currently encountering any string that needs
escapes to be valid JSON, it is better to be safe than sorry,
and this substitution is not adding any potential asserts
during migration.
Adding a return value will let callers that care diagnose the
situation where an attempt was made to output invalid JSON (we
use substitute characters, and in fact guarantee that our
output is ASCII via escapes even if the input was UTF-8). None
of the current callers care, but a future patch wants to make
it possible to conditionally turn this situation into an error.
Signed-off-by: Eric Blake <eblake@redhat.com>
---
previously posted in 'Add qapi-to-JSON visitor' series:
v6: comment tweaks
[no v5 due to series split]
v4: keep helper in qobject-json.[ch], tweak variable name and
for loop iterator, add return value, drop R-b
v3: rebase to include cleanups in master
v2: no change
---
include/qapi/qmp/qjson.h | 2 +
migration/qjson.c | 10 ++--
qobject/qjson.c | 126 ++++++++++++++++++++++++++---------------------
3 files changed, 76 insertions(+), 62 deletions(-)
diff --git a/include/qapi/qmp/qjson.h b/include/qapi/qmp/qjson.h
index 02b1f2c..aa8ddd7 100644
--- a/include/qapi/qmp/qjson.h
+++ b/include/qapi/qmp/qjson.h
@@ -24,4 +24,6 @@ QObject *qobject_from_jsonv(const char *string, va_list *ap) GCC_FMT_ATTR(1, 0);
QString *qobject_to_json(const QObject *obj);
QString *qobject_to_json_pretty(const QObject *obj);
+int qstring_append_json_string(QString *qstring, const char *str);
+
#endif /* QJSON_H */
diff --git a/migration/qjson.c b/migration/qjson.c
index f345904..741f9e6 100644
--- a/migration/qjson.c
+++ b/migration/qjson.c
@@ -26,6 +26,7 @@
#include "qemu/osdep.h"
#include "qapi/qmp/qstring.h"
#include "migration/qjson.h"
+#include "qapi/qmp/qjson.h"
struct QJSON {
QString *str;
@@ -42,9 +43,8 @@ static void json_emit_element(QJSON *json, const char *name)
}
if (name) {
- qstring_append(json->str, "\"");
- qstring_append(json->str, name);
- qstring_append(json->str, "\" : ");
+ qstring_append_json_string(json->str, name);
+ qstring_append(json->str, " : ");
}
}
@@ -83,9 +83,7 @@ void json_prop_int(QJSON *json, const char *name, int64_t val)
void json_prop_str(QJSON *json, const char *name, const char *str)
{
json_emit_element(json, name);
- qstring_append_chr(json->str, '"');
- qstring_append(json->str, str);
- qstring_append_chr(json->str, '"');
+ qstring_append_json_string(json->str, str);
}
const char *qjson_get_str(QJSON *json)
diff --git a/qobject/qjson.c b/qobject/qjson.c
index 9a0de89..daeeb82 100644
--- a/qobject/qjson.c
+++ b/qobject/qjson.c
@@ -81,7 +81,6 @@ static void to_json(const QObject *obj, QString *str, int pretty, int indent);
static void to_json_dict_iter(const char *key, QObject *obj, void *opaque)
{
ToJsonIterState *s = opaque;
- QString *qkey;
int j;
if (s->count) {
@@ -94,9 +93,7 @@ static void to_json_dict_iter(const char *key, QObject *obj, void *opaque)
qstring_append(s->str, " ");
}
- qkey = qstring_from_str(key);
- to_json(QOBJECT(qkey), s->str, s->pretty, s->indent);
- QDECREF(qkey);
+ qstring_append_json_string(s->str, key);
qstring_append(s->str, ": ");
to_json(obj, s->str, s->pretty, s->indent);
@@ -138,58 +135,9 @@ static void to_json(const QObject *obj, QString *str, int pretty, int indent)
}
case QTYPE_QSTRING: {
QString *val = qobject_to_qstring(obj);
- const char *ptr;
- int cp;
- char buf[16];
- char *end;
-
- ptr = qstring_get_str(val);
- qstring_append(str, "\"");
-
- for (; *ptr; ptr = end) {
- cp = mod_utf8_codepoint(ptr, 6, &end);
- switch (cp) {
- case '\"':
- qstring_append(str, "\\\"");
- break;
- case '\\':
- qstring_append(str, "\\\\");
- break;
- case '\b':
- qstring_append(str, "\\b");
- break;
- case '\f':
- qstring_append(str, "\\f");
- break;
- case '\n':
- qstring_append(str, "\\n");
- break;
- case '\r':
- qstring_append(str, "\\r");
- break;
- case '\t':
- qstring_append(str, "\\t");
- break;
- default:
- if (cp < 0) {
- cp = 0xFFFD; /* replacement character */
- }
- if (cp > 0xFFFF) {
- /* beyond BMP; need a surrogate pair */
- snprintf(buf, sizeof(buf), "\\u%04X\\u%04X",
- 0xD800 + ((cp - 0x10000) >> 10),
- 0xDC00 + ((cp - 0x10000) & 0x3FF));
- } else if (cp < 0x20 || cp >= 0x7F) {
- snprintf(buf, sizeof(buf), "\\u%04X", cp);
- } else {
- buf[0] = cp;
- buf[1] = 0;
- }
- qstring_append(str, buf);
- }
- };
-
- qstring_append(str, "\"");
+ /* FIXME: no way inform user if we replaced invalid UTF-8
+ * sequences to avoid invalid JSON */
+ qstring_append_json_string(str, qstring_get_str(val));
break;
}
case QTYPE_QDICT: {
@@ -290,3 +238,69 @@ QString *qobject_to_json_pretty(const QObject *obj)
return str;
}
+
+/**
+ * Append a JSON string to @qstring that encodes the C string @str.
+ *
+ * @str is in UTF-8. The JSON string is enclosed in double quotes and
+ * has funny characters escaped. Invalid UTF-8 sequences are replaced
+ * by (properly escaped) U+0xFFFD replacement characters. Return -1 if
+ * invalid sequences were replaced, else 0.
+ */
+int qstring_append_json_string(QString *qstring, const char *str)
+{
+ const char *ptr;
+ int cp;
+ char buf[16];
+ char *end;
+ int result = 0;
+
+ qstring_append(qstring, "\"");
+
+ for (ptr = str; *ptr; ptr = end) {
+ cp = mod_utf8_codepoint(ptr, 6, &end);
+ switch (cp) {
+ case '\"':
+ qstring_append(qstring, "\\\"");
+ break;
+ case '\\':
+ qstring_append(qstring, "\\\\");
+ break;
+ case '\b':
+ qstring_append(qstring, "\\b");
+ break;
+ case '\f':
+ qstring_append(qstring, "\\f");
+ break;
+ case '\n':
+ qstring_append(qstring, "\\n");
+ break;
+ case '\r':
+ qstring_append(qstring, "\\r");
+ break;
+ case '\t':
+ qstring_append(qstring, "\\t");
+ break;
+ default:
+ if (cp < 0) {
+ cp = 0xFFFD; /* replacement character */
+ result = -1;
+ }
+ if (cp > 0xFFFF) {
+ /* beyond BMP; need a surrogate pair */
+ snprintf(buf, sizeof(buf), "\\u%04X\\u%04X",
+ 0xD800 + ((cp - 0x10000) >> 10),
+ 0xDC00 + ((cp - 0x10000) & 0x3FF));
+ } else if (cp < 0x20 || cp >= 0x7F) {
+ snprintf(buf, sizeof(buf), "\\u%04X", cp);
+ } else {
+ buf[0] = cp;
+ buf[1] = 0;
+ }
+ qstring_append(qstring, buf);
+ }
+ };
+
+ qstring_append(qstring, "\"");
+ return result;
+}
--
2.7.4
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [Qemu-devel] [PATCH 29/36] qapi: Add qstring_append_printf()
2016-11-30 19:44 [Qemu-devel] [PATCH 00/36] Rip out dynamic JSON parsing Eric Blake
` (27 preceding siblings ...)
2016-11-30 19:44 ` [Qemu-devel] [PATCH 28/36] qapi: Factor out JSON string escaping Eric Blake
@ 2016-11-30 19:44 ` Eric Blake
2016-11-30 19:44 ` [Qemu-devel] [PATCH 30/36] qtest: Avoid dynamic JSON in qmp_fd_sendv() Eric Blake
` (7 subsequent siblings)
36 siblings, 0 replies; 45+ messages in thread
From: Eric Blake @ 2016-11-30 19:44 UTC (permalink / raw)
To: qemu-devel; +Cc: armbru, pbonzini, Juan Quintela, Amit Shah
Back in commit 764c1ca (Nov 2009), we added qstring_append_int().
However, it did not see any use until commit 190c882 (Jan 2015).
Furthermore, it has a rather limited use case - to print anything
else, callers still have to format into a temporary buffer, unless
we want to introduce an explosion of new qstring_append_* methods
for each useful type to print.
A much better approach is to add a wrapper that merges printf
behavior onto qstring_append, via the new qstring_append_printf()
(and its vararg counterpart), with a name based on glib's
g_string_append_printf(). In fact, with our wrapper in place, we
no longer need qstring_append_int().
Other immediate uses for the new function include simplifying
two existing clients of qstring_append() on a just-formatted
buffer, and the fact that we can take advantage of printf width
manipulations for more efficient indentation.
Signed-off-by: Eric Blake <eblake@redhat.com>
---
previously posted in 'Add qapi-to-JSON visitor' series:
v6: no change
[no v5 due to series split]
v4: retitle, s/_format/_printf/, drop R-b, move up in series
v3: rebase to master
v2: also simplify qstring_append_json_string(), add assertion that
format is well-formed
---
include/qapi/qmp/qstring.h | 7 +++++--
migration/qjson.c | 2 +-
qobject/qjson.c | 38 ++++++++++----------------------------
qobject/qstring.c | 26 +++++++++++++++++++++-----
4 files changed, 37 insertions(+), 36 deletions(-)
diff --git a/include/qapi/qmp/qstring.h b/include/qapi/qmp/qstring.h
index 10076b7..a987f3b 100644
--- a/include/qapi/qmp/qstring.h
+++ b/include/qapi/qmp/qstring.h
@@ -1,7 +1,7 @@
/*
* QString Module
*
- * Copyright (C) 2009 Red Hat Inc.
+ * Copyright (C) 2009-2016 Red Hat Inc.
*
* Authors:
* Luiz Capitulino <lcapitulino@redhat.com>
@@ -27,9 +27,12 @@ QString *qstring_from_str(const char *str);
QString *qstring_from_substr(const char *str, int start, int end);
size_t qstring_get_length(const QString *qstring);
const char *qstring_get_str(const QString *qstring);
-void qstring_append_int(QString *qstring, int64_t value);
void qstring_append(QString *qstring, const char *str);
void qstring_append_chr(QString *qstring, int c);
+void qstring_append_printf(QString *qstring, const char *fmt, ...)
+ GCC_FMT_ATTR(2, 3);
+void qstring_append_vprintf(QString *qstring, const char *fmt, va_list ap)
+ GCC_FMT_ATTR(2, 0);
QString *qobject_to_qstring(const QObject *obj);
void qstring_destroy_obj(QObject *obj);
diff --git a/migration/qjson.c b/migration/qjson.c
index 741f9e6..f11effd 100644
--- a/migration/qjson.c
+++ b/migration/qjson.c
@@ -77,7 +77,7 @@ void json_end_array(QJSON *json)
void json_prop_int(QJSON *json, const char *name, int64_t val)
{
json_emit_element(json, name);
- qstring_append_int(json->str, val);
+ qstring_append_printf(json->str, "%" PRId64, val);
}
void json_prop_str(QJSON *json, const char *name, const char *str)
diff --git a/qobject/qjson.c b/qobject/qjson.c
index daeeb82..4929008 100644
--- a/qobject/qjson.c
+++ b/qobject/qjson.c
@@ -81,16 +81,13 @@ static void to_json(const QObject *obj, QString *str, int pretty, int indent);
static void to_json_dict_iter(const char *key, QObject *obj, void *opaque)
{
ToJsonIterState *s = opaque;
- int j;
if (s->count) {
qstring_append(s->str, s->pretty ? "," : ", ");
}
if (s->pretty) {
- qstring_append(s->str, "\n");
- for (j = 0 ; j < s->indent ; j++)
- qstring_append(s->str, " ");
+ qstring_append_printf(s->str, "\n%*s", 4 * s->indent, "");
}
qstring_append_json_string(s->str, key);
@@ -103,16 +100,13 @@ static void to_json_dict_iter(const char *key, QObject *obj, void *opaque)
static void to_json_list_iter(QObject *obj, void *opaque)
{
ToJsonIterState *s = opaque;
- int j;
if (s->count) {
qstring_append(s->str, s->pretty ? "," : ", ");
}
if (s->pretty) {
- qstring_append(s->str, "\n");
- for (j = 0 ; j < s->indent ; j++)
- qstring_append(s->str, " ");
+ qstring_append_printf(s->str, "\n%*s", 4 * s->indent, "");
}
to_json(obj, s->str, s->pretty, s->indent);
@@ -127,10 +121,7 @@ static void to_json(const QObject *obj, QString *str, int pretty, int indent)
break;
case QTYPE_QINT: {
QInt *val = qobject_to_qint(obj);
- char buffer[1024];
-
- snprintf(buffer, sizeof(buffer), "%" PRId64, qint_get_int(val));
- qstring_append(str, buffer);
+ qstring_append_printf(str, "%" PRId64, qint_get_int(val));
break;
}
case QTYPE_QSTRING: {
@@ -151,10 +142,7 @@ static void to_json(const QObject *obj, QString *str, int pretty, int indent)
qstring_append(str, "{");
qdict_iter(val, to_json_dict_iter, &s);
if (pretty) {
- int j;
- qstring_append(str, "\n");
- for (j = 0 ; j < indent ; j++)
- qstring_append(str, " ");
+ qstring_append_printf(str, "\n%*s", 4 * indent, "");
}
qstring_append(str, "}");
break;
@@ -170,10 +158,7 @@ static void to_json(const QObject *obj, QString *str, int pretty, int indent)
qstring_append(str, "[");
qlist_iter(val, (void *)to_json_list_iter, &s);
if (pretty) {
- int j;
- qstring_append(str, "\n");
- for (j = 0 ; j < indent ; j++)
- qstring_append(str, " ");
+ qstring_append_printf(str, "\n%*s", 4 * indent, "");
}
qstring_append(str, "]");
break;
@@ -251,7 +236,6 @@ int qstring_append_json_string(QString *qstring, const char *str)
{
const char *ptr;
int cp;
- char buf[16];
char *end;
int result = 0;
@@ -288,16 +272,14 @@ int qstring_append_json_string(QString *qstring, const char *str)
}
if (cp > 0xFFFF) {
/* beyond BMP; need a surrogate pair */
- snprintf(buf, sizeof(buf), "\\u%04X\\u%04X",
- 0xD800 + ((cp - 0x10000) >> 10),
- 0xDC00 + ((cp - 0x10000) & 0x3FF));
+ qstring_append_printf(qstring, "\\u%04X\\u%04X",
+ 0xD800 + ((cp - 0x10000) >> 10),
+ 0xDc00 + ((cp - 0x10000) & 0x3FF));
} else if (cp < 0x20 || cp >= 0x7F) {
- snprintf(buf, sizeof(buf), "\\u%04X", cp);
+ qstring_append_printf(qstring, "\\u%04X", cp);
} else {
- buf[0] = cp;
- buf[1] = 0;
+ qstring_append_chr(qstring, cp);
}
- qstring_append(qstring, buf);
}
};
diff --git a/qobject/qstring.c b/qobject/qstring.c
index 5da7b5f..fbfae27 100644
--- a/qobject/qstring.c
+++ b/qobject/qstring.c
@@ -1,7 +1,7 @@
/*
* QString Module
*
- * Copyright (C) 2009 Red Hat Inc.
+ * Copyright (C) 2009-2016 Red Hat Inc.
*
* Authors:
* Luiz Capitulino <lcapitulino@redhat.com>
@@ -88,12 +88,28 @@ void qstring_append(QString *qstring, const char *str)
qstring->string[qstring->length] = 0;
}
-void qstring_append_int(QString *qstring, int64_t value)
+void qstring_append_printf(QString *qstring, const char *fmt, ...)
{
- char num[32];
+ va_list ap;
- snprintf(num, sizeof(num), "%" PRId64, value);
- qstring_append(qstring, num);
+ va_start(ap, fmt);
+ qstring_append_vprintf(qstring, fmt, ap);
+ va_end(ap);
+}
+
+void qstring_append_vprintf(QString *qstring, const char *fmt, va_list ap)
+{
+ va_list ap2;
+ int len;
+
+ va_copy(ap2, ap);
+ len = vsnprintf(NULL, 0, fmt, ap2);
+ assert(len >= 0);
+ va_end(ap2);
+
+ capacity_increase(qstring, len);
+ vsnprintf(qstring->string + qstring->length, len + 1, fmt, ap);
+ qstring->length += len;
}
/**
--
2.7.4
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [Qemu-devel] [PATCH 30/36] qtest: Avoid dynamic JSON in qmp_fd_sendv()
2016-11-30 19:44 [Qemu-devel] [PATCH 00/36] Rip out dynamic JSON parsing Eric Blake
` (28 preceding siblings ...)
2016-11-30 19:44 ` [Qemu-devel] [PATCH 29/36] qapi: Add qstring_append_printf() Eric Blake
@ 2016-11-30 19:44 ` Eric Blake
2016-11-30 19:44 ` [Qemu-devel] [PATCH 31/36] qtest: Document calling conventions Eric Blake
` (6 subsequent siblings)
36 siblings, 0 replies; 45+ messages in thread
From: Eric Blake @ 2016-11-30 19:44 UTC (permalink / raw)
To: qemu-devel; +Cc: armbru, pbonzini
The only format specifier left in any client of qmp() and friends
is %s. Rather than having to make our JSON parser support varargs,
and use a conversion from string to QObject and back to string, we
can instead just directly build the string and substitute %s
ourselves. With this, the final caller of qobject_from_jsonv() is
eliminated, and followup patches can simplify the parser.
Signed-off-by: Eric Blake <eblake@redhat.com>
---
Too bad glibc's strchrnul() is not universal; also, this patch
could avoid "%.*s" format shenanigans (with the nastiness of
converting ptrdiff_t to int) if we want to first enhance QString
to support a length-limited append primitive.
---
tests/libqtest.c | 42 ++++++++++++++++++++++++++----------------
1 file changed, 26 insertions(+), 16 deletions(-)
diff --git a/tests/libqtest.c b/tests/libqtest.c
index 22bf0ad..a9559d8 100644
--- a/tests/libqtest.c
+++ b/tests/libqtest.c
@@ -427,27 +427,37 @@ QDict *qtest_qmp_receive(QTestState *s)
*/
static void qmp_fd_sendv(int fd, const char *fmt, va_list ap)
{
- va_list ap_copy;
- QObject *qobj;
+ QString *qstr;
- /* Going through qobject ensures we escape strings properly.
- * This seemingly unnecessary copy is required in case va_list
- * is an array type.
+ if (!strchr(fmt, '%')) {
+ return qmp_fd_send(fd, fmt);
+ }
+
+ /* Construct a single string, turning %s in fmt into proper JSON
+ * strings. For now, we don't support any other format specifiers.
*/
- va_copy(ap_copy, ap);
- qobj = qobject_from_jsonv(fmt, &ap_copy);
- va_end(ap_copy);
+ qstr = qstring_new();
+ while (*fmt) {
+ /* Too bad strchrnul() is not universal */
+ const char *p = strchr(fmt, '%');
- /* No need to send anything for an empty QObject. */
- if (qobj) {
- QString *qstr = qobject_to_json(qobj);
- const char *str = qstring_get_str(qstr);
+ if (!p) {
+ p = strchr(fmt, '\0');
+ }
- qmp_fd_send(fd, str);
-
- QDECREF(qstr);
- qobject_decref(qobj);
+ assert(p - fmt < INT_MAX);
+ qstring_append_printf(qstr, "%.*s", (int)(p - fmt), fmt);
+ if (*p) {
+ assert(p[1] == 's');
+ p += 2;
+ qstring_append_json_string(qstr, va_arg(ap, const char *));
+ }
+ fmt = p;
}
+
+ qmp_fd_send(fd, qstring_get_str(qstr));
+
+ QDECREF(qstr);
}
QDict *qtest_qmpv(QTestState *s, const char *fmt, va_list ap)
--
2.7.4
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [Qemu-devel] [PATCH 31/36] qtest: Document calling conventions
2016-11-30 19:44 [Qemu-devel] [PATCH 00/36] Rip out dynamic JSON parsing Eric Blake
` (29 preceding siblings ...)
2016-11-30 19:44 ` [Qemu-devel] [PATCH 30/36] qtest: Avoid dynamic JSON in qmp_fd_sendv() Eric Blake
@ 2016-11-30 19:44 ` Eric Blake
2016-11-30 19:44 ` [Qemu-devel] [PATCH 32/36] qtest: Avoid dynamic JSON in qom-test Eric Blake
` (5 subsequent siblings)
36 siblings, 0 replies; 45+ messages in thread
From: Eric Blake @ 2016-11-30 19:44 UTC (permalink / raw)
To: qemu-devel; +Cc: armbru, pbonzini
We have two flavors of vararg usage in qtest; make it clear that
qmp() has different semantics than hmp(), and let the compiler
enforce that hmp() is used correctly. Since qmp() only accepts
exactly "%s" (asserting on misuse, which would be flagged during
'make check'), I figured that it is probably not worth adding a
format attribute to qmp() at this time.
Signed-off-by: Eric Blake <eblake@redhat.com>
---
tests/libqtest.h | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/tests/libqtest.h b/tests/libqtest.h
index bab8d95..2ff3829 100644
--- a/tests/libqtest.h
+++ b/tests/libqtest.h
@@ -51,7 +51,7 @@ void qtest_qmp_discard_response(QTestState *s, const char *json);
/**
* qtest_qmp:
* @s: #QTestState instance to operate on.
- * @fmt...: QMP message to send to qemu
+ * @fmt...: QMP message to send to qemu; only recognizes "%s"
*
* Sends a QMP message to QEMU and returns the response.
*/
@@ -108,13 +108,13 @@ QDict *qtest_qmp_eventwait_ref(QTestState *s, const char *event);
/**
* qtest_hmpv:
* @s: #QTestState instance to operate on.
- * @fmt...: HMP command to send to QEMU
+ * @fmt...: HMP command to send to QEMU, passed through sprintf()
*
* Send HMP command to QEMU via QMP's human-monitor-command.
*
* Returns: the command's output. The caller should g_free() it.
*/
-char *qtest_hmp(QTestState *s, const char *fmt, ...);
+char *qtest_hmp(QTestState *s, const char *fmt, ...) GCC_FMT_ATTR(2, 3);
/**
* qtest_hmpv:
@@ -507,7 +507,7 @@ static inline void qtest_end(void)
/**
* qmp:
- * @fmt...: QMP message to send to qemu
+ * @fmt...: QMP message to send to qemu; only recognizes "%s"
*
* Sends a QMP message to QEMU and returns the response.
*/
@@ -525,7 +525,7 @@ QDict *qmp_cmd(const char *cmd, QDict *args);
/**
* qmp_async:
- * @fmt...: QMP message to send to qemu
+ * @fmt...: QMP message to send to qemu; only recognizes "%s"
*
* Sends a QMP message to QEMU and leaves the response in the stream.
*/
@@ -584,13 +584,13 @@ static inline QDict *qmp_eventwait_ref(const char *event)
/**
* hmp:
- * @fmt...: HMP command to send to QEMU
+ * @fmt...: HMP command to send to QEMU, passed through printf()
*
* Send HMP command to QEMU via QMP's human-monitor-command.
*
* Returns: the command's output. The caller should g_free() it.
*/
-char *hmp(const char *fmt, ...);
+char *hmp(const char *fmt, ...) GCC_FMT_ATTR(1, 2);
/**
* get_irq:
--
2.7.4
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [Qemu-devel] [PATCH 32/36] qtest: Avoid dynamic JSON in qom-test
2016-11-30 19:44 [Qemu-devel] [PATCH 00/36] Rip out dynamic JSON parsing Eric Blake
` (30 preceding siblings ...)
2016-11-30 19:44 ` [Qemu-devel] [PATCH 31/36] qtest: Document calling conventions Eric Blake
@ 2016-11-30 19:44 ` Eric Blake
2016-11-30 19:44 ` [Qemu-devel] [PATCH 33/36] qtest: Avoid dynamic JSON in test-x86-cpuid-compat Eric Blake
` (4 subsequent siblings)
36 siblings, 0 replies; 45+ messages in thread
From: Eric Blake @ 2016-11-30 19:44 UTC (permalink / raw)
To: qemu-devel; +Cc: armbru, pbonzini, Andreas Färber
As argued elsewhere, it's less code to maintain if we convert
from a dynamic string passed to qobject_from_jsonv() to instead
use hand-built QDict.
Signed-off-by: Eric Blake <eblake@redhat.com>
---
Optional; the "%s" handling in earlier patches is sufficient to
handle this without hand-built QDict, so it is a judgment call
which version is more legible.
---
tests/qom-test.c | 15 ++++++++-------
1 file changed, 8 insertions(+), 7 deletions(-)
diff --git a/tests/qom-test.c b/tests/qom-test.c
index d48f890..780c775 100644
--- a/tests/qom-test.c
+++ b/tests/qom-test.c
@@ -46,13 +46,14 @@ static bool is_blacklisted(const char *arch, const char *mach)
static void test_properties(const char *path, bool recurse)
{
char *child_path;
- QDict *response, *tuple, *tmp;
+ QDict *response, *tuple, *tmp, *args;
QList *list;
QListEntry *entry;
g_test_message("Obtaining properties of %s", path);
- response = qmp("{ 'execute': 'qom-list',"
- " 'arguments': { 'path': %s } }", path);
+ args = qdict_new();
+ qdict_put_str(args, "path", path);
+ response = qmp_cmd("qom-list", args);
g_assert(response);
if (!recurse) {
@@ -75,10 +76,10 @@ static void test_properties(const char *path, bool recurse)
} else {
const char *prop = qdict_get_str(tuple, "name");
g_test_message("Testing property %s.%s", path, prop);
- tmp = qmp("{ 'execute': 'qom-get',"
- " 'arguments': { 'path': %s,"
- " 'property': %s } }",
- path, prop);
+ args = qdict_new();
+ qdict_put_str(args, "path", path);
+ qdict_put_str(args, "property", prop);
+ tmp = qmp_cmd("qom-get", args);
/* qom-get may fail but should not, e.g., segfault. */
g_assert(tmp);
QDECREF(tmp);
--
2.7.4
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [Qemu-devel] [PATCH 33/36] qtest: Avoid dynamic JSON in test-x86-cpuid-compat
2016-11-30 19:44 [Qemu-devel] [PATCH 00/36] Rip out dynamic JSON parsing Eric Blake
` (31 preceding siblings ...)
2016-11-30 19:44 ` [Qemu-devel] [PATCH 32/36] qtest: Avoid dynamic JSON in qom-test Eric Blake
@ 2016-11-30 19:44 ` Eric Blake
2016-11-30 19:44 ` [Qemu-devel] [PATCH 34/36] qapi: Rip out dynamic JSON parser frontend Eric Blake
` (3 subsequent siblings)
36 siblings, 0 replies; 45+ messages in thread
From: Eric Blake @ 2016-11-30 19:44 UTC (permalink / raw)
To: qemu-devel; +Cc: armbru, pbonzini
As argued elsewhere, it's less code to maintain if we convert
from a dynamic string passed to qobject_from_jsonv() to instead
use hand-built QDict.
Signed-off-by: Eric Blake <eblake@redhat.com>
---
Optional; the "%s" handling in earlier patches is sufficient to
handle this without hand-built QDict, so it is a judgment call
which version is more legible.
---
tests/test-x86-cpuid-compat.c | 14 +++++++++-----
1 file changed, 9 insertions(+), 5 deletions(-)
diff --git a/tests/test-x86-cpuid-compat.c b/tests/test-x86-cpuid-compat.c
index 79a2e69..bce5c8a 100644
--- a/tests/test-x86-cpuid-compat.c
+++ b/tests/test-x86-cpuid-compat.c
@@ -4,6 +4,7 @@
#include "qapi/qmp/qdict.h"
#include "qapi/qmp/qint.h"
#include "qapi/qmp/qbool.h"
+#include "qapi/qmp/qstring.h"
#include "libqtest.h"
static char *get_cpu0_qom_path(void)
@@ -25,11 +26,14 @@ static char *get_cpu0_qom_path(void)
static QObject *qom_get(const char *path, const char *prop)
{
- QDict *resp = qmp("{ 'execute': 'qom-get',"
- " 'arguments': { 'path': %s,"
- " 'property': %s } }",
- path, prop);
- QObject *ret = qdict_get(resp, "return");
+ QDict *args = qdict_new();
+ QDict *resp;
+ QObject *ret;
+
+ qdict_put_str(args, "path", path);
+ qdict_put_str(args, "property", prop);
+ resp = qmp_cmd("qom-get", args);
+ ret = qdict_get(resp, "return");
qobject_incref(ret);
QDECREF(resp);
return ret;
--
2.7.4
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [Qemu-devel] [PATCH 34/36] qapi: Rip out dynamic JSON parser frontend
2016-11-30 19:44 [Qemu-devel] [PATCH 00/36] Rip out dynamic JSON parsing Eric Blake
` (32 preceding siblings ...)
2016-11-30 19:44 ` [Qemu-devel] [PATCH 33/36] qtest: Avoid dynamic JSON in test-x86-cpuid-compat Eric Blake
@ 2016-11-30 19:44 ` Eric Blake
2016-11-30 19:44 ` [Qemu-devel] [PATCH 35/36] qapi: Rip out dynamic JSON parser escape sequence support Eric Blake
` (2 subsequent siblings)
36 siblings, 0 replies; 45+ messages in thread
From: Eric Blake @ 2016-11-30 19:44 UTC (permalink / raw)
To: qemu-devel; +Cc: armbru, pbonzini
Except for the testsuite, there are no more callers of
qobject_from_json[fv](). We have no need to maintain dynamic
JSON parsing just for the check-qjson test, so delete the
functions. All callers of json_parser_parse() now pass NULL
for the varargs parameter; the next patch will clean that up.
Signed-off-by: Eric Blake <eblake@redhat.com>
---
include/qapi/qmp/qjson.h | 2 -
qobject/qjson.c | 29 +-----------
tests/check-qjson.c | 113 +----------------------------------------------
3 files changed, 3 insertions(+), 141 deletions(-)
diff --git a/include/qapi/qmp/qjson.h b/include/qapi/qmp/qjson.h
index aa8ddd7..8188353 100644
--- a/include/qapi/qmp/qjson.h
+++ b/include/qapi/qmp/qjson.h
@@ -18,8 +18,6 @@
#include "qapi/qmp/qstring.h"
QObject *qobject_from_json(const char *string);
-QObject *qobject_from_jsonf(const char *string, ...) GCC_FMT_ATTR(1, 2);
-QObject *qobject_from_jsonv(const char *string, va_list *ap) GCC_FMT_ATTR(1, 0);
QString *qobject_to_json(const QObject *obj);
QString *qobject_to_json_pretty(const QObject *obj);
diff --git a/qobject/qjson.c b/qobject/qjson.c
index 4929008..f0ab6df 100644
--- a/qobject/qjson.c
+++ b/qobject/qjson.c
@@ -22,22 +22,19 @@
typedef struct JSONParsingState
{
JSONMessageParser parser;
- va_list *ap;
QObject *result;
} JSONParsingState;
static void parse_json(JSONMessageParser *parser, GQueue *tokens)
{
JSONParsingState *s = container_of(parser, JSONParsingState, parser);
- s->result = json_parser_parse(tokens, s->ap);
+ s->result = json_parser_parse(tokens, NULL);
}
-QObject *qobject_from_jsonv(const char *string, va_list *ap)
+QObject *qobject_from_json(const char *string)
{
JSONParsingState state = {};
- state.ap = ap;
-
json_message_parser_init(&state.parser, parse_json);
json_message_parser_feed(&state.parser, string, strlen(string));
json_message_parser_flush(&state.parser);
@@ -46,28 +43,6 @@ QObject *qobject_from_jsonv(const char *string, va_list *ap)
return state.result;
}
-QObject *qobject_from_json(const char *string)
-{
- return qobject_from_jsonv(string, NULL);
-}
-
-/*
- * IMPORTANT: This function aborts on error, thus it must not
- * be used with untrusted arguments.
- */
-QObject *qobject_from_jsonf(const char *string, ...)
-{
- QObject *obj;
- va_list ap;
-
- va_start(ap, string);
- obj = qobject_from_jsonv(string, &ap);
- va_end(ap);
-
- assert(obj != NULL);
- return obj;
-}
-
typedef struct ToJsonIterState
{
int indent;
diff --git a/tests/check-qjson.c b/tests/check-qjson.c
index 0b21a22..4025182 100644
--- a/tests/check-qjson.c
+++ b/tests/check-qjson.c
@@ -57,7 +57,7 @@ static void escaped_string(void)
g_assert(obj != NULL);
g_assert(qobject_type(obj) == QTYPE_QSTRING);
-
+
str = qobject_to_qstring(obj);
g_assert_cmpstr(qstring_get_str(str), ==, test_cases[i].decoded);
@@ -855,33 +855,6 @@ static void utf8_string(void)
}
}
-static void vararg_string(void)
-{
- int i;
- struct {
- const char *decoded;
- } test_cases[] = {
- { "hello world" },
- { "the quick brown fox jumped over the fence" },
- {}
- };
-
- for (i = 0; test_cases[i].decoded; i++) {
- QObject *obj;
- QString *str;
-
- obj = qobject_from_jsonf("%s", test_cases[i].decoded);
-
- g_assert(obj != NULL);
- g_assert(qobject_type(obj) == QTYPE_QSTRING);
-
- str = qobject_to_qstring(obj);
- g_assert(strcmp(qstring_get_str(str), test_cases[i].decoded) == 0);
-
- QDECREF(str);
- }
-}
-
static void simple_number(void)
{
int i;
@@ -958,43 +931,6 @@ static void float_number(void)
}
}
-static void vararg_number(void)
-{
- QObject *obj;
- QInt *qint;
- QFloat *qfloat;
- int value = 0x2342;
- long long value_ll = 0x2342342343LL;
- double valuef = 2.323423423;
-
- obj = qobject_from_jsonf("%d", value);
- g_assert(obj != NULL);
- g_assert(qobject_type(obj) == QTYPE_QINT);
-
- qint = qobject_to_qint(obj);
- g_assert(qint_get_int(qint) == value);
-
- QDECREF(qint);
-
- obj = qobject_from_jsonf("%lld", value_ll);
- g_assert(obj != NULL);
- g_assert(qobject_type(obj) == QTYPE_QINT);
-
- qint = qobject_to_qint(obj);
- g_assert(qint_get_int(qint) == value_ll);
-
- QDECREF(qint);
-
- obj = qobject_from_jsonf("%f", valuef);
- g_assert(obj != NULL);
- g_assert(qobject_type(obj) == QTYPE_QFLOAT);
-
- qfloat = qobject_to_qfloat(obj);
- g_assert(qfloat_get_double(qfloat) == valuef);
-
- QDECREF(qfloat);
-}
-
static void keyword_literal(void)
{
QObject *obj;
@@ -1028,25 +964,6 @@ static void keyword_literal(void)
QDECREF(qbool);
- obj = qobject_from_jsonf("%i", false);
- g_assert(obj != NULL);
- g_assert(qobject_type(obj) == QTYPE_QBOOL);
-
- qbool = qobject_to_qbool(obj);
- g_assert(qbool_get_bool(qbool) == false);
-
- QDECREF(qbool);
-
- /* Test that non-zero values other than 1 get collapsed to true */
- obj = qobject_from_jsonf("%i", 2);
- g_assert(obj != NULL);
- g_assert(qobject_type(obj) == QTYPE_QBOOL);
-
- qbool = qobject_to_qbool(obj);
- g_assert(qbool_get_bool(qbool) == true);
-
- QDECREF(qbool);
-
obj = qobject_from_json("null");
g_assert(obj != NULL);
g_assert(qobject_type(obj) == QTYPE_QNULL);
@@ -1386,30 +1303,6 @@ static void simple_whitespace(void)
}
}
-static void simple_varargs(void)
-{
- QObject *embedded_obj;
- QObject *obj;
- LiteralQObject decoded = QLIT_QLIST(((LiteralQObject[]){
- QLIT_QINT(1),
- QLIT_QINT(2),
- QLIT_QLIST(((LiteralQObject[]){
- QLIT_QINT(32),
- QLIT_QINT(42),
- {}})),
- {}}));
-
- embedded_obj = qobject_from_json("[32, 42]");
- g_assert(embedded_obj != NULL);
-
- obj = qobject_from_jsonf("[%d, 2, %p]", 1, embedded_obj);
- g_assert(obj != NULL);
-
- g_assert(compare_litqobj_to_qobj(&decoded, obj) == 1);
-
- qobject_decref(obj);
-}
-
static void empty_input(void)
{
const char *empty = "";
@@ -1510,11 +1403,9 @@ int main(int argc, char **argv)
g_test_add_func("/literals/string/escaped", escaped_string);
g_test_add_func("/literals/string/utf8", utf8_string);
g_test_add_func("/literals/string/single_quote", single_quote_string);
- g_test_add_func("/literals/string/vararg", vararg_string);
g_test_add_func("/literals/number/simple", simple_number);
g_test_add_func("/literals/number/float", float_number);
- g_test_add_func("/literals/number/vararg", vararg_number);
g_test_add_func("/literals/keyword", keyword_literal);
@@ -1524,8 +1415,6 @@ int main(int argc, char **argv)
g_test_add_func("/whitespace/simple_whitespace", simple_whitespace);
- g_test_add_func("/varargs/simple_varargs", simple_varargs);
-
g_test_add_func("/errors/empty_input", empty_input);
g_test_add_func("/errors/unterminated/string", unterminated_string);
g_test_add_func("/errors/unterminated/escape", unterminated_escape);
--
2.7.4
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [Qemu-devel] [PATCH 35/36] qapi: Rip out dynamic JSON parser escape sequence support
2016-11-30 19:44 [Qemu-devel] [PATCH 00/36] Rip out dynamic JSON parsing Eric Blake
` (33 preceding siblings ...)
2016-11-30 19:44 ` [Qemu-devel] [PATCH 34/36] qapi: Rip out dynamic JSON parser frontend Eric Blake
@ 2016-11-30 19:44 ` Eric Blake
2016-11-30 19:44 ` [Qemu-devel] [PATCH 36/36] qapi: Rip out dynamic JSON parser backend Eric Blake
2016-11-30 19:50 ` [Qemu-devel] [PATCH 00/36] Rip out dynamic JSON parsing Eric Blake
36 siblings, 0 replies; 45+ messages in thread
From: Eric Blake @ 2016-11-30 19:44 UTC (permalink / raw)
To: qemu-devel; +Cc: armbru, pbonzini
Now that there are no callers of dynamic JSON parsing, the
lexer does not need to special-case escape sequences.
Since the lexer is directly invoked on user-provided input,
this changes behavior when a QMP client passes (bad) JSON,
from:
{'execute':'qmp_capabilities','id':%s}
{"error": {"class": "GenericError", "desc": "Invalid JSON syntax"}}
to the noisier:
{'execute':'qmp_capabilities','id':%s}
{"error": {"class": "GenericError", "desc": "Invalid JSON syntax"}}
{"error": {"class": "GenericError", "desc": "JSON parse error, invalid keyword 's'"}}
{"error": {"class": "GenericError", "desc": "JSON parse error, expecting value"}}
But we've always known our parser is rather noisy when it comes to
dealing with invalid JSON, and valid clients won't see the
difference.
Signed-off-by: Eric Blake <eblake@redhat.com>
---
include/qapi/qmp/json-lexer.h | 1 -
qobject/json-lexer.c | 40 ----------------------------------------
qobject/json-parser.c | 32 --------------------------------
3 files changed, 73 deletions(-)
diff --git a/include/qapi/qmp/json-lexer.h b/include/qapi/qmp/json-lexer.h
index afee782..a872f57 100644
--- a/include/qapi/qmp/json-lexer.h
+++ b/include/qapi/qmp/json-lexer.h
@@ -27,7 +27,6 @@ typedef enum json_token_type {
JSON_FLOAT,
JSON_KEYWORD,
JSON_STRING,
- JSON_ESCAPE,
JSON_SKIP,
JSON_ERROR,
} JSONTokenType;
diff --git a/qobject/json-lexer.c b/qobject/json-lexer.c
index af4a75e..3207306 100644
--- a/qobject/json-lexer.c
+++ b/qobject/json-lexer.c
@@ -58,12 +58,6 @@ enum json_lexer_state {
IN_NONZERO_NUMBER,
IN_NEG_NONZERO_NUMBER,
IN_KEYWORD,
- IN_ESCAPE,
- IN_ESCAPE_L,
- IN_ESCAPE_LL,
- IN_ESCAPE_I,
- IN_ESCAPE_I6,
- IN_ESCAPE_I64,
IN_WHITESPACE,
IN_START,
};
@@ -224,38 +218,6 @@ static const uint8_t json_lexer[][256] = {
['\n'] = IN_WHITESPACE,
},
- /* escape */
- [IN_ESCAPE_LL] = {
- ['d'] = JSON_ESCAPE,
- },
-
- [IN_ESCAPE_L] = {
- ['d'] = JSON_ESCAPE,
- ['l'] = IN_ESCAPE_LL,
- },
-
- [IN_ESCAPE_I64] = {
- ['d'] = JSON_ESCAPE,
- },
-
- [IN_ESCAPE_I6] = {
- ['4'] = IN_ESCAPE_I64,
- },
-
- [IN_ESCAPE_I] = {
- ['6'] = IN_ESCAPE_I6,
- },
-
- [IN_ESCAPE] = {
- ['d'] = JSON_ESCAPE,
- ['i'] = JSON_ESCAPE,
- ['p'] = JSON_ESCAPE,
- ['s'] = JSON_ESCAPE,
- ['f'] = JSON_ESCAPE,
- ['l'] = IN_ESCAPE_L,
- ['I'] = IN_ESCAPE_I,
- },
-
/* top level rule */
[IN_START] = {
['"'] = IN_DQ_STRING,
@@ -270,7 +232,6 @@ static const uint8_t json_lexer[][256] = {
[','] = JSON_COMMA,
[':'] = JSON_COLON,
['a' ... 'z'] = IN_KEYWORD,
- ['%'] = IN_ESCAPE,
[' '] = IN_WHITESPACE,
['\t'] = IN_WHITESPACE,
['\r'] = IN_WHITESPACE,
@@ -311,7 +272,6 @@ static int json_lexer_feed_char(JSONLexer *lexer, char ch, bool flush)
case JSON_RSQUARE:
case JSON_COLON:
case JSON_COMMA:
- case JSON_ESCAPE:
case JSON_INTEGER:
case JSON_FLOAT:
case JSON_KEYWORD:
diff --git a/qobject/json-parser.c b/qobject/json-parser.c
index c18e48a..fec1dae 100644
--- a/qobject/json-parser.c
+++ b/qobject/json-parser.c
@@ -450,36 +450,6 @@ static QObject *parse_keyword(JSONParserContext *ctxt)
return NULL;
}
-static QObject *parse_escape(JSONParserContext *ctxt, va_list *ap)
-{
- JSONToken *token;
-
- if (ap == NULL) {
- return NULL;
- }
-
- token = parser_context_pop_token(ctxt);
- assert(token && token->type == JSON_ESCAPE);
-
- if (!strcmp(token->str, "%p")) {
- return va_arg(*ap, QObject *);
- } else if (!strcmp(token->str, "%i")) {
- return QOBJECT(qbool_from_bool(va_arg(*ap, int)));
- } else if (!strcmp(token->str, "%d")) {
- return QOBJECT(qint_from_int(va_arg(*ap, int)));
- } else if (!strcmp(token->str, "%ld")) {
- return QOBJECT(qint_from_int(va_arg(*ap, long)));
- } else if (!strcmp(token->str, "%lld") ||
- !strcmp(token->str, "%I64d")) {
- return QOBJECT(qint_from_int(va_arg(*ap, long long)));
- } else if (!strcmp(token->str, "%s")) {
- return QOBJECT(qstring_from_str(va_arg(*ap, const char *)));
- } else if (!strcmp(token->str, "%f")) {
- return QOBJECT(qfloat_from_double(va_arg(*ap, double)));
- }
- return NULL;
-}
-
static QObject *parse_literal(JSONParserContext *ctxt)
{
JSONToken *token;
@@ -537,8 +507,6 @@ static QObject *parse_value(JSONParserContext *ctxt, va_list *ap)
return parse_object(ctxt, ap);
case JSON_LSQUARE:
return parse_array(ctxt, ap);
- case JSON_ESCAPE:
- return parse_escape(ctxt, ap);
case JSON_INTEGER:
case JSON_FLOAT:
case JSON_STRING:
--
2.7.4
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [Qemu-devel] [PATCH 36/36] qapi: Rip out dynamic JSON parser backend
2016-11-30 19:44 [Qemu-devel] [PATCH 00/36] Rip out dynamic JSON parsing Eric Blake
` (34 preceding siblings ...)
2016-11-30 19:44 ` [Qemu-devel] [PATCH 35/36] qapi: Rip out dynamic JSON parser escape sequence support Eric Blake
@ 2016-11-30 19:44 ` Eric Blake
2016-11-30 19:50 ` [Qemu-devel] [PATCH 00/36] Rip out dynamic JSON parsing Eric Blake
36 siblings, 0 replies; 45+ messages in thread
From: Eric Blake @ 2016-11-30 19:44 UTC (permalink / raw)
To: qemu-devel; +Cc: armbru, pbonzini, Dr. David Alan Gilbert, Michael Roth
Now that there are no callers of dynamic JSON parsing, the
parser does not need to handle a va_list argument.
Signed-off-by: Eric Blake <eblake@redhat.com>
---
include/qapi/qmp/json-parser.h | 6 +++---
monitor.c | 2 +-
qga/main.c | 2 +-
qobject/json-parser.c | 34 +++++++++++++++++-----------------
qobject/qjson.c | 2 +-
tests/libqtest.c | 2 +-
6 files changed, 24 insertions(+), 24 deletions(-)
diff --git a/include/qapi/qmp/json-parser.h b/include/qapi/qmp/json-parser.h
index 9987f8c..fd37f73 100644
--- a/include/qapi/qmp/json-parser.h
+++ b/include/qapi/qmp/json-parser.h
@@ -1,5 +1,5 @@
/*
- * JSON Parser
+ * JSON Parser
*
* Copyright IBM, Corp. 2009
*
@@ -17,7 +17,7 @@
#include "qemu-common.h"
#include "qapi/qmp/qlist.h"
-QObject *json_parser_parse(GQueue *tokens, va_list *ap);
-QObject *json_parser_parse_err(GQueue *tokens, va_list *ap, Error **errp);
+QObject *json_parser_parse(GQueue *tokens);
+QObject *json_parser_parse_err(GQueue *tokens, Error **errp);
#endif
diff --git a/monitor.c b/monitor.c
index f86a855..9571e07 100644
--- a/monitor.c
+++ b/monitor.c
@@ -3731,7 +3731,7 @@ static void handle_qmp_command(JSONMessageParser *parser, GQueue *tokens)
Monitor *mon = cur_mon;
Error *err = NULL;
- req = json_parser_parse_err(tokens, NULL, &err);
+ req = json_parser_parse_err(tokens, &err);
if (err || !req || qobject_type(req) != QTYPE_QDICT) {
if (!err) {
error_setg(&err, QERR_JSON_PARSING);
diff --git a/qga/main.c b/qga/main.c
index 6caf215..7048646 100644
--- a/qga/main.c
+++ b/qga/main.c
@@ -576,7 +576,7 @@ static void process_event(JSONMessageParser *parser, GQueue *tokens)
g_assert(s && parser);
g_debug("process_event: called");
- qdict = qobject_to_qdict(json_parser_parse_err(tokens, NULL, &err));
+ qdict = qobject_to_qdict(json_parser_parse_err(tokens, &err));
if (err || !qdict) {
QDECREF(qdict);
qdict = qdict_new();
diff --git a/qobject/json-parser.c b/qobject/json-parser.c
index fec1dae..0614a79 100644
--- a/qobject/json-parser.c
+++ b/qobject/json-parser.c
@@ -37,7 +37,7 @@ typedef struct JSONParserContext
* 4) deal with premature EOI
*/
-static QObject *parse_value(JSONParserContext *ctxt, va_list *ap);
+static QObject *parse_value(JSONParserContext *ctxt);
/**
* Error handler
@@ -268,7 +268,7 @@ static void parser_context_free(JSONParserContext *ctxt)
/**
* Parsing rules
*/
-static int parse_pair(JSONParserContext *ctxt, QDict *dict, va_list *ap)
+static int parse_pair(JSONParserContext *ctxt, QDict *dict)
{
QObject *key = NULL, *value;
JSONToken *peek, *token;
@@ -279,7 +279,7 @@ static int parse_pair(JSONParserContext *ctxt, QDict *dict, va_list *ap)
goto out;
}
- key = parse_value(ctxt, ap);
+ key = parse_value(ctxt);
if (!key || qobject_type(key) != QTYPE_QSTRING) {
parse_error(ctxt, peek, "key is not a string in object");
goto out;
@@ -296,7 +296,7 @@ static int parse_pair(JSONParserContext *ctxt, QDict *dict, va_list *ap)
goto out;
}
- value = parse_value(ctxt, ap);
+ value = parse_value(ctxt);
if (value == NULL) {
parse_error(ctxt, token, "Missing value in dict");
goto out;
@@ -314,7 +314,7 @@ out:
return -1;
}
-static QObject *parse_object(JSONParserContext *ctxt, va_list *ap)
+static QObject *parse_object(JSONParserContext *ctxt)
{
QDict *dict = NULL;
JSONToken *token, *peek;
@@ -331,7 +331,7 @@ static QObject *parse_object(JSONParserContext *ctxt, va_list *ap)
}
if (peek->type != JSON_RCURLY) {
- if (parse_pair(ctxt, dict, ap) == -1) {
+ if (parse_pair(ctxt, dict) == -1) {
goto out;
}
@@ -347,7 +347,7 @@ static QObject *parse_object(JSONParserContext *ctxt, va_list *ap)
goto out;
}
- if (parse_pair(ctxt, dict, ap) == -1) {
+ if (parse_pair(ctxt, dict) == -1) {
goto out;
}
@@ -368,7 +368,7 @@ out:
return NULL;
}
-static QObject *parse_array(JSONParserContext *ctxt, va_list *ap)
+static QObject *parse_array(JSONParserContext *ctxt)
{
QList *list = NULL;
JSONToken *token, *peek;
@@ -387,7 +387,7 @@ static QObject *parse_array(JSONParserContext *ctxt, va_list *ap)
if (peek->type != JSON_RSQUARE) {
QObject *obj;
- obj = parse_value(ctxt, ap);
+ obj = parse_value(ctxt);
if (obj == NULL) {
parse_error(ctxt, token, "expecting value");
goto out;
@@ -407,7 +407,7 @@ static QObject *parse_array(JSONParserContext *ctxt, va_list *ap)
goto out;
}
- obj = parse_value(ctxt, ap);
+ obj = parse_value(ctxt);
if (obj == NULL) {
parse_error(ctxt, token, "expecting value");
goto out;
@@ -492,7 +492,7 @@ static QObject *parse_literal(JSONParserContext *ctxt)
}
}
-static QObject *parse_value(JSONParserContext *ctxt, va_list *ap)
+static QObject *parse_value(JSONParserContext *ctxt)
{
JSONToken *token;
@@ -504,9 +504,9 @@ static QObject *parse_value(JSONParserContext *ctxt, va_list *ap)
switch (token->type) {
case JSON_LCURLY:
- return parse_object(ctxt, ap);
+ return parse_object(ctxt);
case JSON_LSQUARE:
- return parse_array(ctxt, ap);
+ return parse_array(ctxt);
case JSON_INTEGER:
case JSON_FLOAT:
case JSON_STRING:
@@ -519,12 +519,12 @@ static QObject *parse_value(JSONParserContext *ctxt, va_list *ap)
}
}
-QObject *json_parser_parse(GQueue *tokens, va_list *ap)
+QObject *json_parser_parse(GQueue *tokens)
{
- return json_parser_parse_err(tokens, ap, NULL);
+ return json_parser_parse_err(tokens, NULL);
}
-QObject *json_parser_parse_err(GQueue *tokens, va_list *ap, Error **errp)
+QObject *json_parser_parse_err(GQueue *tokens, Error **errp)
{
JSONParserContext *ctxt = parser_context_new(tokens);
QObject *result;
@@ -533,7 +533,7 @@ QObject *json_parser_parse_err(GQueue *tokens, va_list *ap, Error **errp)
return NULL;
}
- result = parse_value(ctxt, ap);
+ result = parse_value(ctxt);
error_propagate(errp, ctxt->err);
diff --git a/qobject/qjson.c b/qobject/qjson.c
index f0ab6df..dcfdd88 100644
--- a/qobject/qjson.c
+++ b/qobject/qjson.c
@@ -28,7 +28,7 @@ typedef struct JSONParsingState
static void parse_json(JSONMessageParser *parser, GQueue *tokens)
{
JSONParsingState *s = container_of(parser, JSONParsingState, parser);
- s->result = json_parser_parse(tokens, NULL);
+ s->result = json_parser_parse(tokens);
}
QObject *qobject_from_json(const char *string)
diff --git a/tests/libqtest.c b/tests/libqtest.c
index a9559d8..6432da3 100644
--- a/tests/libqtest.c
+++ b/tests/libqtest.c
@@ -373,7 +373,7 @@ static void qmp_response(JSONMessageParser *parser, GQueue *tokens)
QMPResponseParser *qmp = container_of(parser, QMPResponseParser, parser);
QObject *obj;
- obj = json_parser_parse(tokens, NULL);
+ obj = json_parser_parse(tokens);
if (!obj) {
fprintf(stderr, "QMP JSON response parsing failed\n");
exit(1);
--
2.7.4
^ permalink raw reply related [flat|nested] 45+ messages in thread
* Re: [Qemu-devel] [PATCH 00/36] Rip out dynamic JSON parsing
2016-11-30 19:44 [Qemu-devel] [PATCH 00/36] Rip out dynamic JSON parsing Eric Blake
` (35 preceding siblings ...)
2016-11-30 19:44 ` [Qemu-devel] [PATCH 36/36] qapi: Rip out dynamic JSON parser backend Eric Blake
@ 2016-11-30 19:50 ` Eric Blake
2016-11-30 20:42 ` Paolo Bonzini
36 siblings, 1 reply; 45+ messages in thread
From: Eric Blake @ 2016-11-30 19:50 UTC (permalink / raw)
To: qemu-devel; +Cc: pbonzini, armbru
[-- Attachment #1: Type: text/plain, Size: 548 bytes --]
On 11/30/2016 01:44 PM, Eric Blake wrote:
> Followup series to conversation about PRId64 and MacOS:
> https://lists.gnu.org/archive/html/qemu-devel/2016-11/msg04226.html
>
And I meant to add:
Available as a tag at:
git fetch git://repo.or.cz/qemu/ericb.git qapi-dynamic-json-v1
on top of Markus' qapi-next branch (but presumably will apply without
much effort on top of the final 2.8 release, since this is 2.9 material)
--
Eric Blake eblake redhat com +1-919-301-3266
Libvirt virtualization library http://libvirt.org
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 604 bytes --]
^ permalink raw reply [flat|nested] 45+ messages in thread
* Re: [Qemu-devel] [PATCH 00/36] Rip out dynamic JSON parsing
2016-11-30 19:50 ` [Qemu-devel] [PATCH 00/36] Rip out dynamic JSON parsing Eric Blake
@ 2016-11-30 20:42 ` Paolo Bonzini
0 siblings, 0 replies; 45+ messages in thread
From: Paolo Bonzini @ 2016-11-30 20:42 UTC (permalink / raw)
To: Eric Blake; +Cc: qemu-devel, armbru
----- Original Message -----
> From: "Eric Blake" <eblake@redhat.com>
> To: qemu-devel@nongnu.org
> Cc: pbonzini@redhat.com, armbru@redhat.com
> Sent: Wednesday, November 30, 2016 8:50:05 PM
> Subject: Re: [Qemu-devel] [PATCH 00/36] Rip out dynamic JSON parsing
>
> On 11/30/2016 01:44 PM, Eric Blake wrote:
> > Followup series to conversation about PRId64 and MacOS:
> > https://lists.gnu.org/archive/html/qemu-devel/2016-11/msg04226.html
> >
>
> And I meant to add:
>
> Available as a tag at:
> git fetch git://repo.or.cz/qemu/ericb.git qapi-dynamic-json-v1
>
> on top of Markus' qapi-next branch (but presumably will apply without
> much effort on top of the final 2.8 release, since this is 2.9 material)
I don't see the point, honestly. It's harder to use and hardly
removes any code (the balance is -160 lines, but about 140 of them
come from the parser's test suite).
Using the functionality only in qtest is fine, but it is damn useful
there. If we want to remove the % escaping, let's rewrite the qtests
in Python as they probably should have been since the beginning.
Paolo
^ permalink raw reply [flat|nested] 45+ messages in thread
* Re: [Qemu-devel] [PATCH 07/36] fdc-test: Avoid deprecated 'change' command
2016-11-30 19:44 ` [Qemu-devel] [PATCH 07/36] fdc-test: Avoid deprecated 'change' command Eric Blake
@ 2016-11-30 20:58 ` John Snow
0 siblings, 0 replies; 45+ messages in thread
From: John Snow @ 2016-11-30 20:58 UTC (permalink / raw)
To: Eric Blake, qemu-devel; +Cc: pbonzini, armbru, open list:Floppy
On 11/30/2016 02:44 PM, Eric Blake wrote:
> Use the preferred blockdev-change-medium command instead.
>
> Signed-off-by: Eric Blake <eblake@redhat.com>
> ---
> tests/fdc-test.c | 5 +++--
> 1 file changed, 3 insertions(+), 2 deletions(-)
>
> diff --git a/tests/fdc-test.c b/tests/fdc-test.c
> index 738c6b4..f5ff68d 100644
> --- a/tests/fdc-test.c
> +++ b/tests/fdc-test.c
> @@ -298,8 +298,9 @@ static void test_media_insert(void)
>
> /* Insert media in drive. DSKCHK should not be reset until a step pulse
> * is sent. */
> - qmp_discard_response("{'execute':'change', 'arguments':{"
> - " 'device':'floppy0', 'target': %s, 'arg': 'raw' }}",
> + qmp_discard_response("{'execute':'blockdev-change-medium', 'arguments':{"
> + " 'device':'floppy0', 'filename': %s, "
> + "'format': 'raw' }}",
> test_image);
>
> dir = inb(FLOPPY_BASE + reg_dir);
>
Sure, why not?
Reviewed-by: John Snow <jsnow@redhat.com>
^ permalink raw reply [flat|nested] 45+ messages in thread
* Re: [Qemu-devel] [PATCH 17/36] qtest: Avoid dynamic JSON in ahci-test
2016-11-30 19:44 ` [Qemu-devel] [PATCH 17/36] qtest: Avoid dynamic JSON in ahci-test Eric Blake
@ 2016-11-30 21:02 ` John Snow
2016-11-30 21:19 ` Eric Blake
0 siblings, 1 reply; 45+ messages in thread
From: John Snow @ 2016-11-30 21:02 UTC (permalink / raw)
To: Eric Blake, qemu-devel; +Cc: pbonzini, armbru, open list:IDE
On 11/30/2016 02:44 PM, Eric Blake wrote:
> As argued elsewhere, it's less code to maintain if we convert
> from a dynamic string passed to qobject_from_jsonv() to instead
> use a hand-built QDict.
>
> Rather than build up a QDict by manual qdict_put*() calls, we
> can let QAPI do the work for us. The result is more lines of
> code to initialize the QAPI struct, but the result will force us
> to track any changes to the qapi (whereas the dynamic JSON string
> would not detect qapi changes until runtime).
>
Benefit of doubt that you're right.
> Signed-off-by: Eric Blake <eblake@redhat.com>
> ---
> tests/ahci-test.c | 26 +++++++++++++++++++++-----
> 1 file changed, 21 insertions(+), 5 deletions(-)
>
> diff --git a/tests/ahci-test.c b/tests/ahci-test.c
> index ef17629..dfa9c52 100644
> --- a/tests/ahci-test.c
> +++ b/tests/ahci-test.c
> @@ -32,6 +32,8 @@
>
> #include "qemu-common.h"
> #include "qemu/host-utils.h"
> +#include "qapi/qmp/qjson.h"
> +#include "qapi/qobject-output-visitor.h"
>
> #include "hw/pci/pci_ids.h"
> #include "hw/pci/pci_regs.h"
> @@ -1576,6 +1578,7 @@ static void test_atapi_tray(void)
> uint8_t port, sense, asc;
> uint64_t iso_size = ATAPI_SECTOR_SIZE;
> QDict *rsp;
> + QObject *args;
>
> fd = prepare_iso(iso_size, &tx, &iso);
> ahci = ahci_boot_and_enable("-drive if=none,id=drive0,file=%s,format=raw "
> @@ -1607,11 +1610,24 @@ static void test_atapi_tray(void)
> atapi_wait_tray(true);
>
> /* Re-insert media */
> - qmp_discard_response("{'execute': 'blockdev-add', "
> - "'arguments': {'node-name': 'node0', "
> - "'driver': 'raw', "
> - "'file': { 'driver': 'file', "
> - "'filename': %s }}}", iso);
> + {
> + BlockdevRef ref = {
> + .type = QTYPE_QDICT,
> + .u.definition = {
> + .driver = BLOCKDEV_DRIVER_FILE,
> + .u.file.filename = iso,
> + },
> + };
> + BlockdevOptions opts = {
> + .has_node_name = true,
> + .node_name = (char *)"node0",
> + .driver = BLOCKDEV_DRIVER_RAW,
> + .u.raw.file = &ref,
> + };
> + args = QAPI_TO_QOBJECT(BlockdevOptions, &opts, &error_abort);
> + }
> +
> + qmp_cmd_discard_response("blockdev-add", qobject_to_qdict(args));
> qmp_discard_response("{'execute': 'x-blockdev-insert-medium',"
> "'arguments': { 'device': 'drive0', "
> "'node-name': 'node0' }}");
>
I assume qmp_cmd_discard_response takes ownership of the object we just
built?
Assuming yes:
Reviewed-by: John Snow <jsnow@redhat.com>
^ permalink raw reply [flat|nested] 45+ messages in thread
* Re: [Qemu-devel] [PATCH 18/36] qtest: Avoid dynamic JSON in fdc-test
2016-11-30 19:44 ` [Qemu-devel] [PATCH 18/36] qtest: Avoid dynamic JSON in fdc-test Eric Blake
@ 2016-11-30 21:14 ` John Snow
0 siblings, 0 replies; 45+ messages in thread
From: John Snow @ 2016-11-30 21:14 UTC (permalink / raw)
To: Eric Blake, qemu-devel; +Cc: pbonzini, armbru, open list:Floppy
On 11/30/2016 02:44 PM, Eric Blake wrote:
> As argued elsewhere, it's less code to maintain if we convert
> from a dynamic string passed to qobject_from_jsonv() to instead
> use a hand-built QDict.
>
> Rather than build up a QDict by manual qdict_put*() calls, we
> can let QAPI do the work for us. The result is more lines of
> code to initialize the QAPI struct, but the result will force us
> to track any changes to the qapi (whereas the dynamic JSON string
> would not detect qapi changes until runtime).
>
> Signed-off-by: Eric Blake <eblake@redhat.com>
> ---
> tests/fdc-test.c | 16 ++++++++++++----
> 1 file changed, 12 insertions(+), 4 deletions(-)
>
> diff --git a/tests/fdc-test.c b/tests/fdc-test.c
> index f5ff68d..ac75e87 100644
> --- a/tests/fdc-test.c
> +++ b/tests/fdc-test.c
> @@ -27,6 +27,8 @@
>
> #include "libqtest.h"
> #include "qemu-common.h"
> +#include "qapi/qmp/qjson.h"
> +#include "qapi/qobject-output-visitor.h"
>
> #define TEST_IMAGE_SIZE 1440 * 1024
>
> @@ -295,13 +297,19 @@ static void test_read_without_media(void)
> static void test_media_insert(void)
> {
> uint8_t dir;
> + QObject *args;
> + BlockdevChangeMedium bcm = {
> + .has_device = true,
> + .device = (char *)"floppy0",
> + .filename = test_image,
> + .has_format = true,
> + .format = (char *)"raw",
> + };
>
> /* Insert media in drive. DSKCHK should not be reset until a step pulse
> * is sent. */
> - qmp_discard_response("{'execute':'blockdev-change-medium', 'arguments':{"
> - " 'device':'floppy0', 'filename': %s, "
> - "'format': 'raw' }}",
> - test_image);
> + args = QAPI_TO_QOBJECT(BlockdevChangeMedium, &bcm, &error_abort);
> + qmp_cmd_discard_response("blockdev-change-medium", qobject_to_qdict(args));
>
> dir = inb(FLOPPY_BASE + reg_dir);
> assert_bit_set(dir, DSKCHG);
>
Same statement as on #17:
Reviewed-by: John Snow <jsnow@redhat.com>
^ permalink raw reply [flat|nested] 45+ messages in thread
* Re: [Qemu-devel] [PATCH 01/36] pci: Use struct instead of QDict to pass back parameters
2016-11-30 19:44 ` [Qemu-devel] [PATCH 01/36] pci: Use struct instead of QDict to pass back parameters Eric Blake
@ 2016-11-30 21:15 ` Michael S. Tsirkin
0 siblings, 0 replies; 45+ messages in thread
From: Michael S. Tsirkin @ 2016-11-30 21:15 UTC (permalink / raw)
To: Eric Blake; +Cc: qemu-devel, armbru, pbonzini, Marcel Apfelbaum
On Wed, Nov 30, 2016 at 01:44:19PM -0600, Eric Blake wrote:
> It's simpler to just use a C struct than it is to bundle things
> into a QDict in one function just to pull them back out in the
> caller. Plus, doing this gets rid of one more user of dynamic
> JSON through qobject_from_jsonf().
>
> Signed-off-by: Eric Blake <eblake@redhat.com>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
> ---
> hw/pci/pcie_aer.c | 36 +++++++++++++++++-------------------
> 1 file changed, 17 insertions(+), 19 deletions(-)
>
> diff --git a/hw/pci/pcie_aer.c b/hw/pci/pcie_aer.c
> index 048ce6a..0735796 100644
> --- a/hw/pci/pcie_aer.c
> +++ b/hw/pci/pcie_aer.c
> @@ -43,6 +43,13 @@
> #define PCI_ERR_SRC_COR_OFFS 0
> #define PCI_ERR_SRC_UNCOR_OFFS 2
>
> +typedef struct PCIEErrorInject {
> + const char *id;
> + const char *root_bus;
> + int bus;
> + int devfn;
> +} PCIEErrorInject;
> +
> /* From 6.2.7 Error Listing and Rules. Table 6-2, 6-3 and 6-4 */
> static uint32_t pcie_aer_uncor_default_severity(uint32_t status)
> {
> @@ -946,7 +953,8 @@ static int pcie_aer_parse_error_string(const char *error_name,
> }
>
> static int do_pcie_aer_inject_error(Monitor *mon,
> - const QDict *qdict, QObject **ret_data)
> + const QDict *qdict,
> + PCIEErrorInject *ret_data)
> {
> const char *id = qdict_get_str(qdict, "id");
> const char *error_name;
> @@ -1007,34 +1015,24 @@ static int do_pcie_aer_inject_error(Monitor *mon,
> err.prefix[2] = qdict_get_try_int(qdict, "prefix2", 0);
> err.prefix[3] = qdict_get_try_int(qdict, "prefix3", 0);
>
> - ret = pcie_aer_inject_error(dev, &err);
> - *ret_data = qobject_from_jsonf("{'id': %s, "
> - "'root_bus': %s, 'bus': %d, 'devfn': %d, "
> - "'ret': %d}",
> - id, pci_root_bus_path(dev),
> - pci_bus_num(dev->bus), dev->devfn,
> - ret);
> - assert(*ret_data);
> + pcie_aer_inject_error(dev, &err);
> + ret_data->id = id;
> + ret_data->root_bus = pci_root_bus_path(dev);
> + ret_data->bus = pci_bus_num(dev->bus);
> + ret_data->devfn = dev->devfn;
>
> return 0;
> }
>
> void hmp_pcie_aer_inject_error(Monitor *mon, const QDict *qdict)
> {
> - QObject *data;
> - int devfn;
> + PCIEErrorInject data;
>
> if (do_pcie_aer_inject_error(mon, qdict, &data) < 0) {
> return;
> }
>
> - assert(qobject_type(data) == QTYPE_QDICT);
> - qdict = qobject_to_qdict(data);
> -
> - devfn = (int)qdict_get_int(qdict, "devfn");
> monitor_printf(mon, "OK id: %s root bus: %s, bus: %x devfn: %x.%x\n",
> - qdict_get_str(qdict, "id"),
> - qdict_get_str(qdict, "root_bus"),
> - (int) qdict_get_int(qdict, "bus"),
> - PCI_SLOT(devfn), PCI_FUNC(devfn));
> + data.id, data.root_bus, data.bus,
> + PCI_SLOT(data.devfn), PCI_FUNC(data.devfn));
> }
> --
> 2.7.4
^ permalink raw reply [flat|nested] 45+ messages in thread
* Re: [Qemu-devel] [PATCH 17/36] qtest: Avoid dynamic JSON in ahci-test
2016-11-30 21:02 ` John Snow
@ 2016-11-30 21:19 ` Eric Blake
0 siblings, 0 replies; 45+ messages in thread
From: Eric Blake @ 2016-11-30 21:19 UTC (permalink / raw)
To: John Snow, qemu-devel; +Cc: pbonzini, armbru, open list:IDE
[-- Attachment #1: Type: text/plain, Size: 1867 bytes --]
On 11/30/2016 03:02 PM, John Snow wrote:
>
>
> On 11/30/2016 02:44 PM, Eric Blake wrote:
>> As argued elsewhere, it's less code to maintain if we convert
>> from a dynamic string passed to qobject_from_jsonv() to instead
>> use a hand-built QDict.
>>
>> Rather than build up a QDict by manual qdict_put*() calls, we
>> can let QAPI do the work for us. The result is more lines of
>> code to initialize the QAPI struct, but the result will force us
>> to track any changes to the qapi (whereas the dynamic JSON string
>> would not detect qapi changes until runtime).
>>
>
> Benefit of doubt that you're right.
>
>> Signed-off-by: Eric Blake <eblake@redhat.com>
>> ---
>> tests/ahci-test.c | 26 +++++++++++++++++++++-----
>> 1 file changed, 21 insertions(+), 5 deletions(-)
>> + args = QAPI_TO_QOBJECT(BlockdevOptions, &opts, &error_abort);
>> + }
>> +
>> + qmp_cmd_discard_response("blockdev-add", qobject_to_qdict(args));
>> qmp_discard_response("{'execute': 'x-blockdev-insert-medium',"
>> "'arguments': { 'device': 'drive0', "
>> "'node-name': 'node0' }}");
>>
>
> I assume qmp_cmd_discard_response takes ownership of the object we just
> built?
Yes. I had to track that down myself, which is why in patch 9, I
documented it:
/**
+ * qmp_cmd_discard_response:
+ * @cmd: Command name to send
+ * @args: Arguments to transfer to the command, or NULL.
+ *
+ * Sends a QMP message to QEMU and consumes the response. Calling this will
+ * reduce the reference count of @args.
+ */
+void qmp_cmd_discard_response(const char *cmd, QDict *args);
>
> Assuming yes:
> Reviewed-by: John Snow <jsnow@redhat.com>
>
--
Eric Blake eblake redhat com +1-919-301-3266
Libvirt virtualization library http://libvirt.org
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 604 bytes --]
^ permalink raw reply [flat|nested] 45+ messages in thread
* Re: [Qemu-devel] [PATCH 02/36] qdict: Add convenience helpers for wrapped puts
2016-11-30 19:44 ` [Qemu-devel] [PATCH 02/36] qdict: Add convenience helpers for wrapped puts Eric Blake
@ 2016-12-09 14:06 ` Alberto Garcia
0 siblings, 0 replies; 45+ messages in thread
From: Alberto Garcia @ 2016-12-09 14:06 UTC (permalink / raw)
To: Eric Blake, qemu-devel
Cc: armbru, pbonzini, Kevin Wolf, Max Reitz, Chrysostomos Nanakos,
Jeff Cody, Stefan Hajnoczi, Ronnie Sahlberg, Peter Lieven,
Fam Zheng, Stefan Weil, Richard W.M. Jones, Stefano Stabellini,
Anthony Perard, Gerd Hoffmann, Dr. David Alan Gilbert,
Michael Roth, Richard Henderson, Alexander Graf,
open list:Block layer core, open list:X86
On Wed 30 Nov 2016 08:44:20 PM CET, Eric Blake wrote:
> Quite a few users of qdict_put() were manually wrapping a
> non-QObject. We can make such call-sites shorter, by providing
> common macros to do the tedious work. Also shorten nearby
> qdict_put_obj(,,QOBJECT()) sequences.
>
> Signed-off-by: Eric Blake <eblake@redhat.com>
Thanks, the code looks much better now :)
Reviewed-by: Alberto Garcia <berto@igalia.com>
Berto
^ permalink raw reply [flat|nested] 45+ messages in thread
end of thread, other threads:[~2016-12-09 14:07 UTC | newest]
Thread overview: 45+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-11-30 19:44 [Qemu-devel] [PATCH 00/36] Rip out dynamic JSON parsing Eric Blake
2016-11-30 19:44 ` [Qemu-devel] [PATCH 01/36] pci: Use struct instead of QDict to pass back parameters Eric Blake
2016-11-30 21:15 ` Michael S. Tsirkin
2016-11-30 19:44 ` [Qemu-devel] [PATCH 02/36] qdict: Add convenience helpers for wrapped puts Eric Blake
2016-12-09 14:06 ` Alberto Garcia
2016-11-30 19:44 ` [Qemu-devel] [PATCH 03/36] qlist: Add convenience helpers for wrapped appends Eric Blake
2016-11-30 19:44 ` [Qemu-devel] [PATCH 04/36] qmp-event: Avoid dynamic JSON Eric Blake
2016-11-30 19:44 ` [Qemu-devel] [PATCH 05/36] qmp-dispatch: " Eric Blake
2016-11-30 19:44 ` [Qemu-devel] [PATCH 06/36] qobject-input-visitor: Avoid dynamic JSON in tests Eric Blake
2016-11-30 19:44 ` [Qemu-devel] [PATCH 07/36] fdc-test: Avoid deprecated 'change' command Eric Blake
2016-11-30 20:58 ` John Snow
2016-11-30 19:44 ` [Qemu-devel] [PATCH 08/36] test-qga: Actually test 0xff sync bytes Eric Blake
2016-11-30 19:44 ` [Qemu-devel] [PATCH 09/36] qtest: Add a new helper qmp_cmd() and friends Eric Blake
2016-11-30 19:44 ` [Qemu-devel] [PATCH 10/36] qtest: Avoid dynamic JSON in libqtest Eric Blake
2016-11-30 19:44 ` [Qemu-devel] [PATCH 11/36] qapi: Add QAPI_TO_QOBJECT() convenience macro Eric Blake
2016-11-30 19:44 ` [Qemu-devel] [PATCH 12/36] nbd: Use simpler QAPI_TO_QOBJECT() Eric Blake
2016-11-30 19:44 ` [Qemu-devel] [PATCH 13/36] nfs: " Eric Blake
2016-11-30 19:44 ` [Qemu-devel] [PATCH 14/36] qapi: " Eric Blake
2016-11-30 19:44 ` [Qemu-devel] [PATCH 15/36] blockdev: " Eric Blake
2016-11-30 19:44 ` [Qemu-devel] [PATCH 16/36] qapi: Promote blockdev-change-medium arguments to QAPI type Eric Blake
2016-11-30 19:44 ` [Qemu-devel] [PATCH 17/36] qtest: Avoid dynamic JSON in ahci-test Eric Blake
2016-11-30 21:02 ` John Snow
2016-11-30 21:19 ` Eric Blake
2016-11-30 19:44 ` [Qemu-devel] [PATCH 18/36] qtest: Avoid dynamic JSON in fdc-test Eric Blake
2016-11-30 21:14 ` John Snow
2016-11-30 19:44 ` [Qemu-devel] [PATCH 19/36] qtest: Change qmp_discard_response() to drop varargs Eric Blake
2016-11-30 19:44 ` [Qemu-devel] [PATCH 20/36] qtest: Avoid dynamic JSON in device-introspect-test Eric Blake
2016-11-30 19:44 ` [Qemu-devel] [PATCH 21/36] qtest: Avoid dynamic JSON in tmp105-test Eric Blake
2016-11-30 19:44 ` [Qemu-devel] [PATCH 22/36] qtest: Avoid dynamic JSON in pc-cpu-test Eric Blake
2016-11-30 19:44 ` [Qemu-devel] [PATCH 23/36] qtest: Avoid dynamic JSON in virtio-blk-test Eric Blake
2016-11-30 19:44 ` [Qemu-devel] [PATCH 24/36] qtest: Drop unused qmp_fdv() Eric Blake
2016-11-30 19:44 ` [Qemu-devel] [PATCH 25/36] qtest: Change qmp_fd_send() to drop varags Eric Blake
2016-11-30 19:44 ` [Qemu-devel] [PATCH 26/36] qtest: Drop unused qtest_qmp_async() Eric Blake
2016-11-30 19:44 ` [Qemu-devel] [PATCH 27/36] qtest: Avoid dynamic JSON in qmp_cmd() Eric Blake
2016-11-30 19:44 ` [Qemu-devel] [PATCH 28/36] qapi: Factor out JSON string escaping Eric Blake
2016-11-30 19:44 ` [Qemu-devel] [PATCH 29/36] qapi: Add qstring_append_printf() Eric Blake
2016-11-30 19:44 ` [Qemu-devel] [PATCH 30/36] qtest: Avoid dynamic JSON in qmp_fd_sendv() Eric Blake
2016-11-30 19:44 ` [Qemu-devel] [PATCH 31/36] qtest: Document calling conventions Eric Blake
2016-11-30 19:44 ` [Qemu-devel] [PATCH 32/36] qtest: Avoid dynamic JSON in qom-test Eric Blake
2016-11-30 19:44 ` [Qemu-devel] [PATCH 33/36] qtest: Avoid dynamic JSON in test-x86-cpuid-compat Eric Blake
2016-11-30 19:44 ` [Qemu-devel] [PATCH 34/36] qapi: Rip out dynamic JSON parser frontend Eric Blake
2016-11-30 19:44 ` [Qemu-devel] [PATCH 35/36] qapi: Rip out dynamic JSON parser escape sequence support Eric Blake
2016-11-30 19:44 ` [Qemu-devel] [PATCH 36/36] qapi: Rip out dynamic JSON parser backend Eric Blake
2016-11-30 19:50 ` [Qemu-devel] [PATCH 00/36] Rip out dynamic JSON parsing Eric Blake
2016-11-30 20:42 ` Paolo Bonzini
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).