]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
Add more cf boilerplate, and have cf_item_remove return the previous item to make...
authorArran Cudbard-Bell <a.cudbardb@freeradius.org>
Wed, 15 May 2024 03:55:35 +0000 (21:55 -0600)
committerArran Cudbard-Bell <a.cudbardb@freeradius.org>
Wed, 15 May 2024 04:25:43 +0000 (22:25 -0600)
src/lib/server/cf_priv.h
src/lib/server/cf_util.c
src/lib/server/cf_util.h

index 02d0f3d44876c616b253005ed86af8e1e346fa73..42a714498c5d595be723456360fab53d04663cd6 100644 (file)
@@ -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
index a9bc02401709583f0ff02f5f31bf9ea3ba561583..1bc692893d312bfe6598b70e5a18dca94ec5319c 100644 (file)
@@ -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);
index 4ecbb5f77b72ea4b5962916343e9af49cd3e9fb1..a1e3d0560cb160ef8efe39e9e7d0d7f0f7b8bbd3 100644 (file)
@@ -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);