Signed-off-by: Peter Krempa <pkrempa(a)redhat.com>
---
src/qemu/qemu_qapi.c | 34 ++++++++++++++++++++++++++++++++--
tests/qemumonitorjsontest.c | 3 +++
2 files changed, 35 insertions(+), 2 deletions(-)
diff --git a/src/qemu/qemu_qapi.c b/src/qemu/qemu_qapi.c
index d401e9a303..4ed67b68bc 100644
--- a/src/qemu/qemu_qapi.c
+++ b/src/qemu/qemu_qapi.c
@@ -228,6 +228,35 @@ virQEMUQAPISchemaTraverseBuiltin(virJSONValuePtr cur,
}
+static int
+virQEMUQAPISchemaTraverseAlternate(virJSONValuePtr cur,
+ struct virQEMUQAPISchemaTraverseContext *ctxt)
+{
+ struct virQEMUQAPISchemaTraverseContext savectxt = *ctxt;
+ virJSONValuePtr members;
+ virJSONValuePtr member;
+ const char *membertype;
+ int rc;
+ size_t i;
+
+ if (!(members = virJSONValueObjectGetArray(cur, "members")))
+ return -2;
+
+ for (i = 0; i < virJSONValueArraySize(members); i++) {
+ if (!(member = virJSONValueArrayGet(members, i)) ||
+ !(membertype = virJSONValueObjectGetString(member, "type")))
+ continue;
+
+ *ctxt = savectxt;
+
+ if ((rc = virQEMUQAPISchemaTraverse(membertype, ctxt)) != 0)
+ return rc;
+ }
+
+ return 0;
+}
+
+
/* The function must return 1 on successful query, 0 if the query was not found
* -1 when a libvirt error is reported, -2 if the schema is invalid and -3 if
* the query component is malformed. */
@@ -247,6 +276,7 @@ static const struct virQEMUQAPISchemaTraverseMetaType
traverseMetaType[] = {
{ "event", virQEMUQAPISchemaTraverseCommand },
{ "enum", virQEMUQAPISchemaTraverseEnum },
{ "builtin", virQEMUQAPISchemaTraverseBuiltin },
+ { "alternate", virQEMUQAPISchemaTraverseAlternate },
};
@@ -313,8 +343,8 @@ virQEMUQAPISchemaTraverse(const char *baseName,
* If the name of any (sub)attribute starts with non-alphabetical symbols it
* needs to be prefixed by a single space.
*
- * Array types are automatically flattened to the singular type. Alternate
- * types are currently not supported.
+ * Array types are automatically flattened to the singular type. Alternates are
+ * iterated until first success.
*
* The above types can be chained arbitrarily using slashes to construct any
* path into the schema tree, booleans must be always the last component as they
diff --git a/tests/qemumonitorjsontest.c b/tests/qemumonitorjsontest.c
index ece42aee0b..a25c0ff55b 100644
--- a/tests/qemumonitorjsontest.c
+++ b/tests/qemumonitorjsontest.c
@@ -3095,6 +3095,9 @@ mymain(void)
DO_TEST_QAPI_QUERY("variant property",
"blockdev-add/arg-type/+file/filename", 1, true);
DO_TEST_QAPI_QUERY("enum value",
"query-status/ret-type/status/^debug", 1, false);
DO_TEST_QAPI_QUERY("builtin type",
"query-qmp-schema/ret-type/name/!string", 1, false);
+ DO_TEST_QAPI_QUERY("alternate variant 1",
"blockdev-add/arg-type/+qcow2/backing/!null", 1, false);
+ DO_TEST_QAPI_QUERY("alternate variant 2",
"blockdev-add/arg-type/+qcow2/backing/!string", 1, false);
+ DO_TEST_QAPI_QUERY("alternate variant 3",
"blockdev-add/arg-type/+qcow2/backing/+file/filename", 1, true);
DO_TEST_QAPI_QUERY("nonexistent command", "nonexistent", 0,
false);
DO_TEST_QAPI_QUERY("nonexistent attr",
"screendump/arg-type/nonexistent", 0, false);
--
2.20.1