1 #include "../jsmn.h"
2 #include <errno.h>
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <string.h>
6 #include <unistd.h>
7
8 /* Function realloc_it() is a wrapper function for standard realloc()
9 * with one difference - it frees old memory pointer in case of realloc
10 * failure. Thus, DO NOT use old data pointer in anyway after call to
11 * realloc_it(). If your code has some kind of fallback algorithm if
12 * memory can't be re-allocated - use standard realloc() instead.
13 */
realloc_it(void * ptrmem,size_t size)14 static inline void *realloc_it(void *ptrmem, size_t size) {
15 void *p = realloc(ptrmem, size);
16 if (!p) {
17 free(ptrmem);
18 fprintf(stderr, "realloc(): errno=%d\n", errno);
19 }
20 return p;
21 }
22
23 /*
24 * An example of reading JSON from stdin and printing its content to stdout.
25 * The output looks like YAML, but I'm not sure if it's really compatible.
26 */
27
dump(const char * js,jsmntok_t * t,size_t count,int indent)28 static int dump(const char *js, jsmntok_t *t, size_t count, int indent) {
29 int i, j, k;
30 jsmntok_t *key;
31 if (count == 0) {
32 return 0;
33 }
34 if (t->type == JSMN_PRIMITIVE) {
35 printf("%.*s", t->end - t->start, js + t->start);
36 return 1;
37 } else if (t->type == JSMN_STRING) {
38 printf("'%.*s'", t->end - t->start, js + t->start);
39 return 1;
40 } else if (t->type == JSMN_OBJECT) {
41 printf("\n");
42 j = 0;
43 for (i = 0; i < t->size; i++) {
44 for (k = 0; k < indent; k++) {
45 printf(" ");
46 }
47 key = t + 1 + j;
48 j += dump(js, key, count - j, indent + 1);
49 if (key->size > 0) {
50 printf(": ");
51 j += dump(js, t + 1 + j, count - j, indent + 1);
52 }
53 printf("\n");
54 }
55 return j + 1;
56 } else if (t->type == JSMN_ARRAY) {
57 j = 0;
58 printf("\n");
59 for (i = 0; i < t->size; i++) {
60 for (k = 0; k < indent - 1; k++) {
61 printf(" ");
62 }
63 printf(" - ");
64 j += dump(js, t + 1 + j, count - j, indent + 1);
65 printf("\n");
66 }
67 return j + 1;
68 }
69 return 0;
70 }
71
main()72 int main() {
73 int r;
74 int eof_expected = 0;
75 char *js = NULL;
76 size_t jslen = 0;
77 char buf[BUFSIZ];
78
79 jsmn_parser p;
80 jsmntok_t *tok;
81 size_t tokcount = 2;
82
83 /* Prepare parser */
84 jsmn_init(&p);
85
86 /* Allocate some tokens as a start */
87 tok = malloc(sizeof(*tok) * tokcount);
88 if (tok == NULL) {
89 fprintf(stderr, "malloc(): errno=%d\n", errno);
90 return 3;
91 }
92
93 for (;;) {
94 /* Read another chunk */
95 r = fread(buf, 1, sizeof(buf), stdin);
96 if (r < 0) {
97 fprintf(stderr, "fread(): %d, errno=%d\n", r, errno);
98 return 1;
99 }
100 if (r == 0) {
101 if (eof_expected != 0) {
102 return 0;
103 } else {
104 fprintf(stderr, "fread(): unexpected EOF\n");
105 return 2;
106 }
107 }
108
109 js = realloc_it(js, jslen + r + 1);
110 if (js == NULL) {
111 return 3;
112 }
113 strncpy(js + jslen, buf, r);
114 jslen = jslen + r;
115
116 again:
117 r = jsmn_parse(&p, js, jslen, tok, tokcount);
118 if (r < 0) {
119 if (r == JSMN_ERROR_NOMEM) {
120 tokcount = tokcount * 2;
121 tok = realloc_it(tok, sizeof(*tok) * tokcount);
122 if (tok == NULL) {
123 return 3;
124 }
125 goto again;
126 }
127 } else {
128 dump(js, tok, p.toknext, 0);
129 eof_expected = 1;
130 }
131 }
132
133 return EXIT_SUCCESS;
134 }
135