xref: /freebsd/contrib/ntp/libjsmn/example/jsondump.c (revision 276da39a)
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