summaryrefslogtreecommitdiff
path: root/lib/darr.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/darr.c')
-rw-r--r--lib/darr.c62
1 files changed, 53 insertions, 9 deletions
diff --git a/lib/darr.c b/lib/darr.c
index 282e0dc5dc..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)
{
@@ -52,29 +53,72 @@ 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;
+
+ 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:
+ len = vsnprintf(darr_last(*sp), darr_avail(*sp), fmt, ap);
+ 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 +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;
}