ref: f8d74ea182246209e30cb5e90e7697a5ad99a407
dir: /json2awk.c/
#include <u.h>
#include <libc.h>
#include <bio.h>
#include <json.h>
typedef struct Level Level;
struct Level {
int noquote;
char *name;
Level *next;
Level *prev;
};
Level *head = nil;
Level *tail = nil;
void
lappend(int q, char *s)
{
Level *new;
if((new = mallocz(sizeof(Level), 1)) == nil)
sysfatal("mallocz: %r");
new->noquote = !q;
new->name = s;
if(!head)
head = new;
if(tail)
tail->next = new;
new->prev = tail;
tail = new;
}
void
lremove(void)
{
void *v;
v = tail;
tail = tail->prev;
free(v);
if(tail == nil)
head = nil;
else
tail->next = nil;
}
#pragma varargck type "L" Level*
int
Lfmt(Fmt *f)
{
Level *l;
l = va_arg(f->args, Level*);
while(l != nil){
if(l->noquote){
if(fmtprint(f, "%s", l->name) < 0)
return -1;
}else
if(fmtprint(f, "\"%s\"", l->name) < 0)
return -1;
if(l->next != nil && fmtprint(f, ", ") < 0)
return -1;
l = l->next;
}
return 0;
}
void
json2awk(JSON *j)
{
JSONEl *e;
char *s;
int i;
switch(j->t){
case JSONArray:
e = j->first;
for(i = 0; e; i++){
s = smprint("%d", i);
lappend(0, s);
json2awk(e->val);
lremove();
e = e->next;
free(s);
}
break;
case JSONObject:
e = j->first;
do{
lappend(1, e->name);
json2awk(e->val);
lremove();
}while(e = e->next);
break;
case JSONBool:
print("json[%L] = %d;\n", head, (int)j->n);
break;
case JSONNumber:
print("json[%L] = %g;\n", head, j->n);
break;
case JSONString:
print("json[%L] = \"%s\";\n", head, j->s);
break;
case JSONNull:
break;
}
}
void
main(int argc, char **argv)
{
Level *l, *ln;
Biobuf *b;
JSON *J;
char *j;
int fd;
switch(argc){
case 1:
fd = 0;
break;
case 2:
fd = open(argv[1], OREAD);
break;
default:
fprint(2, "usage: json2awk [file]");
exits("usage");
}
/* read it all into j */
fmtinstall('L', Lfmt);
b = Bfdopen(fd, OREAD);
if((j = Brdstr(b, '\0', '\0')) == nil)
exits(0);
if((J = jsonparse(j)) == nil)
sysfatal("jsonparse: %r");
json2awk(J);
jsonfree(J);
free(j);
free(b);
for(l = head; l != nil; l = ln){
ln = l->next;
free(l);
}
exits(0);
}