summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/plist/plist.h10
-rw-r--r--src/plist.c27
2 files changed, 37 insertions, 0 deletions
diff --git a/include/plist/plist.h b/include/plist/plist.h
index 546e108..41588a8 100644
--- a/include/plist/plist.h
+++ b/include/plist/plist.h
@@ -336,6 +336,16 @@ extern "C"
*/
PLIST_API void plist_dict_remove_item(plist_t node, const char* key);
+ /**
+ * Merge a dictionary into another. This will add all key/value pairs
+ * from the source dictionary to the target dictionary, overwriting
+ * any existing key/value pairs that are already present in target.
+ *
+ * @param target pointer to an existing node of type #PLIST_DICT
+ * @param source node of type #PLIST_DICT that should be merged into target
+ */
+ PLIST_API void plist_dict_merge(plist_t *target, plist_t source);
+
/********************************************
* *
diff --git a/src/plist.c b/src/plist.c
index dcaf601..e077ad9 100644
--- a/src/plist.c
+++ b/src/plist.c
@@ -446,6 +446,33 @@ void plist_dict_remove_item(plist_t node, const char* key)
return;
}
+void plist_dict_merge(plist_t *target, plist_t source)
+{
+ if (!target || !*target || (plist_get_node_type(*target) != PLIST_DICT) || !source || (plist_get_node_type(source) != PLIST_DICT))
+ return;
+
+ char* key = NULL;
+ plist_dict_iter it = NULL;
+ plist_t subnode = NULL;
+ plist_dict_new_iter(source, &it);
+ if (!it)
+ return;
+
+ do {
+ plist_dict_next_item(source, it, &key, &subnode);
+ if (!key)
+ break;
+
+ if (plist_dict_get_item(*target, key) != NULL)
+ plist_dict_remove_item(*target, key);
+
+ plist_dict_insert_item(*target, key, plist_copy(subnode));
+ free(key);
+ key = NULL;
+ } while (1);
+ free(it);
+}
+
plist_t plist_access_pathv(plist_t plist, uint32_t length, va_list v)
{
plist_t current = plist;