@@ -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)
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(-)