From: Alan T. DeKok Date: Thu, 25 Nov 2021 21:30:49 +0000 (-0500) Subject: rename functions and add a few more helper functions X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=819eb3945af9b43b9e1b5b78c2449f7f6bdccb74;p=thirdparty%2Ffreeradius-server.git rename functions and add a few more helper functions --- diff --git a/src/lib/util/edit.c b/src/lib/util/edit.c index a29e3983b36..c59c89092b4 100644 --- a/src/lib/util/edit.c +++ b/src/lib/util/edit.c @@ -28,6 +28,7 @@ RCSID("$Id$") #include #include #include "edit.h" +#include "calc.h" typedef enum { FR_EDIT_INVALID = 0, @@ -409,7 +410,7 @@ static int edit_record(fr_edit_list_t *el, fr_edit_op_t op, fr_pair_t *vp, fr_pa * After this function returns, the new VP has been inserted into the * list. */ -int fr_edit_list_insert_after(fr_edit_list_t *el, fr_pair_list_t *list, fr_pair_t *pos, fr_pair_t *vp) +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) { if (!el) return 0; @@ -423,7 +424,7 @@ int fr_edit_list_insert_after(fr_edit_list_t *el, fr_pair_list_t *list, fr_pair_ * * After this function returns, the VP has been removed from the list. */ -int fr_edit_list_delete(fr_edit_list_t *el, fr_pair_list_t *list, fr_pair_t *vp) +int fr_edit_list_pair_delete(fr_edit_list_t *el, fr_pair_list_t *list, fr_pair_t *vp) { return edit_record(el, FR_EDIT_DELETE, vp, list, NULL); } @@ -432,7 +433,7 @@ int fr_edit_list_delete(fr_edit_list_t *el, fr_pair_list_t *list, fr_pair_t *vp) * * After this function returns, it's safe to edit the pair. */ -int fr_edit_list_save_value(fr_edit_list_t *el, fr_pair_t *vp) +int fr_edit_list_save_pair_value(fr_edit_list_t *el, fr_pair_t *vp) { if (!el) return 0; @@ -445,7 +446,7 @@ int fr_edit_list_save_value(fr_edit_list_t *el, fr_pair_t *vp) * * After this function returns, the value has been updated. */ -int fr_edit_list_replace_value(fr_edit_list_t *el, fr_pair_t *vp, fr_value_box_t *box) +int fr_edit_list_replace_pair_value(fr_edit_list_t *el, fr_pair_t *vp, fr_value_box_t *box) { if (!el) return 0; @@ -465,7 +466,7 @@ int fr_edit_list_replace_value(fr_edit_list_t *el, fr_pair_t *vp, fr_value_box_t * After this function returns, the new VP has replaced the old one, * and the new one can be edited. */ -int fr_edit_list_replace(fr_edit_list_t *el, fr_pair_list_t *list, fr_pair_t *to_replace, fr_pair_t *vp) +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) { if (!el) return 0; @@ -507,7 +508,7 @@ int fr_edit_list_replace(fr_edit_list_t *el, fr_pair_list_t *list, fr_pair_t *to * After this function returns, the new VP has replaced the old one, * and the new one can be edited. */ -int fr_edit_list_free_children(fr_edit_list_t *el, fr_pair_t *vp) +int fr_edit_list_free_pair_children(fr_edit_list_t *el, fr_pair_t *vp) { if (!el) return 0; @@ -521,42 +522,6 @@ int fr_edit_list_free_children(fr_edit_list_t *el, fr_pair_t *vp) return edit_record(el, FR_EDIT_CLEAR, vp, NULL, NULL); } -/** Insert a list after a particular point in another list. - * - * This function mirrors fr_pair_list_append(), but with a bit more - * control over where the to_insert list ends up. - * - * There's nothing magical about this function, it's just easier to - * have it here than in multiple places in the code. - */ -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) -{ - fr_pair_t *prev, *vp; - - if (!el) return 0; - - prev = pos; - - /* - * We have to record each individual insert as a separate - * item. Some later edit may insert pairs in the middle - * of the ones we've added. - */ - while ((vp = fr_pair_list_head(to_insert)) != NULL) { - (void) fr_pair_remove(to_insert, vp); - - if (edit_record(el, FR_EDIT_INSERT, vp, list, prev) < 0) { - fr_pair_prepend(to_insert, vp); /* don't lose it! */ - return -1; - } - - prev = vp; - } - - return 0; -} - - /** Finalize the edits when we destroy the edit list. * * Which in large part means freeing the VPs which have been deleted, @@ -642,3 +607,151 @@ fr_edit_list_t *fr_edit_list_alloc(TALLOC_CTX *ctx, int hint) * free temporary map * commit(edit list) */ + +/********************************************************************** + * + * Now we have helper functions which use the edit list to get things + * done. + * + **********************************************************************/ + +/** Insert a list after a particular point in another list. + * + * This function mirrors fr_pair_list_append(), but with a bit more + * control over where the to_insert list ends up. + * + * There's nothing magical about this function, it's just easier to + * have it here than in multiple places in the code. + */ +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) +{ + fr_pair_t *prev, *vp; + + if (!el) return 0; + + prev = pos; + + /* + * We have to record each individual insert as a separate + * item. Some later edit may insert pairs in the middle + * of the ones we've added. + */ + while ((vp = fr_pair_list_head(to_insert)) != NULL) { + (void) fr_pair_remove(to_insert, vp); + + if (edit_record(el, FR_EDIT_INSERT, vp, list, prev) < 0) { + fr_pair_prepend(to_insert, vp); /* don't lose it! */ + return -1; + } + + prev = vp; + } + + return 0; +} + +/** Apply operators to pairs. + * + * := is "if found vp, call fr_pair_replace(). Otherwise call fr_edit_list_insert_pair_tail() + * = is "if found vp, do nothing. Otherwise call fr_edit_list_insert_pair_tail() + * + */ +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) +{ + if (fr_edit_list_save_pair_value(el, vp) < 0) return -1; + + if (fr_value_calc_assignment_op(vp, &vp->data, op, in) < 0) return -1; + + return 0; +} + +/** Apply operators to lists. + * + * = is "if found vp, do nothing. Otherwise call fr_edit_list_insert_pair_tail() + * + * The src list MUST have been talloc'd from the right place already. + */ +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) +{ + if (!fr_type_is_structural(dst->vp_type)) { + return -1; + } + + switch (op) { + /* + * Over-ride existing value (i.e. children) with + * new list. + */ + case T_OP_SET: + if (fr_edit_list_free_pair_children(el, dst) < 0) return -1; + FALL_THROUGH; + + case T_OP_ADD_EQ: + return fr_edit_list_insert_list_tail(el, &dst->children, src); + + case T_OP_PREPEND: + return fr_edit_list_insert_list_head(el, &dst->children, src); + + default: + break; + } + + fr_strerror_printf("Invalid assignment operator %s for destination type %s", + fr_tokens[op], + fr_table_str_by_value(fr_value_box_type_table, dst->type, "")); + return -1; +} + +/** Apply operators to lists. + * + * = is "if found vp, do nothing. Otherwise call fr_edit_list_insert_pair_tail() + * + * The src list here is "const". This is a separate function, which + * means that in many cases we can avoid copying the source list. + * + * This isn't much use for simple operations, but it can have + * significant benefits for union, merge, etc. where only some of the + * source list is copied. + */ +int fr_edit_list_apply_list_assignment_const(fr_edit_list_t *el, fr_pair_t *dst, fr_token_t op, fr_pair_list_t const *src) +{ + fr_pair_list_t copy; + + if (!fr_type_is_structural(dst->vp_type)) { + return -1; + } + +#define COPY do { \ + fr_pair_list_init(©); \ + if (fr_pair_list_copy(dst, ©, src) < 0) return -1; \ + } while (0) + + + switch (op) { + /* + * Over-ride existing value (i.e. children) with + * new list. + */ + case T_OP_SET: + if (fr_edit_list_free_pair_children(el, dst) < 0) return -1; + FALL_THROUGH; + + case T_OP_ADD_EQ: + COPY; + + return fr_edit_list_insert_list_tail(el, &dst->children, ©); + + case T_OP_PREPEND: + COPY; + + return fr_edit_list_insert_list_head(el, &dst->children, ©); + + default: + break; + } + + fr_strerror_printf("Invalid assignment operator %s for destination type %s", + fr_tokens[op], + fr_table_str_by_value(fr_value_box_type_table, dst->type, "")); + return -1; +} diff --git a/src/lib/util/edit.h b/src/lib/util/edit.h index e83872862c2..0d847ea6fcc 100644 --- a/src/lib/util/edit.h +++ b/src/lib/util/edit.h @@ -39,20 +39,39 @@ void fr_edit_list_abort(fr_edit_list_t *el); #define fr_edit_list_commit(_x) talloc_free(_x) -int fr_edit_list_insert_after(fr_edit_list_t *el, fr_pair_list_t *list, fr_pair_t *pos, fr_pair_t *vp) CC_HINT(nonnull(2,4)); +/* + * Functions to modify #fr_pair_t + */ +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) CC_HINT(nonnull(2,4)); + +#define fr_edit_list_insert_pair_head(_el, _list, _vp) fr_edit_list_insert_after(_el, _list, NULL, _vp) + +#define fr_edit_list_insert_pair_tail(_el, _list, _vp) fr_edit_list_insert_after(_el, _list, fr_pair_list_tail(_list), _vp) + +int fr_edit_list_pair_delete(fr_edit_list_t *el, fr_pair_list_t *list, fr_pair_t *vp) CC_HINT(nonnull(2,3)); -int fr_edit_list_delete(fr_edit_list_t *el, fr_pair_list_t *list, fr_pair_t *vp) CC_HINT(nonnull(2,3)); +int fr_edit_list_save_pair_value(fr_edit_list_t *el, fr_pair_t *vp) CC_HINT(nonnull(2)); -int fr_edit_list_save_value(fr_edit_list_t *el, fr_pair_t *vp) CC_HINT(nonnull(2)); +int fr_edit_list_replace_pair_value(fr_edit_list_t *el, fr_pair_t *vp, fr_value_box_t *box) CC_HINT(nonnull(2,3)); -int fr_edit_list_replace_value(fr_edit_list_t *el, fr_pair_t *vp, fr_value_box_t *box) CC_HINT(nonnull(2,3)); +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) CC_HINT(nonnull(2,3,4)); -int fr_edit_list_replace(fr_edit_list_t *el, fr_pair_list_t *list, fr_pair_t *to_replace, fr_pair_t *vp) CC_HINT(nonnull(2,3,4)); +int fr_edit_list_free_pair_children(fr_edit_list_t *el, fr_pair_t *vp) CC_HINT(nonnull(2)); +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); + +/* + * Functions to modify #fr_pair_list_t + */ 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) CC_HINT(nonnull(2,4)); +#define fr_edit_list_insert_list_head(_el, _list, _to_insert) fr_edit_list_insert_list_after(_el, _list, NULL, _to_insert) + +#define fr_edit_list_insert_list_tail(_el, _list, _to_insert) fr_edit_list_insert_list_after(_el, _list, fr_pair_list_tail(_list), _to_insert) + +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) CC_HINT(nonnull(1,2,4)); -int fr_edit_list_free_children(fr_edit_list_t *el, fr_pair_t *vp) CC_HINT(nonnull(2)); +int fr_edit_list_apply_list_assignment_const(fr_edit_list_t *el, fr_pair_t *dst, fr_token_t op, fr_pair_list_t const *src) CC_HINT(nonnull(1,2,4)); #ifdef __cplusplus } diff --git a/src/lib/util/edit_tests.c b/src/lib/util/edit_tests.c index bef97e4b267..218910d1dc6 100644 --- a/src/lib/util/edit_tests.c +++ b/src/lib/util/edit_tests.c @@ -132,7 +132,7 @@ static void test_pair_delete_head(void) el = fr_edit_list_alloc(NULL, 5); fr_assert(el != NULL); - rcode = fr_edit_list_delete(el, &local_pairs, vp); + rcode = fr_edit_list_pair_delete(el, &local_pairs, vp); TEST_CHECK(rcode == 0); fr_edit_list_commit(el); @@ -165,7 +165,7 @@ static void test_pair_delete_head_abort(void) el = fr_edit_list_alloc(NULL, 5); fr_assert(el != NULL); - rcode = fr_edit_list_delete(el, &local_pairs, vp); + rcode = fr_edit_list_pair_delete(el, &local_pairs, vp); TEST_CHECK(rcode == 0); count = fr_pair_list_len(&local_pairs); @@ -199,7 +199,7 @@ static void test_pair_delete_middle(void) el = fr_edit_list_alloc(NULL, 5); fr_assert(el != NULL); - rcode = fr_edit_list_delete(el, &local_pairs, vp); + rcode = fr_edit_list_pair_delete(el, &local_pairs, vp); TEST_CHECK(rcode == 0); fr_edit_list_commit(el); @@ -238,7 +238,7 @@ static void test_pair_delete_middle_abort(void) el = fr_edit_list_alloc(NULL, 5); fr_assert(el != NULL); - rcode = fr_edit_list_delete(el, &local_pairs, middle); + rcode = fr_edit_list_pair_delete(el, &local_pairs, middle); TEST_CHECK(rcode == 0); count = fr_pair_list_len(&local_pairs); @@ -278,13 +278,13 @@ static void test_pair_delete_multiple(void) el = fr_edit_list_alloc(NULL, 5); fr_assert(el != NULL); - rcode = fr_edit_list_delete(el, &local_pairs, vp); /* middle */ + rcode = fr_edit_list_pair_delete(el, &local_pairs, vp); /* middle */ TEST_CHECK(rcode == 0); vp = fr_pair_list_tail(&local_pairs); fr_assert(vp != NULL); - rcode = fr_edit_list_delete(el, &local_pairs, vp); /* tail */ + rcode = fr_edit_list_pair_delete(el, &local_pairs, vp); /* tail */ TEST_CHECK(rcode == 0); fr_edit_list_commit(el); @@ -321,13 +321,13 @@ static void test_pair_delete_multiple_abort(void) el = fr_edit_list_alloc(NULL, 5); fr_assert(el != NULL); - rcode = fr_edit_list_delete(el, &local_pairs, vp); /* middle */ + rcode = fr_edit_list_pair_delete(el, &local_pairs, vp); /* middle */ TEST_CHECK(rcode == 0); vp = fr_pair_list_tail(&local_pairs); fr_assert(vp != NULL); - rcode = fr_edit_list_delete(el, &local_pairs, vp); /* tail */ + rcode = fr_edit_list_pair_delete(el, &local_pairs, vp); /* tail */ TEST_CHECK(rcode == 0); count = fr_pair_list_len(&local_pairs); @@ -366,7 +366,7 @@ static void test_pair_edit_value(void) el = fr_edit_list_alloc(NULL, 5); fr_assert(el != NULL); - rcode = fr_edit_list_save_value(el, vp); + rcode = fr_edit_list_save_pair_value(el, vp); TEST_CHECK(rcode == 0); TEST_CHECK(vp->vp_uint32 == 0); @@ -400,7 +400,7 @@ static void test_pair_edit_value_abort(void) el = fr_edit_list_alloc(NULL, 5); fr_assert(el != NULL); - rcode = fr_edit_list_save_value(el, vp); + rcode = fr_edit_list_save_pair_value(el, vp); TEST_CHECK(rcode == 0); TEST_CHECK(vp->vp_uint32 == 0); @@ -437,7 +437,7 @@ static void test_pair_insert_after_head(void) TEST_CHECK((vp = fr_pair_afrom_da(autofree, fr_dict_attr_test_string)) != NULL); - rcode = fr_edit_list_insert_after(el, &local_pairs, NULL, vp); + rcode = fr_edit_list_insert_pair_after(el, &local_pairs, NULL, vp); TEST_CHECK(rcode == 0); fr_edit_list_commit(el); @@ -470,7 +470,7 @@ static void test_pair_insert_after_head_abort(void) TEST_CHECK((vp = fr_pair_afrom_da(autofree, fr_dict_attr_test_string)) != NULL); - rcode = fr_edit_list_insert_after(el, &local_pairs, NULL, vp); + rcode = fr_edit_list_insert_pair_after(el, &local_pairs, NULL, vp); TEST_CHECK(rcode == 0); count = fr_pair_list_len(&local_pairs); @@ -506,7 +506,7 @@ static void test_pair_insert_after_middle(void) TEST_CHECK((vp = fr_pair_afrom_da(autofree, fr_dict_attr_test_string)) != NULL); - rcode = fr_edit_list_insert_after(el, &local_pairs, middle, vp); + rcode = fr_edit_list_insert_pair_after(el, &local_pairs, middle, vp); TEST_CHECK(rcode == 0); fr_edit_list_commit(el); @@ -539,7 +539,7 @@ static void test_pair_insert_after_middle_abort(void) TEST_CHECK((vp = fr_pair_afrom_da(autofree, fr_dict_attr_test_string)) != NULL); - rcode = fr_edit_list_insert_after(el, &local_pairs, middle, vp); + rcode = fr_edit_list_insert_pair_after(el, &local_pairs, middle, vp); TEST_CHECK(rcode == 0); count = fr_pair_list_len(&local_pairs); @@ -571,7 +571,7 @@ static void test_pair_edit_value_delete(void) el = fr_edit_list_alloc(NULL, 5); fr_assert(el != NULL); - rcode = fr_edit_list_save_value(el, vp); + rcode = fr_edit_list_save_pair_value(el, vp); TEST_CHECK(rcode == 0); TEST_CHECK(vp->vp_uint32 == 0); @@ -579,7 +579,7 @@ static void test_pair_edit_value_delete(void) vp->vp_uint32 = 1; TEST_CHECK(vp->vp_uint32 == 1); - rcode = fr_edit_list_delete(el, &local_pairs, vp); + rcode = fr_edit_list_pair_delete(el, &local_pairs, vp); TEST_CHECK(rcode == 0); fr_edit_list_commit(el); @@ -609,7 +609,7 @@ static void test_pair_edit_value_delete_abort(void) el = fr_edit_list_alloc(NULL, 5); fr_assert(el != NULL); - rcode = fr_edit_list_save_value(el, vp); + rcode = fr_edit_list_save_pair_value(el, vp); TEST_CHECK(rcode == 0); TEST_CHECK(vp->vp_uint32 == 0); @@ -617,7 +617,7 @@ static void test_pair_edit_value_delete_abort(void) vp->vp_uint32 = 1; TEST_CHECK(vp->vp_uint32 == 1); - rcode = fr_edit_list_delete(el, &local_pairs, vp); + rcode = fr_edit_list_pair_delete(el, &local_pairs, vp); TEST_CHECK(rcode == 0); /* @@ -649,14 +649,14 @@ static void test_pair_insert_after_head_delete(void) TEST_CHECK((vp = fr_pair_afrom_da(autofree, fr_dict_attr_test_string)) != NULL); - rcode = fr_edit_list_insert_after(el, &local_pairs, NULL, vp); + rcode = fr_edit_list_insert_pair_after(el, &local_pairs, NULL, vp); TEST_CHECK(rcode == 0); count = fr_pair_list_len(&local_pairs); TEST_CASE("Expected (count == 4) after inserting a new one"); TEST_CHECK(count == 4); - rcode = fr_edit_list_delete(el, &local_pairs, vp); + rcode = fr_edit_list_pair_delete(el, &local_pairs, vp); TEST_CHECK(rcode == 0); count = fr_pair_list_len(&local_pairs); @@ -685,7 +685,7 @@ static void test_pair_insert_after_head_delete_abort(void) TEST_CHECK((vp = fr_pair_afrom_da(autofree, fr_dict_attr_test_string)) != NULL); - rcode = fr_edit_list_insert_after(el, &local_pairs, NULL, vp); + rcode = fr_edit_list_insert_pair_after(el, &local_pairs, NULL, vp); TEST_CHECK(rcode == 0); count = fr_pair_list_len(&local_pairs);