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 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 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