]> git.alsa-project.org Git - alsa-lib.git/commitdiff
conf: add snd_config_merge() function
authorJaroslav Kysela <perex@perex.cz>
Fri, 9 Apr 2021 16:11:57 +0000 (18:11 +0200)
committerJaroslav Kysela <perex@perex.cz>
Tue, 13 Apr 2021 07:23:06 +0000 (09:23 +0200)
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
include/conf.h
src/conf.c

index cf88f1bd8367ddff39100c84d0475966c28b15c1..e729fb052300d86542e436e73d02df7dd47044d7 100644 (file)
@@ -121,6 +121,7 @@ int snd_config_remove(snd_config_t *config);
 int snd_config_delete(snd_config_t *config);
 int snd_config_delete_compound_members(const snd_config_t *config);
 int snd_config_copy(snd_config_t **dst, snd_config_t *src);
+int snd_config_merge(snd_config_t *dst, snd_config_t *src, int override);
 
 int snd_config_make(snd_config_t **config, const char *key,
                    snd_config_type_t type);
index a2d4d068bab89d6f587e92d9773cc0c6562a15f4..941662ca591d3a4d485992151d8fbeb46f490303 100644 (file)
@@ -2158,6 +2158,61 @@ int snd_config_add_before(snd_config_t *before, snd_config_t *child)
        return 0;
 }
 
+/**
+ * \brief In-place merge of two compounds
+ * \param dst[out] Compound handle for the merged contents
+ * \param src[in] Compound handle to merge into dst (may be NULL)
+ * \param override[in] Override flag
+ * \return Zero if successful, otherwise a negative error code.
+ *
+ * This function merges all fields from the source compound to the destination compound.
+ * When the overwrite flag is set, the related subtree in dst is replaced from src.
+ *
+ * The src compound is deleted.
+ *
+ * \par Errors:
+ * <dl>
+ * <dt>-EINVAL<dd>\dst is not a compound
+ * <dt>-EINVAL<dd>\src is not a compound
+ * </dl>
+ */
+int snd_config_merge(snd_config_t *dst, snd_config_t *src, int override)
+{
+       snd_config_iterator_t di, si, dnext, snext;
+       bool found;
+       int err;
+
+       assert(dst);
+       if (src == NULL)
+               return 0;
+       if (dst->type != SND_CONFIG_TYPE_COMPOUND || src->type != SND_CONFIG_TYPE_COMPOUND)
+               return -EINVAL;
+       snd_config_for_each(si, snext, src) {
+               snd_config_t *sn = snd_config_iterator_entry(si);
+               found = false;
+               snd_config_for_each(di, dnext, dst) {
+                       snd_config_t *dn = snd_config_iterator_entry(di);
+                       if (strcmp(sn->id, dn->id) == 0) {
+                               if (override) {
+                                       err = snd_config_substitute(dn, sn);
+                                       if (err < 0)
+                                               return err;
+                               }
+                               found = true;
+                               break;
+                       }
+               }
+               if (!found) {
+                       /* move config from src to dst */
+                       snd_config_remove(sn);
+                       sn->parent = dst;
+                       list_add_tail(&sn->list, &dst->u.compound.fields);
+               }
+       }
+       snd_config_delete(src);
+       return 0;
+}
+
 /**
  * \brief Removes a configuration node from its tree.
  * \param config Handle to the configuration node to be removed.