From 025e3543702386cca1e52aeba499f0e116af8be1 Mon Sep 17 00:00:00 2001
From: Kevin Wolf <kwolf@redhat.com>
Date: Mon, 12 Mar 2018 09:38:35 -0400
Subject: [PATCH] qdict: Introduce qdict_rename_keys()

A few block drivers will need to rename .bdrv_create options for their
QAPIfication, so let's have a helper function for that.

Backports commit bcebf102ccc3c6db327f341adc379fdf0673ca6b from qemu
---
 qemu/aarch64.h                |  1 +
 qemu/aarch64eb.h              |  1 +
 qemu/arm.h                    |  1 +
 qemu/armeb.h                  |  1 +
 qemu/header_gen.py            |  1 +
 qemu/include/qapi/qmp/qdict.h |  6 ++++++
 qemu/m68k.h                   |  1 +
 qemu/mips.h                   |  1 +
 qemu/mips64.h                 |  1 +
 qemu/mips64el.h               |  1 +
 qemu/mipsel.h                 |  1 +
 qemu/powerpc.h                |  1 +
 qemu/qobject/qdict.c          | 34 ++++++++++++++++++++++++++++++++++
 qemu/sparc.h                  |  1 +
 qemu/sparc64.h                |  1 +
 qemu/x86_64.h                 |  1 +
 16 files changed, 54 insertions(+)

diff --git a/qemu/aarch64.h b/qemu/aarch64.h
index bbcb243e..e519c462 100644
--- a/qemu/aarch64.h
+++ b/qemu/aarch64.h
@@ -2129,6 +2129,7 @@
 #define qdict_put_null qdict_put_null_aarch64
 #define qdict_put_obj qdict_put_obj_aarch64
 #define qdict_put_str qdict_put_str_aarch64
+#define qdict_rename_keys qdict_rename_keys_aarch64
 #define qdict_size qdict_size_aarch64
 #define qdict_type qdict_type_aarch64
 #define qemu_clock_get_us qemu_clock_get_us_aarch64
diff --git a/qemu/aarch64eb.h b/qemu/aarch64eb.h
index 92781ba2..cbcbab67 100644
--- a/qemu/aarch64eb.h
+++ b/qemu/aarch64eb.h
@@ -2129,6 +2129,7 @@
 #define qdict_put_null qdict_put_null_aarch64eb
 #define qdict_put_obj qdict_put_obj_aarch64eb
 #define qdict_put_str qdict_put_str_aarch64eb
+#define qdict_rename_keys qdict_rename_keys_aarch64eb
 #define qdict_size qdict_size_aarch64eb
 #define qdict_type qdict_type_aarch64eb
 #define qemu_clock_get_us qemu_clock_get_us_aarch64eb
diff --git a/qemu/arm.h b/qemu/arm.h
index 85c13212..a1974154 100644
--- a/qemu/arm.h
+++ b/qemu/arm.h
@@ -2129,6 +2129,7 @@
 #define qdict_put_null qdict_put_null_arm
 #define qdict_put_obj qdict_put_obj_arm
 #define qdict_put_str qdict_put_str_arm
+#define qdict_rename_keys qdict_rename_keys_arm
 #define qdict_size qdict_size_arm
 #define qdict_type qdict_type_arm
 #define qemu_clock_get_us qemu_clock_get_us_arm
diff --git a/qemu/armeb.h b/qemu/armeb.h
index 04f44153..d900d7b0 100644
--- a/qemu/armeb.h
+++ b/qemu/armeb.h
@@ -2129,6 +2129,7 @@
 #define qdict_put_null qdict_put_null_armeb
 #define qdict_put_obj qdict_put_obj_armeb
 #define qdict_put_str qdict_put_str_armeb
+#define qdict_rename_keys qdict_rename_keys_armeb
 #define qdict_size qdict_size_armeb
 #define qdict_type qdict_type_armeb
 #define qemu_clock_get_us qemu_clock_get_us_armeb
diff --git a/qemu/header_gen.py b/qemu/header_gen.py
index 841557dd..1ec573af 100644
--- a/qemu/header_gen.py
+++ b/qemu/header_gen.py
@@ -2135,6 +2135,7 @@ symbols = (
     'qdict_put_null',
     'qdict_put_obj',
     'qdict_put_str',
+    'qdict_rename_keys',
     'qdict_size',
     'qdict_type',
     'qemu_clock_get_us',
diff --git a/qemu/include/qapi/qmp/qdict.h b/qemu/include/qapi/qmp/qdict.h
index 9c96f79e..3fd4d413 100644
--- a/qemu/include/qapi/qmp/qdict.h
+++ b/qemu/include/qapi/qmp/qdict.h
@@ -79,4 +79,10 @@ QObject *qdict_crumple(const QDict *src, Error **errp);
 
 void qdict_join(QDict *dest, QDict *src, bool overwrite);
 
+typedef struct QDictRenames {
+    const char *from;
+    const char *to;
+} QDictRenames;
+bool qdict_rename_keys(QDict *qdict, const QDictRenames *renames, Error **errp);
+
 #endif /* QDICT_H */
diff --git a/qemu/m68k.h b/qemu/m68k.h
index 893e247e..b9da9330 100644
--- a/qemu/m68k.h
+++ b/qemu/m68k.h
@@ -2129,6 +2129,7 @@
 #define qdict_put_null qdict_put_null_m68k
 #define qdict_put_obj qdict_put_obj_m68k
 #define qdict_put_str qdict_put_str_m68k
+#define qdict_rename_keys qdict_rename_keys_m68k
 #define qdict_size qdict_size_m68k
 #define qdict_type qdict_type_m68k
 #define qemu_clock_get_us qemu_clock_get_us_m68k
diff --git a/qemu/mips.h b/qemu/mips.h
index 026340d7..b933a882 100644
--- a/qemu/mips.h
+++ b/qemu/mips.h
@@ -2129,6 +2129,7 @@
 #define qdict_put_null qdict_put_null_mips
 #define qdict_put_obj qdict_put_obj_mips
 #define qdict_put_str qdict_put_str_mips
+#define qdict_rename_keys qdict_rename_keys_mips
 #define qdict_size qdict_size_mips
 #define qdict_type qdict_type_mips
 #define qemu_clock_get_us qemu_clock_get_us_mips
diff --git a/qemu/mips64.h b/qemu/mips64.h
index 09e3bc2b..5b72705c 100644
--- a/qemu/mips64.h
+++ b/qemu/mips64.h
@@ -2129,6 +2129,7 @@
 #define qdict_put_null qdict_put_null_mips64
 #define qdict_put_obj qdict_put_obj_mips64
 #define qdict_put_str qdict_put_str_mips64
+#define qdict_rename_keys qdict_rename_keys_mips64
 #define qdict_size qdict_size_mips64
 #define qdict_type qdict_type_mips64
 #define qemu_clock_get_us qemu_clock_get_us_mips64
diff --git a/qemu/mips64el.h b/qemu/mips64el.h
index fcbea15f..7a4abaf3 100644
--- a/qemu/mips64el.h
+++ b/qemu/mips64el.h
@@ -2129,6 +2129,7 @@
 #define qdict_put_null qdict_put_null_mips64el
 #define qdict_put_obj qdict_put_obj_mips64el
 #define qdict_put_str qdict_put_str_mips64el
+#define qdict_rename_keys qdict_rename_keys_mips64el
 #define qdict_size qdict_size_mips64el
 #define qdict_type qdict_type_mips64el
 #define qemu_clock_get_us qemu_clock_get_us_mips64el
diff --git a/qemu/mipsel.h b/qemu/mipsel.h
index 48584ec0..2f86d3b6 100644
--- a/qemu/mipsel.h
+++ b/qemu/mipsel.h
@@ -2129,6 +2129,7 @@
 #define qdict_put_null qdict_put_null_mipsel
 #define qdict_put_obj qdict_put_obj_mipsel
 #define qdict_put_str qdict_put_str_mipsel
+#define qdict_rename_keys qdict_rename_keys_mipsel
 #define qdict_size qdict_size_mipsel
 #define qdict_type qdict_type_mipsel
 #define qemu_clock_get_us qemu_clock_get_us_mipsel
diff --git a/qemu/powerpc.h b/qemu/powerpc.h
index e002aed3..92048014 100644
--- a/qemu/powerpc.h
+++ b/qemu/powerpc.h
@@ -2129,6 +2129,7 @@
 #define qdict_put_null qdict_put_null_powerpc
 #define qdict_put_obj qdict_put_obj_powerpc
 #define qdict_put_str qdict_put_str_powerpc
+#define qdict_rename_keys qdict_rename_keys_powerpc
 #define qdict_size qdict_size_powerpc
 #define qdict_type qdict_type_powerpc
 #define qemu_clock_get_us qemu_clock_get_us_powerpc
diff --git a/qemu/qobject/qdict.c b/qemu/qobject/qdict.c
index ea9e9652..7c70bc90 100644
--- a/qemu/qobject/qdict.c
+++ b/qemu/qobject/qdict.c
@@ -563,6 +563,40 @@ static void qdict_flatten_qdict(QDict *qdict, QDict *target, const char *prefix)
     }
 }
 
+/**
+ * qdict_rename_keys(): Rename keys in qdict according to the replacements
+ * specified in the array renames. The array must be terminated by an entry
+ * with from = NULL.
+ *
+ * The renames are performed individually in the order of the array, so entries
+ * may be renamed multiple times and may or may not conflict depending on the
+ * order of the renames array.
+ *
+ * Returns true for success, false in error cases.
+ */
+bool qdict_rename_keys(QDict *qdict, const QDictRenames *renames, Error **errp)
+{
+    QObject *qobj;
+
+    while (renames->from) {
+        if (qdict_haskey(qdict, renames->from)) {
+            if (qdict_haskey(qdict, renames->to)) {
+                error_setg(errp, "'%s' and its alias '%s' can't be used at the "
+                           "same time", renames->to, renames->from);
+                return false;
+            }
+
+            qobj = qdict_get(qdict, renames->from);
+            qobject_incref(qobj);
+            qdict_put_obj(qdict, renames->to, qobj);
+            qdict_del(qdict, renames->from);
+        }
+
+        renames++;
+    }
+    return true;
+}
+
 /**
  * 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". For each nested
diff --git a/qemu/sparc.h b/qemu/sparc.h
index 6da27e35..ec19d7e6 100644
--- a/qemu/sparc.h
+++ b/qemu/sparc.h
@@ -2129,6 +2129,7 @@
 #define qdict_put_null qdict_put_null_sparc
 #define qdict_put_obj qdict_put_obj_sparc
 #define qdict_put_str qdict_put_str_sparc
+#define qdict_rename_keys qdict_rename_keys_sparc
 #define qdict_size qdict_size_sparc
 #define qdict_type qdict_type_sparc
 #define qemu_clock_get_us qemu_clock_get_us_sparc
diff --git a/qemu/sparc64.h b/qemu/sparc64.h
index 7b172a02..028f5809 100644
--- a/qemu/sparc64.h
+++ b/qemu/sparc64.h
@@ -2129,6 +2129,7 @@
 #define qdict_put_null qdict_put_null_sparc64
 #define qdict_put_obj qdict_put_obj_sparc64
 #define qdict_put_str qdict_put_str_sparc64
+#define qdict_rename_keys qdict_rename_keys_sparc64
 #define qdict_size qdict_size_sparc64
 #define qdict_type qdict_type_sparc64
 #define qemu_clock_get_us qemu_clock_get_us_sparc64
diff --git a/qemu/x86_64.h b/qemu/x86_64.h
index 07273fe4..171f1bcf 100644
--- a/qemu/x86_64.h
+++ b/qemu/x86_64.h
@@ -2129,6 +2129,7 @@
 #define qdict_put_null qdict_put_null_x86_64
 #define qdict_put_obj qdict_put_obj_x86_64
 #define qdict_put_str qdict_put_str_x86_64
+#define qdict_rename_keys qdict_rename_keys_x86_64
 #define qdict_size qdict_size_x86_64
 #define qdict_type qdict_type_x86_64
 #define qemu_clock_get_us qemu_clock_get_us_x86_64