~braiampe/+junk/cgminer

« back to all changes in this revision

Viewing changes to compat/jansson/load.c

  • Committer: Braiam Peguero
  • Date: 2011-10-09 06:47:47 UTC
  • Revision ID: braiamp@gmail.com-20111009064747-iju2nhzrh6ya56zs
* Forgot adding files to the branch.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (c) 2009-2011 Petri Lehtinen <petri@digip.org>
 
3
 *
 
4
 * Jansson is free software; you can redistribute it and/or modify
 
5
 * it under the terms of the MIT license. See LICENSE for details.
 
6
 */
 
7
 
 
8
#define _GNU_SOURCE
 
9
#include <ctype.h>
 
10
#include <errno.h>
 
11
#include <limits.h>
 
12
#include <stdio.h>
 
13
#include <stdlib.h>
 
14
#include <string.h>
 
15
#include <assert.h>
 
16
 
 
17
#include <jansson.h>
 
18
#include "jansson_private.h"
 
19
#include "strbuffer.h"
 
20
#include "utf.h"
 
21
 
 
22
#define STREAM_STATE_OK        0
 
23
#define STREAM_STATE_EOF      -1
 
24
#define STREAM_STATE_ERROR    -2
 
25
 
 
26
#define TOKEN_INVALID         -1
 
27
#define TOKEN_EOF              0
 
28
#define TOKEN_STRING         256
 
29
#define TOKEN_INTEGER        257
 
30
#define TOKEN_REAL           258
 
31
#define TOKEN_TRUE           259
 
32
#define TOKEN_FALSE          260
 
33
#define TOKEN_NULL           261
 
34
 
 
35
/* Read one byte from stream, convert to unsigned char, then int, and
 
36
   return. return EOF on end of file. This corresponds to the
 
37
   behaviour of fgetc(). */
 
38
typedef int (*get_func)(void *data);
 
39
 
 
40
typedef struct {
 
41
    get_func get;
 
42
    void *data;
 
43
    char buffer[5];
 
44
    int buffer_pos;
 
45
    int state;
 
46
    int line;
 
47
    int column, last_column;
 
48
    size_t position;
 
49
} stream_t;
 
50
 
 
51
typedef struct {
 
52
    stream_t stream;
 
53
    strbuffer_t saved_text;
 
54
    int token;
 
55
    union {
 
56
        char *string;
 
57
        json_int_t integer;
 
58
        double real;
 
59
    } value;
 
60
} lex_t;
 
61
 
 
62
#define stream_to_lex(stream) container_of(stream, lex_t, stream)
 
63
 
 
64
 
 
65
/*** error reporting ***/
 
66
 
 
67
static void error_set(json_error_t *error, const lex_t *lex,
 
68
                      const char *msg, ...)
 
69
{
 
70
    va_list ap;
 
71
    char msg_text[JSON_ERROR_TEXT_LENGTH];
 
72
 
 
73
    int line = -1, col = -1;
 
74
    size_t pos = 0;
 
75
    const char *result = msg_text;
 
76
 
 
77
    if(!error)
 
78
        return;
 
79
 
 
80
    va_start(ap, msg);
 
81
    vsnprintf(msg_text, JSON_ERROR_TEXT_LENGTH, msg, ap);
 
82
    va_end(ap);
 
83
 
 
84
    if(lex)
 
85
    {
 
86
        const char *saved_text = strbuffer_value(&lex->saved_text);
 
87
        char msg_with_context[JSON_ERROR_TEXT_LENGTH];
 
88
 
 
89
        line = lex->stream.line;
 
90
        col = lex->stream.column;
 
91
        pos = lex->stream.position;
 
92
 
 
93
        if(saved_text && saved_text[0])
 
94
        {
 
95
            if(lex->saved_text.length <= 20) {
 
96
                snprintf(msg_with_context, JSON_ERROR_TEXT_LENGTH,
 
97
                         "%s near '%s'", msg_text, saved_text);
 
98
                result = msg_with_context;
 
99
            }
 
100
        }
 
101
        else
 
102
        {
 
103
            if(lex->stream.state == STREAM_STATE_ERROR) {
 
104
                /* No context for UTF-8 decoding errors */
 
105
                result = msg_text;
 
106
            }
 
107
            else {
 
108
                snprintf(msg_with_context, JSON_ERROR_TEXT_LENGTH,
 
109
                         "%s near end of file", msg_text);
 
110
                result = msg_with_context;
 
111
            }
 
112
        }
 
113
    }
 
114
 
 
115
    jsonp_error_set(error, line, col, pos, "%s", result);
 
116
}
 
117
 
 
118
 
 
119
/*** lexical analyzer ***/
 
120
 
 
121
static void
 
122
stream_init(stream_t *stream, get_func get, void *data)
 
123
{
 
124
    stream->get = get;
 
125
    stream->data = data;
 
126
    stream->buffer[0] = '\0';
 
127
    stream->buffer_pos = 0;
 
128
 
 
129
    stream->state = STREAM_STATE_OK;
 
130
    stream->line = 1;
 
131
    stream->column = 0;
 
132
    stream->position = 0;
 
133
}
 
134
 
 
135
static int stream_get(stream_t *stream, json_error_t *error)
 
136
{
 
137
    int c;
 
138
 
 
139
    if(stream->state != STREAM_STATE_OK)
 
140
        return stream->state;
 
141
 
 
142
    if(!stream->buffer[stream->buffer_pos])
 
143
    {
 
144
        c = stream->get(stream->data);
 
145
        if(c == EOF) {
 
146
            stream->state = STREAM_STATE_EOF;
 
147
            return STREAM_STATE_EOF;
 
148
        }
 
149
 
 
150
        stream->buffer[0] = c;
 
151
        stream->buffer_pos = 0;
 
152
 
 
153
        if(0x80 <= c && c <= 0xFF)
 
154
        {
 
155
            /* multi-byte UTF-8 sequence */
 
156
            int i, count;
 
157
 
 
158
            count = utf8_check_first(c);
 
159
            if(!count)
 
160
                goto out;
 
161
 
 
162
            assert(count >= 2);
 
163
 
 
164
            for(i = 1; i < count; i++)
 
165
                stream->buffer[i] = stream->get(stream->data);
 
166
 
 
167
            if(!utf8_check_full(stream->buffer, count, NULL))
 
168
                goto out;
 
169
 
 
170
            stream->buffer[count] = '\0';
 
171
        }
 
172
        else
 
173
            stream->buffer[1] = '\0';
 
174
    }
 
175
 
 
176
    c = stream->buffer[stream->buffer_pos++];
 
177
 
 
178
    stream->position++;
 
179
    if(c == '\n') {
 
180
        stream->line++;
 
181
        stream->last_column = stream->column;
 
182
        stream->column = 0;
 
183
    }
 
184
    else if(utf8_check_first(c)) {
 
185
        /* track the Unicode character column, so increment only if
 
186
           this is the first character of a UTF-8 sequence */
 
187
        stream->column++;
 
188
    }
 
189
 
 
190
    return c;
 
191
 
 
192
out:
 
193
    stream->state = STREAM_STATE_ERROR;
 
194
    error_set(error, stream_to_lex(stream), "unable to decode byte 0x%x", c);
 
195
    return STREAM_STATE_ERROR;
 
196
}
 
197
 
 
198
static void stream_unget(stream_t *stream, int c)
 
199
{
 
200
    if(c == STREAM_STATE_EOF || c == STREAM_STATE_ERROR)
 
201
        return;
 
202
 
 
203
    stream->position--;
 
204
    if(c == '\n') {
 
205
        stream->line--;
 
206
        stream->column = stream->last_column;
 
207
    }
 
208
    else if(utf8_check_first(c))
 
209
        stream->column--;
 
210
 
 
211
    assert(stream->buffer_pos > 0);
 
212
    stream->buffer_pos--;
 
213
    assert(stream->buffer[stream->buffer_pos] == c);
 
214
}
 
215
 
 
216
 
 
217
static int lex_get(lex_t *lex, json_error_t *error)
 
218
{
 
219
    return stream_get(&lex->stream, error);
 
220
}
 
221
 
 
222
static void lex_save(lex_t *lex, int c)
 
223
{
 
224
    strbuffer_append_byte(&lex->saved_text, c);
 
225
}
 
226
 
 
227
static int lex_get_save(lex_t *lex, json_error_t *error)
 
228
{
 
229
    int c = stream_get(&lex->stream, error);
 
230
    if(c != STREAM_STATE_EOF && c != STREAM_STATE_ERROR)
 
231
        lex_save(lex, c);
 
232
    return c;
 
233
}
 
234
 
 
235
static void lex_unget(lex_t *lex, int c)
 
236
{
 
237
    stream_unget(&lex->stream, c);
 
238
}
 
239
 
 
240
static void lex_unget_unsave(lex_t *lex, int c)
 
241
{
 
242
    if(c != STREAM_STATE_EOF && c != STREAM_STATE_ERROR) {
 
243
        char d;
 
244
        stream_unget(&lex->stream, c);
 
245
        d = strbuffer_pop(&lex->saved_text);
 
246
        assert(c == d);
 
247
    }
 
248
}
 
249
 
 
250
static void lex_save_cached(lex_t *lex)
 
251
{
 
252
    while(lex->stream.buffer[lex->stream.buffer_pos] != '\0')
 
253
    {
 
254
        lex_save(lex, lex->stream.buffer[lex->stream.buffer_pos]);
 
255
        lex->stream.buffer_pos++;
 
256
        lex->stream.position++;
 
257
    }
 
258
}
 
259
 
 
260
/* assumes that str points to 'u' plus at least 4 valid hex digits */
 
261
static int32_t decode_unicode_escape(const char *str)
 
262
{
 
263
    int i;
 
264
    int32_t value = 0;
 
265
 
 
266
    assert(str[0] == 'u');
 
267
 
 
268
    for(i = 1; i <= 4; i++) {
 
269
        char c = str[i];
 
270
        value <<= 4;
 
271
        if(isdigit(c))
 
272
            value += c - '0';
 
273
        else if(islower(c))
 
274
            value += c - 'a' + 10;
 
275
        else if(isupper(c))
 
276
            value += c - 'A' + 10;
 
277
        else
 
278
            assert(0);
 
279
    }
 
280
 
 
281
    return value;
 
282
}
 
283
 
 
284
static void lex_scan_string(lex_t *lex, json_error_t *error)
 
285
{
 
286
    int c;
 
287
    const char *p;
 
288
    char *t;
 
289
    int i;
 
290
 
 
291
    lex->value.string = NULL;
 
292
    lex->token = TOKEN_INVALID;
 
293
 
 
294
    c = lex_get_save(lex, error);
 
295
 
 
296
    while(c != '"') {
 
297
        if(c == STREAM_STATE_ERROR)
 
298
            goto out;
 
299
 
 
300
        else if(c == STREAM_STATE_EOF) {
 
301
            error_set(error, lex, "premature end of input");
 
302
            goto out;
 
303
        }
 
304
 
 
305
        else if(0 <= c && c <= 0x1F) {
 
306
            /* control character */
 
307
            lex_unget_unsave(lex, c);
 
308
            if(c == '\n')
 
309
                error_set(error, lex, "unexpected newline", c);
 
310
            else
 
311
                error_set(error, lex, "control character 0x%x", c);
 
312
            goto out;
 
313
        }
 
314
 
 
315
        else if(c == '\\') {
 
316
            c = lex_get_save(lex, error);
 
317
            if(c == 'u') {
 
318
                c = lex_get_save(lex, error);
 
319
                for(i = 0; i < 4; i++) {
 
320
                    if(!isxdigit(c)) {
 
321
                        error_set(error, lex, "invalid escape");
 
322
                        goto out;
 
323
                    }
 
324
                    c = lex_get_save(lex, error);
 
325
                }
 
326
            }
 
327
            else if(c == '"' || c == '\\' || c == '/' || c == 'b' ||
 
328
                    c == 'f' || c == 'n' || c == 'r' || c == 't')
 
329
                c = lex_get_save(lex, error);
 
330
            else {
 
331
                error_set(error, lex, "invalid escape");
 
332
                goto out;
 
333
            }
 
334
        }
 
335
        else
 
336
            c = lex_get_save(lex, error);
 
337
    }
 
338
 
 
339
    /* the actual value is at most of the same length as the source
 
340
       string, because:
 
341
         - shortcut escapes (e.g. "\t") (length 2) are converted to 1 byte
 
342
         - a single \uXXXX escape (length 6) is converted to at most 3 bytes
 
343
         - two \uXXXX escapes (length 12) forming an UTF-16 surrogate pair
 
344
           are converted to 4 bytes
 
345
    */
 
346
    lex->value.string = jsonp_malloc(lex->saved_text.length + 1);
 
347
    if(!lex->value.string) {
 
348
        /* this is not very nice, since TOKEN_INVALID is returned */
 
349
        goto out;
 
350
    }
 
351
 
 
352
    /* the target */
 
353
    t = lex->value.string;
 
354
 
 
355
    /* + 1 to skip the " */
 
356
    p = strbuffer_value(&lex->saved_text) + 1;
 
357
 
 
358
    while(*p != '"') {
 
359
        if(*p == '\\') {
 
360
            p++;
 
361
            if(*p == 'u') {
 
362
                char buffer[4];
 
363
                int length;
 
364
                int32_t value;
 
365
 
 
366
                value = decode_unicode_escape(p);
 
367
                p += 5;
 
368
 
 
369
                if(0xD800 <= value && value <= 0xDBFF) {
 
370
                    /* surrogate pair */
 
371
                    if(*p == '\\' && *(p + 1) == 'u') {
 
372
                        int32_t value2 = decode_unicode_escape(++p);
 
373
                        p += 5;
 
374
 
 
375
                        if(0xDC00 <= value2 && value2 <= 0xDFFF) {
 
376
                            /* valid second surrogate */
 
377
                            value =
 
378
                                ((value - 0xD800) << 10) +
 
379
                                (value2 - 0xDC00) +
 
380
                                0x10000;
 
381
                        }
 
382
                        else {
 
383
                            /* invalid second surrogate */
 
384
                            error_set(error, lex,
 
385
                                      "invalid Unicode '\\u%04X\\u%04X'",
 
386
                                      value, value2);
 
387
                            goto out;
 
388
                        }
 
389
                    }
 
390
                    else {
 
391
                        /* no second surrogate */
 
392
                        error_set(error, lex, "invalid Unicode '\\u%04X'",
 
393
                                  value);
 
394
                        goto out;
 
395
                    }
 
396
                }
 
397
                else if(0xDC00 <= value && value <= 0xDFFF) {
 
398
                    error_set(error, lex, "invalid Unicode '\\u%04X'", value);
 
399
                    goto out;
 
400
                }
 
401
                else if(value == 0)
 
402
                {
 
403
                    error_set(error, lex, "\\u0000 is not allowed");
 
404
                    goto out;
 
405
                }
 
406
 
 
407
                if(utf8_encode(value, buffer, &length))
 
408
                    assert(0);
 
409
 
 
410
                memcpy(t, buffer, length);
 
411
                t += length;
 
412
            }
 
413
            else {
 
414
                switch(*p) {
 
415
                    case '"': case '\\': case '/':
 
416
                        *t = *p; break;
 
417
                    case 'b': *t = '\b'; break;
 
418
                    case 'f': *t = '\f'; break;
 
419
                    case 'n': *t = '\n'; break;
 
420
                    case 'r': *t = '\r'; break;
 
421
                    case 't': *t = '\t'; break;
 
422
                    default: assert(0);
 
423
                }
 
424
                t++;
 
425
                p++;
 
426
            }
 
427
        }
 
428
        else
 
429
            *(t++) = *(p++);
 
430
    }
 
431
    *t = '\0';
 
432
    lex->token = TOKEN_STRING;
 
433
    return;
 
434
 
 
435
out:
 
436
    jsonp_free(lex->value.string);
 
437
}
 
438
 
 
439
#if JSON_INTEGER_IS_LONG_LONG
 
440
#define json_strtoint     strtoll
 
441
#else
 
442
#define json_strtoint     strtol
 
443
#endif
 
444
 
 
445
static int lex_scan_number(lex_t *lex, int c, json_error_t *error)
 
446
{
 
447
    const char *saved_text;
 
448
    char *end;
 
449
    double value;
 
450
 
 
451
    lex->token = TOKEN_INVALID;
 
452
 
 
453
    if(c == '-')
 
454
        c = lex_get_save(lex, error);
 
455
 
 
456
    if(c == '0') {
 
457
        c = lex_get_save(lex, error);
 
458
        if(isdigit(c)) {
 
459
            lex_unget_unsave(lex, c);
 
460
            goto out;
 
461
        }
 
462
    }
 
463
    else if(isdigit(c)) {
 
464
        c = lex_get_save(lex, error);
 
465
        while(isdigit(c))
 
466
            c = lex_get_save(lex, error);
 
467
    }
 
468
    else {
 
469
        lex_unget_unsave(lex, c);
 
470
        goto out;
 
471
    }
 
472
 
 
473
    if(c != '.' && c != 'E' && c != 'e') {
 
474
        json_int_t value;
 
475
 
 
476
        lex_unget_unsave(lex, c);
 
477
 
 
478
        saved_text = strbuffer_value(&lex->saved_text);
 
479
 
 
480
        errno = 0;
 
481
        value = json_strtoint(saved_text, &end, 10);
 
482
        if(errno == ERANGE) {
 
483
            if(value < 0)
 
484
                error_set(error, lex, "too big negative integer");
 
485
            else
 
486
                error_set(error, lex, "too big integer");
 
487
            goto out;
 
488
        }
 
489
 
 
490
        assert(end == saved_text + lex->saved_text.length);
 
491
 
 
492
        lex->token = TOKEN_INTEGER;
 
493
        lex->value.integer = value;
 
494
        return 0;
 
495
    }
 
496
 
 
497
    if(c == '.') {
 
498
        c = lex_get(lex, error);
 
499
        if(!isdigit(c)) {
 
500
            lex_unget(lex, c);
 
501
            goto out;
 
502
        }
 
503
        lex_save(lex, c);
 
504
 
 
505
        c = lex_get_save(lex, error);
 
506
        while(isdigit(c))
 
507
            c = lex_get_save(lex, error);
 
508
    }
 
509
 
 
510
    if(c == 'E' || c == 'e') {
 
511
        c = lex_get_save(lex, error);
 
512
        if(c == '+' || c == '-')
 
513
            c = lex_get_save(lex, error);
 
514
 
 
515
        if(!isdigit(c)) {
 
516
            lex_unget_unsave(lex, c);
 
517
            goto out;
 
518
        }
 
519
 
 
520
        c = lex_get_save(lex, error);
 
521
        while(isdigit(c))
 
522
            c = lex_get_save(lex, error);
 
523
    }
 
524
 
 
525
    lex_unget_unsave(lex, c);
 
526
 
 
527
    saved_text = strbuffer_value(&lex->saved_text);
 
528
    errno = 0;
 
529
    value = strtod(saved_text, &end);
 
530
    assert(end == saved_text + lex->saved_text.length);
 
531
 
 
532
    if(errno == ERANGE && value != 0) {
 
533
        error_set(error, lex, "real number overflow");
 
534
        goto out;
 
535
    }
 
536
 
 
537
    lex->token = TOKEN_REAL;
 
538
    lex->value.real = value;
 
539
    return 0;
 
540
 
 
541
out:
 
542
    return -1;
 
543
}
 
544
 
 
545
static int lex_scan(lex_t *lex, json_error_t *error)
 
546
{
 
547
    int c;
 
548
 
 
549
    strbuffer_clear(&lex->saved_text);
 
550
 
 
551
    if(lex->token == TOKEN_STRING) {
 
552
        jsonp_free(lex->value.string);
 
553
        lex->value.string = NULL;
 
554
    }
 
555
 
 
556
    c = lex_get(lex, error);
 
557
    while(c == ' ' || c == '\t' || c == '\n' || c == '\r')
 
558
        c = lex_get(lex, error);
 
559
 
 
560
    if(c == STREAM_STATE_EOF) {
 
561
        lex->token = TOKEN_EOF;
 
562
        goto out;
 
563
    }
 
564
 
 
565
    if(c == STREAM_STATE_ERROR) {
 
566
        lex->token = TOKEN_INVALID;
 
567
        goto out;
 
568
    }
 
569
 
 
570
    lex_save(lex, c);
 
571
 
 
572
    if(c == '{' || c == '}' || c == '[' || c == ']' || c == ':' || c == ',')
 
573
        lex->token = c;
 
574
 
 
575
    else if(c == '"')
 
576
        lex_scan_string(lex, error);
 
577
 
 
578
    else if(isdigit(c) || c == '-') {
 
579
        if(lex_scan_number(lex, c, error))
 
580
            goto out;
 
581
    }
 
582
 
 
583
    else if(isupper(c) || islower(c)) {
 
584
        /* eat up the whole identifier for clearer error messages */
 
585
        const char *saved_text;
 
586
 
 
587
        c = lex_get_save(lex, error);
 
588
        while(isupper(c) || islower(c))
 
589
            c = lex_get_save(lex, error);
 
590
        lex_unget_unsave(lex, c);
 
591
 
 
592
        saved_text = strbuffer_value(&lex->saved_text);
 
593
 
 
594
        if(strcmp(saved_text, "true") == 0)
 
595
            lex->token = TOKEN_TRUE;
 
596
        else if(strcmp(saved_text, "false") == 0)
 
597
            lex->token = TOKEN_FALSE;
 
598
        else if(strcmp(saved_text, "null") == 0)
 
599
            lex->token = TOKEN_NULL;
 
600
        else
 
601
            lex->token = TOKEN_INVALID;
 
602
    }
 
603
 
 
604
    else {
 
605
        /* save the rest of the input UTF-8 sequence to get an error
 
606
           message of valid UTF-8 */
 
607
        lex_save_cached(lex);
 
608
        lex->token = TOKEN_INVALID;
 
609
    }
 
610
 
 
611
out:
 
612
    return lex->token;
 
613
}
 
614
 
 
615
static char *lex_steal_string(lex_t *lex)
 
616
{
 
617
    char *result = NULL;
 
618
    if(lex->token == TOKEN_STRING)
 
619
    {
 
620
        result = lex->value.string;
 
621
        lex->value.string = NULL;
 
622
    }
 
623
    return result;
 
624
}
 
625
 
 
626
static int lex_init(lex_t *lex, get_func get, void *data)
 
627
{
 
628
    stream_init(&lex->stream, get, data);
 
629
    if(strbuffer_init(&lex->saved_text))
 
630
        return -1;
 
631
 
 
632
    lex->token = TOKEN_INVALID;
 
633
    return 0;
 
634
}
 
635
 
 
636
static void lex_close(lex_t *lex)
 
637
{
 
638
    if(lex->token == TOKEN_STRING)
 
639
        jsonp_free(lex->value.string);
 
640
    strbuffer_close(&lex->saved_text);
 
641
}
 
642
 
 
643
 
 
644
/*** parser ***/
 
645
 
 
646
static json_t *parse_value(lex_t *lex, size_t flags, json_error_t *error);
 
647
 
 
648
static json_t *parse_object(lex_t *lex, size_t flags, json_error_t *error)
 
649
{
 
650
    json_t *object = json_object();
 
651
    if(!object)
 
652
        return NULL;
 
653
 
 
654
    lex_scan(lex, error);
 
655
    if(lex->token == '}')
 
656
        return object;
 
657
 
 
658
    while(1) {
 
659
        char *key;
 
660
        json_t *value;
 
661
 
 
662
        if(lex->token != TOKEN_STRING) {
 
663
            error_set(error, lex, "string or '}' expected");
 
664
            goto error;
 
665
        }
 
666
 
 
667
        key = lex_steal_string(lex);
 
668
        if(!key)
 
669
            return NULL;
 
670
 
 
671
        if(flags & JSON_REJECT_DUPLICATES) {
 
672
            if(json_object_get(object, key)) {
 
673
                jsonp_free(key);
 
674
                error_set(error, lex, "duplicate object key");
 
675
                goto error;
 
676
            }
 
677
        }
 
678
 
 
679
        lex_scan(lex, error);
 
680
        if(lex->token != ':') {
 
681
            jsonp_free(key);
 
682
            error_set(error, lex, "':' expected");
 
683
            goto error;
 
684
        }
 
685
 
 
686
        lex_scan(lex, error);
 
687
        value = parse_value(lex, flags, error);
 
688
        if(!value) {
 
689
            jsonp_free(key);
 
690
            goto error;
 
691
        }
 
692
 
 
693
        if(json_object_set_nocheck(object, key, value)) {
 
694
            jsonp_free(key);
 
695
            json_decref(value);
 
696
            goto error;
 
697
        }
 
698
 
 
699
        json_decref(value);
 
700
        jsonp_free(key);
 
701
 
 
702
        lex_scan(lex, error);
 
703
        if(lex->token != ',')
 
704
            break;
 
705
 
 
706
        lex_scan(lex, error);
 
707
    }
 
708
 
 
709
    if(lex->token != '}') {
 
710
        error_set(error, lex, "'}' expected");
 
711
        goto error;
 
712
    }
 
713
 
 
714
    return object;
 
715
 
 
716
error:
 
717
    json_decref(object);
 
718
    return NULL;
 
719
}
 
720
 
 
721
static json_t *parse_array(lex_t *lex, size_t flags, json_error_t *error)
 
722
{
 
723
    json_t *array = json_array();
 
724
    if(!array)
 
725
        return NULL;
 
726
 
 
727
    lex_scan(lex, error);
 
728
    if(lex->token == ']')
 
729
        return array;
 
730
 
 
731
    while(lex->token) {
 
732
        json_t *elem = parse_value(lex, flags, error);
 
733
        if(!elem)
 
734
            goto error;
 
735
 
 
736
        if(json_array_append(array, elem)) {
 
737
            json_decref(elem);
 
738
            goto error;
 
739
        }
 
740
        json_decref(elem);
 
741
 
 
742
        lex_scan(lex, error);
 
743
        if(lex->token != ',')
 
744
            break;
 
745
 
 
746
        lex_scan(lex, error);
 
747
    }
 
748
 
 
749
    if(lex->token != ']') {
 
750
        error_set(error, lex, "']' expected");
 
751
        goto error;
 
752
    }
 
753
 
 
754
    return array;
 
755
 
 
756
error:
 
757
    json_decref(array);
 
758
    return NULL;
 
759
}
 
760
 
 
761
static json_t *parse_value(lex_t *lex, size_t flags, json_error_t *error)
 
762
{
 
763
    json_t *json;
 
764
 
 
765
    switch(lex->token) {
 
766
        case TOKEN_STRING: {
 
767
            json = json_string_nocheck(lex->value.string);
 
768
            break;
 
769
        }
 
770
 
 
771
        case TOKEN_INTEGER: {
 
772
            json = json_integer(lex->value.integer);
 
773
            break;
 
774
        }
 
775
 
 
776
        case TOKEN_REAL: {
 
777
            json = json_real(lex->value.real);
 
778
            break;
 
779
        }
 
780
 
 
781
        case TOKEN_TRUE:
 
782
            json = json_true();
 
783
            break;
 
784
 
 
785
        case TOKEN_FALSE:
 
786
            json = json_false();
 
787
            break;
 
788
 
 
789
        case TOKEN_NULL:
 
790
            json = json_null();
 
791
            break;
 
792
 
 
793
        case '{':
 
794
            json = parse_object(lex, flags, error);
 
795
            break;
 
796
 
 
797
        case '[':
 
798
            json = parse_array(lex, flags, error);
 
799
            break;
 
800
 
 
801
        case TOKEN_INVALID:
 
802
            error_set(error, lex, "invalid token");
 
803
            return NULL;
 
804
 
 
805
        default:
 
806
            error_set(error, lex, "unexpected token");
 
807
            return NULL;
 
808
    }
 
809
 
 
810
    if(!json)
 
811
        return NULL;
 
812
 
 
813
    return json;
 
814
}
 
815
 
 
816
static json_t *parse_json(lex_t *lex, size_t flags, json_error_t *error)
 
817
{
 
818
    json_t *result;
 
819
 
 
820
    lex_scan(lex, error);
 
821
    if(lex->token != '[' && lex->token != '{') {
 
822
        error_set(error, lex, "'[' or '{' expected");
 
823
        return NULL;
 
824
    }
 
825
 
 
826
    result = parse_value(lex, flags, error);
 
827
    if(!result)
 
828
        return NULL;
 
829
 
 
830
    if(!(flags & JSON_DISABLE_EOF_CHECK)) {
 
831
        lex_scan(lex, error);
 
832
        if(lex->token != TOKEN_EOF) {
 
833
            error_set(error, lex, "end of file expected");
 
834
            json_decref(result);
 
835
            result = NULL;
 
836
        }
 
837
    }
 
838
 
 
839
    return result;
 
840
}
 
841
 
 
842
typedef struct
 
843
{
 
844
    const char *data;
 
845
    int pos;
 
846
} string_data_t;
 
847
 
 
848
static int string_get(void *data)
 
849
{
 
850
    char c;
 
851
    string_data_t *stream = (string_data_t *)data;
 
852
    c = stream->data[stream->pos];
 
853
    if(c == '\0')
 
854
        return EOF;
 
855
    else
 
856
    {
 
857
        stream->pos++;
 
858
        return (unsigned char)c;
 
859
    }
 
860
}
 
861
 
 
862
json_t *json_loads(const char *string, size_t flags, json_error_t *error)
 
863
{
 
864
    lex_t lex;
 
865
    json_t *result;
 
866
    string_data_t stream_data;
 
867
 
 
868
    stream_data.data = string;
 
869
    stream_data.pos = 0;
 
870
 
 
871
    if(lex_init(&lex, string_get, (void *)&stream_data))
 
872
        return NULL;
 
873
 
 
874
    jsonp_error_init(error, "<string>");
 
875
    result = parse_json(&lex, flags, error);
 
876
 
 
877
    lex_close(&lex);
 
878
    return result;
 
879
}
 
880
 
 
881
typedef struct
 
882
{
 
883
    const char *data;
 
884
    size_t len;
 
885
    size_t pos;
 
886
} buffer_data_t;
 
887
 
 
888
static int buffer_get(void *data)
 
889
{
 
890
    char c;
 
891
    buffer_data_t *stream = data;
 
892
    if(stream->pos >= stream->len)
 
893
      return EOF;
 
894
 
 
895
    c = stream->data[stream->pos];
 
896
    stream->pos++;
 
897
    return (unsigned char)c;
 
898
}
 
899
 
 
900
json_t *json_loadb(const char *buffer, size_t buflen, size_t flags, json_error_t *error)
 
901
{
 
902
    lex_t lex;
 
903
    json_t *result;
 
904
    buffer_data_t stream_data;
 
905
 
 
906
    stream_data.data = buffer;
 
907
    stream_data.pos = 0;
 
908
    stream_data.len = buflen;
 
909
 
 
910
    if(lex_init(&lex, buffer_get, (void *)&stream_data))
 
911
        return NULL;
 
912
 
 
913
    jsonp_error_init(error, "<buffer>");
 
914
    result = parse_json(&lex, flags, error);
 
915
 
 
916
    lex_close(&lex);
 
917
    return result;
 
918
}
 
919
 
 
920
json_t *json_loadf(FILE *input, size_t flags, json_error_t *error)
 
921
{
 
922
    lex_t lex;
 
923
    const char *source;
 
924
    json_t *result;
 
925
 
 
926
    if(lex_init(&lex, (get_func)fgetc, input))
 
927
        return NULL;
 
928
 
 
929
    if(input == stdin)
 
930
        source = "<stdin>";
 
931
    else
 
932
        source = "<stream>";
 
933
 
 
934
    jsonp_error_init(error, source);
 
935
    result = parse_json(&lex, flags, error);
 
936
 
 
937
    lex_close(&lex);
 
938
    return result;
 
939
}
 
940
 
 
941
json_t *json_load_file(const char *path, size_t flags, json_error_t *error)
 
942
{
 
943
    json_t *result;
 
944
    FILE *fp;
 
945
 
 
946
    jsonp_error_init(error, path);
 
947
 
 
948
    fp = fopen(path, "r");
 
949
    if(!fp)
 
950
    {
 
951
        error_set(error, NULL, "unable to open %s: %s",
 
952
                  path, strerror(errno));
 
953
        return NULL;
 
954
    }
 
955
 
 
956
    result = json_loadf(fp, flags, error);
 
957
 
 
958
    fclose(fp);
 
959
    return result;
 
960
}