summaryrefslogtreecommitdiff
path: root/string.c
diff options
context:
space:
mode:
Diffstat (limited to 'string.c')
-rw-r--r--string.c86
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);
+}