From: Alan T. DeKok Date: Tue, 15 Nov 2022 15:10:36 +0000 (-0500) Subject: add cf_item_insert_after() X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f237ddc632ae12ef7930477346ea9b479f7dfab0;p=thirdparty%2Ffreeradius-server.git add cf_item_insert_after() for use with automagically rewriting edit sections --- diff --git a/src/lib/server/cf_util.c b/src/lib/server/cf_util.c index 1ca457e06b2..6934d0960ba 100644 --- a/src/lib/server/cf_util.c +++ b/src/lib/server/cf_util.c @@ -374,6 +374,38 @@ void _cf_item_add(CONF_ITEM *parent, CONF_ITEM *child) fr_dlist_insert_tail(&parent->children, child); /* Append to the list of children */ } +/** Insert a child after a given one + * + * @param[in] parent to add child to. + * @param[in] prev previous + * @param[in] child to add. + */ +void _cf_item_insert_after(CONF_ITEM *parent, CONF_ITEM *prev, CONF_ITEM *child) +{ + fr_assert(parent != child); + fr_assert(prev != child); + + /* + * Must be given something. Can't insert at HEAD. + */ + if (!parent || !child) return; + + if (!prev) { + cf_item_add(parent, child); + return; + } + + /* + * If there's a prev, then the ident trees must be there. + */ + fr_assert(parent->ident1 != NULL); + fr_assert(parent->ident2 != NULL); + + fr_rb_insert(parent->ident1, child); + fr_rb_insert(parent->ident2, child); /* NULL ident2 is still a value */ + fr_dlist_insert_after(&parent->children, prev, child); /* insert in the list of children */ +} + /** Remove item from parent and fixup trees * * @param[in] parent to remove child from. diff --git a/src/lib/server/cf_util.h b/src/lib/server/cf_util.h index ff1f1836ecb..38ddcc03030 100644 --- a/src/lib/server/cf_util.h +++ b/src/lib/server/cf_util.h @@ -86,6 +86,9 @@ typedef int (*cf_walker_t)(void *data, void *ctx); #define cf_item_add(_parent, _child) _cf_item_add(CF_TO_ITEM(_parent), CF_TO_ITEM(_child)) void _cf_item_add(CONF_ITEM *parent, CONF_ITEM *child); +#define cf_item_insert_after(_parent, _prev, _child) _cf_item_insert_after(CF_TO_ITEM(_parent), CF_TO_ITEM(_prev), CF_TO_ITEM(_child)) +void _cf_item_insert_after(CONF_ITEM *parent, CONF_ITEM *prev, CONF_ITEM *child); + #define cf_item_remove(_parent, _child) _cf_item_remove(CF_TO_ITEM(_parent), CF_TO_ITEM(_child)) CONF_ITEM *_cf_item_remove(CONF_ITEM *parent, CONF_ITEM *child);