]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
add fr_pair_dcursor_nested_init()
authorAlan T. DeKok <aland@freeradius.org>
Wed, 17 Aug 2022 18:19:11 +0000 (14:19 -0400)
committerAlan T. DeKok <aland@freeradius.org>
Mon, 22 Aug 2022 00:34:07 +0000 (20:34 -0400)
which takes a pair dcursor as input uctx, and iterates over that
to produce value-pairs.

This is needed by the xlat / edit code

src/lib/util/pair.c
src/lib/util/pair.h

index 4125053c7e3896cc3784b39cc1c0c3e7aed50d3b..53e70d11b7ffc8002d16001dbd96bffd687f7c0e 100644 (file)
@@ -1096,7 +1096,7 @@ fr_pair_t *_fr_pair_dcursor_by_ancestor_init(fr_dcursor_t *cursor,
  * @param[in] list     to iterate over.
  * @param[in] current  The fr_value_box_t cursor->current.  Will be advanced and checked to
  *                     see if it matches the specified fr_dict_attr_t.
- * @param[in] uctx     The fr_dict_attr_t to search for.
+ * @param[in] uctx     unused
  * @return
  *     - Next matching fr_pair_t.
  *     - NULL if not more matching fr_pair_ts could be found.
@@ -1142,6 +1142,58 @@ fr_value_box_t *_fr_pair_dcursor_value_init(fr_dcursor_t *cursor, fr_pair_list_t
                                _fr_pair_iter_next_value, NULL, NULL, NULL, NULL, NULL, is_const);
 }
 
+/** Iterate over pairs
+ *
+ * @param[in] list     to iterate over.
+ * @param[in] current  The fr_value_box_t cursor->current.  Will be advanced and checked to
+ *                     see if it matches the specified fr_dict_attr_t.
+ * @param[in] uctx     The parent dcursor
+ * @return
+ *     - Next matching fr_pair_t.
+ *     - NULL if not more matching fr_pair_ts could be found.
+ */
+static void *_fr_pair_iter_next_dcursor_value(UNUSED fr_dlist_head_t *list, void *current, void *uctx)
+{
+       fr_pair_t *vp;
+       fr_dcursor_t *parent = uctx;
+
+       if (!current) {
+               vp = NULL;
+       } else {
+               vp = (fr_pair_t *) ((uint8_t *) current - offsetof(fr_pair_t, data));
+               PAIR_VERIFY(vp);
+       }
+
+       while ((vp = fr_dcursor_next(parent))) {
+               PAIR_VERIFY(vp);
+
+               if (!fr_type_is_leaf(vp->da->type)) break;
+
+               continue;
+       }
+
+       return vp;
+}
+
+/** Initialises a special dcursor over another cursor which returns #fr_pair_t, but we return #fr_value_box_t
+ *
+ * Filters can be applied later with fr_dcursor_filter_set.
+ *
+ * @param[out] cursor  to initialise.
+ * @param[in] list     to iterate over.
+ * @param[in] parent   to iterate over
+ * @param[in] is_const whether the fr_pair_list_t is const.
+ * @return
+ *     - NULL if src does not point to any items.
+ *     - The first pair in the list.
+ */
+fr_value_box_t *_fr_pair_dcursor_nested_init(fr_dcursor_t *cursor, fr_pair_list_t const *list, fr_dcursor_t *parent,
+                                           bool is_const)
+{
+       return _fr_dcursor_init(cursor, fr_pair_order_list_dlist_head(&list->order),
+                               _fr_pair_iter_next_dcursor_value, NULL, NULL, NULL, NULL, parent, is_const);
+}
+
 /** Add a VP to the start of the list.
  *
  * Links an additional VP 'add' at the beginning a list.
index aef5843b4115cc8ffd1ee52d555ebffc454baa8a..17f3fff5b6706c62953fd4bf7c65dba4dc6c8dfa 100644 (file)
@@ -607,6 +607,24 @@ fr_value_box_t     *_fr_pair_dcursor_value_init(fr_dcursor_t *cursor, fr_pair_list_t
                                             bool is_const) CC_HINT(nonnull);
 
 
+/** Initialises a special dcursor which returns only the values of a pair from a parent dcursor
+ *
+ *  @note - the list cannot be modified, and structural attributes are not returned.
+ *
+ * @param[out] cursor  to initialise.
+ * @param[in] list     to iterate over.
+ * @return
+ *     - NULL if src does not point to any items.
+ *     - The first pair in the list.
+ */
+#define                fr_pair_dcursor_nested_init(_cursor, _list, _parent) \
+               _fr_pair_dcursor_nested_init(_cursor, \
+                                           _list,    \
+                                           _parent,    \
+                                           IS_CONST(fr_pair_list_t *, _list))
+fr_value_box_t *_fr_pair_dcursor_nested_init(fr_dcursor_t *cursor, fr_pair_list_t const *list, fr_dcursor_t *parent,
+                                            bool is_const) CC_HINT(nonnull);
+
 /** Compare two attributes using and operator.
  *
  * @return