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:
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);