aboutsummaryrefslogtreecommitdiff
path: root/dependencies/jsmn/example/jsondump.c
diff options
context:
space:
mode:
Diffstat (limited to 'dependencies/jsmn/example/jsondump.c')
-rw-r--r--dependencies/jsmn/example/jsondump.c134
1 files changed, 134 insertions, 0 deletions
diff --git a/dependencies/jsmn/example/jsondump.c b/dependencies/jsmn/example/jsondump.c
new file mode 100644
index 000000000..1eb620640
--- /dev/null
+++ b/dependencies/jsmn/example/jsondump.c
@@ -0,0 +1,134 @@
+#include "../jsmn.h"
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+/* Function realloc_it() is a wrapper function for standard realloc()
+ * with one difference - it frees old memory pointer in case of realloc
+ * failure. Thus, DO NOT use old data pointer in anyway after call to
+ * realloc_it(). If your code has some kind of fallback algorithm if
+ * memory can't be re-allocated - use standard realloc() instead.
+ */
+static inline void *realloc_it(void *ptrmem, size_t size) {
+ void *p = realloc(ptrmem, size);
+ if (!p) {
+ free(ptrmem);
+ fprintf(stderr, "realloc(): errno=%d\n", errno);
+ }
+ return p;
+}
+
+/*
+ * An example of reading JSON from stdin and printing its content to stdout.
+ * The output looks like YAML, but I'm not sure if it's really compatible.
+ */
+
+static int dump(const char *js, jsmntok_t *t, size_t count, int indent) {
+ int i, j, k;
+ jsmntok_t *key;
+ if (count == 0) {
+ return 0;
+ }
+ if (t->type == JSMN_PRIMITIVE) {
+ printf("%.*s", t->end - t->start, js + t->start);
+ return 1;
+ } else if (t->type == JSMN_STRING) {
+ printf("'%.*s'", t->end - t->start, js + t->start);
+ return 1;
+ } else if (t->type == JSMN_OBJECT) {
+ printf("\n");
+ j = 0;
+ for (i = 0; i < t->size; i++) {
+ for (k = 0; k < indent; k++) {
+ printf(" ");
+ }
+ key = t + 1 + j;
+ j += dump(js, key, count - j, indent + 1);
+ if (key->size > 0) {
+ printf(": ");
+ j += dump(js, t + 1 + j, count - j, indent + 1);
+ }
+ printf("\n");
+ }
+ return j + 1;
+ } else if (t->type == JSMN_ARRAY) {
+ j = 0;
+ printf("\n");
+ for (i = 0; i < t->size; i++) {
+ for (k = 0; k < indent - 1; k++) {
+ printf(" ");
+ }
+ printf(" - ");
+ j += dump(js, t + 1 + j, count - j, indent + 1);
+ printf("\n");
+ }
+ return j + 1;
+ }
+ return 0;
+}
+
+int main() {
+ int r;
+ int eof_expected = 0;
+ char *js = NULL;
+ size_t jslen = 0;
+ char buf[BUFSIZ];
+
+ jsmn_parser p;
+ jsmntok_t *tok;
+ size_t tokcount = 2;
+
+ /* Prepare parser */
+ jsmn_init(&p);
+
+ /* Allocate some tokens as a start */
+ tok = malloc(sizeof(*tok) * tokcount);
+ if (tok == NULL) {
+ fprintf(stderr, "malloc(): errno=%d\n", errno);
+ return 3;
+ }
+
+ for (;;) {
+ /* Read another chunk */
+ r = fread(buf, 1, sizeof(buf), stdin);
+ if (r < 0) {
+ fprintf(stderr, "fread(): %d, errno=%d\n", r, errno);
+ return 1;
+ }
+ if (r == 0) {
+ if (eof_expected != 0) {
+ return 0;
+ } else {
+ fprintf(stderr, "fread(): unexpected EOF\n");
+ return 2;
+ }
+ }
+
+ js = realloc_it(js, jslen + r + 1);
+ if (js == NULL) {
+ return 3;
+ }
+ strncpy(js + jslen, buf, r);
+ jslen = jslen + r;
+
+ again:
+ r = jsmn_parse(&p, js, jslen, tok, tokcount);
+ if (r < 0) {
+ if (r == JSMN_ERROR_NOMEM) {
+ tokcount = tokcount * 2;
+ tok = realloc_it(tok, sizeof(*tok) * tokcount);
+ if (tok == NULL) {
+ return 3;
+ }
+ goto again;
+ }
+ } else {
+ dump(js, tok, p.toknext, 0);
+ eof_expected = 1;
+ }
+ }
+
+ return EXIT_SUCCESS;
+}