• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <unistd.h>
4 #include <string.h>
5 #include <errno.h>
6 #include "../jsmn.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 	if (count == 0) {
31 		return 0;
32 	}
33 	if (t->type == JSMN_PRIMITIVE) {
34 		printf("%.*s", t->end - t->start, js+t->start);
35 		return 1;
36 	} else if (t->type == JSMN_STRING) {
37 		printf("'%.*s'", t->end - t->start, js+t->start);
38 		return 1;
39 	} else if (t->type == JSMN_OBJECT) {
40 		printf("\n");
41 		j = 0;
42 		for (i = 0; i < t->size; i++) {
43 			for (k = 0; k < indent; k++) printf("  ");
44 			j += dump(js, t+1+j, count-j, indent+1);
45 			printf(": ");
46 			j += dump(js, t+1+j, count-j, indent+1);
47 			printf("\n");
48 		}
49 		return j+1;
50 	} else if (t->type == JSMN_ARRAY) {
51 		j = 0;
52 		printf("\n");
53 		for (i = 0; i < t->size; i++) {
54 			for (k = 0; k < indent-1; k++) printf("  ");
55 			printf("   - ");
56 			j += dump(js, t+1+j, count-j, indent+1);
57 			printf("\n");
58 		}
59 		return j+1;
60 	}
61 	return 0;
62 }
63 
main()64 int main() {
65 	int r;
66 	int eof_expected = 0;
67 	char *js = NULL;
68 	size_t jslen = 0;
69 	char buf[BUFSIZ];
70 
71 	jsmn_parser p;
72 	jsmntok_t *tok;
73 	size_t tokcount = 2;
74 
75 	/* Prepare parser */
76 	jsmn_init(&p);
77 
78 	/* Allocate some tokens as a start */
79 	tok = malloc(sizeof(*tok) * tokcount);
80 	if (tok == NULL) {
81 		fprintf(stderr, "malloc(): errno=%d\n", errno);
82 		return 3;
83 	}
84 
85 	for (;;) {
86 		/* Read another chunk */
87 		r = fread(buf, 1, sizeof(buf), stdin);
88 		if (r < 0) {
89 			fprintf(stderr, "fread(): %d, errno=%d\n", r, errno);
90 			return 1;
91 		}
92 		if (r == 0) {
93 			if (eof_expected != 0) {
94 				return 0;
95 			} else {
96 				fprintf(stderr, "fread(): unexpected EOF\n");
97 				return 2;
98 			}
99 		}
100 
101 		js = realloc_it(js, jslen + r + 1);
102 		if (js == NULL) {
103 			return 3;
104 		}
105 		strncpy(js + jslen, buf, r);
106 		jslen = jslen + r;
107 
108 again:
109 		r = jsmn_parse(&p, js, jslen, tok, tokcount);
110 		if (r < 0) {
111 			if (r == JSMN_ERROR_NOMEM) {
112 				tokcount = tokcount * 2;
113 				tok = realloc_it(tok, sizeof(*tok) * tokcount);
114 				if (tok == NULL) {
115 					return 3;
116 				}
117 				goto again;
118 			}
119 		} else {
120 			dump(js, tok, p.toknext, 0);
121 			eof_expected = 1;
122 		}
123 	}
124 
125 	return EXIT_SUCCESS;
126 }
127