1*276da39aSCy Schubert #include <stdio.h>
2*276da39aSCy Schubert #include <stdlib.h>
3*276da39aSCy Schubert #include <string.h>
4*276da39aSCy Schubert #include <errno.h>
5*276da39aSCy Schubert #include "../jsmn.h"
6*276da39aSCy Schubert
7*276da39aSCy Schubert /*
8*276da39aSCy Schubert * An example of reading JSON from stdin and printing its content to stdout.
9*276da39aSCy Schubert * The output looks like YAML, but I'm not sure if it's really compatible.
10*276da39aSCy Schubert */
11*276da39aSCy Schubert
dump(const char * js,jsmntok_t * t,size_t count,int indent)12*276da39aSCy Schubert static int dump(const char *js, jsmntok_t *t, size_t count, int indent) {
13*276da39aSCy Schubert int i, j, k;
14*276da39aSCy Schubert if (count == 0) {
15*276da39aSCy Schubert return 0;
16*276da39aSCy Schubert }
17*276da39aSCy Schubert if (t->type == JSMN_PRIMITIVE) {
18*276da39aSCy Schubert printf("%.*s", t->end - t->start, js+t->start);
19*276da39aSCy Schubert return 1;
20*276da39aSCy Schubert } else if (t->type == JSMN_STRING) {
21*276da39aSCy Schubert printf("'%.*s'", t->end - t->start, js+t->start);
22*276da39aSCy Schubert return 1;
23*276da39aSCy Schubert } else if (t->type == JSMN_OBJECT) {
24*276da39aSCy Schubert printf("\n");
25*276da39aSCy Schubert j = 0;
26*276da39aSCy Schubert for (i = 0; i < t->size; i++) {
27*276da39aSCy Schubert for (k = 0; k < indent; k++) printf(" ");
28*276da39aSCy Schubert j += dump(js, t+1+j, count-j, indent+1);
29*276da39aSCy Schubert printf(": ");
30*276da39aSCy Schubert j += dump(js, t+1+j, count-j, indent+1);
31*276da39aSCy Schubert printf("\n");
32*276da39aSCy Schubert }
33*276da39aSCy Schubert return j+1;
34*276da39aSCy Schubert } else if (t->type == JSMN_ARRAY) {
35*276da39aSCy Schubert j = 0;
36*276da39aSCy Schubert printf("\n");
37*276da39aSCy Schubert for (i = 0; i < t->size; i++) {
38*276da39aSCy Schubert for (k = 0; k < indent-1; k++) printf(" ");
39*276da39aSCy Schubert printf(" - ");
40*276da39aSCy Schubert j += dump(js, t+1+j, count-j, indent+1);
41*276da39aSCy Schubert printf("\n");
42*276da39aSCy Schubert }
43*276da39aSCy Schubert return j+1;
44*276da39aSCy Schubert }
45*276da39aSCy Schubert return 0;
46*276da39aSCy Schubert }
47*276da39aSCy Schubert
main()48*276da39aSCy Schubert int main() {
49*276da39aSCy Schubert int r;
50*276da39aSCy Schubert int eof_expected = 0;
51*276da39aSCy Schubert char *js = NULL;
52*276da39aSCy Schubert size_t jslen = 0;
53*276da39aSCy Schubert char buf[BUFSIZ];
54*276da39aSCy Schubert
55*276da39aSCy Schubert jsmn_parser p;
56*276da39aSCy Schubert jsmntok_t *tok;
57*276da39aSCy Schubert size_t tokcount = 2;
58*276da39aSCy Schubert
59*276da39aSCy Schubert /* Prepare parser */
60*276da39aSCy Schubert jsmn_init(&p);
61*276da39aSCy Schubert
62*276da39aSCy Schubert /* Allocate some tokens as a start */
63*276da39aSCy Schubert tok = malloc(sizeof(*tok) * tokcount);
64*276da39aSCy Schubert if (tok == NULL) {
65*276da39aSCy Schubert fprintf(stderr, "malloc(): errno=%d\n", errno);
66*276da39aSCy Schubert return 3;
67*276da39aSCy Schubert }
68*276da39aSCy Schubert
69*276da39aSCy Schubert for (;;) {
70*276da39aSCy Schubert /* Read another chunk */
71*276da39aSCy Schubert r = fread(buf, 1, sizeof(buf), stdin);
72*276da39aSCy Schubert if (r < 0) {
73*276da39aSCy Schubert fprintf(stderr, "fread(): %d, errno=%d\n", r, errno);
74*276da39aSCy Schubert return 1;
75*276da39aSCy Schubert }
76*276da39aSCy Schubert if (r == 0) {
77*276da39aSCy Schubert if (eof_expected != 0) {
78*276da39aSCy Schubert return 0;
79*276da39aSCy Schubert } else {
80*276da39aSCy Schubert fprintf(stderr, "fread(): unexpected EOF\n");
81*276da39aSCy Schubert return 2;
82*276da39aSCy Schubert }
83*276da39aSCy Schubert }
84*276da39aSCy Schubert
85*276da39aSCy Schubert js = realloc(js, jslen + r + 1);
86*276da39aSCy Schubert if (js == NULL) {
87*276da39aSCy Schubert fprintf(stderr, "realloc(): errno=%d\n", errno);
88*276da39aSCy Schubert return 3;
89*276da39aSCy Schubert }
90*276da39aSCy Schubert strncpy(js + jslen, buf, r);
91*276da39aSCy Schubert jslen = jslen + r;
92*276da39aSCy Schubert
93*276da39aSCy Schubert again:
94*276da39aSCy Schubert r = jsmn_parse(&p, js, jslen, tok, tokcount);
95*276da39aSCy Schubert if (r < 0) {
96*276da39aSCy Schubert if (r == JSMN_ERROR_NOMEM) {
97*276da39aSCy Schubert tokcount = tokcount * 2;
98*276da39aSCy Schubert tok = realloc(tok, sizeof(*tok) * tokcount);
99*276da39aSCy Schubert if (tok == NULL) {
100*276da39aSCy Schubert fprintf(stderr, "realloc(): errno=%d\n", errno);
101*276da39aSCy Schubert return 3;
102*276da39aSCy Schubert }
103*276da39aSCy Schubert goto again;
104*276da39aSCy Schubert }
105*276da39aSCy Schubert } else {
106*276da39aSCy Schubert dump(js, tok, p.toknext, 0);
107*276da39aSCy Schubert eof_expected = 1;
108*276da39aSCy Schubert }
109*276da39aSCy Schubert }
110*276da39aSCy Schubert
111*276da39aSCy Schubert return 0;
112*276da39aSCy Schubert }
113