stew

a monorepo of some sort
Log | Files | Refs

commit 750c673a3f58812925bb6e142712893dc083aa0c
parent 2ab08c12342839c5a7475c332802d37dfd66dda6
Author: rpa <rpa@laika>
Date:   Sun, 23 Apr 2023 15:46:11 +0000

tablist: looks like it parses I guess

Diffstat:
Msrc/tablist/mktest | 4++--
Msrc/tablist/tablist.c | 143+++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------------
Msrc/tablist/tablist.h | 13+++++++++----
Msrc/tablist/test.c | 39++++++++++++++++++++++++++++++++++-----
4 files changed, 141 insertions(+), 58 deletions(-)

diff --git a/src/tablist/mktest b/src/tablist/mktest @@ -1,7 +1,7 @@ </$objtype/mkfile -test:V: $O.test - $O.test +test:V: $O.test example.tl + $O.test example.tl $O.test: test.c tablist.h libtablist.a$O diff --git a/src/tablist/tablist.c b/src/tablist/tablist.c @@ -5,78 +5,127 @@ struct TLrow { int indent; + TLnode *root; +}; + +struct TLparsecontext { + TLnode *root; + TLnode *stack[64]; int n; - TLNode *nodes; }; -struct TLrow -_tlparseline(char *s) +TLnode * +allocTLnode(char *name, char *value) +{ + TLnode *node = mallocz(sizeof(TLnode), 1); + node->name = name; + node->value = value; + return node; +} + +int +freeTLnode(TLnode *node) +{ + int i; + free(node->name); + free(node->value); + for(i = 0; i< node->count; i++) { + freeTLnode(node->children[node->count - 1]); + } + free(node); + return 0; +} + +int +TLnodeappend(TLnode *parent, TLnode *child) +{ + parent->children = + realloc(parent->children, sizeof(TLnode *) * (parent->count + 1)); + parent->children[parent->count] = child; + parent->count++; + return 0; +} + +int +_tlparseline(struct TLrow *row, char *s) { char *p; - struct TLrow row = {0, 0, nil}; + TLnode **np = &row->root; while (*s == '\t') { - row.indent++; + row->indent++; s++; }; - - fprint(2, "indent %d\n", row.indent); - - if (*s == '\0') return 0; - + if (*s == '\0') { + werrstr("empty line"); + return -1; + } for (;;) { + if (*s == ' ') { + werrstr("unexpected space"); + return -1; + } + if (*np != nil) { + TLnodeappend(*np, nil); + np = &((*np)->children[(*np)->count - 1]); + } if (*s == '\\') { - s++; - row.nodes = realloc(row.nodes, (row.n + 1) * sizeof(TLNode)); - memset(&row.nodes[row.n], 0, sizeof(TLNode)); - char *v = strdup(s); - row.nodes[row.n].value = v; - row.n++; + *np = allocTLnode(nil, strdup(s + 1)); break; } p = strchr(s, ' '); - if (p == s) { - sysfatal("tlparseline: unexpected space"); - } else if (p == nil) { - row.nodes = realloc(row.nodes, (row.n + 1) * sizeof(TLNode)); - memset(&row.nodes[row.n], 0, sizeof(TLNode)); - char *n = strdup(s); - row.nodes[row.n].name = n; - row.n++; - break; - } else { - *p = '\0'; - row.nodes = realloc(row.nodes, (row.n + 1) * sizeof(TLNode)); - memset(&row.nodes[row.n], 0, sizeof(TLNode)); - char *n = strdup(s); - row.nodes[row.n].name = n; - row.n++; - s = p + 1; - } + if (p != nil) *p = '\0'; + *np = allocTLnode(strdup(s), nil); + if (p == nil) break; + else s = p + 1; } - return row; + return 0; } -int +TLnode * _tlparse(char *data, usize count) { + struct TLparsecontext pc = { + .root = allocTLnode(nil, nil), + .n = 0, + }; + pc.stack[0] = pc.root; int rown = 0; - struct TLrow row; char *e, *p = data; while (p < (data + count)) { - - fprint(2, "<%d>\n", rown); - + struct TLrow row = {0, nil}; + rown++; + if (*p == '\n') { + p++; + pc.n = 0; + continue; + } e = memchr(p, '\n', count - (p - data)); if (e == nil) { - werrstr("newline not found"); - return -1; + werrstr("%d, newline not found", rown); + free(pc.root); + return nil; } - if (p != e) { - *e = '\0'; - row = _tlparseline(p); + *e = '\0'; + if (_tlparseline(&row, p) < 0) { + werrstr("%d: %r", rown); + return nil; } p = e + 1; - rown++; + if (row.indent == pc.n + 1) { + pc.n++; + } + if (pc.n >= row.indent) { + pc.n = row.indent; + TLnodeappend(pc.stack[pc.n], row.root); + pc.stack[pc.n + 1] = row.root; + while(pc.stack[pc.n + 1]->count != 0) { + pc.stack[pc.n + 1] = pc.stack[pc.n + 1]->children[0]; + } + } else { + werrstr("%d: too much indent", rown); + // TODO: clean up + return nil; + } } - return 0; + return pc.root; } diff --git a/src/tablist/tablist.h b/src/tablist/tablist.h @@ -1,9 +1,14 @@ #pragma lib "../tablist/libtablist.a$O" -typedef struct TLNode TLNode; -struct TLNode { +typedef struct TLnode TLnode; +struct TLnode { char *name; char *value; - TLNode *children; + TLnode **children; + int count; }; -int _tlparse(char *, usize); +TLnode * allocTLnode(char *, char *); +int freeTLnode(TLnode *); +int TLnodeappend(TLnode *, TLnode *); + +TLnode * _tlparse(char *, usize); diff --git a/src/tablist/test.c b/src/tablist/test.c @@ -2,16 +2,45 @@ #include <libc.h> #include "tablist.h" +void tlprint(int, TLnode *); + +void +tlprint(int indent, TLnode *node) +{ + int i; + for (i = 0; i < indent; i++) print("\t"); + + if (node->name) print("%s", node->name); + else if (node->value) { + print("\\%s", node->value); + } + else print("\\"); + + print("\n"); + + for (i = 0; i < node->count; i++) { + tlprint(indent + 1, node->children[i]); + } +} + void -main(void) +test(char *path) { - print("~~~testing~~~\n"); + TLnode *root; int n, fd; char buf[4096]; - fd = open("example.tl", OREAD); + fd = open(path, OREAD); if (fd < 0) sysfatal("%r"); n = readn(fd, buf, 4096); - _tlparse(buf, n); - print("~~~done!~~~\n"); + root = _tlparse(buf, n); + if (root == nil) sysfatal("%r"); + tlprint(0, root); exits(nil); } + +void +main(int argc, char **argv) +{ + int i; + for (i = 1; i < argc; i++) test(argv[i]); +}