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