Changeset 5ebff60 for lib/json.c


Ignore:
Timestamp:
2015-02-20T22:50:54Z (9 years ago)
Author:
dequis <dx@…>
Branches:
master
Children:
0b9daac, 3d45471, 7733b8c
Parents:
af359b4
git-author:
Indent <please@…> (19-02-15 05:47:20)
git-committer:
dequis <dx@…> (20-02-15 22:50:54)
Message:

Reindent everything to K&R style with tabs

Used uncrustify, with the configuration file in ./doc/uncrustify.cfg

Commit author set to "Indent <please@…>" so that it's easier to
skip while doing git blame.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • lib/json.c

    raf359b4 r5ebff60  
    3939
    4040#ifdef __cplusplus
    41    const struct _json_value json_value_none; /* zero-d by ctor */
     41const struct _json_value json_value_none;    /* zero-d by ctor */
    4242#else
    43    const struct _json_value json_value_none = { 0 };
     43const struct _json_value json_value_none = { 0 };
    4444#endif
    4545
     
    5151typedef unsigned int json_uchar;
    5252
    53 static unsigned char hex_value (json_char c)
     53static unsigned char hex_value(json_char c)
    5454{
    55    if (g_ascii_isdigit(c))
    56       return c - '0';
    57 
    58    switch (c) {
    59       case 'a': case 'A': return 0x0A;
    60       case 'b': case 'B': return 0x0B;
    61       case 'c': case 'C': return 0x0C;
    62       case 'd': case 'D': return 0x0D;
    63       case 'e': case 'E': return 0x0E;
    64       case 'f': case 'F': return 0x0F;
    65       default: return 0xFF;
    66    }
     55        if (g_ascii_isdigit(c)) {
     56                return c - '0';
     57        }
     58
     59        switch (c) {
     60        case 'a': case 'A': return 0x0A;
     61        case 'b': case 'B': return 0x0B;
     62        case 'c': case 'C': return 0x0C;
     63        case 'd': case 'D': return 0x0D;
     64        case 'e': case 'E': return 0x0E;
     65        case 'f': case 'F': return 0x0F;
     66        default: return 0xFF;
     67        }
    6768}
    6869
    69 typedef struct
     70typedef struct {
     71        unsigned long used_memory;
     72
     73        unsigned int uint_max;
     74        unsigned long ulong_max;
     75
     76        json_settings settings;
     77        int first_pass;
     78
     79} json_state;
     80
     81static void * default_alloc(size_t size, int zero, void * user_data)
    7082{
    71    unsigned long used_memory;
    72 
    73    unsigned int uint_max;
    74    unsigned long ulong_max;
    75 
    76    json_settings settings;
    77    int first_pass;
    78 
    79 } json_state;
    80 
    81 static void * default_alloc (size_t size, int zero, void * user_data)
     83        return zero ? calloc(1, size) : malloc(size);
     84}
     85
     86static void default_free(void * ptr, void * user_data)
    8287{
    83    return zero ? calloc (1, size) : malloc (size);
     88        free(ptr);
    8489}
    8590
    86 static void default_free (void * ptr, void * user_data)
     91static void * json_alloc(json_state * state, unsigned long size, int zero)
    8792{
    88    free (ptr);
     93        if ((state->ulong_max - state->used_memory) < size) {
     94                return 0;
     95        }
     96
     97        if (state->settings.max_memory
     98            && (state->used_memory += size) > state->settings.max_memory) {
     99                return 0;
     100        }
     101
     102        return state->settings.mem_alloc(size, zero, state->settings.user_data);
    89103}
    90104
    91 static void * json_alloc (json_state * state, unsigned long size, int zero)
     105static int new_value
     106        (json_state * state, json_value ** top, json_value ** root, json_value ** alloc, json_type type)
    92107{
    93    if ((state->ulong_max - state->used_memory) < size)
    94       return 0;
    95 
    96    if (state->settings.max_memory
    97          && (state->used_memory += size) > state->settings.max_memory)
    98    {
    99       return 0;
    100    }
    101 
    102    return state->settings.mem_alloc (size, zero, state->settings.user_data);
     108        json_value * value;
     109        int values_size;
     110
     111        if (!state->first_pass) {
     112                value = *top = *alloc;
     113                *alloc = (*alloc)->_reserved.next_alloc;
     114
     115                if (!*root) {
     116                        *root = value;
     117                }
     118
     119                switch (value->type) {
     120                case json_array:
     121
     122                        if (!(value->u.array.values = (json_value **) json_alloc
     123                                                              (state, value->u.array.length * sizeof(json_value *),
     124                                                              0))) {
     125                                return 0;
     126                        }
     127
     128                        value->u.array.length = 0;
     129                        break;
     130
     131                case json_object:
     132
     133                        values_size = sizeof(*value->u.object.values) * value->u.object.length;
     134
     135                        if (!((*(void **) &value->u.object.values) = json_alloc
     136                                                                             (state, values_size +
     137                                                                             ((unsigned long) value->u.object.values),
     138                                                                             0))) {
     139                                return 0;
     140                        }
     141
     142                        value->_reserved.object_mem = (*(char **) &value->u.object.values) + values_size;
     143
     144                        value->u.object.length = 0;
     145                        break;
     146
     147                case json_string:
     148
     149                        if (!(value->u.string.ptr = (json_char *) json_alloc
     150                                                            (state, (value->u.string.length + 1) * sizeof(json_char),
     151                                                            0))) {
     152                                return 0;
     153                        }
     154
     155                        value->u.string.length = 0;
     156                        break;
     157
     158                default:
     159                        break;
     160                }
     161                ;
     162
     163                return 1;
     164        }
     165
     166        value = (json_value *) json_alloc(state, sizeof(json_value), 1);
     167
     168        if (!value) {
     169                return 0;
     170        }
     171
     172        if (!*root) {
     173                *root = value;
     174        }
     175
     176        value->type = type;
     177        value->parent = *top;
     178
     179        if (*alloc) {
     180                (*alloc)->_reserved.next_alloc = value;
     181        }
     182
     183        *alloc = *top = value;
     184
     185        return 1;
    103186}
    104187
    105 static int new_value
    106    (json_state * state, json_value ** top, json_value ** root, json_value ** alloc, json_type type)
     188#define e_off \
     189        ((int) (i - cur_line_begin))
     190
     191#define whitespace \
     192case '\n': ++cur_line;  cur_line_begin = i; \
     193case ' ': case '\t': case '\r'
     194
     195#define string_add(b)  \
     196        do { if (!state.first_pass) { string [string_length] = b; } ++string_length; } while (0);
     197
     198static const long
     199        flag_next             = 1 << 0,
     200        flag_reproc           = 1 << 1,
     201        flag_need_comma       = 1 << 2,
     202        flag_seek_value       = 1 << 3,
     203        flag_escaped          = 1 << 4,
     204        flag_string           = 1 << 5,
     205        flag_need_colon       = 1 << 6,
     206        flag_done             = 1 << 7,
     207        flag_num_negative     = 1 << 8,
     208        flag_num_zero         = 1 << 9,
     209        flag_num_e            = 1 << 10,
     210        flag_num_e_got_sign   = 1 << 11,
     211        flag_num_e_negative   = 1 << 12,
     212        flag_line_comment     = 1 << 13,
     213        flag_block_comment    = 1 << 14;
     214
     215json_value * json_parse_ex(json_settings * settings,
     216                           const json_char * json,
     217                           size_t length,
     218                           char * error_buf)
    107219{
    108    json_value * value;
    109    int values_size;
    110 
    111    if (!state->first_pass)
    112    {
    113       value = *top = *alloc;
    114       *alloc = (*alloc)->_reserved.next_alloc;
    115 
    116       if (!*root)
    117          *root = value;
    118 
    119       switch (value->type)
    120       {
    121          case json_array:
    122 
    123             if (! (value->u.array.values = (json_value **) json_alloc
    124                (state, value->u.array.length * sizeof (json_value *), 0)) )
    125             {
    126                return 0;
    127             }
    128 
    129             value->u.array.length = 0;
    130             break;
    131 
    132          case json_object:
    133 
    134             values_size = sizeof (*value->u.object.values) * value->u.object.length;
    135 
    136             if (! ((*(void **) &value->u.object.values) = json_alloc
    137                   (state, values_size + ((unsigned long) value->u.object.values), 0)) )
    138             {
    139                return 0;
    140             }
    141 
    142             value->_reserved.object_mem = (*(char **) &value->u.object.values) + values_size;
    143 
    144             value->u.object.length = 0;
    145             break;
    146 
    147          case json_string:
    148 
    149             if (! (value->u.string.ptr = (json_char *) json_alloc
    150                (state, (value->u.string.length + 1) * sizeof (json_char), 0)) )
    151             {
    152                return 0;
    153             }
    154 
    155             value->u.string.length = 0;
    156             break;
    157 
    158          default:
    159             break;
    160       };
    161 
    162       return 1;
    163    }
    164 
    165    value = (json_value *) json_alloc (state, sizeof (json_value), 1);
    166 
    167    if (!value)
    168       return 0;
    169 
    170    if (!*root)
    171       *root = value;
    172 
    173    value->type = type;
    174    value->parent = *top;
    175 
    176    if (*alloc)
    177       (*alloc)->_reserved.next_alloc = value;
    178 
    179    *alloc = *top = value;
    180 
    181    return 1;
     220        json_char error [json_error_max];
     221        unsigned int cur_line;
     222        const json_char * cur_line_begin, * i, * end;
     223        json_value * top, * root, * alloc = 0;
     224        json_state state = { 0 };
     225        long flags;
     226        long num_digits = 0, num_e = 0;
     227        json_int_t num_fraction = 0;
     228
     229        /* Skip UTF-8 BOM
     230         */
     231        if (length >= 3 && ((unsigned char) json [0]) == 0xEF
     232            && ((unsigned char) json [1]) == 0xBB
     233            && ((unsigned char) json [2]) == 0xBF) {
     234                json += 3;
     235                length -= 3;
     236        }
     237
     238        error[0] = '\0';
     239        end = (json + length);
     240
     241        memcpy(&state.settings, settings, sizeof(json_settings));
     242
     243        if (!state.settings.mem_alloc) {
     244                state.settings.mem_alloc = default_alloc;
     245        }
     246
     247        if (!state.settings.mem_free) {
     248                state.settings.mem_free = default_free;
     249        }
     250
     251        memset(&state.uint_max, 0xFF, sizeof(state.uint_max));
     252        memset(&state.ulong_max, 0xFF, sizeof(state.ulong_max));
     253
     254        state.uint_max -= 8; /* limit of how much can be added before next check */
     255        state.ulong_max -= 8;
     256
     257        for (state.first_pass = 1; state.first_pass >= 0; --state.first_pass) {
     258                json_uchar uchar;
     259                unsigned char uc_b1, uc_b2, uc_b3, uc_b4;
     260                json_char * string = 0;
     261                unsigned int string_length = 0;
     262
     263                top = root = 0;
     264                flags = flag_seek_value;
     265
     266                cur_line = 1;
     267                cur_line_begin = json;
     268
     269                for (i = json;; ++i) {
     270                        json_char b = (i == end ? 0 : *i);
     271
     272                        if (flags & flag_string) {
     273                                if (!b) {
     274                                        sprintf(error, "Unexpected EOF in string (at %d:%d)", cur_line, e_off);
     275                                        goto e_failed;
     276                                }
     277
     278                                if (string_length > state.uint_max) {
     279                                        goto e_overflow;
     280                                }
     281
     282                                if (flags & flag_escaped) {
     283                                        flags &= ~flag_escaped;
     284
     285                                        switch (b) {
     286                                        case 'b':  string_add('\b');  break;
     287                                        case 'f':  string_add('\f');  break;
     288                                        case 'n':  string_add('\n');  break;
     289                                        case 'r':  string_add('\r');  break;
     290                                        case 't':  string_add('\t');  break;
     291                                        case 'u':
     292
     293                                                if (end - i < 4 ||
     294                                                    (uc_b1 = hex_value(*++i)) == 0xFF || (uc_b2 = hex_value(*++i)) ==
     295                                                    0xFF
     296                                                    || (uc_b3 = hex_value(*++i)) == 0xFF || (uc_b4 = hex_value(*++i)) ==
     297                                                    0xFF) {
     298                                                        sprintf(error, "Invalid character value `%c` (at %d:%d)", b,
     299                                                                cur_line, e_off);
     300                                                        goto e_failed;
     301                                                }
     302
     303                                                uc_b1 = (uc_b1 << 4) | uc_b2;
     304                                                uc_b2 = (uc_b3 << 4) | uc_b4;
     305                                                uchar = (uc_b1 << 8) | uc_b2;
     306
     307                                                if ((uchar & 0xF800) == 0xD800) {
     308                                                        json_uchar uchar2;
     309
     310                                                        if (end - i < 6 || (*++i) != '\\' || (*++i) != 'u' ||
     311                                                            (uc_b1 = hex_value(*++i)) == 0xFF ||
     312                                                            (uc_b2 = hex_value(*++i)) == 0xFF
     313                                                            || (uc_b3 = hex_value(*++i)) == 0xFF ||
     314                                                            (uc_b4 = hex_value(*++i)) == 0xFF) {
     315                                                                sprintf(error,
     316                                                                        "Invalid character value `%c` (at %d:%d)", b,
     317                                                                        cur_line, e_off);
     318                                                                goto e_failed;
     319                                                        }
     320
     321                                                        uc_b1 = (uc_b1 << 4) | uc_b2;
     322                                                        uc_b2 = (uc_b3 << 4) | uc_b4;
     323                                                        uchar2 = (uc_b1 << 8) | uc_b2;
     324
     325                                                        uchar = 0x010000 | ((uchar & 0x3FF) << 10) | (uchar2 & 0x3FF);
     326                                                }
     327
     328                                                if (sizeof(json_char) >= sizeof(json_uchar) || (uchar <= 0x7F)) {
     329                                                        string_add((json_char) uchar);
     330                                                        break;
     331                                                }
     332
     333                                                if (uchar <= 0x7FF) {
     334                                                        if (state.first_pass) {
     335                                                                string_length += 2;
     336                                                        } else {                    string [string_length++] = 0xC0 |
     337                                                                                                               (uchar >>
     338                                                                                                                6);
     339                                                                                    string [string_length++] = 0x80 |
     340                                                                                                               (uchar &
     341                                                                                                                0x3F); }
     342
     343                                                        break;
     344                                                }
     345
     346                                                if (uchar <= 0xFFFF) {
     347                                                        if (state.first_pass) {
     348                                                                string_length += 3;
     349                                                        } else {                    string [string_length++] = 0xE0 |
     350                                                                                                               (uchar >>
     351                                                                                                                12);
     352                                                                                    string [string_length++] = 0x80 |
     353                                                                                                               ((uchar
     354                                                                                                                 >> 6) &
     355                                                                                                                0x3F);
     356                                                                                    string [string_length++] = 0x80 |
     357                                                                                                               (uchar &
     358                                                                                                                0x3F); }
     359
     360                                                        break;
     361                                                }
     362
     363                                                if (state.first_pass) {
     364                                                        string_length += 4;
     365                                                } else {                string [string_length++] = 0xF0 | (uchar >> 18);
     366                                                                        string [string_length++] = 0x80 |
     367                                                                                                   ((uchar >>
     368                                                                                                     12) & 0x3F);
     369                                                                        string [string_length++] = 0x80 |
     370                                                                                                   ((uchar >>
     371                                                                                                     6) & 0x3F);
     372                                                                        string [string_length++] = 0x80 |
     373                                                                                                   (uchar & 0x3F); }
     374
     375                                                break;
     376
     377                                        default:
     378                                                string_add(b);
     379                                        }
     380                                        ;
     381
     382                                        continue;
     383                                }
     384
     385                                if (b == '\\') {
     386                                        flags |= flag_escaped;
     387                                        continue;
     388                                }
     389
     390                                if (b == '"') {
     391                                        if (!state.first_pass) {
     392                                                string [string_length] = 0;
     393                                        }
     394
     395                                        flags &= ~flag_string;
     396                                        string = 0;
     397
     398                                        switch (top->type) {
     399                                        case json_string:
     400
     401                                                top->u.string.length = string_length;
     402                                                flags |= flag_next;
     403
     404                                                break;
     405
     406                                        case json_object:
     407
     408                                                if (state.first_pass) {
     409                                                        (*(json_char **) &top->u.object.values) += string_length + 1;
     410                                                } else {
     411                                                        top->u.object.values [top->u.object.length].name
     412                                                                = (json_char *) top->_reserved.object_mem;
     413
     414                                                        top->u.object.values [top->u.object.length].name_length
     415                                                                = string_length;
     416
     417                                                        (*(json_char **) &top->_reserved.object_mem) += string_length +
     418                                                                                                        1;
     419                                                }
     420
     421                                                flags |= flag_seek_value | flag_need_colon;
     422                                                continue;
     423
     424                                        default:
     425                                                break;
     426                                        }
     427                                        ;
     428                                } else {
     429                                        string_add(b);
     430                                        continue;
     431                                }
     432                        }
     433
     434                        if (state.settings.settings & json_enable_comments) {
     435                                if (flags & (flag_line_comment | flag_block_comment)) {
     436                                        if (flags & flag_line_comment) {
     437                                                if (b == '\r' || b == '\n' || !b) {
     438                                                        flags &= ~flag_line_comment;
     439                                                        --i; /* so null can be reproc'd */
     440                                                }
     441
     442                                                continue;
     443                                        }
     444
     445                                        if (flags & flag_block_comment) {
     446                                                if (!b) {
     447                                                        sprintf(error, "%d:%d: Unexpected EOF in block comment",
     448                                                                cur_line, e_off);
     449                                                        goto e_failed;
     450                                                }
     451
     452                                                if (b == '*' && i < (end - 1) && i [1] == '/') {
     453                                                        flags &= ~flag_block_comment;
     454                                                        ++i; /* skip closing sequence */
     455                                                }
     456
     457                                                continue;
     458                                        }
     459                                } else if (b == '/') {
     460                                        if (!(flags & (flag_seek_value | flag_done)) && top->type != json_object) {
     461                                                sprintf(error, "%d:%d: Comment not allowed here", cur_line, e_off);
     462                                                goto e_failed;
     463                                        }
     464
     465                                        if (++i == end) {
     466                                                sprintf(error, "%d:%d: EOF unexpected", cur_line, e_off);
     467                                                goto e_failed;
     468                                        }
     469
     470                                        switch (b = *i) {
     471                                        case '/':
     472                                                flags |= flag_line_comment;
     473                                                continue;
     474
     475                                        case '*':
     476                                                flags |= flag_block_comment;
     477                                                continue;
     478
     479                                        default:
     480                                                sprintf(error, "%d:%d: Unexpected `%c` in comment opening sequence",
     481                                                        cur_line, e_off, b);
     482                                                goto e_failed;
     483                                        }
     484                                        ;
     485                                }
     486                        }
     487
     488                        if (flags & flag_done) {
     489                                if (!b) {
     490                                        break;
     491                                }
     492
     493                                switch (b) {
     494whitespace:
     495                                        continue;
     496
     497                                default:
     498                                        sprintf(error, "%d:%d: Trailing garbage: `%c`", cur_line, e_off, b);
     499                                        goto e_failed;
     500                                }
     501                                ;
     502                        }
     503
     504                        if (flags & flag_seek_value) {
     505                                switch (b) {
     506whitespace:
     507                                        continue;
     508
     509                                case ']':
     510
     511                                        if (top->type == json_array) {
     512                                                flags = (flags & ~(flag_need_comma | flag_seek_value)) | flag_next;
     513                                        } else {              sprintf(error, "%d:%d: Unexpected ]", cur_line, e_off);
     514                                                              goto e_failed; }
     515
     516                                        break;
     517
     518                                default:
     519
     520                                        if (flags & flag_need_comma) {
     521                                                if (b == ',') {
     522                                                        flags &= ~flag_need_comma;
     523                                                        continue;
     524                                                } else { sprintf(error, "%d:%d: Expected , before %c", cur_line, e_off,
     525                                                                 b);
     526                                                         goto e_failed; }
     527                                        }
     528
     529                                        if (flags & flag_need_colon) {
     530                                                if (b == ':') {
     531                                                        flags &= ~flag_need_colon;
     532                                                        continue;
     533                                                } else { sprintf(error, "%d:%d: Expected : before %c", cur_line, e_off,
     534                                                                 b);
     535                                                         goto e_failed; }
     536                                        }
     537
     538                                        flags &= ~flag_seek_value;
     539
     540                                        switch (b) {
     541                                        case '{':
     542
     543                                                if (!new_value(&state, &top, &root, &alloc, json_object)) {
     544                                                        goto e_alloc_failure;
     545                                                }
     546
     547                                                continue;
     548
     549                                        case '[':
     550
     551                                                if (!new_value(&state, &top, &root, &alloc, json_array)) {
     552                                                        goto e_alloc_failure;
     553                                                }
     554
     555                                                flags |= flag_seek_value;
     556                                                continue;
     557
     558                                        case '"':
     559
     560                                                if (!new_value(&state, &top, &root, &alloc, json_string)) {
     561                                                        goto e_alloc_failure;
     562                                                }
     563
     564                                                flags |= flag_string;
     565
     566                                                string = top->u.string.ptr;
     567                                                string_length = 0;
     568
     569                                                continue;
     570
     571                                        case 't':
     572
     573                                                if ((end - i) < 3 || *(++i) != 'r' || *(++i) != 'u' || *(++i) != 'e') {
     574                                                        goto e_unknown_value;
     575                                                }
     576
     577                                                if (!new_value(&state, &top, &root, &alloc, json_boolean)) {
     578                                                        goto e_alloc_failure;
     579                                                }
     580
     581                                                top->u.boolean = 1;
     582
     583                                                flags |= flag_next;
     584                                                break;
     585
     586                                        case 'f':
     587
     588                                                if ((end - i) < 4 || *(++i) != 'a' || *(++i) != 'l' || *(++i) != 's' ||
     589                                                    *(++i) != 'e') {
     590                                                        goto e_unknown_value;
     591                                                }
     592
     593                                                if (!new_value(&state, &top, &root, &alloc, json_boolean)) {
     594                                                        goto e_alloc_failure;
     595                                                }
     596
     597                                                flags |= flag_next;
     598                                                break;
     599
     600                                        case 'n':
     601
     602                                                if ((end - i) < 3 || *(++i) != 'u' || *(++i) != 'l' || *(++i) != 'l') {
     603                                                        goto e_unknown_value;
     604                                                }
     605
     606                                                if (!new_value(&state, &top, &root, &alloc, json_null)) {
     607                                                        goto e_alloc_failure;
     608                                                }
     609
     610                                                flags |= flag_next;
     611                                                break;
     612
     613                                        default:
     614
     615                                                if (g_ascii_isdigit(b) || b == '-') {
     616                                                        if (!new_value(&state, &top, &root, &alloc, json_integer)) {
     617                                                                goto e_alloc_failure;
     618                                                        }
     619
     620                                                        if (!state.first_pass) {
     621                                                                while (g_ascii_isdigit(b) || b == '+' || b == '-'
     622                                                                       || b == 'e' || b == 'E' || b == '.') {
     623                                                                        if ((++i) == end) {
     624                                                                                b = 0;
     625                                                                                break;
     626                                                                        }
     627
     628                                                                        b = *i;
     629                                                                }
     630
     631                                                                flags |= flag_next | flag_reproc;
     632                                                                break;
     633                                                        }
     634
     635                                                        flags &= ~(flag_num_negative | flag_num_e |
     636                                                                   flag_num_e_got_sign | flag_num_e_negative |
     637                                                                   flag_num_zero);
     638
     639                                                        num_digits = 0;
     640                                                        num_fraction = 0;
     641                                                        num_e = 0;
     642
     643                                                        if (b != '-') {
     644                                                                flags |= flag_reproc;
     645                                                                break;
     646                                                        }
     647
     648                                                        flags |= flag_num_negative;
     649                                                        continue;
     650                                                } else { sprintf(error, "%d:%d: Unexpected %c when seeking value",
     651                                                                 cur_line, e_off, b);
     652                                                         goto e_failed; }
     653                                        }
     654                                        ;
     655                                }
     656                                ;
     657                        } else {
     658                                switch (top->type) {
     659                                case json_object:
     660
     661                                        switch (b) {
     662whitespace:
     663                                                continue;
     664
     665                                        case '"':
     666
     667                                                if (flags & flag_need_comma) {
     668                                                        sprintf(error, "%d:%d: Expected , before \"", cur_line, e_off);
     669                                                        goto e_failed;
     670                                                }
     671
     672                                                flags |= flag_string;
     673
     674                                                string = (json_char *) top->_reserved.object_mem;
     675                                                string_length = 0;
     676
     677                                                break;
     678
     679                                        case '}':
     680
     681                                                flags = (flags & ~flag_need_comma) | flag_next;
     682                                                break;
     683
     684                                        case ',':
     685
     686                                                if (flags & flag_need_comma) {
     687                                                        flags &= ~flag_need_comma;
     688                                                        break;
     689                                                }
     690
     691                                        default:
     692
     693                                                sprintf(error, "%d:%d: Unexpected `%c` in object", cur_line, e_off, b);
     694                                                goto e_failed;
     695                                        }
     696                                        ;
     697
     698                                        break;
     699
     700                                case json_integer:
     701                                case json_double:
     702
     703                                        if (g_ascii_isdigit(b)) {
     704                                                ++num_digits;
     705
     706                                                if (top->type == json_integer || flags & flag_num_e) {
     707                                                        if (!(flags & flag_num_e)) {
     708                                                                if (flags & flag_num_zero) {
     709                                                                        sprintf(error,
     710                                                                                "%d:%d: Unexpected `0` before `%c`",
     711                                                                                cur_line, e_off, b);
     712                                                                        goto e_failed;
     713                                                                }
     714
     715                                                                if (num_digits == 1 && b == '0') {
     716                                                                        flags |= flag_num_zero;
     717                                                                }
     718                                                        } else {
     719                                                                flags |= flag_num_e_got_sign;
     720                                                                num_e = (num_e * 10) + (b - '0');
     721                                                                continue;
     722                                                        }
     723
     724                                                        top->u.integer = (top->u.integer * 10) + (b - '0');
     725                                                        continue;
     726                                                }
     727
     728                                                num_fraction = (num_fraction * 10) + (b - '0');
     729                                                continue;
     730                                        }
     731
     732                                        if (b == '+' || b == '-') {
     733                                                if ((flags & flag_num_e) && !(flags & flag_num_e_got_sign)) {
     734                                                        flags |= flag_num_e_got_sign;
     735
     736                                                        if (b == '-') {
     737                                                                flags |= flag_num_e_negative;
     738                                                        }
     739
     740                                                        continue;
     741                                                }
     742                                        } else if (b == '.' && top->type == json_integer) {
     743                                                if (!num_digits) {
     744                                                        sprintf(error, "%d:%d: Expected digit before `.`", cur_line,
     745                                                                e_off);
     746                                                        goto e_failed;
     747                                                }
     748
     749                                                top->type = json_double;
     750                                                top->u.dbl = (double) top->u.integer;
     751
     752                                                num_digits = 0;
     753                                                continue;
     754                                        }
     755
     756                                        if (!(flags & flag_num_e)) {
     757                                                if (top->type == json_double) {
     758                                                        if (!num_digits) {
     759                                                                sprintf(error, "%d:%d: Expected digit after `.`",
     760                                                                        cur_line, e_off);
     761                                                                goto e_failed;
     762                                                        }
     763
     764                                                        top->u.dbl += ((double) num_fraction) /
     765                                                                      (pow(10, (double) num_digits));
     766                                                }
     767
     768                                                if (b == 'e' || b == 'E') {
     769                                                        flags |= flag_num_e;
     770
     771                                                        if (top->type == json_integer) {
     772                                                                top->type = json_double;
     773                                                                top->u.dbl = (double) top->u.integer;
     774                                                        }
     775
     776                                                        num_digits = 0;
     777                                                        flags &= ~flag_num_zero;
     778
     779                                                        continue;
     780                                                }
     781                                        } else {
     782                                                if (!num_digits) {
     783                                                        sprintf(error, "%d:%d: Expected digit after `e`", cur_line,
     784                                                                e_off);
     785                                                        goto e_failed;
     786                                                }
     787
     788                                                top->u.dbl *=
     789                                                        pow(10,
     790                                                            (double) (flags & flag_num_e_negative ? -num_e : num_e));
     791                                        }
     792
     793                                        if (flags & flag_num_negative) {
     794                                                if (top->type == json_integer) {
     795                                                        top->u.integer = -top->u.integer;
     796                                                } else {
     797                                                        top->u.dbl = -top->u.dbl;
     798                                                }
     799                                        }
     800
     801                                        flags |= flag_next | flag_reproc;
     802                                        break;
     803
     804                                default:
     805                                        break;
     806                                }
     807                                ;
     808                        }
     809
     810                        if (flags & flag_reproc) {
     811                                flags &= ~flag_reproc;
     812                                --i;
     813                        }
     814
     815                        if (flags & flag_next) {
     816                                flags = (flags & ~flag_next) | flag_need_comma;
     817
     818                                if (!top->parent) {
     819                                        /* root value done */
     820
     821                                        flags |= flag_done;
     822                                        continue;
     823                                }
     824
     825                                if (top->parent->type == json_array) {
     826                                        flags |= flag_seek_value;
     827                                }
     828
     829                                if (!state.first_pass) {
     830                                        json_value * parent = top->parent;
     831
     832                                        switch (parent->type) {
     833                                        case json_object:
     834
     835                                                parent->u.object.values
     836                                                [parent->u.object.length].value = top;
     837
     838                                                break;
     839
     840                                        case json_array:
     841
     842                                                parent->u.array.values
     843                                                [parent->u.array.length] = top;
     844
     845                                                break;
     846
     847                                        default:
     848                                                break;
     849                                        }
     850                                        ;
     851                                }
     852
     853                                if ((++top->parent->u.array.length) > state.uint_max) {
     854                                        goto e_overflow;
     855                                }
     856
     857                                top = top->parent;
     858
     859                                continue;
     860                        }
     861                }
     862
     863                alloc = root;
     864        }
     865
     866        return root;
     867
     868e_unknown_value:
     869
     870        sprintf(error, "%d:%d: Unknown value", cur_line, e_off);
     871        goto e_failed;
     872
     873e_alloc_failure:
     874
     875        strcpy(error, "Memory allocation failure");
     876        goto e_failed;
     877
     878e_overflow:
     879
     880        sprintf(error, "%d:%d: Too long (caught overflow)", cur_line, e_off);
     881        goto e_failed;
     882
     883e_failed:
     884
     885        if (error_buf) {
     886                if (*error) {
     887                        strcpy(error_buf, error);
     888                } else {
     889                        strcpy(error_buf, "Unknown error");
     890                }
     891        }
     892
     893        if (state.first_pass) {
     894                alloc = root;
     895        }
     896
     897        while (alloc) {
     898                top = alloc->_reserved.next_alloc;
     899                state.settings.mem_free(alloc, state.settings.user_data);
     900                alloc = top;
     901        }
     902
     903        if (!state.first_pass) {
     904                json_value_free_ex(&state.settings, root);
     905        }
     906
     907        return 0;
    182908}
    183909
    184 #define e_off \
    185    ((int) (i - cur_line_begin))
    186 
    187 #define whitespace \
    188    case '\n': ++ cur_line;  cur_line_begin = i; \
    189    case ' ': case '\t': case '\r'
    190 
    191 #define string_add(b)  \
    192    do { if (!state.first_pass) string [string_length] = b;  ++ string_length; } while (0);
    193 
    194 static const long
    195    flag_next             = 1 << 0,
    196    flag_reproc           = 1 << 1,
    197    flag_need_comma       = 1 << 2,
    198    flag_seek_value       = 1 << 3,
    199    flag_escaped          = 1 << 4,
    200    flag_string           = 1 << 5,
    201    flag_need_colon       = 1 << 6,
    202    flag_done             = 1 << 7,
    203    flag_num_negative     = 1 << 8,
    204    flag_num_zero         = 1 << 9,
    205    flag_num_e            = 1 << 10,
    206    flag_num_e_got_sign   = 1 << 11,
    207    flag_num_e_negative   = 1 << 12,
    208    flag_line_comment     = 1 << 13,
    209    flag_block_comment    = 1 << 14;
    210 
    211 json_value * json_parse_ex (json_settings * settings,
    212                             const json_char * json,
    213                             size_t length,
    214                             char * error_buf)
     910json_value * json_parse(const json_char * json, size_t length)
    215911{
    216    json_char error [json_error_max];
    217    unsigned int cur_line;
    218    const json_char * cur_line_begin, * i, * end;
    219    json_value * top, * root, * alloc = 0;
    220    json_state state = { 0 };
    221    long flags;
    222    long num_digits = 0, num_e = 0;
    223    json_int_t num_fraction = 0;
    224 
    225    /* Skip UTF-8 BOM
    226     */
    227    if (length >= 3 && ((unsigned char) json [0]) == 0xEF
    228                    && ((unsigned char) json [1]) == 0xBB
    229                    && ((unsigned char) json [2]) == 0xBF)
    230    {
    231       json += 3;
    232       length -= 3;
    233    }
    234 
    235    error[0] = '\0';
    236    end = (json + length);
    237 
    238    memcpy (&state.settings, settings, sizeof (json_settings));
    239 
    240    if (!state.settings.mem_alloc)
    241       state.settings.mem_alloc = default_alloc;
    242 
    243    if (!state.settings.mem_free)
    244       state.settings.mem_free = default_free;
    245 
    246    memset (&state.uint_max, 0xFF, sizeof (state.uint_max));
    247    memset (&state.ulong_max, 0xFF, sizeof (state.ulong_max));
    248 
    249    state.uint_max -= 8; /* limit of how much can be added before next check */
    250    state.ulong_max -= 8;
    251 
    252    for (state.first_pass = 1; state.first_pass >= 0; -- state.first_pass)
    253    {
    254       json_uchar uchar;
    255       unsigned char uc_b1, uc_b2, uc_b3, uc_b4;
    256       json_char * string = 0;
    257       unsigned int string_length = 0;
    258 
    259       top = root = 0;
    260       flags = flag_seek_value;
    261 
    262       cur_line = 1;
    263       cur_line_begin = json;
    264 
    265       for (i = json ;; ++ i)
    266       {
    267          json_char b = (i == end ? 0 : *i);
    268          
    269          if (flags & flag_string)
    270          {
    271             if (!b)
    272             {  sprintf (error, "Unexpected EOF in string (at %d:%d)", cur_line, e_off);
    273                goto e_failed;
    274             }
    275 
    276             if (string_length > state.uint_max)
    277                goto e_overflow;
    278 
    279             if (flags & flag_escaped)
    280             {
    281                flags &= ~ flag_escaped;
    282 
    283                switch (b)
    284                {
    285                   case 'b':  string_add ('\b');  break;
    286                   case 'f':  string_add ('\f');  break;
    287                   case 'n':  string_add ('\n');  break;
    288                   case 'r':  string_add ('\r');  break;
    289                   case 't':  string_add ('\t');  break;
    290                   case 'u':
    291 
    292                     if (end - i < 4 ||
    293                         (uc_b1 = hex_value (*++ i)) == 0xFF || (uc_b2 = hex_value (*++ i)) == 0xFF
    294                           || (uc_b3 = hex_value (*++ i)) == 0xFF || (uc_b4 = hex_value (*++ i)) == 0xFF)
    295                     {
    296                         sprintf (error, "Invalid character value `%c` (at %d:%d)", b, cur_line, e_off);
    297                         goto e_failed;
    298                     }
    299 
    300                     uc_b1 = (uc_b1 << 4) | uc_b2;
    301                     uc_b2 = (uc_b3 << 4) | uc_b4;
    302                     uchar = (uc_b1 << 8) | uc_b2;
    303 
    304                     if ((uchar & 0xF800) == 0xD800) {
    305                         json_uchar uchar2;
    306                        
    307                         if (end - i < 6 || (*++ i) != '\\' || (*++ i) != 'u' ||
    308                             (uc_b1 = hex_value (*++ i)) == 0xFF || (uc_b2 = hex_value (*++ i)) == 0xFF
    309                               || (uc_b3 = hex_value (*++ i)) == 0xFF || (uc_b4 = hex_value (*++ i)) == 0xFF)
    310                         {
    311                             sprintf (error, "Invalid character value `%c` (at %d:%d)", b, cur_line, e_off);
    312                             goto e_failed;
    313                         }
    314 
    315                         uc_b1 = (uc_b1 << 4) | uc_b2;
    316                         uc_b2 = (uc_b3 << 4) | uc_b4;
    317                         uchar2 = (uc_b1 << 8) | uc_b2;
    318                        
    319                         uchar = 0x010000 | ((uchar & 0x3FF) << 10) | (uchar2 & 0x3FF);
    320                     }
    321 
    322                     if (sizeof (json_char) >= sizeof (json_uchar) || (uchar <= 0x7F))
    323                     {
    324                        string_add ((json_char) uchar);
    325                        break;
    326                     }
    327 
    328                     if (uchar <= 0x7FF)
    329                     {
    330                         if (state.first_pass)
    331                            string_length += 2;
    332                         else
    333                         {  string [string_length ++] = 0xC0 | (uchar >> 6);
    334                            string [string_length ++] = 0x80 | (uchar & 0x3F);
    335                         }
    336 
    337                         break;
    338                     }
    339 
    340                     if (uchar <= 0xFFFF) {
    341                         if (state.first_pass)
    342                            string_length += 3;
    343                         else
    344                         {  string [string_length ++] = 0xE0 | (uchar >> 12);
    345                            string [string_length ++] = 0x80 | ((uchar >> 6) & 0x3F);
    346                            string [string_length ++] = 0x80 | (uchar & 0x3F);
    347                         }
    348                        
    349                         break;
    350                     }
    351 
    352                     if (state.first_pass)
    353                        string_length += 4;
    354                     else
    355                     {  string [string_length ++] = 0xF0 | (uchar >> 18);
    356                        string [string_length ++] = 0x80 | ((uchar >> 12) & 0x3F);
    357                        string [string_length ++] = 0x80 | ((uchar >> 6) & 0x3F);
    358                        string [string_length ++] = 0x80 | (uchar & 0x3F);
    359                     }
    360 
    361                     break;
    362 
    363                   default:
    364                      string_add (b);
    365                };
    366 
    367                continue;
    368             }
    369 
    370             if (b == '\\')
    371             {
    372                flags |= flag_escaped;
    373                continue;
    374             }
    375 
    376             if (b == '"')
    377             {
    378                if (!state.first_pass)
    379                   string [string_length] = 0;
    380 
    381                flags &= ~ flag_string;
    382                string = 0;
    383 
    384                switch (top->type)
    385                {
    386                   case json_string:
    387 
    388                      top->u.string.length = string_length;
    389                      flags |= flag_next;
    390 
    391                      break;
    392 
    393                   case json_object:
    394 
    395                      if (state.first_pass)
    396                         (*(json_char **) &top->u.object.values) += string_length + 1;
    397                      else
    398                      { 
    399                         top->u.object.values [top->u.object.length].name
    400                            = (json_char *) top->_reserved.object_mem;
    401 
    402                         top->u.object.values [top->u.object.length].name_length
    403                            = string_length;
    404 
    405                         (*(json_char **) &top->_reserved.object_mem) += string_length + 1;
    406                      }
    407 
    408                      flags |= flag_seek_value | flag_need_colon;
    409                      continue;
    410 
    411                   default:
    412                      break;
    413                };
    414             }
    415             else
    416             {
    417                string_add (b);
    418                continue;
    419             }
    420          }
    421 
    422          if (state.settings.settings & json_enable_comments)
    423          {
    424             if (flags & (flag_line_comment | flag_block_comment))
    425             {
    426                if (flags & flag_line_comment)
    427                {
    428                   if (b == '\r' || b == '\n' || !b)
    429                   {
    430                      flags &= ~ flag_line_comment;
    431                      -- i;  /* so null can be reproc'd */
    432                   }
    433 
    434                   continue;
    435                }
    436 
    437                if (flags & flag_block_comment)
    438                {
    439                   if (!b)
    440                   {  sprintf (error, "%d:%d: Unexpected EOF in block comment", cur_line, e_off);
    441                      goto e_failed;
    442                   }
    443 
    444                   if (b == '*' && i < (end - 1) && i [1] == '/')
    445                   {
    446                      flags &= ~ flag_block_comment;
    447                      ++ i;  /* skip closing sequence */
    448                   }
    449 
    450                   continue;
    451                }
    452             }
    453             else if (b == '/')
    454             {
    455                if (! (flags & (flag_seek_value | flag_done)) && top->type != json_object)
    456                {
    457                   sprintf (error, "%d:%d: Comment not allowed here", cur_line, e_off);
    458                   goto e_failed;
    459                }
    460 
    461                if (++ i == end)
    462                {  sprintf (error, "%d:%d: EOF unexpected", cur_line, e_off);
    463                   goto e_failed;
    464                }
    465 
    466                switch (b = *i)
    467                {
    468                   case '/':
    469                      flags |= flag_line_comment;
    470                      continue;
    471 
    472                   case '*':
    473                      flags |= flag_block_comment;
    474                      continue;
    475 
    476                   default:
    477                      sprintf (error, "%d:%d: Unexpected `%c` in comment opening sequence", cur_line, e_off, b);
    478                      goto e_failed;
    479                };
    480             }
    481          }
    482 
    483          if (flags & flag_done)
    484          {
    485             if (!b)
    486                break;
    487 
    488             switch (b)
    489             {
    490                whitespace:
    491                   continue;
    492 
    493                default:
    494                   sprintf (error, "%d:%d: Trailing garbage: `%c`", cur_line, e_off, b);
    495                   goto e_failed;
    496             };
    497          }
    498 
    499          if (flags & flag_seek_value)
    500          {
    501             switch (b)
    502             {
    503                whitespace:
    504                   continue;
    505 
    506                case ']':
    507 
    508                   if (top->type == json_array)
    509                      flags = (flags & ~ (flag_need_comma | flag_seek_value)) | flag_next;
    510                   else
    511                   {  sprintf (error, "%d:%d: Unexpected ]", cur_line, e_off);
    512                      goto e_failed;
    513                   }
    514 
    515                   break;
    516 
    517                default:
    518 
    519                   if (flags & flag_need_comma)
    520                   {
    521                      if (b == ',')
    522                      {  flags &= ~ flag_need_comma;
    523                         continue;
    524                      }
    525                      else
    526                      {  sprintf (error, "%d:%d: Expected , before %c", cur_line, e_off, b);
    527                         goto e_failed;
    528                      }
    529                   }
    530 
    531                   if (flags & flag_need_colon)
    532                   {
    533                      if (b == ':')
    534                      {  flags &= ~ flag_need_colon;
    535                         continue;
    536                      }
    537                      else
    538                      {  sprintf (error, "%d:%d: Expected : before %c", cur_line, e_off, b);
    539                         goto e_failed;
    540                      }
    541                   }
    542 
    543                   flags &= ~ flag_seek_value;
    544 
    545                   switch (b)
    546                   {
    547                      case '{':
    548 
    549                         if (!new_value (&state, &top, &root, &alloc, json_object))
    550                            goto e_alloc_failure;
    551 
    552                         continue;
    553 
    554                      case '[':
    555 
    556                         if (!new_value (&state, &top, &root, &alloc, json_array))
    557                            goto e_alloc_failure;
    558 
    559                         flags |= flag_seek_value;
    560                         continue;
    561 
    562                      case '"':
    563 
    564                         if (!new_value (&state, &top, &root, &alloc, json_string))
    565                            goto e_alloc_failure;
    566 
    567                         flags |= flag_string;
    568 
    569                         string = top->u.string.ptr;
    570                         string_length = 0;
    571 
    572                         continue;
    573 
    574                      case 't':
    575 
    576                         if ((end - i) < 3 || *(++ i) != 'r' || *(++ i) != 'u' || *(++ i) != 'e')
    577                            goto e_unknown_value;
    578 
    579                         if (!new_value (&state, &top, &root, &alloc, json_boolean))
    580                            goto e_alloc_failure;
    581 
    582                         top->u.boolean = 1;
    583 
    584                         flags |= flag_next;
    585                         break;
    586 
    587                      case 'f':
    588 
    589                         if ((end - i) < 4 || *(++ i) != 'a' || *(++ i) != 'l' || *(++ i) != 's' || *(++ i) != 'e')
    590                            goto e_unknown_value;
    591 
    592                         if (!new_value (&state, &top, &root, &alloc, json_boolean))
    593                            goto e_alloc_failure;
    594 
    595                         flags |= flag_next;
    596                         break;
    597 
    598                      case 'n':
    599 
    600                         if ((end - i) < 3 || *(++ i) != 'u' || *(++ i) != 'l' || *(++ i) != 'l')
    601                            goto e_unknown_value;
    602 
    603                         if (!new_value (&state, &top, &root, &alloc, json_null))
    604                            goto e_alloc_failure;
    605 
    606                         flags |= flag_next;
    607                         break;
    608 
    609                      default:
    610 
    611                         if (g_ascii_isdigit (b) || b == '-')
    612                         {
    613                            if (!new_value (&state, &top, &root, &alloc, json_integer))
    614                               goto e_alloc_failure;
    615 
    616                            if (!state.first_pass)
    617                            {
    618                               while (g_ascii_isdigit (b) || b == '+' || b == '-'
    619                                         || b == 'e' || b == 'E' || b == '.')
    620                               {
    621                                  if ( (++ i) == end)
    622                                  {
    623                                     b = 0;
    624                                     break;
    625                                  }
    626 
    627                                  b = *i;
    628                               }
    629 
    630                               flags |= flag_next | flag_reproc;
    631                               break;
    632                            }
    633 
    634                            flags &= ~ (flag_num_negative | flag_num_e |
    635                                         flag_num_e_got_sign | flag_num_e_negative |
    636                                            flag_num_zero);
    637 
    638                            num_digits = 0;
    639                            num_fraction = 0;
    640                            num_e = 0;
    641 
    642                            if (b != '-')
    643                            {
    644                               flags |= flag_reproc;
    645                               break;
    646                            }
    647 
    648                            flags |= flag_num_negative;
    649                            continue;
    650                         }
    651                         else
    652                         {  sprintf (error, "%d:%d: Unexpected %c when seeking value", cur_line, e_off, b);
    653                            goto e_failed;
    654                         }
    655                   };
    656             };
    657          }
    658          else
    659          {
    660             switch (top->type)
    661             {
    662             case json_object:
    663                
    664                switch (b)
    665                {
    666                   whitespace:
    667                      continue;
    668 
    669                   case '"':
    670 
    671                      if (flags & flag_need_comma)
    672                      {
    673                         sprintf (error, "%d:%d: Expected , before \"", cur_line, e_off);
    674                         goto e_failed;
    675                      }
    676 
    677                      flags |= flag_string;
    678 
    679                      string = (json_char *) top->_reserved.object_mem;
    680                      string_length = 0;
    681 
    682                      break;
    683                  
    684                   case '}':
    685 
    686                      flags = (flags & ~ flag_need_comma) | flag_next;
    687                      break;
    688 
    689                   case ',':
    690 
    691                      if (flags & flag_need_comma)
    692                      {
    693                         flags &= ~ flag_need_comma;
    694                         break;
    695                      }
    696 
    697                   default:
    698 
    699                      sprintf (error, "%d:%d: Unexpected `%c` in object", cur_line, e_off, b);
    700                      goto e_failed;
    701                };
    702 
    703                break;
    704 
    705             case json_integer:
    706             case json_double:
    707 
    708                if (g_ascii_isdigit (b))
    709                {
    710                   ++ num_digits;
    711 
    712                   if (top->type == json_integer || flags & flag_num_e)
    713                   {
    714                      if (! (flags & flag_num_e))
    715                      {
    716                         if (flags & flag_num_zero)
    717                         {  sprintf (error, "%d:%d: Unexpected `0` before `%c`", cur_line, e_off, b);
    718                            goto e_failed;
    719                         }
    720 
    721                         if (num_digits == 1 && b == '0')
    722                            flags |= flag_num_zero;
    723                      }
    724                      else
    725                      {
    726                         flags |= flag_num_e_got_sign;
    727                         num_e = (num_e * 10) + (b - '0');
    728                         continue;
    729                      }
    730 
    731                      top->u.integer = (top->u.integer * 10) + (b - '0');
    732                      continue;
    733                   }
    734 
    735                   num_fraction = (num_fraction * 10) + (b - '0');
    736                   continue;
    737                }
    738 
    739                if (b == '+' || b == '-')
    740                {
    741                   if ( (flags & flag_num_e) && !(flags & flag_num_e_got_sign))
    742                   {
    743                      flags |= flag_num_e_got_sign;
    744 
    745                      if (b == '-')
    746                         flags |= flag_num_e_negative;
    747 
    748                      continue;
    749                   }
    750                }
    751                else if (b == '.' && top->type == json_integer)
    752                {
    753                   if (!num_digits)
    754                   {  sprintf (error, "%d:%d: Expected digit before `.`", cur_line, e_off);
    755                      goto e_failed;
    756                   }
    757 
    758                   top->type = json_double;
    759                   top->u.dbl = (double) top->u.integer;
    760 
    761                   num_digits = 0;
    762                   continue;
    763                }
    764 
    765                if (! (flags & flag_num_e))
    766                {
    767                   if (top->type == json_double)
    768                   {
    769                      if (!num_digits)
    770                      {  sprintf (error, "%d:%d: Expected digit after `.`", cur_line, e_off);
    771                         goto e_failed;
    772                      }
    773 
    774                      top->u.dbl += ((double) num_fraction) / (pow (10, (double) num_digits));
    775                   }
    776 
    777                   if (b == 'e' || b == 'E')
    778                   {
    779                      flags |= flag_num_e;
    780 
    781                      if (top->type == json_integer)
    782                      {
    783                         top->type = json_double;
    784                         top->u.dbl = (double) top->u.integer;
    785                      }
    786 
    787                      num_digits = 0;
    788                      flags &= ~ flag_num_zero;
    789 
    790                      continue;
    791                   }
    792                }
    793                else
    794                {
    795                   if (!num_digits)
    796                   {  sprintf (error, "%d:%d: Expected digit after `e`", cur_line, e_off);
    797                      goto e_failed;
    798                   }
    799 
    800                   top->u.dbl *= pow (10, (double) (flags & flag_num_e_negative ? - num_e : num_e));
    801                }
    802 
    803                if (flags & flag_num_negative)
    804                {
    805                   if (top->type == json_integer)
    806                      top->u.integer = - top->u.integer;
    807                   else
    808                      top->u.dbl = - top->u.dbl;
    809                }
    810 
    811                flags |= flag_next | flag_reproc;
    812                break;
    813 
    814             default:
    815                break;
    816             };
    817          }
    818 
    819          if (flags & flag_reproc)
    820          {
    821             flags &= ~ flag_reproc;
    822             -- i;
    823          }
    824 
    825          if (flags & flag_next)
    826          {
    827             flags = (flags & ~ flag_next) | flag_need_comma;
    828 
    829             if (!top->parent)
    830             {
    831                /* root value done */
    832 
    833                flags |= flag_done;
    834                continue;
    835             }
    836 
    837             if (top->parent->type == json_array)
    838                flags |= flag_seek_value;
    839                
    840             if (!state.first_pass)
    841             {
    842                json_value * parent = top->parent;
    843 
    844                switch (parent->type)
    845                {
    846                   case json_object:
    847 
    848                      parent->u.object.values
    849                         [parent->u.object.length].value = top;
    850 
    851                      break;
    852 
    853                   case json_array:
    854 
    855                      parent->u.array.values
    856                            [parent->u.array.length] = top;
    857 
    858                      break;
    859 
    860                   default:
    861                      break;
    862                };
    863             }
    864 
    865             if ( (++ top->parent->u.array.length) > state.uint_max)
    866                goto e_overflow;
    867 
    868             top = top->parent;
    869 
    870             continue;
    871          }
    872       }
    873 
    874       alloc = root;
    875    }
    876 
    877    return root;
    878 
    879 e_unknown_value:
    880 
    881    sprintf (error, "%d:%d: Unknown value", cur_line, e_off);
    882    goto e_failed;
    883 
    884 e_alloc_failure:
    885 
    886    strcpy (error, "Memory allocation failure");
    887    goto e_failed;
    888 
    889 e_overflow:
    890 
    891    sprintf (error, "%d:%d: Too long (caught overflow)", cur_line, e_off);
    892    goto e_failed;
    893 
    894 e_failed:
    895 
    896    if (error_buf)
    897    {
    898       if (*error)
    899          strcpy (error_buf, error);
    900       else
    901          strcpy (error_buf, "Unknown error");
    902    }
    903 
    904    if (state.first_pass)
    905       alloc = root;
    906 
    907    while (alloc)
    908    {
    909       top = alloc->_reserved.next_alloc;
    910       state.settings.mem_free (alloc, state.settings.user_data);
    911       alloc = top;
    912    }
    913 
    914    if (!state.first_pass)
    915       json_value_free_ex (&state.settings, root);
    916 
    917    return 0;
     912        json_settings settings = { 0 };
     913
     914        return json_parse_ex(&settings, json, length, 0);
    918915}
    919916
    920 json_value * json_parse (const json_char * json, size_t length)
     917void json_value_free_ex(json_settings * settings, json_value * value)
    921918{
    922    json_settings settings = { 0 };
    923    return json_parse_ex (&settings, json, length, 0);
     919        json_value * cur_value;
     920
     921        if (!value) {
     922                return;
     923        }
     924
     925        value->parent = 0;
     926
     927        while (value) {
     928                switch (value->type) {
     929                case json_array:
     930
     931                        if (!value->u.array.length) {
     932                                settings->mem_free(value->u.array.values, settings->user_data);
     933                                break;
     934                        }
     935
     936                        value = value->u.array.values [--value->u.array.length];
     937                        continue;
     938
     939                case json_object:
     940
     941                        if (!value->u.object.length) {
     942                                settings->mem_free(value->u.object.values, settings->user_data);
     943                                break;
     944                        }
     945
     946                        value = value->u.object.values [--value->u.object.length].value;
     947                        continue;
     948
     949                case json_string:
     950
     951                        settings->mem_free(value->u.string.ptr, settings->user_data);
     952                        break;
     953
     954                default:
     955                        break;
     956                }
     957                ;
     958
     959                cur_value = value;
     960                value = value->parent;
     961                settings->mem_free(cur_value, settings->user_data);
     962        }
    924963}
    925964
    926 void json_value_free_ex (json_settings * settings, json_value * value)
     965void json_value_free(json_value * value)
    927966{
    928    json_value * cur_value;
    929 
    930    if (!value)
    931       return;
    932 
    933    value->parent = 0;
    934 
    935    while (value)
    936    {
    937       switch (value->type)
    938       {
    939          case json_array:
    940 
    941             if (!value->u.array.length)
    942             {
    943                settings->mem_free (value->u.array.values, settings->user_data);
    944                break;
    945             }
    946 
    947             value = value->u.array.values [-- value->u.array.length];
    948             continue;
    949 
    950          case json_object:
    951 
    952             if (!value->u.object.length)
    953             {
    954                settings->mem_free (value->u.object.values, settings->user_data);
    955                break;
    956             }
    957 
    958             value = value->u.object.values [-- value->u.object.length].value;
    959             continue;
    960 
    961          case json_string:
    962 
    963             settings->mem_free (value->u.string.ptr, settings->user_data);
    964             break;
    965 
    966          default:
    967             break;
    968       };
    969 
    970       cur_value = value;
    971       value = value->parent;
    972       settings->mem_free (cur_value, settings->user_data);
    973    }
     967        json_settings settings = { 0 };
     968
     969        settings.mem_free = default_free;
     970        json_value_free_ex(&settings, value);
    974971}
    975972
    976 void json_value_free (json_value * value)
    977 {
    978    json_settings settings = { 0 };
    979    settings.mem_free = default_free;
    980    json_value_free_ex (&settings, value);
    981 }
    982 
Note: See TracChangeset for help on using the changeset viewer.