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