Extract the code into qemu_qapi.c/h so that we separate it from various parts of the code. Signed-off-by: Peter Krempa <pkrempa@xxxxxxxxxx> --- po/POTFILES.in | 1 + src/qemu/Makefile.inc.am | 2 + src/qemu/qemu_capabilities.c | 158 +----------------------------------- src/qemu/qemu_qapi.c | 187 +++++++++++++++++++++++++++++++++++++++++++ src/qemu/qemu_qapi.h | 36 +++++++++ 5 files changed, 227 insertions(+), 157 deletions(-) create mode 100644 src/qemu/qemu_qapi.c create mode 100644 src/qemu/qemu_qapi.h diff --git a/po/POTFILES.in b/po/POTFILES.in index 71c61dec95..d84859a4e3 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -141,6 +141,7 @@ src/qemu/qemu_monitor_json.c src/qemu/qemu_monitor_text.c src/qemu/qemu_parse_command.c src/qemu/qemu_process.c +src/qemu/qemu_qapi.c src/remote/remote_client_bodies.h src/remote/remote_daemon.c src/remote/remote_daemon_config.c diff --git a/src/qemu/Makefile.inc.am b/src/qemu/Makefile.inc.am index 2ad062cdb5..8ef290a6c1 100644 --- a/src/qemu/Makefile.inc.am +++ b/src/qemu/Makefile.inc.am @@ -46,6 +46,8 @@ QEMU_DRIVER_SOURCES = \ qemu/qemu_capspriv.h \ qemu/qemu_security.c \ qemu/qemu_security.h \ + qemu/qemu_qapi.c \ + qemu/qemu_qapi.h \ $(NULL) diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index 3eb5ed6d1a..7801c9b33c 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -46,6 +46,7 @@ #include "qemu_domain.h" #define __QEMU_CAPSPRIV_H_ALLOW__ #include "qemu_capspriv.h" +#include "qemu_qapi.h" #include <fcntl.h> #include <sys/stat.h> @@ -4564,163 +4565,6 @@ virQEMUCapsInitQMPBasicArch(virQEMUCapsPtr qemuCaps) } -/** - * virQEMUCapsQMPSchemaObjectGetType: - * @field: name of the object containing the requested type - * @name: name of the requested type - * @namefield: name of the object property holding @name - * - * Helper that selects the type of a QMP schema object member or it's variant - * member. Returns the type string on success or NULL on error. - */ -static const char * -virQEMUCapsQMPSchemaObjectGetType(const char *field, - const char *name, - const char *namefield, - virJSONValuePtr elem) -{ - virJSONValuePtr arr; - virJSONValuePtr cur; - const char *curname; - const char *type; - size_t i; - - if (!(arr = virJSONValueObjectGetArray(elem, field))) - return NULL; - - for (i = 0; i < virJSONValueArraySize(arr); i++) { - if (!(cur = virJSONValueArrayGet(arr, i)) || - !(curname = virJSONValueObjectGetString(cur, namefield)) || - !(type = virJSONValueObjectGetString(cur, "type"))) - continue; - - if (STREQ(name, curname)) - return type; - } - - return NULL; -} - - -static virJSONValuePtr -virQEMUCapsQMPSchemaTraverse(const char *baseName, - char **query, - virHashTablePtr schema) -{ - virJSONValuePtr base; - const char *metatype; - - do { - if (!(base = virHashLookup(schema, baseName))) - return NULL; - - if (!*query) - return base; - - if (!(metatype = virJSONValueObjectGetString(base, "meta-type"))) - return NULL; - - /* flatten arrays by default */ - if (STREQ(metatype, "array")) { - if (!(baseName = virJSONValueObjectGetString(base, "element-type"))) - return NULL; - - continue; - } else if (STREQ(metatype, "object")) { - if (**query == '+') - baseName = virQEMUCapsQMPSchemaObjectGetType("variants", - *query + 1, - "case", base); - else - baseName = virQEMUCapsQMPSchemaObjectGetType("members", - *query, - "name", base); - - if (!baseName) - return NULL; - } else if (STREQ(metatype, "command") || - STREQ(metatype, "event")) { - if (!(baseName = virJSONValueObjectGetString(base, *query))) - return NULL; - } else { - /* alternates, basic types and enums can't be entered */ - return NULL; - } - - query++; - } while (*query); - - return base; -} - - -/** - * virQEMUCapsQMPSchemaGetByPath: - * @query: string specifying the required data type (see below) - * @schema: hash table containing the schema data - * @entry: filled with the located schema object requested by @query - * - * Retrieves the requested schema entry specified by @query to @entry. The - * @query parameter has the following syntax which is very closely tied to the - * qemu schema syntax entries separated by slashes with a few special characters: - * - * "command_or_event/attribute/subattribute/+variant_discriminator/subattribute" - * - * command_or_event: name of the event or attribute to introspect - * attribute: selects whether arguments or return type should be introspected - * ("arg-type" or "ret-type" for commands, "arg-type" for events) - * subattribute: specifies member name of object types - * +variant_discriminator: In the case of unionized objects, select a - * specific case to introspect. - * - * Array types are automatically flattened to the singular type. Alternate - * types are currently not supported. - * - * The above types can be chained arbitrarily using slashes to construct any - * path into the schema tree. - * - * Returns 0 on success (including if the requested schema was not found) and - * fills @entry appropriately. On failure returns -1 and sets an appropriate - * error message. - */ -static int -virQEMUCapsQMPSchemaGetByPath(const char *query, - virHashTablePtr schema, - virJSONValuePtr *entry) -{ - char **elems = NULL; - - *entry = NULL; - - if (!(elems = virStringSplit(query, "/", 0))) - return -1; - - if (!*elems) { - virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("malformed query string")); - virStringListFree(elems); - return -1; - } - - *entry = virQEMUCapsQMPSchemaTraverse(*elems, elems + 1, schema); - - virStringListFree(elems); - return 0; -} - - -static bool -virQEMUCapsQMPSchemaQueryPath(const char *query, - virHashTablePtr schema) -{ - virJSONValuePtr entry; - - if (virQEMUCapsQMPSchemaGetByPath(query, schema, &entry)) - return false; - - return !!entry; -} - - static int virQEMUCapsProbeQMPSchemaCapabilities(virQEMUCapsPtr qemuCaps, qemuMonitorPtr mon) diff --git a/src/qemu/qemu_qapi.c b/src/qemu/qemu_qapi.c new file mode 100644 index 0000000000..2646afeee2 --- /dev/null +++ b/src/qemu/qemu_qapi.c @@ -0,0 +1,187 @@ +/* + * qemu_qapi.c: helper functions for QEMU QAPI schema handling + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * <http://www.gnu.org/licenses/>. + */ + +#include <config.h> + +#include "qemu_qapi.h" + +#include "viralloc.h" +#include "virstring.h" +#include "virerror.h" +#include "virlog.h" + +#define VIR_FROM_THIS VIR_FROM_QEMU + +VIR_LOG_INIT("qemu.qemu_qapi"); + + +/** + * virQEMUCapsQMPSchemaObjectGetType: + * @field: name of the object containing the requested type + * @name: name of the requested type + * @namefield: name of the object property holding @name + * + * Helper that selects the type of a QMP schema object member or it's variant + * member. Returns the type string on success or NULL on error. + */ +static const char * +virQEMUCapsQMPSchemaObjectGetType(const char *field, + const char *name, + const char *namefield, + virJSONValuePtr elem) +{ + virJSONValuePtr arr; + virJSONValuePtr cur; + const char *curname; + const char *type; + size_t i; + + if (!(arr = virJSONValueObjectGetArray(elem, field))) + return NULL; + + for (i = 0; i < virJSONValueArraySize(arr); i++) { + if (!(cur = virJSONValueArrayGet(arr, i)) || + !(curname = virJSONValueObjectGetString(cur, namefield)) || + !(type = virJSONValueObjectGetString(cur, "type"))) + continue; + + if (STREQ(name, curname)) + return type; + } + + return NULL; +} + + +static virJSONValuePtr +virQEMUCapsQMPSchemaTraverse(const char *baseName, + char **query, + virHashTablePtr schema) +{ + virJSONValuePtr base; + const char *metatype; + + do { + if (!(base = virHashLookup(schema, baseName))) + return NULL; + + if (!*query) + return base; + + if (!(metatype = virJSONValueObjectGetString(base, "meta-type"))) + return NULL; + + /* flatten arrays by default */ + if (STREQ(metatype, "array")) { + if (!(baseName = virJSONValueObjectGetString(base, "element-type"))) + return NULL; + + continue; + } else if (STREQ(metatype, "object")) { + if (**query == '+') + baseName = virQEMUCapsQMPSchemaObjectGetType("variants", + *query + 1, + "case", base); + else + baseName = virQEMUCapsQMPSchemaObjectGetType("members", + *query, + "name", base); + + if (!baseName) + return NULL; + } else if (STREQ(metatype, "command") || + STREQ(metatype, "event")) { + if (!(baseName = virJSONValueObjectGetString(base, *query))) + return NULL; + } else { + /* alternates, basic types and enums can't be entered */ + return NULL; + } + + query++; + } while (*query); + + return base; +} + + +/** + * virQEMUCapsQMPSchemaGetByPath: + * @query: string specifying the required data type (see below) + * @schema: hash table containing the schema data + * @entry: filled with the located schema object requested by @query + * + * Retrieves the requested schema entry specified by @query to @entry. The + * @query parameter has the following syntax which is very closely tied to the + * qemu schema syntax entries separated by slashes with a few special characters: + * + * "command_or_event/attribute/subattribute/+variant_discriminator/subattribute" + * + * command_or_event: name of the event or attribute to introspect + * attribute: selects whether arguments or return type should be introspected + * ("arg-type" or "ret-type" for commands, "arg-type" for events) + * subattribute: specifies member name of object types + * +variant_discriminator: In the case of unionized objects, select a + * specific case to introspect. + * + * Array types are automatically flattened to the singular type. Alternate + * types are currently not supported. + * + * The above types can be chained arbitrarily using slashes to construct any + * path into the schema tree. + * + * Returns 0 on success (including if the requested schema was not found) and + * fills @entry appropriately. On failure returns -1 and sets an appropriate + * error message. + */ +int +virQEMUCapsQMPSchemaGetByPath(const char *query, + virHashTablePtr schema, + virJSONValuePtr *entry) +{ + char **elems = NULL; + + *entry = NULL; + + if (!(elems = virStringSplit(query, "/", 0))) + return -1; + + if (!*elems) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("malformed query string")); + virStringListFree(elems); + return -1; + } + + *entry = virQEMUCapsQMPSchemaTraverse(*elems, elems + 1, schema); + + virStringListFree(elems); + return 0; +} + + +bool +virQEMUCapsQMPSchemaQueryPath(const char *query, + virHashTablePtr schema) +{ + virJSONValuePtr entry; + + if (virQEMUCapsQMPSchemaGetByPath(query, schema, &entry)) + return false; + + return !!entry; +} diff --git a/src/qemu/qemu_qapi.h b/src/qemu/qemu_qapi.h new file mode 100644 index 0000000000..413d0629b5 --- /dev/null +++ b/src/qemu/qemu_qapi.h @@ -0,0 +1,36 @@ +/* + * qemu_qapi.h: helper functions for QEMU QAPI schema + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * <http://www.gnu.org/licenses/>. + */ + +#ifndef __QEMU_QAPI_H__ +# define __QEMU_QAPI_H__ + +# include "internal.h" + +# include "virhash.h" +# include "virjson.h" + +int +virQEMUCapsQMPSchemaGetByPath(const char *query, + virHashTablePtr schema, + virJSONValuePtr *entry); + +bool +virQEMUCapsQMPSchemaQueryPath(const char *query, + virHashTablePtr schema); + +#endif /* __QEMU_QAPI_H__ */ -- 2.16.2 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list