summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJaroslav Kysela <perex@perex.cz>2021-05-13 11:02:41 +0200
committerJaroslav Kysela <perex@perex.cz>2021-05-13 11:02:41 +0200
commit1aef5a8f8a8c122262cf0eca739a63ce843d8fa6 (patch)
treed216976f451bbadc351d9a0a5be885f042ec8f7f
parent3050af4b90ff6ecf41c931164ab3010b5d248a91 (diff)
downloadalsa-lib-1aef5a8f8a8c122262cf0eca739a63ce843d8fa6.tar.gz
conf: add snd_config_make_path() function
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
-rw-r--r--include/conf.h2
-rw-r--r--src/conf.c97
2 files changed, 99 insertions, 0 deletions
diff --git a/include/conf.h b/include/conf.h
index 5c70ebcc..9cf39dc0 100644
--- a/include/conf.h
+++ b/include/conf.h
@@ -131,6 +131,8 @@ int snd_config_make_real(snd_config_t **config, const char *key);
int snd_config_make_string(snd_config_t **config, const char *key);
int snd_config_make_pointer(snd_config_t **config, const char *key);
int snd_config_make_compound(snd_config_t **config, const char *key, int join);
+int snd_config_make_path(snd_config_t **config, snd_config_t *root, const char *key,
+ int join, int override);
int snd_config_imake_integer(snd_config_t **config, const char *key, const long value);
int snd_config_imake_integer64(snd_config_t **config, const char *key, const long long value);
diff --git a/src/conf.c b/src/conf.c
index 7ebf7577..f40fe883 100644
--- a/src/conf.c
+++ b/src/conf.c
@@ -2548,6 +2548,103 @@ int snd_config_make_compound(snd_config_t **config, const char *id,
}
/**
+ * \brief Creates an empty compound configuration node in the path.
+ * \param[out] config The function puts the handle to the new or
+ * existing compound node at the address specified
+ * by \a config.
+ * \param[in] root The id of the new node.
+ * \param[in] key The id of the new node.
+ * \param[in] join Join flag.
+ * \param[in] override Override flag.
+ * \return Zero if successful, otherwise a negative error code.
+ *
+ * This function creates a new empty node of type
+ * #SND_CONFIG_TYPE_COMPOUND if the path does not exist. Otherwise,
+ * the node from the current configuration tree is returned without
+ * any modification. The \a join argument is ignored in this case.
+ *
+ * \a join determines how the compound node's id is printed when the
+ * configuration is saved to a text file. For example, if the join flag
+ * of compound node \c a is zero, the output will look as follows:
+ * \code
+ * a {
+ * b "hello"
+ * c 42
+ * }
+ * \endcode
+ * If, however, the join flag of \c a is nonzero, its id will be joined
+ * with its children's ids, like this:
+ * \code
+ * a.b "hello"
+ * a.c 42
+ * \endcode
+ * An \e empty compound node with its join flag set would result in no
+ * output, i.e., after saving and reloading the configuration file, that
+ * compound node would be lost.
+ *
+ * \par Errors:
+ * <dl>
+ * <dt>-ENOMEM<dd>Out of memory.
+ * <dt>-EACCESS<dd>Path exists, but it's not a compound (!override)
+ * </dl>
+ */
+int snd_config_make_path(snd_config_t **config, snd_config_t *root,
+ const char *key, int join, int override)
+{
+ snd_config_t *n;
+ const char *p;
+ int err;
+
+ while (1) {
+ p = strchr(key, '.');
+ if (p) {
+ err = _snd_config_search(root, key, p - key, &n);
+ if (err < 0) {
+ size_t l = p - key;
+ char *s = malloc(l + 1);
+ if (s == NULL)
+ return -ENOMEM;
+ strncpy(s, key, l);
+ s[l] = '\0';
+ err = snd_config_make_compound(&n, s, join);
+ free(s);
+ if (err < 0)
+ return err;
+ err = snd_config_add(root, n);
+ if (err < 0)
+ return err;
+ }
+ root = n;
+ key = p + 1;
+ } else {
+ err = _snd_config_search(root, key, -1, config);
+ if (err == 0) {
+ if ((*config)->type != SND_CONFIG_TYPE_COMPOUND) {
+ if (override) {
+ err = snd_config_delete(*config);
+ if (err < 0)
+ return err;
+ goto __make;
+ } else {
+ return -EACCES;
+ }
+ }
+ return 0;
+ }
+__make:
+ err = snd_config_make_compound(&n, key, join);
+ if (err < 0)
+ return err;
+ err = snd_config_add(root, n);
+ if (err < 0)
+ return err;
+ *config = n;
+ return 0;
+ }
+ }
+}
+
+/**
* \brief Creates an integer configuration node with the given initial value.
* \param[out] config The function puts the handle to the new node at
* the address specified by \a config.