From: Arran Cudbard-Bell Date: Wed, 15 May 2024 03:55:35 +0000 (-0600) Subject: Add more cf boilerplate, and have cf_item_remove return the previous item to make... X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=8a397c74b88245b9d0a5626d9e824e1deaee8af0;p=thirdparty%2Ffreeradius-server.git Add more cf boilerplate, and have cf_item_remove return the previous item to make iterating easier --- diff --git a/src/lib/server/cf_priv.h b/src/lib/server/cf_priv.h index 02d0f3d448..42a714498c 100644 --- a/src/lib/server/cf_priv.h +++ b/src/lib/server/cf_priv.h @@ -145,9 +145,19 @@ typedef struct { * Will be declared in the scope of the loop. * @param[in] _prev previous pointer */ -#define cf_item_foreach_prev(_ci, _iter, _prev) \ +#define cf_item_foreach_next(_ci, _iter, _prev) \ for (CONF_ITEM *_iter = fr_dlist_next(&(_ci)->children, _prev); _iter; _iter = fr_dlist_next(&(_ci)->children, _iter)) +/** Iterate over the contents of a list in reverse order + * + * @param[in] _ci to iterate over. + * @param[in] _iter Name of iteration variable. + * Will be declared in the scope of the loop. + * @param[in] _prev previous pointer + */ +#define cf_item_foreach_prev(_ci, _iter, _prev) \ + for (CONF_ITEM *_iter = fr_dlist_prev(&(_ci)->children, _prev); _iter; _iter = fr_dlist_prev(&(_ci)->children, _iter)) + /** Check if the CONF_ITEM has no children. * * Which is the common use-case diff --git a/src/lib/server/cf_util.c b/src/lib/server/cf_util.c index a9bc024017..1bc692893d 100644 --- a/src/lib/server/cf_util.c +++ b/src/lib/server/cf_util.c @@ -39,15 +39,34 @@ static int8_t _cf_ident2_cmp(void const *a, void const *b); /** Return the next child that's of the specified type * * @param[in] parent to return children from. - * @param[in] prev child to start searching from. + * @param[in] current child to start searching from. + * @param[in] type to search for. + * @return + * - The next #CONF_ITEM that's a child of ci matching type. + * - NULL if no #CONF_ITEM matches that criteria. + */ +static CONF_ITEM *cf_next(CONF_ITEM const *parent, CONF_ITEM const *current, CONF_ITEM_TYPE type) +{ + cf_item_foreach_next(parent, ci, UNCONST(CONF_ITEM *, current)) { + if (ci->type == type) return ci; + } + + return NULL; +} + +/** Return the previos child that's of the specified type + * + * @param[in] parent to return children from. + * @param[in] current child to start searching from. * @param[in] type to search for. * @return * - The next #CONF_ITEM that's a child of ci matching type. * - NULL if no #CONF_ITEM matches that criteria. */ -static CONF_ITEM *cf_next(CONF_ITEM const *parent, CONF_ITEM const *prev, CONF_ITEM_TYPE type) +static inline CC_HINT(always_inline) +CONF_ITEM *cf_prev(CONF_ITEM const *parent, CONF_ITEM const *current, CONF_ITEM_TYPE type) { - cf_item_foreach_prev(parent, ci, UNCONST(CONF_ITEM *, prev)) { + cf_item_foreach_prev(parent, ci, UNCONST(CONF_ITEM *, current)) { if (ci->type == type) return ci; } @@ -205,7 +224,7 @@ static CONF_ITEM *cf_find_next(CONF_ITEM const *parent, CONF_ITEM const *prev, } if (IS_WILDCARD(ident1)) { - cf_item_foreach_prev(parent, ci, prev) { + cf_item_foreach_next(parent, ci, prev) { if (cf_ident2_cmp(ci, find) == 0) return ci; } @@ -213,7 +232,7 @@ static CONF_ITEM *cf_find_next(CONF_ITEM const *parent, CONF_ITEM const *prev, } if (IS_WILDCARD(ident2)) { - cf_item_foreach_prev(parent, ci, prev) { + cf_item_foreach_next(parent, ci, prev) { if (_cf_ident1_cmp(ci, find) == 0) return ci; } @@ -221,7 +240,7 @@ static CONF_ITEM *cf_find_next(CONF_ITEM const *parent, CONF_ITEM const *prev, return NULL; } - cf_item_foreach_prev(parent, ci, prev) { + cf_item_foreach_next(parent, ci, prev) { if (_cf_ident2_cmp(ci, find) == 0) return ci; } @@ -422,12 +441,13 @@ void _cf_item_insert_after(CONF_ITEM *parent, CONF_ITEM *prev, CONF_ITEM *child) * @param[in] parent to remove child from. * @param[in] child to remove. * @return - * - The item removed. + * - The previous item (makes iteration easier) * - NULL if the item wasn't set. */ CONF_ITEM *_cf_item_remove(CONF_ITEM *parent, CONF_ITEM *child) { CONF_ITEM *found = NULL; + CONF_ITEM *prev; bool in_ident1, in_ident2; if (!parent || cf_item_has_no_children(parent)) return NULL; @@ -445,7 +465,7 @@ CONF_ITEM *_cf_item_remove(CONF_ITEM *parent, CONF_ITEM *child) /* * Fixup the linked list */ - fr_dlist_remove(&parent->children, child); + prev = fr_dlist_remove(&parent->children, child); in_ident1 = (fr_rb_remove_by_inline_node(parent->ident1, &child->ident1_node) != NULL); @@ -476,7 +496,7 @@ CONF_ITEM *_cf_item_remove(CONF_ITEM *parent, CONF_ITEM *child) } } - return child; + return prev; } /** Return the next child of cs @@ -941,17 +961,42 @@ CONF_SECTION *cf_section_dup(TALLOC_CTX *ctx, CONF_SECTION *parent, CONF_SECTION return new; } +/** Return the first child in a CONF_SECTION + * + * @param[in] cs to return children from. + * @return + * - The next #CONF_ITEM that's a child of cs and a CONF_SECTION. + * - NULL if no #CONF_ITEM matches that criteria. + */ +CONF_SECTION *cf_section_first(CONF_SECTION const *cs) +{ + return cf_item_to_section(cf_next(cf_section_to_item(cs), NULL, CONF_ITEM_SECTION)); +} + /** Return the next child that's a #CONF_SECTION * * @param[in] cs to return children from. - * @param[in] prev child to start searching from. + * @param[in] curr child to start searching from. + * @return + * - The next #CONF_ITEM that's a child of cs and a CONF_SECTION. + * - NULL if no #CONF_ITEM matches that criteria. + */ +CONF_SECTION *cf_section_next(CONF_SECTION const *cs, CONF_SECTION const *curr) +{ + return cf_item_to_section(cf_next(cf_section_to_item(cs), cf_section_to_item(curr), CONF_ITEM_SECTION)); +} + +/** Return the previous child that's a #CONF_SECTION + * + * @param[in] cs to return children from. + * @param[in] curr child to start searching from. * @return * - The next #CONF_ITEM that's a child of cs and a CONF_SECTION. * - NULL if no #CONF_ITEM matches that criteria. */ -CONF_SECTION *cf_section_next(CONF_SECTION const *cs, CONF_SECTION const *prev) +CONF_SECTION *cf_section_prev(CONF_SECTION const *cs, CONF_SECTION const *curr) { - return cf_item_to_section(cf_next(cf_section_to_item(cs), cf_section_to_item(prev), CONF_ITEM_SECTION)); + return cf_item_to_section(cf_prev(cf_section_to_item(cs), cf_section_to_item(curr), CONF_ITEM_SECTION)); } /** Find a CONF_SECTION with name1 and optionally name2. @@ -1291,15 +1336,13 @@ CONF_PAIR *cf_pair_dup(CONF_SECTION *parent, CONF_PAIR *cp, bool copy_meta) int cf_pair_replace(CONF_SECTION *cs, CONF_PAIR *cp, char const *value) { CONF_PAIR *new_cp; - CONF_ITEM *ci; if (!cs || !cp || !value) return -1; /* * Remove the old CONF_PAIR */ - ci = cf_item_remove(cs, cp); - if (!fr_cond_assert(!ci || (ci == cf_pair_to_item(cp)))) return -1; + (void)cf_item_remove(cs, cp); /* * Add the new CONF_PAIR @@ -1336,14 +1379,39 @@ bool cf_pair_is_parsed(CONF_PAIR *cp) /** Return the next child that's a #CONF_PAIR * * @param[in] cs to return children from. - * @param[in] prev child to start searching from. * @return * - The next #CONF_ITEM that's a child of cs and a CONF_PAIR. * - NULL if no #CONF_ITEM matches that criteria. */ -CONF_PAIR *cf_pair_next(CONF_SECTION const *cs, CONF_PAIR const *prev) +CONF_PAIR *cf_pair_first(CONF_SECTION const *cs) +{ + return cf_item_to_pair(cf_next(cf_section_to_item(cs), NULL, CONF_ITEM_PAIR)); +} + +/** Return the next child that's a #CONF_PAIR + * + * @param[in] cs to return children from. + * @param[in] curr child to start searching from. + * @return + * - The next #CONF_ITEM that's a child of cs and a CONF_PAIR. + * - NULL if no #CONF_ITEM matches that criteria. + */ +CONF_PAIR *cf_pair_next(CONF_SECTION const *cs, CONF_PAIR const *curr) +{ + return cf_item_to_pair(cf_next(cf_section_to_item(cs), cf_pair_to_item(curr), CONF_ITEM_PAIR)); +} + +/** Return the next child that's a #CONF_PAIR + * + * @param[in] cs to return children from. + * @param[in] curr child to start searching from. + * @return + * - The next #CONF_ITEM that's a child of cs and a CONF_PAIR. + * - NULL if no #CONF_ITEM matches that criteria. + */ +CONF_PAIR *cf_pair_prev(CONF_SECTION const *cs, CONF_PAIR const *curr) { - return cf_item_to_pair(cf_next(cf_section_to_item(cs), cf_pair_to_item(prev), CONF_ITEM_PAIR)); + return cf_item_to_pair(cf_prev(cf_section_to_item(cs), cf_pair_to_item(curr), CONF_ITEM_PAIR)); } /** Search for a #CONF_PAIR with a specific name @@ -1790,13 +1858,10 @@ CONF_DATA const *_cf_data_add_static(CONF_ITEM *ci, void const *data, char const void *_cf_data_remove(CONF_ITEM *parent, CONF_DATA const *cd) { void *data; - CONF_ITEM *ci; if (!cd) return NULL; - ci = cf_item_remove(parent, cd); - if (!fr_cond_assert(!ci || (ci == cf_data_to_item(cd)))) return NULL; - if (!ci) return NULL; + (void)cf_item_remove(parent, cd); talloc_set_destructor(cd, NULL); /* Disarm the destructor */ memcpy(&data, &cd->data, sizeof(data)); @@ -2250,7 +2315,7 @@ void _cf_debug(CONF_ITEM const *ci) DEBUG(" filename : %s", ci->filename); DEBUG(" line : %i", ci->lineno); - DEBUG(" next : %p", fr_dlist_next(&ci->parent->children, ci)); + if (ci->parent) DEBUG(" next : %p", fr_dlist_next(&ci->parent->children, ci)); DEBUG(" parent : %p", ci->parent); DEBUG(" children : %s", cf_item_has_no_children(ci) ? "no" : "yes"); DEBUG(" ident1 tree : %p (%u entries)", ci->ident1, ci->ident1 ? fr_rb_num_elements(ci->ident1) : 0); diff --git a/src/lib/server/cf_util.h b/src/lib/server/cf_util.h index 4ecbb5f77b..a1e3d0560c 100644 --- a/src/lib/server/cf_util.h +++ b/src/lib/server/cf_util.h @@ -145,8 +145,19 @@ CONF_SECTION *_cf_section_alloc(TALLOC_CTX *ctx, CONF_SECTION *parent, char const *filename, int lineno); CONF_SECTION *cf_section_dup(TALLOC_CTX *ctx, CONF_SECTION *parent, CONF_SECTION const *cs, char const *name1, char const *name2, bool copy_meta); + +#define cf_section_foreach(_parent, _iter) \ + for (CONF_SECTION *_iter = cf_section_first(_parent); _iter; _iter = cf_section_next(_parent, _iter)) + /** @hidecallergraph */ -CONF_SECTION *cf_section_next(CONF_SECTION const *cs, CONF_SECTION const *prev); +CONF_SECTION *cf_section_first(CONF_SECTION const *cs); + +/** @hidecallergraph */ +CONF_SECTION *cf_section_next(CONF_SECTION const *cs, CONF_SECTION const *curr); + +/** @hidecallergraph */ +CONF_SECTION *cf_section_prev(CONF_SECTION const *cs, CONF_SECTION const *curr); + /** @hidecallergraph */ CONF_SECTION *cf_section_find(CONF_SECTION const *cs, char const *name1, char const *name2); /** @hidecallergraph */ @@ -190,7 +201,11 @@ void cf_pair_mark_parsed(CONF_PAIR *cp); bool cf_pair_is_parsed(CONF_PAIR *cp); -CONF_PAIR *cf_pair_next(CONF_SECTION const *cs, CONF_PAIR const *prev); +CONF_PAIR *cf_pair_first(CONF_SECTION const *cs); + +CONF_PAIR *cf_pair_next(CONF_SECTION const *cs, CONF_PAIR const *curr); + +CONF_PAIR *cf_pair_prev(CONF_SECTION const *cs, CONF_PAIR const *curr); CONF_PAIR *cf_pair_find(CONF_SECTION const *cs, char const *name);