From: Jaroslav Kysela Date: Thu, 14 Nov 2019 15:56:05 +0000 (+0100) Subject: conf: implement snd_config_add_before() and snd_config_add_after() X-Git-Tag: android-x86-9.0-r1~21 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=4c021697f11dfcf74c68bbc7aed0f660f3c0dcb3;p=android-x86%2Fexternal-alsa-lib.git conf: implement snd_config_add_before() and snd_config_add_after() Signed-off-by: Jaroslav Kysela --- diff --git a/include/conf.h b/include/conf.h index d44c0a2f..456b272e 100644 --- a/include/conf.h +++ b/include/conf.h @@ -114,7 +114,9 @@ int snd_config_expand(snd_config_t *config, snd_config_t *root, int snd_config_evaluate(snd_config_t *config, snd_config_t *root, snd_config_t *private_data, snd_config_t **result); -int snd_config_add(snd_config_t *config, snd_config_t *leaf); +int snd_config_add(snd_config_t *config, snd_config_t *child); +int snd_config_add_before(snd_config_t *before, snd_config_t *child); +int snd_config_add_after(snd_config_t *after, snd_config_t *child); 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); diff --git a/include/list.h b/include/list.h index 947c1f84..7f0cfc0c 100644 --- a/include/list.h +++ b/include/list.h @@ -86,6 +86,21 @@ static inline void list_add_tail(struct list_head *p, struct list_head *list) list->prev = p; } +/* list_insert - insert a new list entry between two known consecutive entries + * @p: the new entry to be inserted between prev and next + * @prev: the left-side entry + * @next: the right-side entry + */ +static inline void list_insert(struct list_head *p, + struct list_head *prev, + struct list_head *next) +{ + next->prev = p; + p->next = next; + p->prev = prev; + prev->next = p; +} + /* list_del - delete the given list entry */ static inline void list_del(struct list_head *p) { diff --git a/src/conf.c b/src/conf.c index 558114ad..ffdbdd1a 100644 --- a/src/conf.c +++ b/src/conf.c @@ -1979,6 +1979,88 @@ int snd_config_add(snd_config_t *parent, snd_config_t *child) } /** + * \brief Adds a child after another child configuration node. + * \param after Handle to the start configuration node. + * \param child Handle to the configuration node to be added. + * \return Zero if successful, otherwise a negative error code. + * + * This function makes the node \a child a child of the parent of + * the node \a after. + * + * The parent node then owns the child node, i.e., the child node gets + * deleted together with its parent. + * + * \a child must have an id. + * + * \par Errors: + *
+ *
-EINVAL
\a child does not have an id. + *
-EINVAL
\a child already has a parent. + *
-EEXIST
\a parent already contains a child node with the same + * id as \a child. + *
+ */ +int snd_config_add_after(snd_config_t *after, snd_config_t *child) +{ + snd_config_iterator_t i, next; + snd_config_t *parent; + assert(after && child); + parent = after->parent; + assert(parent); + if (!child->id || child->parent) + return -EINVAL; + snd_config_for_each(i, next, parent) { + snd_config_t *n = snd_config_iterator_entry(i); + if (strcmp(child->id, n->id) == 0) + return -EEXIST; + } + child->parent = parent; + list_insert(&child->list, &after->list, after->list.next); + return 0; +} + +/** + * \brief Adds a child before another child configuration node. + * \param before Handle to the start configuration node. + * \param child Handle to the configuration node to be added. + * \return Zero if successful, otherwise a negative error code. + * + * This function makes the node \a child a child of the parent of + * the node \a before. + * + * The parent node then owns the child node, i.e., the child node gets + * deleted together with its parent. + * + * \a child must have an id. + * + * \par Errors: + *
+ *
-EINVAL
\a child does not have an id. + *
-EINVAL
\a child already has a parent. + *
-EEXIST
\a parent already contains a child node with the same + * id as \a child. + *
+ */ +int snd_config_add_before(snd_config_t *before, snd_config_t *child) +{ + snd_config_iterator_t i, next; + snd_config_t *parent; + assert(before && child); + parent = before->parent; + assert(parent); + if (!child->id || child->parent) + return -EINVAL; + snd_config_for_each(i, next, parent) { + snd_config_t *n = snd_config_iterator_entry(i); + if (strcmp(child->id, n->id) == 0) + return -EEXIST; + } + child->parent = parent; + list_insert(&child->list, before->list.prev, &before->list); + return 0; +} + +/** * \brief Removes a configuration node from its tree. * \param config Handle to the configuration node to be removed. * \return Zero if successful, otherwise a negative error code.