1284990Scy#include <stdio.h>
2284990Scy#include <stdlib.h>
3284990Scy#include <string.h>
4284990Scy#include <errno.h>
5284990Scy#include "../jsmn.h"
6284990Scy
7284990Scy/*
8284990Scy * An example of reading JSON from stdin and printing its content to stdout.
9284990Scy * The output looks like YAML, but I'm not sure if it's really compatible.
10284990Scy */
11284990Scy
12284990Scystatic int dump(const char *js, jsmntok_t *t, size_t count, int indent) {
13284990Scy	int i, j, k;
14284990Scy	if (count == 0) {
15284990Scy		return 0;
16284990Scy	}
17284990Scy	if (t->type == JSMN_PRIMITIVE) {
18284990Scy		printf("%.*s", t->end - t->start, js+t->start);
19284990Scy		return 1;
20284990Scy	} else if (t->type == JSMN_STRING) {
21284990Scy		printf("'%.*s'", t->end - t->start, js+t->start);
22284990Scy		return 1;
23284990Scy	} else if (t->type == JSMN_OBJECT) {
24284990Scy		printf("\n");
25284990Scy		j = 0;
26284990Scy		for (i = 0; i < t->size; i++) {
27284990Scy			for (k = 0; k < indent; k++) printf("  ");
28284990Scy			j += dump(js, t+1+j, count-j, indent+1);
29284990Scy			printf(": ");
30284990Scy			j += dump(js, t+1+j, count-j, indent+1);
31284990Scy			printf("\n");
32284990Scy		}
33284990Scy		return j+1;
34284990Scy	} else if (t->type == JSMN_ARRAY) {
35284990Scy		j = 0;
36284990Scy		printf("\n");
37284990Scy		for (i = 0; i < t->size; i++) {
38284990Scy			for (k = 0; k < indent-1; k++) printf("  ");
39284990Scy			printf("   - ");
40284990Scy			j += dump(js, t+1+j, count-j, indent+1);
41284990Scy			printf("\n");
42284990Scy		}
43284990Scy		return j+1;
44284990Scy	}
45284990Scy	return 0;
46284990Scy}
47284990Scy
48284990Scyint main() {
49284990Scy	int r;
50284990Scy	int eof_expected = 0;
51284990Scy	char *js = NULL;
52284990Scy	size_t jslen = 0;
53284990Scy	char buf[BUFSIZ];
54284990Scy
55284990Scy	jsmn_parser p;
56284990Scy	jsmntok_t *tok;
57284990Scy	size_t tokcount = 2;
58284990Scy
59284990Scy	/* Prepare parser */
60284990Scy	jsmn_init(&p);
61284990Scy
62284990Scy	/* Allocate some tokens as a start */
63284990Scy	tok = malloc(sizeof(*tok) * tokcount);
64284990Scy	if (tok == NULL) {
65284990Scy		fprintf(stderr, "malloc(): errno=%d\n", errno);
66284990Scy		return 3;
67284990Scy	}
68284990Scy
69284990Scy	for (;;) {
70284990Scy		/* Read another chunk */
71284990Scy		r = fread(buf, 1, sizeof(buf), stdin);
72284990Scy		if (r < 0) {
73284990Scy			fprintf(stderr, "fread(): %d, errno=%d\n", r, errno);
74284990Scy			return 1;
75284990Scy		}
76284990Scy		if (r == 0) {
77284990Scy			if (eof_expected != 0) {
78284990Scy				return 0;
79284990Scy			} else {
80284990Scy				fprintf(stderr, "fread(): unexpected EOF\n");
81284990Scy				return 2;
82284990Scy			}
83284990Scy		}
84284990Scy
85284990Scy		js = realloc(js, jslen + r + 1);
86284990Scy		if (js == NULL) {
87284990Scy			fprintf(stderr, "realloc(): errno=%d\n", errno);
88284990Scy			return 3;
89284990Scy		}
90284990Scy		strncpy(js + jslen, buf, r);
91284990Scy		jslen = jslen + r;
92284990Scy
93284990Scyagain:
94284990Scy		r = jsmn_parse(&p, js, jslen, tok, tokcount);
95284990Scy		if (r < 0) {
96284990Scy			if (r == JSMN_ERROR_NOMEM) {
97284990Scy				tokcount = tokcount * 2;
98284990Scy				tok = realloc(tok, sizeof(*tok) * tokcount);
99284990Scy				if (tok == NULL) {
100284990Scy					fprintf(stderr, "realloc(): errno=%d\n", errno);
101284990Scy					return 3;
102284990Scy				}
103284990Scy				goto again;
104284990Scy			}
105284990Scy		} else {
106284990Scy			dump(js, tok, p.toknext, 0);
107284990Scy			eof_expected = 1;
108284990Scy		}
109284990Scy	}
110284990Scy
111284990Scy	return 0;
112284990Scy}
113