libstr-c

C string library
git clone https://git.sinitax.com/sinitax/libstr-c
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

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:
Mbuild.jst.tmpl | 4++--
Minclude/str.h | 24++++++++++++++++++++----
Mlibstr.api | 6++++++
Mlibstr.lds | 6++++++
Msrc/str.c | 58++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
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;