Add a callback interface for non-closing punctuation

This commit is contained in:
Eric Fischer 2014-02-07 15:51:46 -08:00
parent f67e97cd08
commit fee27e1353
3 changed files with 84 additions and 20 deletions

View File

@ -12,7 +12,7 @@ static void indent(int depth) {
}
}
void json_print(json_object *j, int depth) {
void json_print_one(json_object *j, int *depth) {
if (j == NULL) {
printf("NULL");
} else if (j->type == JSON_STRING) {
@ -39,6 +39,20 @@ void json_print(json_object *j, int depth) {
} else if (j->type == JSON_FALSE) {
printf("false");
} else if (j->type == JSON_HASH) {
printf("\n");
(*depth)--;
indent(*depth);
printf("}");
} else if (j->type == JSON_ARRAY) {
printf("\n");
(*depth)--;
indent(*depth);
printf("]");
}
}
void json_print(json_object *j, int depth) {
if (j->type == JSON_HASH) {
printf("{\n");
indent(depth + 1);
@ -71,7 +85,40 @@ void json_print(json_object *j, int depth) {
indent(depth);
printf("]");
} else {
printf("what type? %d", j->type);
json_print_one(j, &depth);
}
}
void callback(json_type type, json_pull *jp, void *state) {
int *level = state;
if (type == JSON_ARRAY) {
printf("[\n");
(*level)++;
indent(*level);
} else if (type == JSON_HASH) {
printf("{\n");
(*level)++;
indent(*level);
} else if (type == JSON_COMMA) {
printf(", ");
} else if (type == JSON_COLON) {
printf(": ");
}
}
void process_callback(FILE *f, char *fname) {
json_pull *jp = json_begin_file(f);
json_object *j;
int level = 0;
while ((j = json_parse_with_separators(jp, callback, &level)) != NULL) {
json_print_one(j, &level);
json_free(j);
}
if (jp->error != NULL) {
fprintf(stderr, "%s: %d: %s\n", fname, jp->line, jp->error);
}
}
@ -82,6 +129,7 @@ void process(FILE *f, char *fname) {
while ((j = json_parse(jp)) != NULL) {
if (j->parent == NULL) {
json_print(j, 0);
json_free(j);
printf("\n");
}
}

View File

@ -5,10 +5,6 @@
#include <stdarg.h>
#include "jsonpull.h"
typedef enum json_expect {
JSON_ITEM, JSON_COMMA, JSON_COLON, JSON_KEY, JSON_VALUE,
} json_expect;
static json_pull *json_init() {
json_pull *j = malloc(sizeof(json_pull));
j->error = NULL;
@ -76,16 +72,20 @@ json_pull *json_begin_string(char *s) {
#define SIZE_FOR(i) (((i) + 31) & ~31)
static json_object *add_object(json_pull *j, json_type type) {
static json_object *fabricate_object(json_object *parent, json_type type) {
json_object *o = malloc(sizeof(struct json_object));
o->type = type;
o->parent = j->container;
o->parent = parent;
o->array = NULL;
o->keys = NULL;
o->values = NULL;
o->length = 0;
return o;
}
static json_object *add_object(json_pull *j, json_type type) {
json_object *c = j->container;
json_object *o = fabricate_object(c, type);
if (c != NULL) {
if (c->type == JSON_ARRAY) {
@ -178,7 +178,7 @@ static void string_free(struct string *s) {
free(s->buf);
}
json_object *json_parse(json_pull *j) {
json_object *json_parse_with_separators(json_pull *j, json_separator_callback cb, void *state) {
int c;
again:
/////////////////////////// Whitespace
@ -203,6 +203,11 @@ again:
}
j->container = o;
j->container->expect = JSON_ITEM;
if (cb != NULL) {
cb(JSON_ARRAY, j, state);
}
goto again;
} else if (c == ']') {
if (j->container == NULL) {
@ -236,6 +241,11 @@ again:
}
j->container = o;
j->container->expect = JSON_KEY;
if (cb != NULL) {
cb(JSON_HASH, j, state);
}
goto again;
} else if (c == '}') {
if (j->container == NULL) {
@ -312,6 +322,10 @@ again:
j->container->expect = JSON_ITEM;
}
if (cb != NULL) {
cb(JSON_COMMA, j, state);
}
goto again;
}
@ -329,6 +343,11 @@ again:
}
j->container->expect = JSON_VALUE;
if (cb != NULL) {
cb(JSON_COLON, j, state);
}
goto again;
}
@ -459,15 +478,8 @@ again:
return NULL;
}
static json_object *fabricate_null(json_object *parent) {
json_object *o = malloc(sizeof(struct json_object));
o->type = JSON_NULL;
o->parent = parent;
o->array = NULL;
o->keys = NULL;
o->values = NULL;
o->length = 0;
return o;
json_object *json_parse(json_pull *j) {
return json_parse_with_separators(j, NULL, NULL);
}
void json_free(json_object *o) {
@ -531,11 +543,11 @@ void json_free(json_object *o) {
if (o->parent->type == JSON_HASH) {
for (i = 0; i < o->parent->length; i++) {
if (o->parent->keys[i] == o) {
o->parent->keys[i] = fabricate_null(o->parent);
o->parent->keys[i] = fabricate_object(o->parent, JSON_NULL);
break;
}
if (o->parent->values[i] == o) {
o->parent->values[i] = fabricate_null(o->parent);
o->parent->values[i] = fabricate_object(o->parent, JSON_NULL);
break;
}
}

View File

@ -1,5 +1,6 @@
typedef enum json_type {
JSON_HASH, JSON_ARRAY, JSON_NUMBER, JSON_STRING, JSON_TRUE, JSON_FALSE, JSON_NULL,
JSON_COMMA, JSON_COLON, JSON_ITEM, JSON_KEY, JSON_VALUE,
} json_type;
typedef struct json_object {
@ -30,9 +31,12 @@ struct json_pull {
};
typedef struct json_pull json_pull;
typedef void (*json_separator_callback)(json_type type, json_pull *j, void *state);
json_pull *json_begin_file(FILE *f);
json_pull *json_begin_string(char *s);
json_object *json_parse(json_pull *j);
json_object *json_parse_with_separators(json_pull *j, json_separator_callback cb, void *state);
void json_free(json_object *j);
json_object *json_hash_get(json_object *o, char *s);