From 5e9bb704c80c2b7211de8e0d3411d9347d11a48e Mon Sep 17 00:00:00 2001 From: Lassi Kortela Date: Sun, 13 Oct 2019 22:56:45 +0300 Subject: [PATCH] Add string-vector accumulator utility for C --- c/scheme.h | 9 +++++++++ c/util.c | 40 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+) diff --git a/c/scheme.h b/c/scheme.h index c2bff38..3ac87df 100644 --- a/c/scheme.h +++ b/c/scheme.h @@ -1053,6 +1053,15 @@ void accum_elt(struct accum *accum, value_t elt); void accum_pair(struct accum *accum, value_t a, value_t d); void accum_name_value(struct accum *accum, const char *name, value_t value); +struct sv_accum { + char **vec; + size_t cap; + size_t fill; +}; + +void sv_accum_init(struct sv_accum *accum); +void sv_accum_strdup(struct sv_accum *accum, const char *str); + // boot_image.c extern char boot_image[]; diff --git a/c/util.c b/c/util.c index 53bc169..525b3da 100644 --- a/c/util.c +++ b/c/util.c @@ -14,6 +14,13 @@ #include "scheme.h" +static void *reallocarray(void *ptr, size_t nmemb, size_t size) +{ + return realloc(ptr, nmemb * size); +} + +// + void accum_elt(struct accum *accum, value_t elt) { value_t newtail; @@ -36,3 +43,36 @@ void accum_name_value(struct accum *accum, const char *name, value_t value) { accum_pair(accum, string_from_cstr(name), value); } + +// + +void sv_accum_init(struct sv_accum *accum) +{ + accum->fill = 0; + accum->cap = 8; + accum->vec = calloc(accum->cap, sizeof(char *)); + if (!accum->vec) { + lerror(MemoryError, "out of memory"); + } +} + +void sv_accum_strdup(struct sv_accum *accum, const char *str) +{ + char *dup; + + if (__unlikely(accum->cap <= accum->fill + 1)) { + while (accum->cap <= accum->fill + 1) { + accum->cap *= 2; + } + accum->vec = reallocarray(accum->vec, accum->cap, sizeof(char *)); + if (!accum->vec) { + lerror(MemoryError, "out of memory"); + } + } + dup = strdup(str); + if (!dup) { + lerror(MemoryError, "out of memory"); + } + accum->vec[accum->fill++] = dup; + accum->vec[accum->fill] = 0; +}