diff options
author | Jaroslav Kysela <perex@perex.cz> | 2021-05-13 11:02:41 +0200 |
---|---|---|
committer | Jaroslav Kysela <perex@perex.cz> | 2021-05-13 11:02:41 +0200 |
commit | 1aef5a8f8a8c122262cf0eca739a63ce843d8fa6 (patch) | |
tree | d216976f451bbadc351d9a0a5be885f042ec8f7f | |
parent | 3050af4b90ff6ecf41c931164ab3010b5d248a91 (diff) | |
download | alsa-lib-1aef5a8f8a8c122262cf0eca739a63ce843d8fa6.tar.gz |
conf: add snd_config_make_path() function
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
-rw-r--r-- | include/conf.h | 2 | ||||
-rw-r--r-- | src/conf.c | 97 |
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); @@ -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. |