commit ec3fa2663a65c6a4e331ae1704824ffb9f2168f6
parent 2b31ee715a28168d77861e55424096251a7268b8
Author: rpa <rpa@grass>
Date: Thu, 15 Jun 2023 11:23:22 +0000
tablist: redo decode
Diffstat:
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);