Signed-off-by: Peter Krempa <pkrempa(a)redhat.com>
---
src/qemu/qemu_qapi.c | 42 ++++++++++++++++++++++++++++++++++++-
tests/qemumonitorjsontest.c | 3 +++
2 files changed, 44 insertions(+), 1 deletion(-)
diff --git a/src/qemu/qemu_qapi.c b/src/qemu/qemu_qapi.c
index f17a162434..8a695e022d 100644
--- a/src/qemu/qemu_qapi.c
+++ b/src/qemu/qemu_qapi.c
@@ -120,6 +120,10 @@ virQEMUQAPISchemaTraverseObject(virJSONValuePtr cur,
if (!c_isalpha(modifier))
query++;
+ /* exit on modifers for other types */
+ if (modifier == '^')
+ return 0;
+
if (modifier == '+') {
obj = virQEMUQAPISchemaObjectGet("variants", query, "case",
cur);
} else {
@@ -164,6 +168,41 @@ virQEMUQAPISchemaTraverseCommand(virJSONValuePtr cur,
return virQEMUQAPISchemaTraverse(querytype, ctxt);
}
+
+static int
+virQEMUQAPISchemaTraverseEnum(virJSONValuePtr cur,
+ struct virQEMUQAPISchemaTraverseContext *ctxt)
+{
+ const char *query = virQEMUQAPISchemaTraverseContextNextQuery(ctxt);
+ virJSONValuePtr values;
+ virJSONValuePtr enumval;
+ const char *value;
+ size_t i;
+
+ if (query[0] != '^')
+ return 0;
+
+ if (virQEMUQAPISchemaTraverseContextHasNextQuery(ctxt))
+ return -3;
+
+ query++;
+
+ if (!(values = virJSONValueObjectGetArray(cur, "values")))
+ return -2;
+
+ for (i = 0; i < virJSONValueArraySize(values); i++) {
+ if (!(enumval = virJSONValueArrayGet(values, i)) ||
+ !(value = virJSONValueGetString(enumval)))
+ continue;
+
+ if (STREQ(value, query))
+ return 1;
+ }
+
+ 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. */
@@ -181,6 +220,7 @@ static const struct virQEMUQAPISchemaTraverseMetaType
traverseMetaType[] = {
{ "array", virQEMUQAPISchemaTraverseArray },
{ "command", virQEMUQAPISchemaTraverseCommand },
{ "event", virQEMUQAPISchemaTraverseCommand },
+ { "enum", virQEMUQAPISchemaTraverseEnum },
};
@@ -239,7 +279,7 @@ virQEMUQAPISchemaTraverse(const char *baseName,
* the prevously selected member
*
* - Boolean queries - @entry remains NULL, return value indicates success:
- * (none)
+ * '^enumval': returns true if the previously selected enum contains
'enumval'
*
* If the name of any (sub)attribute starts with non-alphabetical symbols it
* needs to be prefixed by a single space.
diff --git a/tests/qemumonitorjsontest.c b/tests/qemumonitorjsontest.c
index 339ee20b29..1c8ecead98 100644
--- a/tests/qemumonitorjsontest.c
+++ b/tests/qemumonitorjsontest.c
@@ -3093,10 +3093,13 @@ mymain(void)
DO_TEST_QAPI_QUERY("optional property",
"block-commit/arg-type/*top", 1, true);
DO_TEST_QAPI_QUERY("variant", "blockdev-add/arg-type/+file", 1,
true);
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("nonexistent command", "nonexistent", 0,
false);
DO_TEST_QAPI_QUERY("nonexistent attr",
"screendump/arg-type/nonexistent", 0, false);
DO_TEST_QAPI_QUERY("nonexistent variant",
"blockdev-add/arg-type/+nonexistent", 0, false);
+ DO_TEST_QAPI_QUERY("nonexistent enum value",
"query-status/ret-type/status/^nonexistentdebug", 0, false);
+ DO_TEST_QAPI_QUERY("broken query for enum value",
"query-status/ret-type/status/^debug/test", -1, false);
#undef DO_TEST_QAPI_QUERY
--
2.20.1