|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <errno.h>
|
|
|
|
#include "../jsmn.h"
|
|
|
|
|
|
|
|
/*
|
|
|
|
* An example of reading JSON from stdin and printing its content to stdout.
|
|
|
|
* The output looks like YAML, but I'm not sure if it's really compatible.
|
|
|
|
*/
|
|
|
|
|
|
|
|
static int dump(const char *js, jsmntok_t *t, size_t count, int indent) {
|
|
|
|
int i, j, k;
|
|
|
|
if (count == 0) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
if (t->type == JSMN_PRIMITIVE) {
|
|
|
|
printf("%.*s", t->end - t->start, js+t->start);
|
|
|
|
return 1;
|
|
|
|
} else if (t->type == JSMN_STRING) {
|
|
|
|
printf("'%.*s'", t->end - t->start, js+t->start);
|
|
|
|
return 1;
|
|
|
|
} else if (t->type == JSMN_OBJECT) {
|
|
|
|
printf("\n");
|
|
|
|
j = 0;
|
|
|
|
for (i = 0; i < t->size; i++) {
|
|
|
|
for (k = 0; k < indent; k++) printf(" ");
|
|
|
|
j += dump(js, t+1+j, count-j, indent+1);
|
|
|
|
printf(": ");
|
|
|
|
j += dump(js, t+1+j, count-j, indent+1);
|
|
|
|
printf("\n");
|
|
|
|
}
|
|
|
|
return j+1;
|
|
|
|
} else if (t->type == JSMN_ARRAY) {
|
|
|
|
j = 0;
|
|
|
|
printf("\n");
|
|
|
|
for (i = 0; i < t->size; i++) {
|
|
|
|
for (k = 0; k < indent-1; k++) printf(" ");
|
|
|
|
printf(" - ");
|
|
|
|
j += dump(js, t+1+j, count-j, indent+1);
|
|
|
|
printf("\n");
|
|
|
|
}
|
|
|
|
return j+1;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int main() {
|
|
|
|
int r;
|
|
|
|
int eof_expected = 0;
|
|
|
|
char *tmp, *js = NULL;
|
|
|
|
size_t jslen = 0;
|
|
|
|
char buf[BUFSIZ];
|
|
|
|
|
|
|
|
jsmn_parser p;
|
|
|
|
jsmntok_t *tok;
|
|
|
|
size_t tokcount = 2;
|
|
|
|
|
|
|
|
/* Prepare parser */
|
|
|
|
jsmn_init(&p);
|
|
|
|
|
|
|
|
/* Allocate some tokens as a start */
|
|
|
|
tok = malloc(sizeof(*tok) * tokcount);
|
|
|
|
if (tok == NULL) {
|
|
|
|
fprintf(stderr, "malloc(): errno=%d\n", errno);
|
|
|
|
return 3;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (;;) {
|
|
|
|
/* Read another chunk */
|
|
|
|
r = fread(buf, 1, sizeof(buf), stdin);
|
|
|
|
if (r < 0) {
|
|
|
|
fprintf(stderr, "fread(): %d, errno=%d\n", r, errno);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
if (r == 0) {
|
|
|
|
if (eof_expected != 0) {
|
|
|
|
return 0;
|
|
|
|
} else {
|
|
|
|
fprintf(stderr, "fread(): unexpected EOF\n");
|
|
|
|
return 2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
tmp = realloc(js, jslen + r + 1);
|
|
|
|
if (tmp == NULL) {
|
|
|
|
free (js);
|
|
|
|
fprintf(stderr, "realloc(): errno=%d\n", errno);
|
|
|
|
return 3;
|
|
|
|
}
|
|
|
|
js = tmp;
|
|
|
|
strncpy(js + jslen, buf, r);
|
|
|
|
jslen = jslen + r;
|
|
|
|
|
|
|
|
again:
|
|
|
|
r = jsmn_parse(&p, js, jslen, tok, tokcount);
|
|
|
|
if (r < 0) {
|
|
|
|
if (r == JSMN_ERROR_NOMEM) {
|
|
|
|
jsmntok_t *tmptok;
|
|
|
|
|
|
|
|
tokcount = tokcount * 2;
|
|
|
|
tmptok = realloc(tok, sizeof(*tok) * tokcount);
|
|
|
|
if (tmptok == NULL) {
|
|
|
|
free (tok);
|
|
|
|
fprintf(stderr, "realloc(): errno=%d\n", errno);
|
|
|
|
return 3;
|
|
|
|
}
|
|
|
|
tok = tmptok;
|
|
|
|
goto again;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
dump(js, tok, p.toknext, 0);
|
|
|
|
eof_expected = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|