summaryrefslogtreecommitdiff
path: root/memory.c
diff options
context:
space:
mode:
Diffstat (limited to 'memory.c')
-rw-r--r--memory.c59
1 files changed, 59 insertions, 0 deletions
diff --git a/memory.c b/memory.c
new file mode 100644
index 0000000..b65ad42
--- /dev/null
+++ b/memory.c
@@ -0,0 +1,59 @@
+#include "memory.h"
+#include "slice.h"
+#include <stdlib.h>
+#include <stdio.h>
+
+static int
+strings_len(Token *list)
+{
+ int len = 0;
+ for (Token *e = list; e != NULL; e = e->next)
+ if (e->type == TOK_GROUP)
+ len += strings_len(e->group.tokens);
+ else if (e->type == TOK_STRING)
+ len += slice_len(e->slice) + 1;
+ return len;
+}
+
+static int
+strings_cat(char *mem, Token *list)
+{
+ int len = 0;
+ for (Token *e = list; e != NULL; e = e->next)
+ if (e->type == TOK_GROUP)
+ len += strings_cat(mem + len, e->group.tokens);
+ else if (e->type == TOK_STRING) {
+ slice_cpy(mem + len, e->slice);
+ len += slice_len(e->slice) + 1;
+ }
+ return len;
+}
+
+int
+memory_create(Memory *memory, Token *list)
+{
+ const int len = strings_len(list);
+ memory->strings = malloc(len);
+ if (memory->strings == NULL) {
+ perror("memory_create:malloc");
+ return 1;
+ }
+ const int cated = strings_cat(memory->strings, list);
+ if (cated != len) {
+ fprintf(stderr, "strings_cat wrote %d bytes instead of %d",
+ cated, len);
+ free(memory->strings);
+ memory->strings = NULL;
+ return 1;
+ }
+ return 0;
+}
+
+void
+memory_destroy(Memory *memory)
+{
+ if (memory->strings != NULL) {
+ free(memory->strings);
+ memory->strings = NULL;
+ }
+}