12 #include "strbuffer.h"
14 #define TOKEN_INVALID -1
16 #define TOKEN_STRING 256
17 #define TOKEN_INTEGER 257
18 #define TOKEN_REAL 258
19 #define TOKEN_TRUE 259
20 #define TOKEN_FALSE 260
21 #define TOKEN_NULL 261
36 /*** error reporting ***/
38 static void error_set(json_error_t *error, const lex_t *lex,
42 char text[JSON_ERROR_TEXT_LENGTH];
48 vsnprintf(text, JSON_ERROR_TEXT_LENGTH, msg, ap);
53 error->line = lex->line;
56 int n = (int)(lex->input - lex->start);
57 snprintf(error->text, JSON_ERROR_TEXT_LENGTH,
58 "%s near '%.*s'", text, n, lex->start);
62 snprintf(error->text, JSON_ERROR_TEXT_LENGTH,
63 "%s near end of file", text);
69 snprintf(error->text, JSON_ERROR_TEXT_LENGTH, "%s", text);
74 /*** lexical analyzer ***/
76 static void lex_scan_string(lex_t *lex)
79 const char *p = lex->input + 1;
82 lex->token = TOKEN_INVALID;
86 /* unterminated string literal */
90 if(0 <= *p && *p <= 0x1F) {
91 /* control character */
98 for(int i = 0; i < 4; i++, p++) {
103 else if(*p == '"' || *p == '\\' || *p == '/' || *p == 'b' ||
104 *p == 'f' || *p == 'n' || *p == 'r' || *p == 't')
113 /* the actual value is at most of the same length as the source
115 lex->value.string = malloc(p - lex->start);
116 if(!lex->value.string) {
117 /* this is not very nice, since TOKEN_INVALID is returned */
122 t = lex->value.string;
129 /* TODO: \uXXXX not supported yet */
130 free(lex->value.string);
131 lex->value.string = NULL;
135 case '"': case '\\': case '/':
137 case 'b': *t = '\b'; break;
138 case 'f': *t = '\f'; break;
139 case 'n': *t = '\n'; break;
140 case 'r': *t = '\r'; break;
141 case 't': *t = '\t'; break;
156 lex->token = TOKEN_STRING;
162 static void lex_scan_number(lex_t *lex)
164 const char *p = lex->input;
167 lex->token = TOKEN_INVALID;
177 else /* *p != '0' */ {
183 if(*p != '.' && *p != 'E' && *p != 'e') {
184 lex->token = TOKEN_INTEGER;
186 lex->value.integer = strtol(lex->start, &end, 10);
202 if(*p == 'E' || *p == 'e') {
204 if(*p == '+' || *p == '-')
215 lex->token = TOKEN_REAL;
217 lex->value.real = strtod(lex->start, &end);
224 static int lex_scan(lex_t *lex)
228 if(lex->token == TOKEN_STRING) {
229 free(lex->value.string);
230 lex->value.string = NULL;
234 while(c == ' ' || c == '\t' || c == '\n' || c == '\r')
243 lex->start = lex->input;
247 lex->token = TOKEN_EOF;
249 else if(c == '{' || c == '}' || c == '[' || c == ']' ||
250 c == ':' || c == ',')
257 lex_scan_string(lex);
259 else if(isdigit(c) || c == '-')
260 lex_scan_number(lex);
262 else if(isupper(c) || islower(c)) {
263 /* eat up the whole identifier for clearer error messages */
266 while(isupper(*lex->input) || islower(*lex->input))
268 len = lex->input - lex->start;
270 if(strncmp(lex->start, "true", len) == 0)
271 lex->token = TOKEN_TRUE;
272 else if(strncmp(lex->start, "false", len) == 0)
273 lex->token = TOKEN_FALSE;
274 else if(strncmp(lex->start, "null", len) == 0)
275 lex->token = TOKEN_NULL;
277 lex->token = TOKEN_INVALID;
281 lex->token = TOKEN_INVALID;
288 static int lex_init(lex_t *lex, const char *input)
291 lex->token = TOKEN_INVALID;
298 static void lex_close(lex_t *lex)
300 if(lex->token == TOKEN_STRING)
301 free(lex->value.string);
307 static json_t *parse_value(lex_t *lex, json_error_t *error);
309 static json_t *parse_object(lex_t *lex, json_error_t *error)
311 json_t *object = json_object();
316 if(lex->token == '}')
323 if(lex->token != TOKEN_STRING) {
324 error_set(error, lex, "string expected");
328 key = strdup(lex->value.string);
333 if(lex->token != ':') {
335 error_set(error, lex, "':' expected");
341 value = parse_value(lex, error);
347 if(json_object_set(object, key, value)) {
356 if(lex->token != ',')
362 if(lex->token != '}') {
363 error_set(error, lex, "'}' expected");
374 static json_t *parse_array(lex_t *lex, json_error_t *error)
376 json_t *array = json_array();
381 if(lex->token == ']')
385 json_t *elem = parse_value(lex, error);
389 if(json_array_append(array, elem)) {
395 if(lex->token != ',')
402 if(lex->token != ']') {
403 error_set(error, lex, "']' expected");
414 static json_t *parse_value(lex_t *lex, json_error_t *error)
420 json = json_string(lex->value.string);
424 case TOKEN_INTEGER: {
425 json = json_integer(lex->value.integer);
430 json = json_real(lex->value.real);
447 json = parse_object(lex, error);
451 json = parse_array(lex, error);
455 error_set(error, lex, "invalid token");
459 error_set(error, lex, "unexpected token");
470 json_t *parse_json(lex_t *lex, json_error_t *error)
472 if(lex->token != '[' && lex->token != '{') {
473 error_set(error, lex, "'[' or '{' expected");
477 return parse_value(lex, error);
480 json_t *json_load(const char *path, json_error_t *error)
485 fp = fopen(path, "r");
488 error_set(error, NULL, "unable to open %s: %s",
489 path, strerror(errno));
493 result = json_loadf(fp, error);
499 json_t *json_loads(const char *string, json_error_t *error)
502 json_t *result = NULL;
504 if(lex_init(&lex, string))
507 result = parse_json(&lex, error);
511 if(lex.token != TOKEN_EOF) {
512 error_set(error, &lex, "end of file expected");
522 #define BUFFER_SIZE 4096
524 json_t *json_loadf(FILE *input, json_error_t *error)
527 char buffer[BUFFER_SIZE];
529 json_t *result = NULL;
531 if(strbuffer_init(&strbuff))
536 length = fread(buffer, 1, BUFFER_SIZE, input);
541 error_set(error, NULL, "read error");
546 if(strbuffer_append_bytes(&strbuff, buffer, length))
550 result = json_loads(strbuffer_value(&strbuff), error);
553 strbuffer_close(&strbuff);
557 json_t *json_loadfd(int fd, json_error_t *error)
560 char buffer[BUFFER_SIZE];
562 json_t *result = NULL;
564 if(strbuffer_init(&strbuff))
569 length = read(fd, buffer, BUFFER_SIZE);
572 error_set(error, NULL, "read error: %s", strerror(errno));
578 if(strbuffer_append_bytes(&strbuff, buffer, length))
580 error_set(error, NULL, "error allocating memory");
585 result = json_loads(strbuffer_value(&strbuff), error);
588 strbuffer_close(&strbuff);