]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
rearrange / rename API, and add fr_edit_list_replace()
authorAlan T. DeKok <aland@freeradius.org>
Fri, 12 Nov 2021 20:56:40 +0000 (15:56 -0500)
committerAlan T. DeKok <aland@freeradius.org>
Fri, 12 Nov 2021 21:19:01 +0000 (16:19 -0500)
src/lib/util/edit.c
src/lib/util/edit.h
src/lib/util/edit_tests.c

index 038020af51f34b33050db430da2320d836b333f3..d226ba58c1f6bc064ec1bbec7643818c13307c74 100644 (file)
@@ -162,7 +162,8 @@ static int edit_record(fr_edit_list_t *el, fr_edit_op_t op, fr_pair_t *vp, fr_pa
 {
        fr_edit_t *e;
 
-       if (!el) return 0;
+       fr_assert(el != NULL);
+       fr_assert(vp != NULL);
 
        /*
         *      Search for previous edits.
@@ -339,21 +340,81 @@ static int edit_record(fr_edit_list_t *el, fr_edit_op_t op, fr_pair_t *vp, fr_pa
        return 0;
 }
 
-int fr_edit_list_insert(fr_edit_list_t *el, fr_pair_t *vp, fr_pair_list_t *list, fr_pair_t *prev)
+
+/** Insert a new VP after an existing one.
+ *
+ *  This function mirrors fr_pair_insert_after().
+ *
+ *  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)
 {
-       return edit_record(el, FR_EDIT_INSERT, vp, list, prev);
+       if (!el) return 0;
+
+       return edit_record(el, FR_EDIT_INSERT, vp, list, pos);
 }
 
-int fr_edit_list_delete(fr_edit_list_t *el, fr_pair_t *vp, fr_pair_list_t *list)
+
+/** Delete a VP
+ *
+ *  This function mirrors fr_pair_delete()
+ *
+ *  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)
 {
        return edit_record(el, FR_EDIT_DELETE, vp, list, NULL);
 }
 
-int fr_edit_list_record(fr_edit_list_t *el, fr_pair_t *vp)
+/** Record the value of a leaf #fr_value_box_t
+ *
+ *  After this function returns, it's safe to edit the pair.
+ */
+int fr_edit_list_record_value(fr_edit_list_t *el, fr_pair_t *vp)
 {
+       if (!el) return 0;
+
+       if (!fr_type_is_leaf(vp->vp_type)) return -1;
+
        return edit_record(el, FR_EDIT_VALUE, vp, NULL, NULL);
 }
 
+/** Replace a pair with another one.
+ *
+ *  This function mirrors fr_pair_replace().
+ *
+ *  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)
+{
+       if (!el) return 0;
+
+       if (to_replace->da != vp->da) return -1;
+
+       if (edit_record(el, FR_EDIT_INSERT, vp, list, to_replace) < 0) return -1;
+
+       /*
+        *      If deleting the old entry fails, then the new entry
+        *      above MUST be the last member of the edit list.  If
+        *      it's not the last member, then it means that it
+        *      already existed in the list (either VP list of edit
+        *      list).  The edit_record() function checks for that,
+        *      and errors if so.
+        */
+       if (edit_record(el, FR_EDIT_DELETE, to_replace, list, NULL) < 0) {
+               fr_edit_t *e = fr_dlist_pop_tail(&el->list);
+
+               fr_assert(e != NULL);
+               fr_assert(e->vp == vp);
+               talloc_free(e);
+               return -1;
+       }
+
+       return 0;
+}
+
 
 /** Finalize the edits when we destroy the edit list.
  *
index 13d3e1ba4b51e026e196e2d0cf6d12b7ee97e17c..5d1902a1150ad38dcb002e39fef74f265153cf14 100644 (file)
@@ -37,11 +37,13 @@ fr_edit_list_t *fr_edit_list_alloc(TALLOC_CTX *ctx);
 
 void fr_edit_list_abort(fr_edit_list_t *el);
 
-int fr_edit_list_insert(fr_edit_list_t *el, fr_pair_t *vp, fr_pair_list_t *list, fr_pair_t *prev);
+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));
 
-int fr_edit_list_delete(fr_edit_list_t *el, fr_pair_t *vp, fr_pair_list_t *list);
+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_record(fr_edit_list_t *el, fr_pair_t *vp);
+int fr_edit_list_record_value(fr_edit_list_t *el, fr_pair_t *vp) CC_HINT(nonnull(2));
+
+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));
 
 #ifdef __cplusplus
 }
index 1eb8753a765fb0127b9ff470c9eb01ac8cd57652..3965162520168711405aa929ab5c83f70961bdfd 100644 (file)
@@ -132,7 +132,7 @@ static void test_pair_delete_head(void)
        el = fr_edit_list_alloc(NULL);
        fr_assert(el != NULL);
 
-       rcode = fr_edit_list_delete(el, vp, &local_pairs);
+       rcode = fr_edit_list_delete(el, &local_pairs, vp);
        TEST_CHECK(rcode == 0);
 
        talloc_free(el);
@@ -165,7 +165,7 @@ static void test_pair_delete_head_abort(void)
        el = fr_edit_list_alloc(NULL);
        fr_assert(el != NULL);
 
-       rcode = fr_edit_list_delete(el, vp, &local_pairs);
+       rcode = fr_edit_list_delete(el, &local_pairs, vp);
        TEST_CHECK(rcode == 0);
 
        count = fr_pair_list_len(&local_pairs);
@@ -201,7 +201,7 @@ static void test_pair_delete_middle(void)
        el = fr_edit_list_alloc(NULL);
        fr_assert(el != NULL);
 
-       rcode = fr_edit_list_delete(el, vp, &local_pairs);
+       rcode = fr_edit_list_delete(el, &local_pairs, vp);
        TEST_CHECK(rcode == 0);
 
        talloc_free(el);
@@ -240,7 +240,7 @@ static void test_pair_delete_middle_abort(void)
        el = fr_edit_list_alloc(NULL);
        fr_assert(el != NULL);
 
-       rcode = fr_edit_list_delete(el, middle, &local_pairs);
+       rcode = fr_edit_list_delete(el, &local_pairs, middle);
        TEST_CHECK(rcode == 0);
 
        count = fr_pair_list_len(&local_pairs);
@@ -282,13 +282,13 @@ static void test_pair_delete_multiple(void)
        el = fr_edit_list_alloc(NULL);
        fr_assert(el != NULL);
 
-       rcode = fr_edit_list_delete(el, vp, &local_pairs); /* middle */
+       rcode = fr_edit_list_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, vp, &local_pairs); /* tail */
+       rcode = fr_edit_list_delete(el, &local_pairs, vp); /* tail */
        TEST_CHECK(rcode == 0);
 
        talloc_free(el);
@@ -325,13 +325,13 @@ static void test_pair_delete_multiple_abort(void)
        el = fr_edit_list_alloc(NULL);
        fr_assert(el != NULL);
 
-       rcode = fr_edit_list_delete(el, vp, &local_pairs); /* middle */
+       rcode = fr_edit_list_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, vp, &local_pairs); /* tail */
+       rcode = fr_edit_list_delete(el, &local_pairs, vp); /* tail */
        TEST_CHECK(rcode == 0);
 
        count = fr_pair_list_len(&local_pairs);
@@ -372,7 +372,7 @@ static void test_pair_edit_value(void)
        el = fr_edit_list_alloc(NULL);
        fr_assert(el != NULL);
 
-       rcode = fr_edit_list_record(el, vp);
+       rcode = fr_edit_list_record_value(el, vp);
        TEST_CHECK(rcode == 0);
 
        TEST_CHECK(vp->vp_uint32 == 0);
@@ -406,7 +406,7 @@ static void test_pair_edit_value_abort(void)
        el = fr_edit_list_alloc(NULL);
        fr_assert(el != NULL);
 
-       rcode = fr_edit_list_record(el, vp);
+       rcode = fr_edit_list_record_value(el, vp);
        TEST_CHECK(rcode == 0);
 
        TEST_CHECK(vp->vp_uint32 == 0);