From: Arran Cudbard-Bell Date: Mon, 21 Dec 2020 17:40:26 +0000 (-0600) Subject: Allow insertion of new dlist items at a specific position X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=23aefbadb6c7ce3b07934dd3c7b5b0ea71f895b2;p=thirdparty%2Ffreeradius-server.git Allow insertion of new dlist items at a specific position --- diff --git a/src/lib/util/dlist.h b/src/lib/util/dlist.h index 36d66812432..d350dd73437 100644 --- a/src/lib/util/dlist.h +++ b/src/lib/util/dlist.h @@ -221,6 +221,80 @@ static inline CC_HINT(nonnull(1)) void fr_dlist_insert_tail(fr_dlist_head_t *lis list_head->num_elements++; } +/** Insert an item after an item already in the list + * + * @note If #fr_dlist_talloc_init was used to initialise #fr_dlist_head_t + * ptr must be a talloced chunk of the type passed to #fr_dlist_talloc_init. + * + * @param[in] list_head to insert ptr into. + * @param[in] pos to insert ptr after. + * @param[in] ptr to insert. + */ +static inline CC_HINT(nonnull(1)) void fr_dlist_insert_after(fr_dlist_head_t *list_head, void *pos, void *ptr) +{ + fr_dlist_t *entry, *pos_entry; + + if (!ptr) return; + +#ifndef TALLOC_GET_TYPE_ABORT_NOOP + if (list_head->type) ptr = _talloc_get_type_abort(ptr, list_head->type, __location__); +#endif + + entry = (fr_dlist_t *) (((uint8_t *) ptr) + list_head->offset); + if (!pos) { + pos_entry = &(list_head->entry); + } else { + pos_entry = (fr_dlist_t *) (((uint8_t *) pos) + list_head->offset); + } + + if (!fr_cond_assert(pos_entry->next != NULL)) return; + if (!fr_cond_assert(pos_entry->prev != NULL)) return; + + entry->prev = pos_entry; + entry->next = pos_entry->next; + pos_entry->next->prev = entry; + pos_entry->next = entry; + + list_head->num_elements++; +} + +/** Insert an item before an item already in the list + * + * @note If #fr_dlist_talloc_init was used to initialise #fr_dlist_head_t + * ptr must be a talloced chunk of the type passed to #fr_dlist_talloc_init. + * + * @param[in] list_head to insert ptr into. + * @param[in] pos to insert ptr before. + * @param[in] ptr to insert. + */ +static inline CC_HINT(nonnull(1)) void fr_dlist_insert_before(fr_dlist_head_t *list_head, void *pos, void *ptr) +{ + fr_dlist_t *entry, *pos_entry; + + if (!pos || !ptr) return; + +#ifndef TALLOC_GET_TYPE_ABORT_NOOP + if (list_head->type) ptr = _talloc_get_type_abort(ptr, list_head->type, __location__); +#endif + + entry = (fr_dlist_t *) (((uint8_t *) ptr) + list_head->offset); + if (!pos) { + pos_entry = &(list_head->entry); + } else { + pos_entry = (fr_dlist_t *) (((uint8_t *) pos) + list_head->offset); + } + + if (!fr_cond_assert(pos_entry->next != NULL)) return; + if (!fr_cond_assert(pos_entry->prev != NULL)) return; + + entry->next = pos_entry; + entry->prev = pos_entry->prev; + pos_entry->prev->next = entry; + pos_entry->prev = entry; + + list_head->num_elements++; +} + /** Return the HEAD item of a list or NULL if the list is empty * * @param[in] list_head to return the HEAD item from.