]> git.puffer.fish Git - mirror/frr.git/commitdiff
lib: darr: add free with element cleanup functions
authorChristian Hopps <chopps@labn.net>
Tue, 4 Jun 2024 09:43:49 +0000 (05:43 -0400)
committerChristian Hopps <chopps@labn.net>
Fri, 7 Jun 2024 02:38:48 +0000 (22:38 -0400)
- `darr_free_free` to `darr_free` each element prior to `darr_free`
  the array.
- `darr_free_func` to call `func` on each element prior to `darr_free`
  the array.

Signed-off-by: Christian Hopps <chopps@labn.net>
lib/darr.h
tests/lib/test_darr.c

index 404869d9a252d2b6169e4b71b4a7ccf4b04d181d..2b9a0a0c025b5177bbe31d652c2d004a54c4a762 100644 (file)
@@ -24,6 +24,8 @@
  *  - darr_ensure_i
  *  - darr_ensure_i_mt
  *  - darr_free
+ *  - darr_free_free
+ *  - darr_free_func
  *  - darr_insert
  *  - darr_insert_mt
  *  - darr_insertz
@@ -217,6 +219,41 @@ void *__darr_resize(void *a, uint count, size_t esize, struct memtype *mt);
                }                                                              \
        } while (0)
 
+/**
+ * Free memory allocated for the dynamic array `A`, calling `darr_free` for
+ * each element of the array first.
+ *
+ * Args:
+ *     A: The dynamic array, can be NULL.
+ */
+#define darr_free_free(A)                                                      \
+       do {                                                                   \
+               for (uint __i = 0; __i < darr_len(A); __i++)                   \
+                       if ((A)[__i]) {                                        \
+                               struct darr_metadata *__meta =                 \
+                                       _darr_meta((A)[__i]);                  \
+                               XFREE(__meta->mtype, __meta);                  \
+                       }                                                      \
+               darr_free(A);                                                  \
+       } while (0)
+
+/**
+ * Free memory allocated for the dynamic array `A`, calling `F` routine
+ * for each element of the array first.
+ *
+ * Args:
+ *     A: The dynamic array, can be NULL.
+ *     F: The function to call for each element.
+ */
+
+#define darr_free_func(A, F)                                                   \
+       do {                                                                   \
+               for (uint __i = 0; __i < darr_len(A); __i++) {                 \
+                       F((A)[__i]);                                           \
+               }                                                              \
+               darr_free(A);                                                  \
+       } while (0)
+
 /**
  * Make sure that there is room in the dynamic array `A` to add `C` elements.
  *
index 74aedac4b7e783c178b47a5ddf0d4095fd208d08..87f9e3e5642cdf2350ff8fa98198115ec2ef426e 100644 (file)
@@ -20,6 +20,8 @@
  * [x] - darr_foreach_i
  * [x] - darr_foreach_p
  * [x] - darr_free
+ * [x] - darr_free_free
+ * [x] - darr_free_func
  * [x] - darr_insert
  * [ ] - darr_insertz
  * [x] - darr_insert_n
@@ -318,6 +320,8 @@ static void test_string(void)
        uint addlen = strlen(add);
        char *da1 = NULL;
        char *da2 = NULL;
+       const char **strings = NULL;
+       uint sum = 0;
 
        assert(darr_strlen(da1) == 0);
 
@@ -412,6 +416,29 @@ static void test_string(void)
        da1 = darr_in_strcatf(da1, "0123456789: %08x", 0xDEADBEEF);
        assert(!strcmp("0123456789: deadbeef", da1));
        darr_free(da1);
+
+       sum = 0;
+       *darr_append(strings) = "1";
+       *darr_append(strings) = "2";
+       *darr_append(strings) = "3";
+#define adder(x) (sum += atoi(x))
+       darr_free_func(strings, adder);
+       assert(sum == 6);
+       assert(strings == NULL);
+
+       sum = 0;
+       darr_free_func(strings, adder);
+       assert(sum == 0);
+       assert(strings == NULL);
+
+       *darr_append(strings) = NULL;
+       *darr_append(strings) = darr_strdup("2");
+       *darr_append(strings) = darr_strdup("3");
+       darr_free_free(strings);
+       assert(strings == NULL);
+
+       darr_free_free(strings);
+       assert(strings == NULL);
 }
 
 int main(int argc, char **argv)