summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/darr.c23
-rw-r--r--lib/darr.h113
2 files changed, 91 insertions, 45 deletions
diff --git a/lib/darr.c b/lib/darr.c
index 9ec3cb63b0..f7a64fc394 100644
--- a/lib/darr.c
+++ b/lib/darr.c
@@ -10,6 +10,7 @@
#include "memory.h"
DEFINE_MTYPE(LIB, DARR, "Dynamic Array");
+DEFINE_MTYPE(LIB, DARR_STR, "Dynamic Array String");
static uint _msb(uint count)
{
@@ -90,28 +91,34 @@ char *__darr_in_sprintf(char **sp, bool concat, const char *fmt, ...)
}
-void *__darr_resize(void *a, uint count, size_t esize)
+void *__darr_resize(void *a, uint count, size_t esize, struct memtype *mtype)
{
uint ncount = darr_next_count(count, esize);
size_t osz = (a == NULL) ? 0 : darr_size(darr_cap(a), esize);
size_t sz = darr_size(ncount, esize);
- struct darr_metadata *dm = XREALLOC(MTYPE_DARR,
- a ? _darr_meta(a) : NULL, sz);
+ struct darr_metadata *dm;
- if (sz > osz)
- memset((char *)dm + osz, 0, sz - osz);
+ if (a) {
+ dm = XREALLOC(_darr_meta(a)->mtype, _darr_meta(a), sz);
+ if (sz > osz)
+ memset((char *)dm + osz, 0, sz - osz);
+ } else {
+ dm = XCALLOC(mtype, sz);
+ dm->mtype = mtype;
+ }
dm->cap = ncount;
return (void *)(dm + 1);
}
-void *__darr_insert_n(void *a, uint at, uint count, size_t esize, bool zero)
+void *__darr_insert_n(void *a, uint at, uint count, size_t esize, bool zero,
+ struct memtype *mtype)
{
struct darr_metadata *dm;
uint olen, nlen;
if (!a)
- a = __darr_resize(NULL, at + count, esize);
+ a = __darr_resize(NULL, at + count, esize, mtype);
dm = (struct darr_metadata *)a - 1;
olen = dm->len;
@@ -126,7 +133,7 @@ void *__darr_insert_n(void *a, uint at, uint count, size_t esize, bool zero)
nlen = olen + count;
if (nlen > dm->cap) {
- a = __darr_resize(a, nlen, esize);
+ a = __darr_resize(a, nlen, esize, mtype);
dm = (struct darr_metadata *)a - 1;
}
diff --git a/lib/darr.h b/lib/darr.h
index 81443bfc83..2b6f0db0b9 100644
--- a/lib/darr.h
+++ b/lib/darr.h
@@ -3,21 +3,35 @@
* June 23 2023, Christian Hopps <chopps@labn.net>
*
* Copyright (c) 2023, LabN Consulting, L.L.C.
- *
+ */
+#ifndef _FRR_DARR_H_
+#define _FRR_DARR_H_
+
+/*
* API functions:
* ==============
* - darr_append
+ * - darr_append_mt
* - darr_append_n
+ * - darr_append_n_mt
* - darr_append_nz
+ * - darr_append_nz_mt
* - darr_cap
* - darr_ensure_avail
+ * - darr_ensure_avail_mt
* - darr_ensure_cap
+ * - darr_ensure_cap_mt
* - darr_ensure_i
+ * - darr_ensure_i_mt
* - darr_free
* - darr_insert
+ * - darr_insert_mt
* - darr_insertz
+ * - darr_insertz_mt
* - darr_insert_n
+ * - darr_insert_n_mt
* - darr_insert_nz
+ * - darr_insert_nz_mt
* - darr_last
* - darr_lasti
* - darr_len
@@ -66,24 +80,30 @@
#include "memory.h"
DECLARE_MTYPE(DARR);
+DECLARE_MTYPE(DARR_STR);
struct darr_metadata {
uint32_t len;
uint32_t cap;
+ struct memtype *mtype;
};
-void *__darr_insert_n(void *a, uint at, uint count, size_t esize, bool zero);
+
+void *__darr_insert_n(void *a, uint at, uint count, size_t esize, bool zero,
+ struct memtype *mt);
char *__darr_in_sprintf(char **sp, bool concat, const char *fmt, ...)
PRINTFRR(3, 4);
char *__darr_in_vsprintf(char **sp, bool concat, const char *fmt, va_list ap)
PRINTFRR(3, 0);
-void *__darr_resize(void *a, uint count, size_t esize);
+void *__darr_resize(void *a, uint count, size_t esize, struct memtype *mt);
-#define _darr_esize(A) sizeof((A)[0])
-#define darr_esize(A) sizeof((A)[0])
-#define _darr_len(A) _darr_meta(A)->len
-#define _darr_meta(A) (((struct darr_metadata *)(A)) - 1)
-#define _darr_resize(A, C) ({ (A) = __darr_resize((A), C, _darr_esize(A)); })
+#define _darr_esize(A) sizeof((A)[0])
+#define darr_esize(A) sizeof((A)[0])
+#define _darr_len(A) _darr_meta(A)->len
+#define _darr_meta(A) (((struct darr_metadata *)(A)) - 1)
+#define _darr_resize_mt(A, C, MT) \
+ ({ (A) = __darr_resize(A, C, _darr_esize(A), MT); })
+#define _darr_resize(A, C) _darr_resize_mt(A, C, MTYPE_DARR)
/* Get the current capacity of the array */
#define darr_cap(A) (((A) == NULL) ? 0 : _darr_meta(A)->cap)
@@ -190,8 +210,8 @@ void *__darr_resize(void *a, uint count, size_t esize);
#define darr_free(A) \
do { \
if ((A)) { \
- void *__ptr = _darr_meta(A); \
- XFREE(MTYPE_DARR, __ptr); \
+ struct darr_metadata *__meta = _darr_meta(A); \
+ XFREE(__meta->mtype, __meta); \
(A) = NULL; \
} \
} while (0)
@@ -212,14 +232,15 @@ void *__darr_resize(void *a, uint count, size_t esize);
* Return:
* A pointer to the (possibly moved) array.
*/
-#define darr_ensure_avail(A, S) \
+#define darr_ensure_avail_mt(A, S, MT) \
({ \
ssize_t need = (ssize_t)(S) - \
(ssize_t)(darr_cap(A) - darr_len(A)); \
if (need > 0) \
- _darr_resize((A), darr_cap(A) + need); \
+ _darr_resize_mt((A), darr_cap(A) + need, MT); \
(A); \
})
+#define darr_ensure_avail(A, S) darr_ensure_avail_mt(A, S, MTYPE_DARR)
/**
* Make sure that there is room in the dynamic array `A` for `C` elements.
@@ -235,13 +256,14 @@ void *__darr_resize(void *a, uint count, size_t esize);
* Return:
* A pointer to the (possibly moved) array.
*/
-#define darr_ensure_cap(A, C) \
+#define darr_ensure_cap_mt(A, C, MT) \
({ \
/* Cast to avoid warning when C == 0 */ \
if ((ssize_t)darr_cap(A) < (ssize_t)(C)) \
- _darr_resize((A), (C)); \
+ _darr_resize_mt((A), (C), MT); \
(A); \
})
+#define darr_ensure_cap(A, C) darr_ensure_cap_mt(A, C, MTYPE_DARR)
/**
* Return a pointer to the (I)th element of array `A`, making sure there is
@@ -261,18 +283,19 @@ void *__darr_resize(void *a, uint count, size_t esize);
* Return:
* A pointer to the (I)th element in `A`
*/
-#define darr_ensure_i(A, I) \
+#define darr_ensure_i_mt(A, I, MT) \
({ \
if ((int)(I) > darr_maxi(A)) \
- _darr_resize((A), (I) + 1); \
+ _darr_resize_mt((A), (I) + 1, MT); \
if ((I) + 1 > _darr_len(A)) \
_darr_len(A) = (I) + 1; \
&(A)[I]; \
})
+#define darr_ensure_i(A, I) darr_ensure_i_mt(A, I, MTYPE_DARR)
-#define _darr_insert_n(A, I, N, Z) \
+#define _darr_insert_n(A, I, N, Z, MT) \
({ \
- (A) = __darr_insert_n(A, I, N, _darr_esize(A), Z); \
+ (A) = __darr_insert_n(A, I, N, _darr_esize(A), Z, MT); \
&(A)[I]; \
})
/**
@@ -293,8 +316,10 @@ void *__darr_resize(void *a, uint count, size_t esize);
* Return:
* A pointer to the first inserted element in the array.
*/
-#define darr_insert_n(A, I, N) _darr_insert_n(A, I, N, false)
-#define darr_insert_nz(A, I, N) _darr_insert_n(A, I, N, true)
+#define darr_insert_n(A, I, N) _darr_insert_n(A, I, N, false, MTYPE_DARR)
+#define darr_insert_n_mt(A, I, N) _darr_insert_n(A, I, N, false, MT)
+#define darr_insert_nz(A, I, N) _darr_insert_n(A, I, N, true, MTYPE_DARR)
+#define darr_insert_nz_mt(A, I, N) _darr_insert_n(A, I, N, true, MT)
/**
* Insert an uninitialized element in the array at index `I`.
@@ -314,8 +339,10 @@ void *__darr_resize(void *a, uint count, size_t esize);
* Return:
* A pointer to the element in the array.
*/
-#define darr_insert(A, I) _darr_insert_n(A, I, 1, false)
-#define darr_insertz(A, I) _darr_insert_n(A, I, 1, true)
+#define darr_insert(A, I) _darr_insert_n(A, I, 1, false, MTYPE_DARR)
+#define darr_insert_mt(A, I) _darr_insert_n(A, I, 1, false, MT)
+#define darr_insertz(A, I) _darr_insert_n(A, I, 1, true, MTYPE_DARR)
+#define darr_insertz_mt(A, I) _darr_insert_n(A, I, 1, true, MT)
/**
* Remove `N` elements from the array starting at index `I`.
@@ -353,10 +380,10 @@ void *__darr_resize(void *a, uint count, size_t esize);
#define darr_remove(A, I) darr_remove_n(A, I, 1)
-#define _darr_append_n(A, N, Z) \
+#define _darr_append_n(A, N, Z, MT) \
({ \
uint __len = darr_len(A); \
- darr_ensure_cap(A, __len + (N)); \
+ darr_ensure_cap_mt(A, __len + (N), MT); \
_darr_len(A) = __len + (N); \
if (Z) \
memset(&(A)[__len], 0, (N)*_darr_esize(A)); \
@@ -373,8 +400,10 @@ void *__darr_resize(void *a, uint count, size_t esize);
* Return:
* A pointer to the first of the added elements at the end of the array.
*/
-#define darr_append_n(A, N) _darr_append_n(A, N, false)
-#define darr_append_nz(A, N) _darr_append_n(A, N, true)
+#define darr_append_n(A, N) _darr_append_n(A, N, false, MTYPE_DARR)
+#define darr_append_n_mt(A, N, MT) _darr_append_n(A, N, false, MT)
+#define darr_append_nz(A, N) _darr_append_n(A, N, true, MTYPE_DARR)
+#define darr_append_nz_mt(A, N, MT) _darr_append_n(A, N, true, MT)
/**
* Extending the array's length by 1.
@@ -387,8 +416,10 @@ void *__darr_resize(void *a, uint count, size_t esize);
* Return:
* A pointer to the new element at the end of the array.
*/
-#define darr_append(A) _darr_append_n(A, 1, false)
-#define darr_appendz(A) _darr_append_n(A, 1, true)
+#define darr_append(A) _darr_append_n(A, 1, false, MTYPE_DARR)
+#define darr_append_mt(A, MT) _darr_append_n(A, 1, false, MT)
+#define darr_appendz(A) _darr_append_n(A, 1, true, MTYPE_DARR)
+#define darr_appendz_mt(A, MT) _darr_append_n(A, 1, true, MT)
/**
* Append an element `E` onto the array `A`, extending it's length by 1.
@@ -401,8 +432,10 @@ void *__darr_resize(void *a, uint count, size_t esize);
* Return:
* A pointer to the element in the array.
*/
-#define darr_push(A, E) (*darr_append(A) = (E))
-#define darr_pushz(A) (darr_appendz(A))
+#define darr_push(A, E) (*darr_append(A) = (E))
+#define darr_push_mt(A, E, MT) (*darr_append_mt(A, MT) = (E))
+#define darr_pushz(A) (darr_appendz(A))
+#define darr_pushz_mt(A, MT) (darr_appendz_mt(A, MT))
/**
@@ -496,7 +529,7 @@ void *__darr_resize(void *a, uint count, size_t esize);
({ \
uint __dlen = darr_strlen(D); \
uint __slen = strlen(S); \
- darr_ensure_cap(D, __dlen + __slen + 1); \
+ darr_ensure_cap_mt(D, __dlen + __slen + 1, MTYPE_DARR_STR); \
if (darr_len(D) == 0) \
*darr_append(D) = 0; \
memcpy(darr_last(D), (S), __slen + 1); \
@@ -552,7 +585,7 @@ void *__darr_resize(void *a, uint count, size_t esize);
__ssize = darr_ilen(S); \
__extra = __ssize - __dsize; \
if (__extra > 0) { \
- darr_ensure_cap(D, (uint)__ssize); \
+ darr_ensure_cap_mt(D, (uint)__ssize, MTYPE_DARR_STR); \
memcpy(darr_last(D), (S) + __dsize - 1, __extra + 1); \
_darr_len(D) += __extra; \
} \
@@ -575,8 +608,10 @@ void *__darr_resize(void *a, uint count, size_t esize);
({ \
size_t __size = strlen(S) + 1; \
darr_reset(D); \
- darr_ensure_cap(D, ((size_t)(C) > __size) ? (size_t)(C) \
- : __size); \
+ darr_ensure_cap_mt(D, \
+ ((size_t)(C) > __size) ? (size_t)(C) \
+ : __size, \
+ MTYPE_DARR_STR); \
strlcpy(D, (S), darr_cap(D)); \
darr_setlen((D), (size_t)__size); \
D; \
@@ -642,9 +677,11 @@ void *__darr_resize(void *a, uint count, size_t esize);
size_t __size = strlen(S) + 1; \
char *__s = NULL; \
/* Cast to ssize_t to avoid warning when C == 0 */ \
- darr_ensure_cap(__s, ((ssize_t)(C) > (ssize_t)__size) \
- ? (size_t)(C) \
- : __size); \
+ darr_ensure_cap_mt(__s, \
+ ((ssize_t)(C) > (ssize_t)__size) \
+ ? (size_t)(C) \
+ : __size, \
+ MTYPE_DARR_STR); \
strlcpy(__s, (S), darr_cap(__s)); \
darr_setlen(__s, (size_t)__size); \
__s; \
@@ -703,3 +740,5 @@ void *__darr_resize(void *a, uint count, size_t esize);
* I: A uint variable to store the current element index in.
*/
#define darr_foreach_i(A, I) for ((I) = 0; (I) < darr_len(A); (I)++)
+
+#endif /* _FRR_DARR_H_ */