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;
}
-