12 #include "strbuffer.h"
15 #define JSON_TOKEN_INVALID -1
16 #define JSON_TOKEN_EOF 0
17 #define JSON_TOKEN_STRING 256
18 #define JSON_TOKEN_NUMBER 257
19 #define JSON_TOKEN_TRUE 258
20 #define JSON_TOKEN_FALSE 259
21 #define JSON_TOKEN_NULL 260
35 /*** error reporting ***/
37 static void json_set_error(json_error_t *error, const json_lex *lex,
41 char text[JSON_ERROR_TEXT_LENGTH];
47 vsnprintf(text, JSON_ERROR_TEXT_LENGTH, msg, ap);
52 error->line = lex->line;
55 int n = (int)(lex->input - lex->start);
56 snprintf(error->text, JSON_ERROR_TEXT_LENGTH,
57 "%s near '%.*s'", text, n, lex->start);
61 snprintf(error->text, JSON_ERROR_TEXT_LENGTH,
62 "%s near end of file", text);
68 snprintf(error->text, JSON_ERROR_TEXT_LENGTH, "%s", text);
73 /*** lexical analyzer ***/
75 static void json_scan_string(json_lex *lex)
78 const char *p = lex->input + 1;
81 lex->token = JSON_TOKEN_INVALID;
85 /* unterminated string literal */
89 if(0 <= *p && *p <= 31) {
90 /* control character */
97 for(int i = 0; i < 4; i++, p++) {
102 if(*p == '"' || *p == '\\' || *p == '/' || *p == 'b' ||
103 *p == 'f' || *p == 'n' || *p == 'r' || *p == 't')
112 /* the actual value is at most of the same length as the source
114 lex->value.string = malloc(p - lex->start);
115 if(!lex->value.string) {
116 /* this is not very nice, since TOKEN_INVALID is returned */
121 t = lex->value.string;
128 /* TODO: \uXXXX not supported yet */
129 free(lex->value.string);
130 lex->value.string = NULL;
134 case '"': case '\\': case '/':
136 case 'b': *t = '\b'; break;
137 case 'f': *t = '\f'; break;
138 case 'n': *t = '\n'; break;
139 case 'r': *t = '\r'; break;
140 case 't': *t = '\t'; break;
155 lex->token = JSON_TOKEN_STRING;
161 static void json_scan_number(json_lex *lex)
163 const char *p = lex->input;
166 lex->token = JSON_TOKEN_INVALID;
173 else /* *p != '0' */ {
188 if(*p == 'E' || *p == 'e') {
190 if(*p == '+' || *p == '-')
200 lex->token = JSON_TOKEN_NUMBER;
202 lex->value.number = strtod(lex->start, &end);
209 static int json_lex_scan(json_lex *lex)
213 if(lex->token == JSON_TOKEN_STRING) {
214 free(lex->value.string);
215 lex->value.string = NULL;
218 while(isspace(*lex->input)) {
219 if(*lex->input == '\n')
225 lex->start = lex->input;
229 lex->token = JSON_TOKEN_EOF;
231 else if(c == '{' || c == '}' || c == '[' || c == ']' ||
232 c == ':' || c == ',') {
238 json_scan_string(lex);
240 else if(isdigit(c) || c == '-')
241 json_scan_number(lex);
243 else if(isalpha(c)) {
244 /* eat up the whole identifier for clearer error messages */
247 while(isalpha(*lex->input))
249 len = lex->input - lex->start;
251 if(strncmp(lex->start, "true", len) == 0)
252 lex->token = JSON_TOKEN_TRUE;
253 else if(strncmp(lex->start, "false", len) == 0)
254 lex->token = JSON_TOKEN_FALSE;
255 else if(strncmp(lex->start, "null", len) == 0)
256 lex->token = JSON_TOKEN_NULL;
258 lex->token = JSON_TOKEN_INVALID;
262 lex->token = JSON_TOKEN_INVALID;
269 static int json_lex_init(json_lex *lex, const char *input)
272 lex->token = JSON_TOKEN_INVALID;
279 static void json_lex_close(json_lex *lex)
281 if(lex->token == JSON_TOKEN_STRING)
282 free(lex->value.string);
288 static json_t *json_parse(json_lex *lex, json_error_t *error);
290 static json_t *json_parse_object(json_lex *lex, json_error_t *error)
292 json_t *object = json_object();
297 if(lex->token == '}')
304 if(lex->token != JSON_TOKEN_STRING) {
305 json_set_error(error, lex, "string expected");
309 key = strdup(lex->value.string);
314 if(lex->token != ':') {
316 json_set_error(error, lex, "':' expected");
322 value = json_parse(lex, error);
328 if(json_object_set(object, key, value)) {
337 if(lex->token != ',')
343 if(lex->token != '}') {
344 json_set_error(error, lex, "'}' expected");
355 static json_t *json_parse_array(json_lex *lex, json_error_t *error)
357 json_t *array = json_array();
362 if(lex->token == ']')
366 json_t *elem = json_parse(lex, error);
370 if(json_array_append(array, elem)) {
376 if(lex->token != ',')
383 if(lex->token != ']') {
384 json_set_error(error, lex, "']' expected");
395 static json_t *json_parse(json_lex *lex, json_error_t *error)
400 case JSON_TOKEN_STRING: {
401 json = json_string(lex->value.string);
405 case JSON_TOKEN_NUMBER: {
406 json = json_number(lex->value.number);
410 case JSON_TOKEN_TRUE:
414 case JSON_TOKEN_FALSE:
418 case JSON_TOKEN_NULL:
423 json = json_parse_object(lex, error);
427 json = json_parse_array(lex, error);
430 case JSON_TOKEN_INVALID:
431 json_set_error(error, lex, "invalid token");
435 json_set_error(error, lex, "unexpected token");
446 json_t *json_load(const char *path, json_error_t *error)
451 fp = fopen(path, "r");
454 json_set_error(error, NULL, "unable to open %s: %s",
455 path, strerror(errno));
459 result = json_loadf(fp, error);
465 json_t *json_loads(const char *string, json_error_t *error)
468 json_t *result = NULL;
470 if(json_lex_init(&lex, string))
473 if(lex.token != '[' && lex.token != '{') {
474 json_set_error(error, &lex, "'[' or '{' expected");
478 result = json_parse(&lex, error);
482 if(lex.token != JSON_TOKEN_EOF) {
483 json_set_error(error, &lex, "end of file expected");
489 json_lex_close(&lex);
493 #define BUFFER_SIZE 4096
495 json_t *json_loadf(FILE *input, json_error_t *error)
498 char buffer[BUFFER_SIZE];
500 json_t *result = NULL;
502 if(strbuffer_init(&strbuff))
507 length = fread(buffer, 1, BUFFER_SIZE, input);
512 json_set_error(error, NULL, "read error");
517 if(strbuffer_append_bytes(&strbuff, buffer, length))
521 result = json_loads(strbuffer_value(&strbuff), error);
524 strbuffer_close(&strbuff);
528 json_t *json_loadfd(int fd, json_error_t *error)
531 char buffer[BUFFER_SIZE];
533 json_t *result = NULL;
535 if(strbuffer_init(&strbuff))
540 length = read(fd, buffer, BUFFER_SIZE);
543 json_set_error(error, NULL, "read error: %s", strerror(errno));
549 if(strbuffer_append_bytes(&strbuff, buffer, length))
551 json_set_error(error, NULL, "error allocating memory");
556 result = json_loads(strbuffer_value(&strbuff), error);
559 strbuffer_close(&strbuff);