commit 046ba9da8e832c36a3a3734f70f19125c1c5cba5
parent bb13628866489dcc9acd398cfc29c3046d51ec88
Author: William Casarin <jb55@jb55.com>
Date:   Fri,  6 Nov 2020 22:50:50 -0800
parse: move away from static data
next up: parser itself
Signed-off-by: William Casarin <jb55@jb55.com>
Diffstat:
| M | parse.c |  |  | 82 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ | 
| M | parse.h |  |  | 5 | ++++- | 
| M | protoverse.c |  |  | 53 | +++++------------------------------------------------ | 
3 files changed, 91 insertions(+), 49 deletions(-)
diff --git a/parse.c b/parse.c
@@ -1,6 +1,7 @@
 
 #include "util.h"
 #include "parse.h"
+#include "io.h"
 
 #include <stdio.h>
 #include <string.h>
@@ -1316,3 +1317,84 @@ close:
 
 	return 1;
 }
+
+
+int init_parser(struct parser *parser)
+{
+	int attrs_size = sizeof(struct attribute) * 1024;
+	int tokens_size = 2048;
+	int cells_size = sizeof(struct cell) * 1024;
+
+	u8 *token_buf = calloc(1, tokens_size);
+	u8 *attrs_buf = calloc(1, attrs_size);
+	u8 *cells_buf = calloc(1, cells_size);
+
+	static struct token_cursor tokens;
+	static struct cursor attributes;
+	static struct cursor cells;
+
+	if (!token_buf) return 0;
+	if (!attrs_buf) return 0;
+	if (!cells_buf) return 0;
+
+	parser->tokens = &tokens;
+	parser->attributes = &attributes;
+	parser->cells = &cells;
+
+	make_cursor(cells_buf, cells_buf + cells_size, &cells);
+	make_cursor(attrs_buf, attrs_buf + attrs_size, &attributes);
+	make_token_cursor(token_buf, token_buf + tokens_size, &tokens);
+
+	return 1;
+}
+
+int free_parser(struct parser *parser)
+{
+	free(parser->tokens->c.start);
+	free(parser->attributes->start);
+	free(parser->cells->start);
+
+	return 1;
+}
+
+int parse_buffer(struct parser *parser, u8 *file_buf, int len, u16 *root)
+{
+	int ok;
+
+	ok = tokenize_cells(file_buf, len, parser->tokens);
+
+	if (!ok) {
+		printf("failed to tokenize\n");
+		return 0;
+	}
+
+	ok = parse_cell(parser, root);
+	if (!ok) {
+		print_token_error(parser->tokens);
+		return 0;
+	}
+
+	return 1;
+}
+
+
+int parse_file(struct parser *parser, const char *filename, u16 *root)
+{
+	/* TODO: increase these limits */
+	int bufsize = 4096*4;
+	u8 *file_buf = calloc(1, bufsize);
+
+	int count, ok;
+
+	ok = read_file(filename, file_buf, bufsize, &count);
+
+	if (!ok) {
+		printf("failed to load '%s'\n", filename);
+		return 0;
+	}
+
+	ok = parse_buffer(parser, file_buf, count, root);
+	free(file_buf);
+	return ok;
+}
+
diff --git a/parse.h b/parse.h
@@ -130,7 +130,10 @@ struct parser {
 	struct cursor *cells;
 };
 
-
+int parse_buffer(struct parser *parser, u8 *file_buf, int len, u16 *root);
+int parse_file(struct parser *parser, const char *filename, u16 *root);
+int init_parser(struct parser *parser);
+int free_parser(struct parser *parser);
 void print_cell(struct cursor *attributes, struct cell *cell);
 int tokenize_cells(unsigned char *buf, int buf_size, struct token_cursor *tokens);
 void make_token_cursor(u8 *start, u8 *end, struct token_cursor *cursor);
diff --git a/protoverse.c b/protoverse.c
@@ -54,53 +54,6 @@ static int print_cell_tree(struct parser *parser, u16 root, int depth)
 	return 1;
 }
 
-static int parse_file(struct parser *parser, const char *filename, u16 *root)
-{
-	/* TODO: increase these limits */
-	static u8 file_buf[4096];
-	static u8 token_buf[2048];
-	static u8 attrs_buf[sizeof(struct attribute) * 1024];
-	static u8 cells_buf[sizeof(struct cell) * 1024];
-
-	struct token_cursor tokens;
-	struct cursor attributes;
-	struct cursor cells;
-
-	int count, ok;
-
-	parser->tokens = &tokens;
-	parser->attributes = &attributes;
-	parser->cells = &cells;
-
-	make_cursor(cells_buf, cells_buf + sizeof(cells_buf), &cells);
-	make_cursor(attrs_buf, attrs_buf + sizeof(attrs_buf), &attributes);
-	make_token_cursor(token_buf, token_buf + sizeof(token_buf), &tokens);
-
-	ok = read_file(filename, file_buf, sizeof(file_buf), &count);
-
-	if (!ok) {
-		printf("failed to load '%s'\n", filename);
-		return 0;
-	}
-
-	ok = tokenize_cells(file_buf, count, &tokens);
-
-	if (!ok) {
-		printf("failed to tokenize\n");
-		return 0;
-	}
-
-	assert(tokens.c.p == token_buf);
-
-	ok = parse_cell(parser, root);
-	if (!ok) {
-		print_token_error(&tokens);
-		return 0;
-	}
-
-	return 1;
-}
-
 static int usage(void)
 {
 	printf("usage: protoverse <command> [args]\n\n");
@@ -112,6 +65,8 @@ static int usage(void)
 	return 1;
 }
 
+
+
 int main(int argc, const char *argv[])
 {
 	const char *space;
@@ -129,6 +84,8 @@ int main(int argc, const char *argv[])
 	if (streq(cmd, "parse")) {
 		if (argc != 3)
 			return usage();
+		ok = init_parser(&parser);
+		if (!ok) return 1;
 		space = argv[2];
 		ok = parse_file(&parser, space, &root);
 		if (!ok) return 1;
@@ -136,6 +93,7 @@ int main(int argc, const char *argv[])
 		print_cell_tree(&parser, root, 0);
 
 		describe(&parser, root);
+		free_parser(&parser);
 	} else if (streq(cmd, "serve")) {
 		if (argc != 3)
 			return usage();
@@ -152,4 +110,3 @@ int main(int argc, const char *argv[])
 
 	return 0;
 }
-