Imported Upstream version 0.10
[platform/upstream/json-c.git] / json_tokener.c
1 /*
2  * $Id: json_tokener.c,v 1.20 2006/07/25 03:24:50 mclark Exp $
3  *
4  * Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd.
5  * Michael Clark <michael@metaparadigm.com>
6  *
7  * This library is free software; you can redistribute it and/or modify
8  * it under the terms of the MIT license. See COPYING for details.
9  *
10  *
11  * Copyright (c) 2008-2009 Yahoo! Inc.  All rights reserved.
12  * The copyrights to the contents of this file are licensed under the MIT License
13  * (http://www.opensource.org/licenses/mit-license.php)
14  */
15
16 #include "config.h"
17
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <stddef.h>
21 #include <ctype.h>
22 #include <string.h>
23 #include <limits.h>
24
25 #include "bits.h"
26 #include "debug.h"
27 #include "printbuf.h"
28 #include "arraylist.h"
29 #include "json_inttypes.h"
30 #include "json_object.h"
31 #include "json_tokener.h"
32 #include "json_util.h"
33
34 #if !HAVE_STRNCASECMP && defined(_MSC_VER)
35   /* MSC has the version as _strnicmp */
36 # define strncasecmp _strnicmp
37 #elif !HAVE_STRNCASECMP
38 # error You do not have strncasecmp on your system.
39 #endif /* HAVE_STRNCASECMP */
40
41
42 static const char* json_null_str = "null";
43 static const char* json_true_str = "true";
44 static const char* json_false_str = "false";
45
46 // XXX after v0.10 this array will become static:
47 const char* json_tokener_errors[] = {
48   "success",
49   "continue",
50   "nesting too deep",
51   "unexpected end of data",
52   "unexpected character",
53   "null expected",
54   "boolean expected",
55   "number expected",
56   "array value separator ',' expected",
57   "quoted object property name expected",
58   "object property name separator ':' expected",
59   "object value separator ',' expected",
60   "invalid string sequence",
61   "expected comment",
62 };
63
64 const char *json_tokener_error_desc(enum json_tokener_error jerr)
65 {
66         if (jerr < 0 || jerr > sizeof(json_tokener_errors))
67                 return "Unknown error, invalid json_tokener_error value passed to json_tokener_error_desc()";
68         return json_tokener_errors[jerr];
69 }
70
71 enum json_tokener_error json_tokener_get_error(json_tokener *tok)
72 {
73         return tok->err;
74 }
75
76 /* Stuff for decoding unicode sequences */
77 #define IS_HIGH_SURROGATE(uc) (((uc) & 0xFC00) == 0xD800)
78 #define IS_LOW_SURROGATE(uc)  (((uc) & 0xFC00) == 0xDC00)
79 #define DECODE_SURROGATE_PAIR(hi,lo) ((((hi) & 0x3FF) << 10) + ((lo) & 0x3FF) + 0x10000)
80 static unsigned char utf8_replacement_char[3] = { 0xEF, 0xBF, 0xBD };
81
82
83 struct json_tokener* json_tokener_new(void)
84 {
85   struct json_tokener *tok;
86
87   tok = (struct json_tokener*)calloc(1, sizeof(struct json_tokener));
88   if (!tok) return NULL;
89   tok->pb = printbuf_new();
90   json_tokener_reset(tok);
91   return tok;
92 }
93
94 void json_tokener_free(struct json_tokener *tok)
95 {
96   json_tokener_reset(tok);
97   if(tok) printbuf_free(tok->pb);
98   free(tok);
99 }
100
101 static void json_tokener_reset_level(struct json_tokener *tok, int depth)
102 {
103   tok->stack[depth].state = json_tokener_state_eatws;
104   tok->stack[depth].saved_state = json_tokener_state_start;
105   json_object_put(tok->stack[depth].current);
106   tok->stack[depth].current = NULL;
107   free(tok->stack[depth].obj_field_name);
108   tok->stack[depth].obj_field_name = NULL;
109 }
110
111 void json_tokener_reset(struct json_tokener *tok)
112 {
113   int i;
114   if (!tok)
115     return;
116
117   for(i = tok->depth; i >= 0; i--)
118     json_tokener_reset_level(tok, i);
119   tok->depth = 0;
120   tok->err = json_tokener_success;
121 }
122
123 struct json_object* json_tokener_parse(const char *str)
124 {
125     enum json_tokener_error jerr_ignored;
126     struct json_object* obj;
127     obj = json_tokener_parse_verbose(str, &jerr_ignored);
128     return obj;
129 }
130
131 struct json_object* json_tokener_parse_verbose(const char *str, enum json_tokener_error *error)
132 {
133     struct json_tokener* tok;
134     struct json_object* obj;
135
136     tok = json_tokener_new();
137     if (!tok)
138       return NULL;
139     obj = json_tokener_parse_ex(tok, str, -1);
140     *error = tok->err;
141     if(tok->err != json_tokener_success) {
142                 if (obj != NULL)
143                         json_object_put(obj);
144         obj = NULL;
145     }
146
147     json_tokener_free(tok);
148     return obj;
149 }
150
151
152 #if !HAVE_STRNDUP
153 /* CAW: compliant version of strndup() */
154 char* strndup(const char* str, size_t n)
155 {
156   if(str) {
157     size_t len = strlen(str);
158     size_t nn = json_min(len,n);
159     char* s = (char*)malloc(sizeof(char) * (nn + 1));
160
161     if(s) {
162       memcpy(s, str, nn);
163       s[nn] = '\0';
164     }
165
166     return s;
167   }
168
169   return NULL;
170 }
171 #endif
172
173
174 #define state  tok->stack[tok->depth].state
175 #define saved_state  tok->stack[tok->depth].saved_state
176 #define current tok->stack[tok->depth].current
177 #define obj_field_name tok->stack[tok->depth].obj_field_name
178
179 /* Optimization:
180  * json_tokener_parse_ex() consumed a lot of CPU in its main loop,
181  * iterating character-by character.  A large performance boost is
182  * achieved by using tighter loops to locally handle units such as
183  * comments and strings.  Loops that handle an entire token within 
184  * their scope also gather entire strings and pass them to 
185  * printbuf_memappend() in a single call, rather than calling
186  * printbuf_memappend() one char at a time.
187  *
188  * POP_CHAR() and ADVANCE_CHAR() macros are used for code that is
189  * common to both the main loop and the tighter loops.
190  */
191
192 /* POP_CHAR(dest, tok) macro:
193  *   Not really a pop()...peeks at the current char and stores it in dest.
194  *   Returns 1 on success, sets tok->err and returns 0 if no more chars.
195  *   Implicit inputs:  str, len vars
196  */
197 #define POP_CHAR(dest, tok)                                                  \
198   (((tok)->char_offset == len) ?                                          \
199    (((tok)->depth == 0 && state == json_tokener_state_eatws && saved_state == json_tokener_state_finish) ? \
200     (((tok)->err = json_tokener_success), 0)                              \
201     :                                                                   \
202     (((tok)->err = json_tokener_continue), 0)                             \
203     ) :                                                                 \
204    (((dest) = *str), 1)                                                 \
205    )
206  
207 /* ADVANCE_CHAR() macro:
208  *   Incrementes str & tok->char_offset.
209  *   For convenience of existing conditionals, returns the old value of c (0 on eof)
210  *   Implicit inputs:  c var
211  */
212 #define ADVANCE_CHAR(str, tok) \
213   ( ++(str), ((tok)->char_offset)++, c)
214
215
216 /* End optimization macro defs */
217
218
219 struct json_object* json_tokener_parse_ex(struct json_tokener *tok,
220                                           const char *str, int len)
221 {
222   struct json_object *obj = NULL;
223   char c = '\1';
224
225   tok->char_offset = 0;
226   tok->err = json_tokener_success;
227
228   while (POP_CHAR(c, tok)) {
229
230   redo_char:
231     switch(state) {
232
233     case json_tokener_state_eatws:
234       /* Advance until we change state */
235       while (isspace((int)c)) {
236         if ((!ADVANCE_CHAR(str, tok)) || (!POP_CHAR(c, tok)))
237           goto out;
238       }
239       if(c == '/') {
240         printbuf_reset(tok->pb);
241         printbuf_memappend_fast(tok->pb, &c, 1);
242         state = json_tokener_state_comment_start;
243       } else {
244         state = saved_state;
245         goto redo_char;
246       }
247       break;
248
249     case json_tokener_state_start:
250       switch(c) {
251       case '{':
252         state = json_tokener_state_eatws;
253         saved_state = json_tokener_state_object_field_start;
254         current = json_object_new_object();
255         break;
256       case '[':
257         state = json_tokener_state_eatws;
258         saved_state = json_tokener_state_array;
259         current = json_object_new_array();
260         break;
261       case 'N':
262       case 'n':
263         state = json_tokener_state_null;
264         printbuf_reset(tok->pb);
265         tok->st_pos = 0;
266         goto redo_char;
267       case '"':
268       case '\'':
269         state = json_tokener_state_string;
270         printbuf_reset(tok->pb);
271         tok->quote_char = c;
272         break;
273       case 'T':
274       case 't':
275       case 'F':
276       case 'f':
277         state = json_tokener_state_boolean;
278         printbuf_reset(tok->pb);
279         tok->st_pos = 0;
280         goto redo_char;
281 #if defined(__GNUC__)
282           case '0' ... '9':
283 #else
284           case '0':
285       case '1':
286       case '2':
287       case '3':
288       case '4':
289       case '5':
290       case '6':
291       case '7':
292       case '8':
293       case '9':
294 #endif
295       case '-':
296         state = json_tokener_state_number;
297         printbuf_reset(tok->pb);
298         tok->is_double = 0;
299         goto redo_char;
300       default:
301         tok->err = json_tokener_error_parse_unexpected;
302         goto out;
303       }
304       break;
305
306     case json_tokener_state_finish:
307       if(tok->depth == 0) goto out;
308       obj = json_object_get(current);
309       json_tokener_reset_level(tok, tok->depth);
310       tok->depth--;
311       goto redo_char;
312
313     case json_tokener_state_null:
314       printbuf_memappend_fast(tok->pb, &c, 1);
315       if(strncasecmp(json_null_str, tok->pb->buf,
316                      json_min(tok->st_pos+1, strlen(json_null_str))) == 0) {
317         if(tok->st_pos == strlen(json_null_str)) {
318           current = NULL;
319           saved_state = json_tokener_state_finish;
320           state = json_tokener_state_eatws;
321           goto redo_char;
322         }
323       } else {
324         tok->err = json_tokener_error_parse_null;
325         goto out;
326       }
327       tok->st_pos++;
328       break;
329
330     case json_tokener_state_comment_start:
331       if(c == '*') {
332         state = json_tokener_state_comment;
333       } else if(c == '/') {
334         state = json_tokener_state_comment_eol;
335       } else {
336         tok->err = json_tokener_error_parse_comment;
337         goto out;
338       }
339       printbuf_memappend_fast(tok->pb, &c, 1);
340       break;
341
342     case json_tokener_state_comment:
343               {
344           /* Advance until we change state */
345           const char *case_start = str;
346           while(c != '*') {
347             if (!ADVANCE_CHAR(str, tok) || !POP_CHAR(c, tok)) {
348               printbuf_memappend_fast(tok->pb, case_start, str-case_start);
349               goto out;
350             } 
351           }
352           printbuf_memappend_fast(tok->pb, case_start, 1+str-case_start);
353           state = json_tokener_state_comment_end;
354         }
355             break;
356
357     case json_tokener_state_comment_eol:
358       {
359         /* Advance until we change state */
360         const char *case_start = str;
361         while(c != '\n') {
362           if (!ADVANCE_CHAR(str, tok) || !POP_CHAR(c, tok)) {
363             printbuf_memappend_fast(tok->pb, case_start, str-case_start);
364             goto out;
365           }
366         }
367         printbuf_memappend_fast(tok->pb, case_start, str-case_start);
368         MC_DEBUG("json_tokener_comment: %s\n", tok->pb->buf);
369         state = json_tokener_state_eatws;
370       }
371       break;
372
373     case json_tokener_state_comment_end:
374       printbuf_memappend_fast(tok->pb, &c, 1);
375       if(c == '/') {
376         MC_DEBUG("json_tokener_comment: %s\n", tok->pb->buf);
377         state = json_tokener_state_eatws;
378       } else {
379         state = json_tokener_state_comment;
380       }
381       break;
382
383     case json_tokener_state_string:
384       {
385         /* Advance until we change state */
386         const char *case_start = str;
387         while(1) {
388           if(c == tok->quote_char) {
389             printbuf_memappend_fast(tok->pb, case_start, str-case_start);
390             current = json_object_new_string(tok->pb->buf);
391             saved_state = json_tokener_state_finish;
392             state = json_tokener_state_eatws;
393             break;
394           } else if(c == '\\') {
395             printbuf_memappend_fast(tok->pb, case_start, str-case_start);
396             saved_state = json_tokener_state_string;
397             state = json_tokener_state_string_escape;
398             break;
399           }
400           if (!ADVANCE_CHAR(str, tok) || !POP_CHAR(c, tok)) {
401             printbuf_memappend_fast(tok->pb, case_start, str-case_start);
402             goto out;
403           }
404         }
405       }
406       break;
407
408     case json_tokener_state_string_escape:
409       switch(c) {
410       case '"':
411       case '\\':
412       case '/':
413         printbuf_memappend_fast(tok->pb, &c, 1);
414         state = saved_state;
415         break;
416       case 'b':
417       case 'n':
418       case 'r':
419       case 't':
420         if(c == 'b') printbuf_memappend_fast(tok->pb, "\b", 1);
421         else if(c == 'n') printbuf_memappend_fast(tok->pb, "\n", 1);
422         else if(c == 'r') printbuf_memappend_fast(tok->pb, "\r", 1);
423         else if(c == 't') printbuf_memappend_fast(tok->pb, "\t", 1);
424         state = saved_state;
425         break;
426       case 'u':
427         tok->ucs_char = 0;
428         tok->st_pos = 0;
429         state = json_tokener_state_escape_unicode;
430         break;
431       default:
432         tok->err = json_tokener_error_parse_string;
433         goto out;
434       }
435       break;
436
437     case json_tokener_state_escape_unicode:
438         {
439           unsigned int got_hi_surrogate = 0;
440
441           /* Handle a 4-byte sequence, or two sequences if a surrogate pair */
442           while(1) {
443             if(strchr(json_hex_chars, c)) {
444               tok->ucs_char += ((unsigned int)hexdigit(c) << ((3-tok->st_pos++)*4));
445               if(tok->st_pos == 4) {
446                 unsigned char unescaped_utf[4];
447
448                 if (got_hi_surrogate) {
449                   if (IS_LOW_SURROGATE(tok->ucs_char)) {
450                     /* Recalculate the ucs_char, then fall thru to process normally */
451                     tok->ucs_char = DECODE_SURROGATE_PAIR(got_hi_surrogate, tok->ucs_char);
452                   } else {
453                     /* Hi surrogate was not followed by a low surrogate */
454                     /* Replace the hi and process the rest normally */
455                     printbuf_memappend_fast(tok->pb, (char*)utf8_replacement_char, 3);
456                   }
457                   got_hi_surrogate = 0;
458                 }
459
460                 if (tok->ucs_char < 0x80) {
461                   unescaped_utf[0] = tok->ucs_char;
462                   printbuf_memappend_fast(tok->pb, (char*)unescaped_utf, 1);
463                 } else if (tok->ucs_char < 0x800) {
464                   unescaped_utf[0] = 0xc0 | (tok->ucs_char >> 6);
465                   unescaped_utf[1] = 0x80 | (tok->ucs_char & 0x3f);
466                   printbuf_memappend_fast(tok->pb, (char*)unescaped_utf, 2);
467                 } else if (IS_HIGH_SURROGATE(tok->ucs_char)) {
468                   /* Got a high surrogate.  Remember it and look for the
469                    * the beginning of another sequence, which should be the
470                    * low surrogate.
471                    */
472                   got_hi_surrogate = tok->ucs_char;
473                   /* Not at end, and the next two chars should be "\u" */
474                   if ((tok->char_offset+1 != len) &&
475                       (tok->char_offset+2 != len) &&
476                       (str[1] == '\\') &&
477                       (str[2] == 'u'))
478                   {
479                     ADVANCE_CHAR(str, tok);
480                     ADVANCE_CHAR(str, tok);
481
482                     /* Advance to the first char of the next sequence and
483                      * continue processing with the next sequence.
484                      */
485                     if (!ADVANCE_CHAR(str, tok) || !POP_CHAR(c, tok)) {
486                       printbuf_memappend_fast(tok->pb, (char*)utf8_replacement_char, 3);
487                       goto out;
488                     }
489                     tok->ucs_char = 0;
490                     tok->st_pos = 0;
491                     continue; /* other json_tokener_state_escape_unicode */
492                   } else {
493                     /* Got a high surrogate without another sequence following
494                      * it.  Put a replacement char in for the hi surrogate
495                      * and pretend we finished.
496                      */
497                     printbuf_memappend_fast(tok->pb, (char*)utf8_replacement_char, 3);
498                   }
499                 } else if (IS_LOW_SURROGATE(tok->ucs_char)) {
500                   /* Got a low surrogate not preceded by a high */
501                   printbuf_memappend_fast(tok->pb, (char*)utf8_replacement_char, 3);
502                 } else if (tok->ucs_char < 0x10000) {
503                   unescaped_utf[0] = 0xe0 | (tok->ucs_char >> 12);
504                   unescaped_utf[1] = 0x80 | ((tok->ucs_char >> 6) & 0x3f);
505                   unescaped_utf[2] = 0x80 | (tok->ucs_char & 0x3f);
506                   printbuf_memappend_fast(tok->pb, (char*)unescaped_utf, 3);
507                 } else if (tok->ucs_char < 0x110000) {
508                   unescaped_utf[0] = 0xf0 | ((tok->ucs_char >> 18) & 0x07);
509                   unescaped_utf[1] = 0x80 | ((tok->ucs_char >> 12) & 0x3f);
510                   unescaped_utf[2] = 0x80 | ((tok->ucs_char >> 6) & 0x3f);
511                   unescaped_utf[3] = 0x80 | (tok->ucs_char & 0x3f);
512                   printbuf_memappend_fast(tok->pb, (char*)unescaped_utf, 4);
513                 } else {
514                   /* Don't know what we got--insert the replacement char */
515                   printbuf_memappend_fast(tok->pb, (char*)utf8_replacement_char, 3);
516                 }
517                 state = saved_state;
518                 break;
519               }
520             } else {
521               tok->err = json_tokener_error_parse_string;
522               goto out;
523             }
524           if (!ADVANCE_CHAR(str, tok) || !POP_CHAR(c, tok)) {
525             if (got_hi_surrogate) /* Clean up any pending chars */
526               printbuf_memappend_fast(tok->pb, (char*)utf8_replacement_char, 3);
527             goto out;
528           }
529         }
530       }
531       break;
532
533     case json_tokener_state_boolean:
534       printbuf_memappend_fast(tok->pb, &c, 1);
535       if(strncasecmp(json_true_str, tok->pb->buf,
536                      json_min(tok->st_pos+1, strlen(json_true_str))) == 0) {
537         if(tok->st_pos == strlen(json_true_str)) {
538           current = json_object_new_boolean(1);
539           saved_state = json_tokener_state_finish;
540           state = json_tokener_state_eatws;
541           goto redo_char;
542         }
543       } else if(strncasecmp(json_false_str, tok->pb->buf,
544                             json_min(tok->st_pos+1, strlen(json_false_str))) == 0) {
545         if(tok->st_pos == strlen(json_false_str)) {
546           current = json_object_new_boolean(0);
547           saved_state = json_tokener_state_finish;
548           state = json_tokener_state_eatws;
549           goto redo_char;
550         }
551       } else {
552         tok->err = json_tokener_error_parse_boolean;
553         goto out;
554       }
555       tok->st_pos++;
556       break;
557
558     case json_tokener_state_number:
559       {
560         /* Advance until we change state */
561         const char *case_start = str;
562         int case_len=0;
563         while(c && strchr(json_number_chars, c)) {
564           ++case_len;
565           if(c == '.' || c == 'e' || c == 'E')
566             tok->is_double = 1;
567           if (!ADVANCE_CHAR(str, tok) || !POP_CHAR(c, tok)) {
568             printbuf_memappend_fast(tok->pb, case_start, case_len);
569             goto out;
570           }
571         }
572         if (case_len>0)
573           printbuf_memappend_fast(tok->pb, case_start, case_len);
574       }
575       {
576         int64_t num64;
577         double  numd;
578         if (!tok->is_double && json_parse_int64(tok->pb->buf, &num64) == 0) {
579                 current = json_object_new_int64(num64);
580         } else if(tok->is_double && sscanf(tok->pb->buf, "%lf", &numd) == 1) {
581           current = json_object_new_double(numd);
582         } else {
583           tok->err = json_tokener_error_parse_number;
584           goto out;
585         }
586         saved_state = json_tokener_state_finish;
587         state = json_tokener_state_eatws;
588         goto redo_char;
589       }
590       break;
591
592     case json_tokener_state_array:
593       if(c == ']') {
594         saved_state = json_tokener_state_finish;
595         state = json_tokener_state_eatws;
596       } else {
597         if(tok->depth >= JSON_TOKENER_MAX_DEPTH-1) {
598           tok->err = json_tokener_error_depth;
599           goto out;
600         }
601         state = json_tokener_state_array_add;
602         tok->depth++;
603         json_tokener_reset_level(tok, tok->depth);
604         goto redo_char;
605       }
606       break;
607
608     case json_tokener_state_array_add:
609       json_object_array_add(current, obj);
610       saved_state = json_tokener_state_array_sep;
611       state = json_tokener_state_eatws;
612       goto redo_char;
613
614     case json_tokener_state_array_sep:
615       if(c == ']') {
616         saved_state = json_tokener_state_finish;
617         state = json_tokener_state_eatws;
618       } else if(c == ',') {
619         saved_state = json_tokener_state_array;
620         state = json_tokener_state_eatws;
621       } else {
622         tok->err = json_tokener_error_parse_array;
623         goto out;
624       }
625       break;
626
627     case json_tokener_state_object_field_start:
628       if(c == '}') {
629         saved_state = json_tokener_state_finish;
630         state = json_tokener_state_eatws;
631       } else if (c == '"' || c == '\'') {
632         tok->quote_char = c;
633         printbuf_reset(tok->pb);
634         state = json_tokener_state_object_field;
635       } else {
636         tok->err = json_tokener_error_parse_object_key_name;
637         goto out;
638       }
639       break;
640
641     case json_tokener_state_object_field:
642       {
643         /* Advance until we change state */
644         const char *case_start = str;
645         while(1) {
646           if(c == tok->quote_char) {
647             printbuf_memappend_fast(tok->pb, case_start, str-case_start);
648             obj_field_name = strdup(tok->pb->buf);
649             saved_state = json_tokener_state_object_field_end;
650             state = json_tokener_state_eatws;
651             break;
652           } else if(c == '\\') {
653             printbuf_memappend_fast(tok->pb, case_start, str-case_start);
654             saved_state = json_tokener_state_object_field;
655             state = json_tokener_state_string_escape;
656             break;
657           }
658           if (!ADVANCE_CHAR(str, tok) || !POP_CHAR(c, tok)) {
659             printbuf_memappend_fast(tok->pb, case_start, str-case_start);
660             goto out;
661           }
662         }
663       }
664       break;
665
666     case json_tokener_state_object_field_end:
667       if(c == ':') {
668         saved_state = json_tokener_state_object_value;
669         state = json_tokener_state_eatws;
670       } else {
671         tok->err = json_tokener_error_parse_object_key_sep;
672         goto out;
673       }
674       break;
675
676     case json_tokener_state_object_value:
677       if(tok->depth >= JSON_TOKENER_MAX_DEPTH-1) {
678         tok->err = json_tokener_error_depth;
679         goto out;
680       }
681       state = json_tokener_state_object_value_add;
682       tok->depth++;
683       json_tokener_reset_level(tok, tok->depth);
684       goto redo_char;
685
686     case json_tokener_state_object_value_add:
687       json_object_object_add(current, obj_field_name, obj);
688       free(obj_field_name);
689       obj_field_name = NULL;
690       saved_state = json_tokener_state_object_sep;
691       state = json_tokener_state_eatws;
692       goto redo_char;
693
694     case json_tokener_state_object_sep:
695       if(c == '}') {
696         saved_state = json_tokener_state_finish;
697         state = json_tokener_state_eatws;
698       } else if(c == ',') {
699         saved_state = json_tokener_state_object_field_start;
700         state = json_tokener_state_eatws;
701       } else {
702         tok->err = json_tokener_error_parse_object_value_sep;
703         goto out;
704       }
705       break;
706
707     }
708     if (!ADVANCE_CHAR(str, tok))
709       goto out;
710   } /* while(POP_CHAR) */
711
712  out:
713   if (!c) { /* We hit an eof char (0) */
714     if(state != json_tokener_state_finish &&
715        saved_state != json_tokener_state_finish)
716       tok->err = json_tokener_error_parse_eof;
717   }
718
719   if (tok->err == json_tokener_success) 
720   {
721     json_object *ret = json_object_get(current);
722         int ii;
723
724         /* Partially reset, so we parse additional objects on subsequent calls. */
725     for(ii = tok->depth; ii >= 0; ii--)
726       json_tokener_reset_level(tok, ii);
727     return ret;
728   }
729
730   MC_DEBUG("json_tokener_parse_ex: error %s at offset %d\n",
731            json_tokener_errors[tok->err], tok->char_offset);
732   return NULL;
733 }