From: Alan T. DeKok Date: Wed, 17 Aug 2022 18:19:11 +0000 (-0400) Subject: add fr_pair_dcursor_nested_init() X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=11abde6444702376fd44a8ffb8dce06f66fcbfa7;p=thirdparty%2Ffreeradius-server.git add fr_pair_dcursor_nested_init() which takes a pair dcursor as input uctx, and iterates over that to produce value-pairs. This is needed by the xlat / edit code --- diff --git a/src/lib/util/pair.c b/src/lib/util/pair.c index 4125053c7e3..53e70d11b7f 100644 --- a/src/lib/util/pair.c +++ b/src/lib/util/pair.c @@ -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. diff --git a/src/lib/util/pair.h b/src/lib/util/pair.h index aef5843b411..17f3fff5b67 100644 --- a/src/lib/util/pair.h +++ b/src/lib/util/pair.h @@ -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