commit a68de3466d84ec72c2838d4a4ae20a3a03588802
parent b444f7ce9e7e4237937a6cdb284e02b482537bb8
Author: rpa <rpa@grass>
Date: Sat, 15 Jul 2023 20:48:20 +0000
srv/tablist: sync
Diffstat:
3 files changed, 92 insertions(+), 130 deletions(-)
diff --git a/src/tablist/tablist.c b/src/tablist/tablist.c
@@ -30,6 +30,18 @@ TLnodeappend(TLnode *parent, TLnode *child)
return 0;
}
+static void
+_printnode(TLnode *n)
+{
+ print("NODE %p\n", n);
+ if (n->name != nil) print("NAME: %.*s\n", n->name->len, n->name->p);
+ if (n->value != nil) print("VALUE: %.*s\n", n->value->len, n->value->p);
+ print("CHILDREN: %d\n", n->children->len);
+ print("END\n");
+}
+
+/***** DECODER *****/
+
TLdecoder *
initTLdecoder(char *file)
{
@@ -56,7 +68,6 @@ TLdecode(TLdecoder *r, char *buf, usize count)
r->state = Begin;
case Begin:
- print("sp %d\n", r->sp);
r->sp = 0;
r->indent = 0;
if (buf[i] == '\t') r->state = Indent;
@@ -107,10 +118,7 @@ TLdecode(TLdecoder *r, char *buf, usize count)
case Indent:
if (buf[i] == '\t') r->indent++, i++;
- else {
- print("indent %d\n", r->indent);
- r->state = Node;
- }
+ else r->state = Node;
break;
default:
@@ -120,138 +128,93 @@ TLdecode(TLdecoder *r, char *buf, usize count)
return 0;
}
+/******* ENCODER *******/
+
+typedef void * (TLencstate)(TLencoder *, char *);
+TLencstate _encnode, _encname, _encvalue, _encnl, _encsp, _encind, _encend;
+
+// #define ENCTOS(X) ( *(TLnode **)slicegetp(X->ns[X->sp], X->cs[X->sp]) )
+#define ENCTOS(X) ( *(TLnode **)slicegetp(X->ns[0], 0) )
TLencoder *
initTLencoder(Slice *nodes)
{
TLencoder *w = mallocz(sizeof(TLencoder), 1);
w->ns[0] = nodes;
+ w->state = _encnode;
return w;
}
-int
-TLencode(TLencoder *w, char *buf, usize count)
+void *
+_encnode(TLencoder *w, char *c)
{
- enum {
- Start = 0,
- Node, Next, Space, Newline, Escape,
- Indent, Name, Value, Select, End,
- };
-
- usize i;
- char c;
- TLnode **v;
-
- for (i = 0; i < count;) {
- switch (w->state) {
-
- case Start:
- print("start\n");
- case Node:
- 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;
- if (w->np->name != nil) {
- w->state = Name;
- }
- else if (w->np->value != nil) {
- w->state = Escape;
- }
- else w->state = Next;
- break;
-
- case Next:
- if (w->cs[w->n] < w->np->children->len) {
- w->ns[w->n + 1] = w->np->children;
- w->cs[w->n + 1] = 0;
- w->n++;
- } else {
- w->n--;
- if (w->n < 0) {
- w->state = End;
- break;
- }
- 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;
- }
- w->state = Node;
- break;
-
- case Name:
- print("name\n");
- c = *((char *)slicegetp(w->np->name, w->i++)); // ((char *)w->np->name->p)[w->i++];
- if (c != '\0') {
- buf[i++] = c;
- }
- else {
- if (w->np->children->len == 1) w->state = Space;
- else w->state = Newline;
- }
- break;
+ print("node [%d %d]\n", w->sp, w->cs[w->sp]);
+ // TLnode *n = ENCTOS(w);
+ TLnode **v = slicegetp(w->ns[0], 0);
+ TLnode *n = *v;
+ assert(n != nil);
+ _printnode(n);
+ w->i = 0;
+ if (n->name != nil) return _encname(w, c);
+ if (n->value != nil) return _encvalue(w, c);
+ return _encend(w, c);
+}
- case Value:
- c = *((char *)slicegetp(w->np->value, w->i++)); // ((char *)w->np->name->p)[w->i++];
- if (c != '\0') {
- buf[i++] = c;
- }
- else w->state = Newline;
- break;
+void *
+_encname(TLencoder *w, char *c)
+{
+ print("name\n");
+ TLnode *n = ENCTOS(w);
+ if (w->i >= n->name->len) return _encnl(w, c);
+ char *s = slicegetp(n->name, w->i);
+ *c = *s;
+ w->i++;
+ return _encname;
+}
- case Space:
- buf[i++] = ' ';
- w->state = Next;
- break;
+void *
+_encvalue(TLencoder *w, char *c)
+{
+ print("value\n");
+ TLnode *n = ENCTOS(w);
+ if (w->i >= n->value->len) return _encnl(w, c);
+ char *s = slicegetp(n->value, w->i);
+ *c = *s;
+ w->i++;
+ return _encvalue;
+}
- case Newline:
- buf[i++] = '\n';
- w->i = 0;
- w->nl = 1;
- w->indent = 0;
- w->state = Next;
- break;
+void *
+_encnl(TLencoder *, char *c)
+{
+ print("nl\n");
+ *c = '\n';
+ return _encend;
+}
- case Escape:
- buf[i++] = '\\';
- w->state = Value;
- break;
+void *
+_encsp(TLencoder *, char *c)
+{
+ print("sp\n");
+ *c = ' ';
+ return _encend;
+}
- case Indent:
- if (w->i++ < w->n - 1) {
- if (w->ns[w->i]->len > 1) buf[i++] = '\t';
- }
- else {
- w->state = Select;
- w->nl = 0;
- }
- break;
+void *
+_encend(TLencoder *, char *c)
+{
+ print("end\n");
+ *c = '\0';
+ return _encend;
+}
- case End:
- print("end\n");
- return i;
+int
+TLencode(TLencoder *w, char *buf, usize count)
+{
- default:
- sysfatal("TLencode: unknown state %d", w->state);
- }
+ usize i;
+ for (i = 0; i < count; i++) {
+ if (w->state == _encend) return i;
+ w->state = w->state(w, buf+i);
}
return i;
}
diff --git a/src/tablist/tablist.h b/src/tablist/tablist.h
@@ -25,7 +25,8 @@ typedef struct TLencoder TLencoder;
struct TLencoder {
TLnode *np;
Slice *ns[TLstackdepth];
- int state, i, nl, indent, n, cs[TLstackdepth];
+ void* (*state)(TLencoder *, char *);
+ int sp, i, cs[TLstackdepth];
};
TLnode * allocTLnode(void);
diff --git a/src/tablist/test.c b/src/tablist/test.c
@@ -36,16 +36,14 @@ test(char *path)
TLdecoder *tld = initTLdecoder(path);
TLdecode(tld, buf, n);
- Slice *nodes = tld->nodes;
+ print("DEBUGPRINT\n");
+ printnodes(tld->nodes, 0);
- // printnodes(nodes, 0);
-
- TLencoder *tle = initTLencoder(tld->stack[0]);
+ TLencoder *tle = initTLencoder(tld->nodes);
print("WRITE\n");
- while (n > 0) {
- n = TLencode(tle, buf, 4096);
- write(1, buf, n);
- }
+ n = TLencode(tle, buf, 4096);
+ write(1, buf, n);
+ print("%d bytes\n", n);
}
void