[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 30/36] qtest: Avoid dynamic JSON in qmp_fd_sendv()
From: |
Eric Blake |
Subject: |
[Qemu-devel] [PATCH 30/36] qtest: Avoid dynamic JSON in qmp_fd_sendv() |
Date: |
Wed, 30 Nov 2016 13:44:48 -0600 |
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 <address@hidden>
---
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
- [Qemu-devel] [PATCH 31/36] qtest: Document calling conventions, (continued)
- [Qemu-devel] [PATCH 31/36] qtest: Document calling conventions, Eric Blake, 2016/11/30
- [Qemu-devel] [PATCH 15/36] blockdev: Use simpler QAPI_TO_QOBJECT(), Eric Blake, 2016/11/30
- [Qemu-devel] [PATCH 34/36] qapi: Rip out dynamic JSON parser frontend, Eric Blake, 2016/11/30
- [Qemu-devel] [PATCH 32/36] qtest: Avoid dynamic JSON in qom-test, Eric Blake, 2016/11/30
- [Qemu-devel] [PATCH 17/36] qtest: Avoid dynamic JSON in ahci-test, Eric Blake, 2016/11/30
- [Qemu-devel] [PATCH 36/36] qapi: Rip out dynamic JSON parser backend, Eric Blake, 2016/11/30
- [Qemu-devel] [PATCH 02/36] qdict: Add convenience helpers for wrapped puts, Eric Blake, 2016/11/30
- [Qemu-devel] [PATCH 23/36] qtest: Avoid dynamic JSON in virtio-blk-test, Eric Blake, 2016/11/30
- [Qemu-devel] [PATCH 30/36] qtest: Avoid dynamic JSON in qmp_fd_sendv(),
Eric Blake <=
- [Qemu-devel] [PATCH 29/36] qapi: Add qstring_append_printf(), Eric Blake, 2016/11/30
- Re: [Qemu-devel] [PATCH 00/36] Rip out dynamic JSON parsing, Eric Blake, 2016/11/30