Signed-off-by: Peter Krempa <pkrempa@xxxxxxxxxx> --- 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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list