plan9port

fork of plan9port with libvec, libstr and libsdb
Log | Files | Refs | README | LICENSE

json2sdb.c (1758B)


      1 #include <u.h>
      2 #include <libc.h>
      3 
      4 #include <bio.h>
      5 #include <str.h>
      6 #include <vec.h>
      7 #include <sdbr.h>
      8 #include <json.h>
      9 
     10 static String node;
     11 static String tmp;
     12 
     13 static void
     14 JObj2r(Json *j)
     15 {
     16 	JsonObj *o;
     17 	ulong i;
     18 	char t, last;
     19 
     20 	Strzero(&node);
     21 	last = 0;
     22 	for (i = 0; i < j->n; ++i) {
     23 		o = j->o + j->st[i];
     24 		t = o->v.c;
     25 		if (t == '{' || t != last)
     26 			Strprint(&node, "%U", o->k.s);
     27 		if (j->cur->t == JObj && i == j->n - 1) {
     28 			last = t;
     29 			continue;
     30 		}
     31 		if (t == '{')
     32 			Straddc(&node, '.');
     33 		else
     34 			Strprint(&node, "[]");
     35 		last = t;
     36 	}
     37 	o = j->cur;
     38 	if (o->t == JObj) {
     39 		t = (o->v.c == '{') ? 'o' : 'a';
     40 		print("%c\t%s\n", t, node.s);
     41 		if (!json_next(j, 0))
     42 			return;
     43 		JObj2r(j);
     44 		return;
     45 	}
     46 	t = (o->t == JStr) ? 's' : 'n';
     47 	print("%c\t%s%U=", t, node.s, o->k.s);
     48 	if (o->t == JNum)
     49 		print("%.17g\n", o->v.n);
     50 	else {
     51 		sdbr_escape(&tmp, o->v.s);
     52 		print("%s\n", tmp.s);
     53 	}
     54 }
     55 
     56 static int
     57 Ufmt(Fmt *fmt)
     58 {
     59 	char *s;
     60 
     61 	s = va_arg(fmt->args, char*);
     62 	if (!s)
     63 		return 0;
     64 	for (; *s; ++s) {
     65 		switch (*s) {
     66 		case ' ': fmtrune(fmt, '+'); break;
     67 		case '#': fmtprint(fmt, "\\x23"); break;
     68 		case '+': fmtprint(fmt, "\\x2b"); break;
     69 		case '=': fmtprint(fmt, "\\x3d"); break;
     70 		case '\\': fmtprint(fmt, "\\\\"); break;
     71 		case '\f': fmtprint(fmt, "\\f"); break;
     72 		case '\n': fmtprint(fmt, "\\n"); break;
     73 		case '\r': fmtprint(fmt, "\\r"); break;
     74 		case '\t': fmtprint(fmt, "\\t"); break;
     75 		case '\v': fmtprint(fmt, "\\v"); break;
     76 		default: fmtrune(fmt, *s);
     77 		}
     78 	}
     79 	return 0;
     80 }
     81 
     82 void
     83 main(int argc, char *argv[])
     84 {
     85 	Json j;
     86 
     87 	fmtinstall('U', Ufmt);
     88 	Strinit(&node);
     89 	Strinit(&tmp);
     90 	json_init(&j, argv[1]);
     91 	for (;json_next(&j, 0);)
     92 		JObj2r(&j);
     93 	if (j.cur->t == JErr)
     94 		sysfatal("%s at line %d", j.cur->k.s, (int)j.cur->v.n);
     95 	exits(0);
     96 }