]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
add APIs to get parent list / vp from an input vp
authorAlan T. DeKok <aland@freeradius.org>
Fri, 8 Apr 2022 13:17:00 +0000 (09:17 -0400)
committerAlan T. DeKok <aland@freeradius.org>
Fri, 8 Apr 2022 13:17:29 +0000 (09:17 -0400)
which means that the caller has to do less tracking, if it wants

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

index f36a84fdb73d64360209ce85165a9ef26e005726..20fd0e80c4d477fefba07924d471263c915e9692 100644 (file)
@@ -47,6 +47,8 @@ void fr_pair_list_init(fr_pair_list_t *list)
         *      all of them.
         */
        fr_pair_order_list_talloc_init(&list->order);
+
+       list->is_child = false;
 }
 
 /** Free a fr_pair_t
@@ -180,6 +182,7 @@ static inline CC_HINT(always_inline) void pair_init_from_da(fr_pair_t *vp, fr_di
        } else {
                vp->type = da->type; /* overlaps with vp->vp_type, and everyone needs it! */
                fr_pair_list_init(&vp->vp_group);
+               vp->vp_group.is_child = true;
                fr_pair_order_list_talloc_init_children(vp, &vp->vp_group.order);
        }
 }
@@ -813,16 +816,6 @@ fr_pair_t *fr_pair_find_by_child_num_idx(fr_pair_list_t const *list,
        return fr_pair_find_by_da_idx(list, da, idx);
 }
 
-/** Return a pointer to the pair list
- *
- */
-static inline CC_HINT(always_inline) CC_HINT(nonnull) fr_pair_list_t *pair_children(fr_pair_t *vp)
-{
-       if (fr_type_is_structural(vp->da->type)) return &vp->vp_group;
-
-       return NULL;
-}
-
 /** Get the child list of a group
  *
  * @param[in] vp       which MUST be of a type
@@ -833,7 +826,38 @@ static inline CC_HINT(always_inline) CC_HINT(nonnull) fr_pair_list_t *pair_child
  */
 fr_pair_list_t *fr_pair_children(fr_pair_t *vp)
 {
-       return pair_children(vp);
+       if (!fr_type_is_structural(vp->da->type)) return NULL;
+
+       return &vp->vp_group;
+}
+
+/** Return a pointer to the parent pair list
+ *
+ */
+fr_pair_list_t *fr_pair_parent_list(fr_pair_t const *vp)
+{
+       FR_TLIST_HEAD(fr_pair_order_list) *parent;
+
+       if (!vp) return NULL;
+
+       parent = fr_pair_order_list_parent(vp);
+       if (!parent) return NULL;
+
+       return (fr_pair_list_t *) (UNCONST(uint8_t *, parent) - offsetof(fr_pair_list_t, order));
+}
+
+/** Return a pointer to the parent pair.
+ *
+ */
+fr_pair_t *fr_pair_parent(fr_pair_t const *vp)
+{
+       fr_pair_list_t *list = fr_pair_parent_list(vp);
+
+       if (!list) return NULL;
+
+       if (!list->is_child) return NULL;
+
+       return (fr_pair_t *) (UNCONST(uint8_t *, list) - offsetof(fr_pair_t, vp_group));
 }
 
 /** Keep attr tree and sublists synced on cursor insert
index b23ace0ebe83783507b15f317407e94bcc009498..7339a8d0cc161a106aec6972ac18613339ff3d8a 100644 (file)
@@ -50,7 +50,9 @@ typedef struct value_pair_s fr_pair_t;
 FR_TLIST_TYPES(fr_pair_order_list)
 
 typedef struct {
-        FR_TLIST_HEAD(fr_pair_order_list)              order;                  //!< Maintains the relative order of pairs in a list.
+        FR_TLIST_HEAD(fr_pair_order_list)      order;                  //!< Maintains the relative order of pairs in a list.
+
+       bool                             _CONST is_child;               //!< is a child of a VP
 } fr_pair_list_t;
 
 /** Stores an attribute, a value and various bits of other data
@@ -289,6 +291,10 @@ fr_pair_t  *fr_pair_delete(fr_pair_list_t *list, fr_pair_t *vp) CC_HINT(nonnull);
 /* functions for FR_TYPE_STRUCTURAL */
 fr_pair_list_t *fr_pair_children(fr_pair_t *head) CC_HINT(nonnull);
 
+fr_pair_list_t *fr_pair_parent_list(fr_pair_t const *vp);
+
+fr_pair_t *fr_pair_parent(fr_pair_t const *vp);
+
 /** Initialises a special dcursor with callbacks that will maintain the attr sublists correctly
  *
  * Filters can be applied later with fr_dcursor_filter_set.