summaryrefslogtreecommitdiffstats
path: root/lib/darr.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/darr.c')
-rw-r--r--lib/darr.c67
1 files changed, 57 insertions, 10 deletions
diff --git a/lib/darr.c b/lib/darr.c
index bef51b8..7a01274 100644
--- a/lib/darr.c
+++ b/lib/darr.c
@@ -9,7 +9,8 @@
#include "darr.h"
#include "memory.h"
-DEFINE_MTYPE_STATIC(LIB, DARR, "Dynamic Array");
+DEFINE_MTYPE(LIB, DARR, "Dynamic Array");
+DEFINE_MTYPE(LIB, DARR_STR, "Dynamic Array String");
static uint _msb(uint count)
{
@@ -52,29 +53,75 @@ static size_t darr_size(uint count, size_t esize)
return count * esize + sizeof(struct darr_metadata);
}
-void *__darr_resize(void *a, uint count, size_t esize)
+char *__darr_in_vsprintf(char **sp, bool concat, const char *fmt, va_list ap)
+{
+ size_t inlen = concat ? darr_strlen(*sp) : 0;
+ size_t capcount = strlen(fmt) + MIN(inlen + 64, 128);
+ ssize_t len;
+ va_list ap_copy;
+
+ darr_ensure_cap(*sp, capcount);
+
+ if (!concat)
+ darr_reset(*sp);
+
+ /* code below counts on having a NUL terminated string */
+ if (darr_len(*sp) == 0)
+ *darr_append(*sp) = 0;
+again:
+ va_copy(ap_copy, ap);
+ len = vsnprintf(darr_last(*sp), darr_avail(*sp) + 1, fmt, ap_copy);
+ va_end(ap_copy);
+ if (len < 0)
+ darr_in_strcat(*sp, fmt);
+ else if ((size_t)len <= darr_avail(*sp))
+ _darr_len(*sp) += len;
+ else {
+ darr_ensure_cap(*sp, darr_len(*sp) + (size_t)len);
+ goto again;
+ }
+ return *sp;
+}
+
+char *__darr_in_sprintf(char **sp, bool concat, const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ (void)__darr_in_vsprintf(sp, concat, fmt, ap);
+ va_end(ap);
+ return *sp;
+}
+
+
+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;
@@ -89,7 +136,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;
}