diff options
Diffstat (limited to 'string.c')
| -rw-r--r-- | string.c | 86 |
1 files changed, 86 insertions, 0 deletions
diff --git a/string.c b/string.c new file mode 100644 index 0000000..68b01e4 --- /dev/null +++ b/string.c @@ -0,0 +1,86 @@ +#include "string.h" + +#include <stdlib.h> +#include <assert.h> +#include <string.h> +#include <stdio.h> +#include <stdarg.h> + +void sp_init(StringPool *sp, size_t len) { + assert(sp != NULL); + sp->mem = malloc(len); + if (sp->mem == NULL) { + printf("Malloc failed during sp_init!"); + exit(1); + } + sp->size = len; + sp->offset = 0; +} + +void* sp_reserve(StringPool *sp, size_t len) { + assert(sp != NULL); + if (sp->offset + len > sp->size) { + printf("String pool full!"); + exit(1); + } + + void *mem = sp->mem + sp->offset; + sp->offset += len; + return mem; +} + +StringView sv_create(StringPool *sp, char *str, size_t len) { + assert(str != NULL); + assert(len != 0); + void *mem = sp_reserve(sp, len); + memcpy(mem, str, len); + ((char*)mem)[len] = '\0'; + return (StringView){(char*)mem, len}; +} + +StringView sv_concat_ss(StringPool *sp, StringView a, StringView b) { + assert(sp != NULL); + + if (a.len == 0) return b; + if (b.len == 0) return a; // Handle the case where both strings are empty. + + size_t alen = a.len; + size_t blen = b.len; + + if (a.buf[a.len - 1] == '\0') alen -= 1; + if (b.buf[b.len - 1] == '\0') blen -= 1; + + size_t len = alen + blen; + char *mem = (char *)sp_reserve(sp, len + 1); + memcpy(mem, a.buf, alen); + memcpy(mem + alen, b.buf, blen); + mem[len] = '\0'; + return (StringView){.buf = mem, .len = len}; +} + +StringView sv_concat_ss_n(StringPool *sp, int n, ...) { + va_list args; + va_start(args, n); + StringView res = {.buf = "", .len = 0}; + for (int i = 0; i < n; i++) { + res = sv_concat_ss(sp, res, va_arg(args, StringView)); + } + va_end(args); + return res; +} + +StringView sv_sizet_to_string(StringPool *sp, size_t s) { + assert(sp != NULL); + size_t size = sizeof(size_t); + char* buf = sp_reserve(sp, size); + snprintf(buf, size, "%d", s); + size_t len = strlen(buf); + return (StringView){.buf = buf, .len = len}; +} + +void sv_printf_cs(char *fmt, ...) { + va_list args; + va_start(args, fmt); + vprintf(fmt, args); + va_end(args); +} |
