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 }