commit e4352a504acf83163fe41a3c1a557fbb3fb17878
parent cedc8995374227141a55c363a442f93a8486f8c8
Author: ssnf <ssnf@ssnf.xyz>
Date: Wed, 27 Aug 2025 14:59:02 +0000
json2sdb
Diffstat:
3 files changed, 96 insertions(+), 0 deletions(-)
diff --git a/.gitignore b/.gitignore
@@ -111,6 +111,7 @@ bin/img
bin/import
bin/join
bin/jpg
+bin/json2sdb
bin/lex
bin/listen1
bin/look
diff --git a/src/cmd/sdb/json2sdb.c b/src/cmd/sdb/json2sdb.c
@@ -0,0 +1,94 @@
+#include <u.h>
+#include <libc.h>
+
+#include <bio.h>
+#include <str.h>
+#include <vec.h>
+#include <sdbr.h>
+#include <json.h>
+
+static String node;
+static String tmp;
+
+static void
+JObj2r(Json *j)
+{
+ JsonObj *o;
+ ulong i;
+ char t, last;
+
+ if (j->cur->t == JErr)
+ sysfatal("%s at line %d", j->cur->k.s, (int)j->cur->v.n);
+ Strzero(&node);
+ last = 0;
+ for (i = 0; i < j->n; ++i) {
+ o = j->o + j->st[i];
+ t = o->v.c;
+ if (t == '{' || t != last)
+ Strprint(&node, "%U", o->k.s);
+ if (j->cur->t == JObj && i == j->n - 1) {
+ last = t;
+ continue;
+ }
+ if (t == '{')
+ Straddc(&node, '.');
+ else
+ Strprint(&node, "[]");
+ last = t;
+ }
+ o = j->cur;
+ if (o->t == JObj) {
+ t = (o->v.c == '{') ? 'o' : 'a';
+ print("%c\t%s\n", t, node.s);
+ json_next(j, 0);
+ JObj2r(j);
+ return;
+ }
+ t = (o->t == JStr) ? 's' : 'n';
+ print("%c\t%s%U=", t, node.s, o->k.s);
+ if (o->t == JNum)
+ print("%.17g\n", o->v.n);
+ else {
+ sdbr_escape(&tmp, o->v.s);
+ print("%s\n", tmp.s);
+ }
+}
+
+static int
+Ufmt(Fmt *fmt)
+{
+ char *s;
+
+ s = va_arg(fmt->args, char*);
+ if (!s)
+ return 0;
+ for (; *s; ++s) {
+ switch (*s) {
+ case ' ': fmtrune(fmt, '+'); break;
+ case '+': fmtprint(fmt, "\\x2b"); break;
+ case '=': fmtprint(fmt, "\\x3d"); break;
+ case '%': fmtprint(fmt, "\\x25"); break;
+ case '\f': fmtprint(fmt, "\\f"); break;
+ case '\n': fmtprint(fmt, "\\n"); break;
+ case '\r': fmtprint(fmt, "\\r"); break;
+ case '\t': fmtprint(fmt, "\\t"); break;
+ case '\v': fmtprint(fmt, "\\v"); break;
+ default: fmtrune(fmt, *s);
+ }
+ }
+ return 0;
+}
+
+void
+main(int argc, char *argv[])
+{
+ Json j;
+
+ fmtinstall('U', Ufmt);
+ Strinit(&node);
+ Strinit(&tmp);
+ json_init(&j, argv[1]);
+ for (;json_next(&j, 0);)
+ JObj2r(&j);
+ exits(0);
+}
diff --git a/src/cmd/sdb/mkfile b/src/cmd/sdb/mkfile
@@ -1,6 +1,7 @@
<$PLAN9/src/mkhdr
TARG=\
+ json2sdb\
sdbedit\
sdbjoin\
sdbmap\