48 RCSID(
"$Id: 64d211a250036ca5102ed65474d431be3773b387 $")
50 #include <freeradius-devel/util/value.h>
51 #include <freeradius-devel/util/talloc.h>
68 static const char *edit_names[4] = {
265 if (i->list != list)
continue;
344 if (e->
vp !=
vp)
continue;
607 if (
vp->
da != da)
continue;
639 if (
vp->vp_immutable) {
660 if (to_replace->
da !=
vp->
da)
return -1;
803 if (!
el)
return NULL;
843 if (
el->parent)
return;
959 if (rcode < 0)
return -1;
961 if (!rcode)
continue;
987 if (box.vb_bool)
return 0;
1009 #define COPY(_x) do { if (copy) { \
1010 c = fr_pair_copy(dst, _x); \
1011 if (!c) return -1; \
1013 c = talloc_steal(dst, _x); \
1014 fr_pair_remove(src, c); \
1018 #define NEXT_A do { a = an; an = fr_pair_list_next(&dst->children, a); } while (0)
1019 #define NEXT_B do { b = bn; bn = fr_pair_list_next(src, b); } while (0)
1041 fr_strerror_printf(
"Cannot take union of STRUCT data types, it would break the structure");
1124 if (rcode < 0)
return rcode;
1137 while (a && b && (a->
da == b->
da)) {
1247 if (rcode < 0)
return rcode;
1351 if (rcode < 0)
return rcode;
1384 fr_strerror_printf(
"Cannot take intersection of STRUCT data types, it would break the structure");
1426 if (rcode < 0)
goto delete_a;
1447 if (rcode < 0)
return rcode;
1461 while (a && b && (a->
da == b->
da)) {
1498 #define COPY do { if (copy) { \
1499 fr_pair_list_init(&list); \
1500 if (fr_pair_list_copy(dst, &list, src) < 0) return -1;\
1503 fr_pair_list_steal(dst, src); \
1514 if (&dst->children == src)
return 0;
1520 if (&dst->children == src) {
1532 if (&dst->children == src) {
1545 if (&dst->children == src) {
1554 if (&dst->children == src)
return 0;
1565 if (&dst->children == src)
return 0;
1572 if (&dst->children == src)
return 0;
1579 if (&dst->children == src)
return 0;
#define FALL_THROUGH
clang 10 doesn't recognised the FALL-THROUGH comment anymore
int fr_value_calc_assignment_op(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_token_t op, fr_value_box_t const *src)
Calculate DST OP SRC.
int fr_value_calc_binary_op(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_type_t hint, fr_value_box_t const *a, fr_token_t op, fr_value_box_t const *b)
Calculate DST = A OP B.
#define fr_dlist_init(_head, _type, _field)
Initialise the head structure of a doubly linked list.
#define fr_dlist_foreach(_list_head, _type, _iter)
Iterate over the contents of a list.
static void * fr_dlist_next(fr_dlist_head_t const *list_head, void const *ptr)
Get the next item in a list.
static void * fr_dlist_pop_tail(fr_dlist_head_t *list_head)
Remove the tail item in a list.
static bool fr_dlist_empty(fr_dlist_head_t const *list_head)
Check whether a list has any items.
static void * fr_dlist_head(fr_dlist_head_t const *list_head)
Return the HEAD item of a list or NULL if the list is empty.
static int fr_dlist_insert_tail(fr_dlist_head_t *list_head, void *ptr)
Insert an item into the tail of a list.
static void * fr_dlist_remove(fr_dlist_head_t *list_head, void *ptr)
Remove an item from the list.
Head of a doubly linked list.
Entry in a doubly linked list.
@ FR_TYPE_STRUCT
like TLV, but without T or L, and fixed-width children
@ FR_TYPE_BOOL
A truth value.
fr_pair_t * fr_pair_find_by_da(fr_pair_list_t const *list, fr_pair_t const *prev, fr_dict_attr_t const *da)
Find the first pair with a matching da.
int8_t fr_pair_cmp_by_parent_num(void const *a, void const *b)
Order attributes by their parent(s), attribute number, and tag.
int fr_pair_append(fr_pair_list_t *list, fr_pair_t *to_add)
Add a VP to the end of the list.
int fr_pair_delete_by_da(fr_pair_list_t *list, fr_dict_attr_t const *da)
Delete matching pairs from the specified list.
void fr_pair_list_init(fr_pair_list_t *list)
Initialise a pair list header.
bool fr_pair_immutable(fr_pair_t const *vp)
int fr_pair_delete(fr_pair_list_t *list, fr_pair_t *vp)
Remove fr_pair_t from a list and free.
int fr_pair_insert_after(fr_pair_list_t *list, fr_pair_t *pos, fr_pair_t *to_add)
Add a VP after another VP.
int fr_pair_prepend(fr_pair_list_t *list, fr_pair_t *to_add)
Add a VP to the start of the list.
Stores an attribute, a value and various bits of other data.
fr_dict_attr_t const *_CONST da
Dictionary attribute defines the attribute number, vendor and type of the pair.
#define talloc_zero_pooled_object(_ctx, _type, _num_subobjects, _total_subobjects_size)
char const * fr_tokens[T_TOKEN_LAST]
static fr_event_list_t * el
int fr_edit_list_apply_list_assignment(fr_edit_list_t *el, fr_pair_t *dst, fr_token_t op, fr_pair_list_t *src, bool copy)
Apply operators to lists.
int fr_edit_list_pair_delete(fr_edit_list_t *el, fr_pair_list_t *list, fr_pair_t *vp)
Delete a VP.
int fr_edit_list_replace_pair_value(fr_edit_list_t *el, fr_pair_t *vp, fr_value_box_t *box)
Write a new value to the fr_value_box_t.
static int edit_undo(fr_edit_t *e)
Undo one particular edit.
void fr_edit_list_commit(fr_edit_list_t *el)
Commit an edit list.
fr_edit_op_t op
edit operation to perform
fr_edit_list_t * parent
for nested transactions
int fr_edit_list_insert_pair_after(fr_edit_list_t *el, fr_pair_list_t *list, fr_pair_t *pos, fr_pair_t *vp)
Insert a new VP after an existing one.
fr_dlist_t entry
linked list of edits
int fr_edit_list_save_pair_value(fr_edit_list_t *el, fr_pair_t *vp)
Record the value of a leaf fr_value_box_t.
static int _edit_list_destructor(fr_edit_list_t *el)
Finalize the edits when we destroy the edit list.
static int list_merge_lhs(fr_edit_list_t *el, fr_pair_t *dst, fr_pair_list_t *src, bool copy)
A MERGE B.
static int edit_record(fr_edit_list_t *el, fr_edit_op_t op, fr_pair_t *vp, fr_pair_list_t *list, fr_pair_t *ref)
Record one particular edit.
static int fr_edit_list_delete_list(fr_edit_list_t *el, fr_pair_list_t *list, fr_pair_list_t *to_remove)
Removes elements matching a list.
int fr_edit_list_insert_list_after(fr_edit_list_t *el, fr_pair_list_t *list, fr_pair_t *pos, fr_pair_list_t *to_insert)
Notes.
void fr_edit_list_abort(fr_edit_list_t *el)
Abort the entries in an edit list.
int fr_edit_list_replace_pair(fr_edit_list_t *el, fr_pair_list_t *list, fr_pair_t *to_replace, fr_pair_t *vp)
Replace a pair with another one.
static int list_intersection(fr_edit_list_t *el, fr_pair_t *dst, fr_pair_list_t *src)
A INTERSECTION B.
static int list_merge_rhs(fr_edit_list_t *el, fr_pair_t *dst, fr_pair_list_t *src, bool copy)
A MERGE B.
fr_pair_t * vp
pair edited, deleted, or inserted
fr_dlist_head_t ignore
lists to ignore
fr_pair_list_t deleted_pairs
static bool fr_edit_list_empty(fr_edit_list_t *el)
fr_pair_list_t * list
list to ignore (never dereferenced)
@ FR_EDIT_CHILD
child edit list
@ FR_EDIT_CLEAR
clear the children of a structural entry.
@ FR_EDIT_DELETE
delete a VP
@ FR_EDIT_VALUE
edit a VP in place
@ FR_EDIT_INSERT
insert a VP into a list, after another one.
int fr_edit_list_free_pair_children(fr_edit_list_t *el, fr_pair_t *vp)
Free children of a structural pair.
int fr_edit_list_apply_pair_assignment(fr_edit_list_t *el, fr_pair_t *vp, fr_token_t op, fr_value_box_t const *in)
Apply operators to pairs.
static int list_union(fr_edit_list_t *el, fr_pair_t *dst, fr_pair_list_t *src, bool copy)
A UNION B.
fr_edit_list_t * fr_edit_list_alloc(TALLOC_CTX *ctx, int hint, fr_edit_list_t *parent)
Allocate an edit list.
int fr_edit_list_pair_delete_by_da(fr_edit_list_t *el, fr_pair_list_t *list, fr_dict_attr_t const *da)
Delete VPs with a matching da.
fr_edit_t * e
so we don't have to loop over parent edits on abort
Track one particular edit.
Structures and prototypes for editing lists.
#define fr_edit_list_insert_pair_tail(_el, _list, _vp)
#define fr_edit_list_insert_list_tail(_el, _list, _to_insert)
#define fr_edit_list_insert_pair_before(_el, _list, _pos, _vp)
#define fr_edit_list_insert_list_head(_el, _list, _to_insert)
fr_pair_t * fr_pair_list_head(fr_pair_list_t const *list)
Get the head of a valuepair list.
fr_pair_t * fr_pair_remove(fr_pair_list_t *list, fr_pair_t *vp)
Remove fr_pair_t from a list without freeing.
bool fr_pair_list_empty(fr_pair_list_t const *list)
Is a valuepair list empty.
fr_pair_t * fr_pair_list_next(fr_pair_list_t const *list, fr_pair_t const *item))
Get the next item in a valuepair list after a specific entry.
void fr_pair_list_sort(fr_pair_list_t *list, fr_cmp_t cmp)
Sort a doubly linked list of fr_pair_ts using merge sort.
#define fr_pair_list_foreach(_list_head, _iter)
Iterate over the contents of a fr_pair_list_t.
void fr_pair_list_free(fr_pair_list_t *list)
Free memory used by a valuepair list.
void fr_pair_list_append(fr_pair_list_t *dst, fr_pair_list_t *src)
Appends a list of fr_pair_t from a temporary list to a destination list.
fr_pair_t * fr_pair_list_prev(fr_pair_list_t const *list, fr_pair_t const *item))
Get the previous item in a valuepair list before a specific entry.
#define PAIR_LIST_VERIFY(_x)
#define fr_strerror_printf(_fmt,...)
Log to thread local error buffer.
static char const * fr_type_to_str(fr_type_t type)
Return a static string containing the type name.
#define fr_type_is_structural(_x)
#define fr_type_is_fixed_size(_x)
#define fr_type_is_leaf(_x)
int fr_value_box_cast(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_type_t dst_type, fr_dict_attr_t const *dst_enumv, fr_value_box_t const *src)
Convert one type of fr_value_box_t to another.
int8_t fr_value_box_cmp(fr_value_box_t const *a, fr_value_box_t const *b)
Compare two values.
int fr_value_box_copy(TALLOC_CTX *ctx, fr_value_box_t *dst, const fr_value_box_t *src)
Copy value data verbatim duplicating any buffers.
int fr_value_box_cmp_op(fr_token_t op, fr_value_box_t const *a, fr_value_box_t const *b)
Compare two attributes using an operator.
void fr_value_box_copy_shallow(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_value_box_t const *src)
Perform a shallow copy of a value_box.
void fr_value_box_clear_value(fr_value_box_t *data)
Clear/free any existing value.
void fr_value_box_clear(fr_value_box_t *data)
Clear/free any existing value and metadata.
#define fr_value_box_init_null(_vb)
Initialise an empty/null box that will be filled later.