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