commit fcceba5c6d10e38454a8940966fec86a3ee28c35
parent 75182685b04a5dc38c56a843ca8533ec7b45a5dd
Author: Louis Burda <quent.burda@gmail.com>
Date: Sat, 3 Jun 2023 02:41:54 +0200
Add realloc variants to reuse memory
Diffstat:
5 files changed, 92 insertions(+), 6 deletions(-)
diff --git a/build.jst.tmpl b/build.jst.tmpl
@@ -39,10 +39,10 @@ target lib/liballoc/build/liballoc.a
just lib/liballoc
target build/libstr.a
- liba src/str.c | include/str.h build
+ liba src/str.c | include/str.h libstr.api build
target build/libstr.so
- libso src/str.c | include/str.h build
+ libso src/str.c | include/str.h libstr.lds build
target build/test
cc src/test.c build/libstr.a lib/liballoc/build/liballoc.a | build
diff --git a/include/str.h b/include/str.h
@@ -16,7 +16,23 @@
#define LIBSTR_ABORT_ON_ALLOC(cond)
#endif
-char *str_fmt(const struct allocator *allocator, int *rc, const char *fmstr, ...);
-char *str_dup(const struct allocator *allocator, int *rc, const char *str);
-char *str_ndup(const struct allocator *allocator, int *rc, const char *str, size_t n);
-char *str_app(const struct allocator *allocator, int *rc, char *str, const char *app);
+char * __attribute__((format(printf, 3, 4)))
+str_fmt(const struct allocator *allocator, int *rc,
+ const char *fmstr, ...);
+char * __attribute__((format(printf, 4, 5)))
+str_fmt_realloc(const struct allocator *allocator, int *rc,
+ void *alloc, const char *fmtstr, ...);
+
+char *str_dup(const struct allocator *allocator, int *rc,
+ const char *str);
+char *str_dup_realloc(const struct allocator *allocator, int *rc,
+ void *alloc, const char *str);
+
+char *str_ndup(const struct allocator *allocator, int *rc,
+ const char *str, size_t n);
+char *str_ndup_realloc(const struct allocator *allocator, int *rc,
+ void *alloc, const char *str, size_t n);
+
+char *str_app(const struct allocator *allocator, int *rc,
+ char *str, const char *app);
+
diff --git a/libstr.api b/libstr.api
@@ -1,4 +1,10 @@
str_fmt
+str_fmt_realloc
+
str_dup
+str_dup_realloc
+
str_ndup
+str_ndup_realloc
+
str_app
diff --git a/libstr.lds b/libstr.lds
@@ -1,8 +1,14 @@
LIBSTR_1.0 {
global:
str_fmt;
+ str_fmt_realloc;
+
str_dup;
+ str_dup_realloc;
+
str_ndup;
+ str_ndup_realloc;
+
str_app;
local: *;
};
diff --git a/src/str.c b/src/str.c
@@ -39,12 +39,52 @@ str_fmt(const struct allocator *allocator, int *rc, const char *fmtstr, ...)
}
char *
+str_fmt_realloc(const struct allocator *allocator, int *rc,
+ void *alloc, const char *fmtstr, ...)
+{
+ va_list ap, cpy;
+ char *str;
+ ssize_t n;
+
+ LIBSTR_ABORT_ON_ARGS(!allocator || !fmtstr);
+
+ va_copy(cpy, ap);
+
+ va_start(cpy, fmtstr);
+ n = vsnprintf(NULL, 0, fmtstr, cpy);
+ va_end(cpy);
+
+ if (n <= 0) {
+ if (rc) *rc = 1;
+ return NULL;
+ }
+
+ str = allocator->realloc(allocator, alloc, (size_t) (n + 1), rc);
+ LIBSTR_ABORT_ON_ALLOC(!str);
+ if (!str && rc) *rc = -*rc;
+ if (!str) return NULL;
+
+ va_start(ap, fmtstr);
+ vsnprintf(str, (size_t) (n + 1), fmtstr, ap);
+ va_end(ap);
+
+ return str;
+}
+
+char *
str_dup(const struct allocator *allocator, int *rc, const char *str)
{
return str_ndup(allocator, rc, str, strlen(str));
}
char *
+str_dup_realloc(const struct allocator *allocator, int *rc,
+ void *alloc, const char *str)
+{
+ return str_ndup_realloc(allocator, rc, alloc, str, strlen(str));
+}
+
+char *
str_ndup(const struct allocator *allocator, int *rc, const char *str, size_t n)
{
char *nstr;
@@ -62,6 +102,24 @@ str_ndup(const struct allocator *allocator, int *rc, const char *str, size_t n)
}
char *
+str_ndup_realloc(const struct allocator *allocator, int *rc,
+ void *alloc, const char *str, size_t n)
+{
+ char *nstr;
+
+ LIBSTR_ABORT_ON_ARGS(!allocator || !str);
+
+ nstr = allocator->realloc(allocator, alloc, n + 1, rc);
+ LIBSTR_ABORT_ON_ALLOC(!nstr);
+ if (!nstr && rc) *rc = -*rc;
+ if (!nstr) return NULL;
+
+ strncpy(nstr, str, n + 1);
+
+ return nstr;
+}
+
+char *
str_app(const struct allocator *allocator, int *rc, char *str, const char *app)
{
size_t slen, alen;