stew

a monorepo of some sort
Log | Files | Refs

commit 4a719ad817fa583f48b8150f00bc2c0ef9f52723
parent e168181e64907d62c30af2bb6feb0a82f13a0a33
Author: rpa <rpa@grass>
Date:   Mon, 31 Jul 2023 21:38:49 +0000

src/tablist: decoder is probably fixed, but encoder is still broken

Diffstat:
Msrc/tablist/tablist.c | 59++++++++++++++++++++++++++++++++++++++++++++++-------------
Msrc/tablist/tablist.h | 4+++-
Msrc/tablist/test.c | 9+++++----
3 files changed, 54 insertions(+), 18 deletions(-)

diff --git a/src/tablist/tablist.c b/src/tablist/tablist.c @@ -1,3 +1,12 @@ +/***** TODO ***** + + Implement decoding from buffer (aka file) instead of stream. + Boilerplate should include capability of navigating the buffer + via next_token/prev_token commands, while keeping track of + current line and indentation level. + +*/ + #include <u.h> #include <libc.h> @@ -42,13 +51,13 @@ _printnode(TLnode *n) /***** DECODER *****/ + TLdecoder * 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; @@ -65,13 +74,12 @@ TLdecode(TLdecoder *r, char *buf, usize count) for (i = 0; i < count;) { switch (r->state) { case Start: - r->sp = 0; r->state = Begin; case Begin: r->indent = 0; if (buf[i] == '\t') r->state = Indent; - else r->stack[0] = r->nodes, r->state = Node; + else r->sp = 0, r->state = Node; break; case Node: @@ -90,15 +98,25 @@ TLdecode(TLdecoder *r, char *buf, usize count) case FlushName: new = allocTLnode(); new->name = slicecopy(r->acc); - sliceappendp(r->stack[r->sp], 1, &new); - print("indent %d\n", r->indent); + if (r->indent == 0) { + r->sp = 0; + sliceappendp(r->nodes, 1, &new); + } else if (r->indent == -1) { + sliceappendp(r->stack[r->sp]->children, 1, &new); + } else if (r->indent <= r->sp) { + r->sp = r->indent; + sliceappendp(r->stack[r->sp - 1]->children, 1, &new); + } else if (r->indent == r->sp + 1) { + sliceappendp(r->stack[r->sp]->children, 1, &new); + r->sp = r->indent; + } else sysfatal("TLdecode/FlushName: indent is no good"); - if (r->indent <= r->sp + 1) r->sp = r->indent; - else sysfatal("TLdecode/FlushName: indent is no good"); + r->stack[r->sp] = new; - r->stack[r->sp] = new->children; - if (buf[i] == ' ') r->state = Node, i++; + print("indent %d sp %d %.*s\n", r->indent, r->sp, new->name->len, new->name->p); + + if (buf[i] == ' ') r->state = Node, r->indent = -1, i++; else r->state = Begin, i++; break; @@ -111,12 +129,24 @@ TLdecode(TLdecoder *r, char *buf, usize count) case FlushValue: new = allocTLnode(); new->value = slicecopy(r->acc); - sliceappendp(r->stack[r->sp], 1, &new); - if (r->indent <= r->sp + 1) r->sp = r->indent; - else sysfatal("TLdecode/FlushValue: indent is no good"); + if (r->indent == 0) { + r->sp = 0; + sliceappendp(r->nodes, 1, &new); + } else if (r->indent == -1) { + sliceappendp(r->stack[r->sp]->children, 1, &new); + } else if (r->indent <= r->sp) { + r->sp = r->indent; + sliceappendp(r->stack[r->sp - 1]->children, 1, &new); + } else if (r->indent == r->sp + 1) { + sliceappendp(r->stack[r->sp]->children, 1, &new); + r->sp = r->indent; + } else sysfatal("TLdecode/FlushName: indent is no good"); + + r->stack[r->sp] = new; + + print("indent %d sp %d %.*s\n", r->indent, r->sp, new->value->len, new->value->p); - r->stack[r->sp] = new->children; r->state = Begin, i++; break; @@ -195,6 +225,7 @@ _encnext(TLencoder *w, char *c) TLnode *fc = nil; if (n->children->len > 0) fc = *(TLnode **)slicegetp(n->children, 0); if (n->children->len == 0) { + print("no children\n"); w->cs[w->sp]++; return _encnl(w, c); } else if ((n->children->len == 1) && (fc->name != nil)) { @@ -212,8 +243,10 @@ _encnext(TLencoder *w, char *c) void * _encnl(TLencoder *w, char *c) { + print("nl\n"); *c = '\n'; while (w->cs[w->sp] == w->ns[w->sp]->len) { + print("sp %d\n", w->sp); w->sp--; if (w->sp < 0) return _encend; w->cs[w->sp]++; diff --git a/src/tablist/tablist.h b/src/tablist/tablist.h @@ -12,12 +12,14 @@ struct TLnode { Slice *name; Slice *value; Slice *children; + TLnode *parent; }; typedef struct TLdecoder TLdecoder; struct TLdecoder { char *file, *buf; - Slice *nodes, *acc, *stack[TLstackdepth]; + Slice *nodes, *acc; + TLnode *stack[TLstackdepth]; int state, indent, sp, row, col; }; diff --git a/src/tablist/test.c b/src/tablist/test.c @@ -6,14 +6,15 @@ void printnodes(Slice *nodes, int indent) { - int i; + int i, j; for (i = 0; i < nodes->len; i++) { TLnode **v = slicegetp(nodes, i); TLnode *n = *v; - print ("[%d/%d]", indent, i); + print ("%d:", i); + for (j = 0; j < indent; j++) print(" "); 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->name != nil) print("[n %.*s]", n->name->len, n->name->p); + else if (n->value != nil) print("[v %.*s]", n->value->len, n->value->p); if (n->children != nil) { print("[children %d]\n", n->children->len); printnodes(n->children, indent + 1);