stew

a monorepo of some sort
Log | Files | Refs

commit 752a2f5617d6b6ccf9758a19372b27fadfe6c65d
parent e39cc9652d340623fd4fba9c2f938fd168e8d5be
Author: Renev Pavel <an2qzavok@gmail.com>
Date:   Thu, 11 May 2023 23:27:18 +0000

tablist: encoder is operational!

Diffstat:
Msrc/tablist/example.tl | 24++++++++++++++----------
Msrc/tablist/tablist.c | 141+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/tablist/tablist.h | 27++++++++++++++++++++-------
Msrc/tablist/test.c | 47+++++++++++++++++------------------------------
4 files changed, 192 insertions(+), 47 deletions(-)

diff --git a/src/tablist/example.tl b/src/tablist/example.tl @@ -1,10 +1,14 @@ -wdbentry - uuid \5cb897dd-0fcb-4102-204b-5fdede76930c - name - \Shinju no Nectar - \Nectar of Dharani - \Nectar of Divine Curse - \神呪のネクタール - status \ch 31 - tags \setting:fantasy isekai ecchi smut - type \manga +a +aa + b + c + d + cc dd +name + \Shinju no Nectar + \Nectar of Dharani + \Nectar of Divine Curse + \神呪のネクタール +status \ch 31 +tags \setting:fantasy isekai ecchi smut +type \manga diff --git a/src/tablist/tablist.c b/src/tablist/tablist.c @@ -129,3 +129,144 @@ _tlparse(char *data, usize count) } return pc.root; } + +TLdecoder * +initTLdecoder(char *file) +{ + TLdecoder *tlp; + tlp = mallocz(sizeof(TLdecoder), 1); + tlp->file = file; + // tlp->root = allocTLnode(strdup("root"), nil); + return tlp; +} + +int +TLdecode(TLdecoder *tlp, char *buf, usize count) +{ + tlp->root = _tlparse(buf, count); + return 0; +} + +TLencoder * +initTLencoder(TLnode *root) +{ + TLencoder *w = mallocz(sizeof(TLencoder), 1); + w->root = root; + w->np = root; + w->ns[0] = root; + w->n = 0; + return w; +} + +int +TLencode(TLencoder *w, char *buf, usize count) +{ + enum { + Start = 0, + Node, Next, Space, Newline, Escape, + Indent, Name, Value, Select, End, + }; + + usize i; + int j; + char c; + + for (i = 0; i < count;) { + switch (w->state) { + + case Start: + case Node: + w->np = w->ns[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->count) { + assert(w->np->children != nil); + w->ns[w->n + 1] = w->np->children[w->cs[w->n]]; + w->cs[w->n + 1] = 0; + w->n++; + } else { + w->n--; + if (w->n < 0) { + w->state = End; + break; + } + w->np = w->ns[w->n]; + w->cs[w->n]++; + w->state = Next; + break; + } + w->state = Node; + break; + + case Name: + c = w->np->name[w->i++]; + if (c != '\0') { + buf[i++] = c; + } + else { + if (w->np->count == 1) w->state = Space; + else w->state = Newline; + } + break; + + case Value: + c = w->np->value[w->i++]; + if (c != '\0') { + buf[i++] = c; + } + else w->state = Newline; + break; + + case Space: + buf[i++] = ' '; + w->state = Next; + break; + + case Newline: + buf[i++] = '\n'; + w->i = 0; + w->nl = 1; + w->indent = 0; + w->state = Next; + break; + + case Escape: + buf[i++] = '\\'; + w->state = Value; + break; + + case Indent: + if (w->i++ < w->n - 1) { + if (w->ns[w->i]->count >1) buf[i++] = '\t'; + } + else { + w->state = Select; + w->nl = 0; + } + break; + + case End: + return i; + + default: + sysfatal("TLencode: unknown state %d", w->state); + } + } + return i; +} diff --git a/src/tablist/tablist.h b/src/tablist/tablist.h @@ -1,4 +1,10 @@ #pragma lib "../tablist/libtablist.a$O" + +enum { + TLstackdepth = 256, + TLbufsize = 1024, +}; + typedef struct TLnode TLnode; struct TLnode { char *name; @@ -7,18 +13,25 @@ struct TLnode { int count; }; -typedef struct TLparser TLparser; -struct TLparserr { - char *file; +typedef struct TLdecoder TLdecoder; +struct TLdecoder { + char *file, *buf; + TLnode *root, *stack[TLstackdepth]; int sp, row, col; - TLnode *root, *stack[64]; }; -TLparesr * initTLparser(char *); -int TLparse(TLparser *, void *, size); +typedef struct TLencoder TLencoder; +struct TLencoder { + TLnode *root, *np, *ns[TLstackdepth]; + int state, i, nl, indent, n, cs[TLstackdepth]; +}; TLnode * allocTLnode(char *, char *); int freeTLnode(TLnode *); int TLnodeappend(TLnode *, TLnode *); -TLnode * _tlparse(char *, usize); +TLdecoder * initTLdecoder(char *); +int TLdecode(TLdecoder *, char *, usize); + +TLencoder * initTLencoder(TLnode *); +int TLencode(TLencoder *, char *, usize); diff --git a/src/tablist/test.c b/src/tablist/test.c @@ -2,40 +2,25 @@ #include <libc.h> #include "tablist.h" -void tlprint(int, TLnode *); - -void -tlprint(int indent, TLnode *node) -{ - int i; - for (i = 0; i < indent; i++) print("\t"); - - if (node->name) print("%s", node->name); - else if (node->value) { - print("\\%s", node->value); - } - else print("\\"); - - print("\n"); - - for (i = 0; i < node->count; i++) { - tlprint(indent + 1, node->children[i]); - } -} - void test(char *path) { - TLnode *root; - int n, fd; - char buf[4096]; - fd = open(path, OREAD); + fprint(2, "%s...\n", path); + char *buf = malloc(4096); + int fd = open(path, OREAD); if (fd < 0) sysfatal("%r"); - n = readn(fd, buf, 4096); - root = _tlparse(buf, n); - if (root == nil) sysfatal("%r"); - tlprint(0, root); - exits(nil); + usize n = read(fd, buf, 4096); + print("READ %d bytes\n", n); + write(1, buf, n); + TLdecoder *tld = initTLdecoder(path); + TLdecode(tld, buf, n); + + TLencoder *tle = initTLencoder(tld->root); + print("WRITE\n"); + while (n > 0) { + n = TLencode(tle, buf, 4096); + write(1, buf, n); + } } void @@ -43,4 +28,6 @@ main(int argc, char **argv) { int i; for (i = 1; i < argc; i++) test(argv[i]); + fprint(2, "OVER\n"); + exits(nil); }