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