stew

a monorepo of some sort
Log | Files | Refs

commit ec3fa2663a65c6a4e331ae1704824ffb9f2168f6
parent 2b31ee715a28168d77861e55424096251a7268b8
Author: rpa <rpa@grass>
Date:   Thu, 15 Jun 2023 11:23:22 +0000

tablist: redo decode

Diffstat:
Msrc/tablist/tablist.c | 139+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------
Msrc/tablist/tablist.h | 16++++++++--------
Msrc/tablist/test.c | 25++++++++++++++++++++++++-
3 files changed, 139 insertions(+), 41 deletions(-)

diff --git a/src/tablist/tablist.c b/src/tablist/tablist.c @@ -6,24 +6,11 @@ Type TLnodeType = {.nbytes = sizeof(TLnode *), }; -struct TLrow { - int indent; - TLnode *root; -}; - -struct TLparsecontext { - TLnode *root; - TLnode *stack[64]; - int n; -}; - TLnode * -allocTLnode(char *name, char *value) +allocTLnode(void) { TLnode *node = mallocz(sizeof(TLnode), 1); - node->children = allocslice(&TLnodeType, 0, 1); - node->name = name; - node->value = value; + node->children = allocslice(&TLnodeType, 0, 0); return node; } @@ -49,24 +36,95 @@ initTLdecoder(char *file) TLdecoder *tlp; tlp = mallocz(sizeof(TLdecoder), 1); tlp->nodes = allocslice(&TLnodeType, 0, 1); + tlp->stack[0] = tlp->nodes; + tlp->acc = allocslice(&CharType, 0, 256); tlp->file = file; return tlp; } int -TLdecode(TLdecoder *tlp, char *buf, usize count) +TLdecode(TLdecoder *r, char *buf, usize count) { + enum { + Start, Begin, Node, Name, FlushName, Value, FlushValue, Indent, + }; + usize i; + TLnode *new; + for (i = 0; i < count;) { + switch (r->state) { + case Start: + r->state = Begin; + + case Begin: + print("sp %d\n", r->sp); + r->sp = 0; + r->indent = 0; + if (buf[i] == '\t') r->state = Indent; + else r->stack[0] = r->nodes, r->state = Node; + break; + + case Node: + r->acc->len = 0; + if (buf[i] == '\\') r->state = Value, i++; + else r->state = Name; + break; + + case Name: + if ((buf[i] != ' ') && (buf[i] != '\n')) { + r->acc = sliceappendp(r->acc, 1, buf+i), i++; + break; + } + else r->state = FlushName; + + case FlushName: + new = allocTLnode(); + new->name = slicecopy(r->acc); + sliceappendp(r->stack[r->sp], 1, &new); + if (r->indent == r->sp + 1) r->sp++; + else if (r->indent <= r->sp) r->sp = r->indent; + else sysfatal("TLdecode: indent is no good"); + r->stack[r->sp] = new->children; + if (buf[i] == ' ') r->state = Node, i++; + else if (buf[i] == '\n') r->state = Begin, i++; + break; + + case Value: + if (buf[i] != '\n') { + r->acc = sliceappendp(r->acc, 1, buf+i), i++; + break; + } else r->state = FlushValue; + + case FlushValue: + new = allocTLnode(); + new->value = slicecopy(r->acc); + sliceappendp(r->stack[r->sp], 1, &new); + if (r->indent == r->sp + 1) r->sp++; + else if (r->indent <= r->sp) r->sp = r->indent; + else sysfatal("TLdecode: indent is no good"); + r->stack[r->sp] = new->children; + r->state = Begin, i++; + break; + + case Indent: + if (buf[i] == '\t') r->indent++, i++; + else { + print("indent %d\n", r->indent); + r->state = Node; + } + break; + + default: + sysfatal("TLdecode: unknown state %d", r->state); + } + } return 0; } TLencoder * -initTLencoder(TLnode *root) +initTLencoder(Slice *nodes) { TLencoder *w = mallocz(sizeof(TLencoder), 1); - w->root = root; - w->np = root; - w->ns[0] = root; - w->n = 0; + w->ns[0] = nodes; return w; } @@ -81,18 +139,28 @@ TLencode(TLencoder *w, char *buf, usize count) usize i; char c; + TLnode **v; for (i = 0; i < count;) { switch (w->state) { case Start: + print("start\n"); case Node: - w->np = w->ns[w->n]; - if (w->nl != 0) { - w->state = Indent; - break; - } - else w->state = Select; + print("node\n"); + print("\tlen %d n %d\n", w->ns[w->n]->len, w->cs[w->n]); + if (w->ns[w->n]->len <= w->cs[w->n]) { + w->state = End; + break; + } + v = slicegetp(w->ns[w->n], w->cs[w->n]); + w->np = *v; + print("\t%d %d\n", w->n, w->cs[w->n]); + if (w->nl != 0) { + w->state = Indent; + break; + } + else w->state = Select; case Select: w->i = 0; @@ -107,7 +175,7 @@ TLencode(TLencoder *w, char *buf, usize count) case Next: if (w->cs[w->n] < w->np->children->len) { - w->ns[w->n + 1] = w->np->children[w->cs[w->n]]; + w->ns[w->n + 1] = w->np->children; w->cs[w->n + 1] = 0; w->n++; } else { @@ -116,7 +184,12 @@ TLencode(TLencoder *w, char *buf, usize count) w->state = End; break; } - w->np = w->ns[w->n]; + if (w->cs[w->n] >= w->ns[w->n]->len) { + w->state = End; + break; + } + v = slicegetp(w->ns[w->n], w->cs[w->n]); + w->np = *v; w->cs[w->n]++; w->state = Next; break; @@ -125,7 +198,8 @@ TLencode(TLencoder *w, char *buf, usize count) break; case Name: - c = w->np->name[w->i++]; + print("name\n"); + c = *((char *)slicegetp(w->np->name, w->i++)); // ((char *)w->np->name->p)[w->i++]; if (c != '\0') { buf[i++] = c; } @@ -136,7 +210,7 @@ TLencode(TLencoder *w, char *buf, usize count) break; case Value: - c = w->np->value[w->i++]; + c = *((char *)slicegetp(w->np->value, w->i++)); // ((char *)w->np->name->p)[w->i++]; if (c != '\0') { buf[i++] = c; } @@ -163,7 +237,7 @@ TLencode(TLencoder *w, char *buf, usize count) case Indent: if (w->i++ < w->n - 1) { - if (w->ns[w->i]->children->len > 1) buf[i++] = '\t'; + if (w->ns[w->i]->len > 1) buf[i++] = '\t'; } else { w->state = Select; @@ -172,6 +246,7 @@ TLencode(TLencoder *w, char *buf, usize count) break; case End: + print("end\n"); return i; default: diff --git a/src/tablist/tablist.h b/src/tablist/tablist.h @@ -9,31 +9,31 @@ extern Type TLnodeType; typedef struct TLnode TLnode; struct TLnode { - char *name; - char *value; + Slice *name; + Slice *value; Slice *children; }; typedef struct TLdecoder TLdecoder; struct TLdecoder { char *file, *buf; - TLnode *stack[TLstackdepth]; - Slice *nodes; - int sp, row, col; + Slice *nodes, *acc, *stack[TLstackdepth]; + int state, indent, sp, row, col; }; typedef struct TLencoder TLencoder; struct TLencoder { - TLnode *root, *np, *ns[TLstackdepth]; + TLnode *np; + Slice *ns[TLstackdepth]; int state, i, nl, indent, n, cs[TLstackdepth]; }; -TLnode * allocTLnode(char *, char *); +TLnode * allocTLnode(void); void freeTLnode(TLnode *); int TLnodeappend(TLnode *, TLnode *); TLdecoder * initTLdecoder(char *); int TLdecode(TLdecoder *, char *, usize); -TLencoder * initTLencoder(TLnode *); +TLencoder * initTLencoder(Slice *); int TLencode(TLencoder *, char *, usize); diff --git a/src/tablist/test.c b/src/tablist/test.c @@ -3,6 +3,25 @@ #include "../util/util.h" #include "tablist.h" +void +printnodes(Slice *nodes, int indent) +{ + int i; + for (i = 0; i < nodes->len; i++) { + TLnode **v = slicegetp(nodes, i); + TLnode *n = *v; + print ("[%d/%d]", indent, i); + if (n == nil) {print("<nil>\n"); continue;} + if (n->name != nil) print("[name %.*s]", n->name->len, n->name->p); + else if (n->value != nil) print("[value %.*s]", n->value->len, n->value->p); + if (n->children != nil) { + print("[children %d]\n", n->children->len); + printnodes(n->children, indent + 1); + } + else print("\n"); + } +} + void test(char *path) @@ -17,7 +36,11 @@ test(char *path) TLdecoder *tld = initTLdecoder(path); TLdecode(tld, buf, n); - TLencoder *tle = initTLencoder(tld->root); + Slice *nodes = tld->nodes; + + // printnodes(nodes, 0); + + TLencoder *tle = initTLencoder(tld->stack[0]); print("WRITE\n"); while (n > 0) { n = TLencode(tle, buf, 4096);