[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PULL 21/93] qapi: extend qdict_flatten() for QLists
From: |
Kevin Wolf |
Subject: |
[Qemu-devel] [PULL 21/93] qapi: extend qdict_flatten() for QLists |
Date: |
Fri, 24 Jan 2014 18:21:04 +0100 |
From: Max Reitz <address@hidden>
Reversing qdict_array_split(), qdict_flatten() should flatten QLists as
well by interpreting them as QDicts where every entry's key is its
index.
This allows bringing QDicts with QLists from QMP commands to the same
form as they would be given as command-line options, thereby allowing
them to be parsed the same way.
Signed-off-by: Max Reitz <address@hidden>
Reviewed-by: Eric Blake <address@hidden>
Signed-off-by: Kevin Wolf <address@hidden>
---
qobject/qdict.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++------
1 file changed, 48 insertions(+), 6 deletions(-)
diff --git a/qobject/qdict.c b/qobject/qdict.c
index 2d5848d..a3924f2 100644
--- a/qobject/qdict.c
+++ b/qobject/qdict.c
@@ -477,7 +477,43 @@ static void qdict_destroy_obj(QObject *obj)
g_free(qdict);
}
-static void qdict_do_flatten(QDict *qdict, QDict *target, const char *prefix)
+static void qdict_flatten_qdict(QDict *qdict, QDict *target,
+ const char *prefix);
+
+static void qdict_flatten_qlist(QList *qlist, QDict *target, const char
*prefix)
+{
+ QObject *value;
+ const QListEntry *entry;
+ char *new_key;
+ int i;
+
+ /* This function is never called with prefix == NULL, i.e., it is always
+ * called from within qdict_flatten_q(list|dict)(). Therefore, it does not
+ * need to remove list entries during the iteration (the whole list will be
+ * deleted eventually anyway from qdict_flatten_qdict()). */
+ assert(prefix);
+
+ entry = qlist_first(qlist);
+
+ for (i = 0; entry; entry = qlist_next(entry), i++) {
+ value = qlist_entry_obj(entry);
+ new_key = g_strdup_printf("%s.%i", prefix, i);
+
+ if (qobject_type(value) == QTYPE_QDICT) {
+ qdict_flatten_qdict(qobject_to_qdict(value), target, new_key);
+ } else if (qobject_type(value) == QTYPE_QLIST) {
+ qdict_flatten_qlist(qobject_to_qlist(value), target, new_key);
+ } else {
+ /* All other types are moved to the target unchanged. */
+ qobject_incref(value);
+ qdict_put_obj(target, new_key, value);
+ }
+
+ g_free(new_key);
+ }
+}
+
+static void qdict_flatten_qdict(QDict *qdict, QDict *target, const char
*prefix)
{
QObject *value;
const QDictEntry *entry, *next;
@@ -500,8 +536,12 @@ static void qdict_do_flatten(QDict *qdict, QDict *target,
const char *prefix)
if (qobject_type(value) == QTYPE_QDICT) {
/* Entries of QDicts are processed recursively, the QDict object
* itself disappears. */
- qdict_do_flatten(qobject_to_qdict(value), target,
- new_key ? new_key : entry->key);
+ qdict_flatten_qdict(qobject_to_qdict(value), target,
+ new_key ? new_key : entry->key);
+ delete = true;
+ } else if (qobject_type(value) == QTYPE_QLIST) {
+ qdict_flatten_qlist(qobject_to_qlist(value), target,
+ new_key ? new_key : entry->key);
delete = true;
} else if (prefix) {
/* All other objects are moved to the target unchanged. */
@@ -526,12 +566,14 @@ static void qdict_do_flatten(QDict *qdict, QDict *target,
const char *prefix)
/**
* qdict_flatten(): For each nested QDict with key x, all fields with key y
- * are moved to this QDict and their key is renamed to "x.y". This operation
- * is applied recursively for nested QDicts.
+ * are moved to this QDict and their key is renamed to "x.y". For each nested
+ * QList with key x, the field at index y is moved to this QDict with the key
+ * "x.y" (i.e., the reverse of what qdict_array_split() does).
+ * This operation is applied recursively for nested QDicts and QLists.
*/
void qdict_flatten(QDict *qdict)
{
- qdict_do_flatten(qdict, qdict, NULL);
+ qdict_flatten_qdict(qdict, qdict, NULL);
}
/* extract all the src QDict entries starting by start into dst */
--
1.8.1.4
- [Qemu-devel] [PULL 11/93] docs: qcow2 compat=1.1 is now the default, (continued)
- [Qemu-devel] [PULL 11/93] docs: qcow2 compat=1.1 is now the default, Kevin Wolf, 2014/01/24
- [Qemu-devel] [PULL 12/93] vmdk: Fix big flat extent IO, Kevin Wolf, 2014/01/24
- [Qemu-devel] [PULL 13/93] readline: decouple readline from the monitor, Kevin Wolf, 2014/01/24
- [Qemu-devel] [PULL 14/93] readline: move readline to a generic location, Kevin Wolf, 2014/01/24
- [Qemu-devel] [PULL 15/93] osdep: add qemu_set_tty_echo(), Kevin Wolf, 2014/01/24
- [Qemu-devel] [PULL 16/93] qemu-io: use readline.c, Kevin Wolf, 2014/01/24
- [Qemu-devel] [PULL 17/93] qemu-io: add command completion, Kevin Wolf, 2014/01/24
- [Qemu-devel] [PULL 18/93] blkdebug: Use errp for read_config(), Kevin Wolf, 2014/01/24
- [Qemu-devel] [PULL 19/93] blkdebug: Don't require sophisticated filename, Kevin Wolf, 2014/01/24
- [Qemu-devel] [PULL 20/93] qdict: Add qdict_array_split(), Kevin Wolf, 2014/01/24
- [Qemu-devel] [PULL 21/93] qapi: extend qdict_flatten() for QLists,
Kevin Wolf <=
- [Qemu-devel] [PULL 22/93] qemu-option: Add qemu_config_parse_qdict(), Kevin Wolf, 2014/01/24
- [Qemu-devel] [PULL 23/93] blkdebug: Always call read_config(), Kevin Wolf, 2014/01/24
- [Qemu-devel] [PULL 24/93] blkdebug: Use command-line in read_config(), Kevin Wolf, 2014/01/24
- [Qemu-devel] [PULL 25/93] block: Allow reference for bdrv_file_open(), Kevin Wolf, 2014/01/24
- [Qemu-devel] [PULL 26/93] block: Pass reference to bdrv_file_open(), Kevin Wolf, 2014/01/24
- [Qemu-devel] [PULL 27/93] block: Allow block devices without files, Kevin Wolf, 2014/01/24
- [Qemu-devel] [PULL 29/93] block: Use bdrv_open_image() in bdrv_open(), Kevin Wolf, 2014/01/24
- [Qemu-devel] [PULL 30/93] block: Allow recursive "file"s, Kevin Wolf, 2014/01/24
- [Qemu-devel] [PULL 28/93] block: Add bdrv_open_image(), Kevin Wolf, 2014/01/24
- [Qemu-devel] [PULL 32/93] blkdebug: Allow command-line file configuration, Kevin Wolf, 2014/01/24