json-maglev- 1.5.4 → 1.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. data/CHANGES +11 -1
  2. data/Rakefile +14 -12
  3. data/VERSION +1 -1
  4. data/ext/json/ext/generator/extconf.rb +0 -7
  5. data/ext/json/ext/generator/generator.c +55 -10
  6. data/ext/json/ext/generator/generator.h +7 -5
  7. data/ext/json/ext/parser/extconf.rb +0 -3
  8. data/ext/json/ext/parser/parser.c +418 -207
  9. data/ext/json/ext/parser/parser.h +11 -10
  10. data/ext/json/ext/parser/parser.rl +178 -104
  11. data/install.rb +1 -8
  12. data/java/src/json/ext/Generator.java +3 -3
  13. data/java/src/json/ext/GeneratorMethods.java +2 -2
  14. data/java/src/json/ext/GeneratorService.java +1 -1
  15. data/java/src/json/ext/GeneratorState.java +41 -13
  16. data/java/src/json/ext/OptionsReader.java +1 -1
  17. data/java/src/json/ext/Parser.java +382 -107
  18. data/java/src/json/ext/Parser.rl +97 -28
  19. data/java/src/json/ext/ParserService.java +1 -1
  20. data/java/src/json/ext/Utils.java +1 -1
  21. data/json.gemspec +5 -6
  22. data/json_pure.gemspec +5 -9
  23. data/lib/json.rb +4 -4
  24. data/lib/json/add/complex.rb +22 -0
  25. data/lib/json/add/core.rb +9 -241
  26. data/lib/json/add/date.rb +34 -0
  27. data/lib/json/add/date_time.rb +50 -0
  28. data/lib/json/add/exception.rb +31 -0
  29. data/lib/json/add/range.rb +29 -0
  30. data/lib/json/add/rational.rb +22 -0
  31. data/lib/json/add/regexp.rb +30 -0
  32. data/lib/json/add/struct.rb +30 -0
  33. data/lib/json/add/symbol.rb +25 -0
  34. data/lib/json/add/time.rb +35 -0
  35. data/lib/json/common.rb +47 -35
  36. data/lib/json/ext.rb +2 -15
  37. data/lib/json/pure/generator.rb +17 -2
  38. data/lib/json/pure/parser.rb +89 -55
  39. data/lib/json/version.rb +1 -1
  40. data/tests/test_json.rb +36 -0
  41. data/tests/test_json_addition.rb +8 -1
  42. data/tests/test_json_generate.rb +34 -1
  43. data/tools/server.rb +1 -0
  44. metadata +20 -24
  45. data/bin/edit_json.rb +0 -9
  46. data/bin/prettify_json.rb +0 -48
  47. data/lib/json/Array.xpm +0 -21
  48. data/lib/json/FalseClass.xpm +0 -21
  49. data/lib/json/Hash.xpm +0 -21
  50. data/lib/json/Key.xpm +0 -73
  51. data/lib/json/NilClass.xpm +0 -21
  52. data/lib/json/Numeric.xpm +0 -28
  53. data/lib/json/String.xpm +0 -96
  54. data/lib/json/TrueClass.xpm +0 -21
  55. data/lib/json/add/rails.rb +0 -8
  56. data/lib/json/editor.rb +0 -1369
  57. data/lib/json/json.xpm +0 -1499
@@ -3,7 +3,7 @@
3
3
 
4
4
  #include "ruby.h"
5
5
 
6
- #if HAVE_RE_H
6
+ #ifndef HAVE_RUBY_RE_H
7
7
  #include "re.h"
8
8
  #endif
9
9
 
@@ -36,15 +36,16 @@ typedef unsigned char UTF8; /* typically 8 bits */
36
36
  typedef struct JSON_ParserStruct {
37
37
  VALUE dwrapped_parser;
38
38
  VALUE Vsource;
39
- const char *source;
39
+ char *source;
40
40
  long len;
41
- const char *memo;
41
+ char *memo;
42
42
  VALUE create_id;
43
43
  int max_nesting;
44
44
  int current_nesting;
45
45
  int allow_nan;
46
46
  int parsing_name;
47
47
  int symbolize_names;
48
+ int quirks_mode;
48
49
  VALUE object_class;
49
50
  VALUE array_class;
50
51
  int create_additions;
@@ -63,13 +64,13 @@ typedef struct JSON_ParserStruct {
63
64
 
64
65
  static UTF32 unescape_unicode(const unsigned char *p);
65
66
  static int convert_UTF32_to_UTF8(char *buf, UTF32 ch);
66
- static const char *JSON_parse_object(JSON_Parser *json, const char *p, const char *pe, VALUE *result);
67
- static const char *JSON_parse_value(JSON_Parser *json, const char *p, const char *pe, VALUE *result);
68
- static const char *JSON_parse_integer(JSON_Parser *json, const char *p, const char *pe, VALUE *result);
69
- static const char *JSON_parse_float(JSON_Parser *json, const char *p, const char *pe, VALUE *result);
70
- static const char *JSON_parse_array(JSON_Parser *json, const char *p, const char *pe, VALUE *result);
71
- static VALUE json_string_unescape(VALUE result, const char *string, const char *stringEnd);
72
- static const char *JSON_parse_string(JSON_Parser *json, const char *p, const char *pe, VALUE *result);
67
+ static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *result);
68
+ static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *result);
69
+ static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *result);
70
+ static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *result);
71
+ static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *result);
72
+ static VALUE json_string_unescape(VALUE result, char *string, char *stringEnd);
73
+ static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *result);
73
74
  static VALUE convert_encoding(VALUE source);
74
75
  static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self);
75
76
  static VALUE cParser_parse(VALUE self);
@@ -76,8 +76,9 @@ static VALUE mJSON, mExt, cParser, eParserError, eNestingError;
76
76
  static VALUE CNaN, CInfinity, CMinusInfinity;
77
77
 
78
78
  static ID i_json_creatable_p, i_json_create, i_create_id, i_create_additions,
79
- i_chr, i_max_nesting, i_allow_nan, i_symbolize_names, i_object_class,
80
- i_array_class, i_key_p, i_deep_const_get, i_match, i_match_string, i_aset, i_leftshift;
79
+ i_chr, i_max_nesting, i_allow_nan, i_symbolize_names, i_quirks_mode,
80
+ i_object_class, i_array_class, i_key_p, i_deep_const_get, i_match,
81
+ i_match_string, i_aset, i_leftshift;
81
82
 
82
83
  %%{
83
84
  machine JSON_common;
@@ -115,7 +116,7 @@ static ID i_json_creatable_p, i_json_create, i_create_id, i_create_additions,
115
116
 
116
117
  action parse_value {
117
118
  VALUE v = Qnil;
118
- const char *np = JSON_parse_value(json, fpc, pe, &v);
119
+ char *np = JSON_parse_value(json, fpc, pe, &v);
119
120
  if (np == NULL) {
120
121
  fhold; fbreak;
121
122
  } else {
@@ -129,7 +130,7 @@ static ID i_json_creatable_p, i_json_create, i_create_id, i_create_additions,
129
130
  }
130
131
 
131
132
  action parse_name {
132
- const char *np;
133
+ char *np;
133
134
  json->parsing_name = 1;
134
135
  np = JSON_parse_string(json, fpc, pe, &last_name);
135
136
  json->parsing_name = 0;
@@ -138,16 +139,17 @@ static ID i_json_creatable_p, i_json_create, i_create_id, i_create_additions,
138
139
 
139
140
  action exit { fhold; fbreak; }
140
141
 
141
- a_pair = ignore* begin_name >parse_name
142
- ignore* name_separator ignore*
143
- begin_value >parse_value;
142
+ pair = ignore* begin_name >parse_name ignore* name_separator ignore* begin_value >parse_value;
143
+ next_pair = ignore* value_separator pair;
144
144
 
145
- main := begin_object
146
- (a_pair (ignore* value_separator a_pair)*)?
147
- ignore* end_object @exit;
145
+ main := (
146
+ begin_object
147
+ (pair (next_pair)*)? ignore*
148
+ end_object
149
+ ) @exit;
148
150
  }%%
149
151
 
150
- static const char *JSON_parse_object(JSON_Parser *json, const char *p, const char *pe, VALUE *result)
152
+ static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *result)
151
153
  {
152
154
  int cs = EVIL;
153
155
  VALUE last_name = Qnil;
@@ -178,6 +180,7 @@ static const char *JSON_parse_object(JSON_Parser *json, const char *p, const cha
178
180
  }
179
181
  }
180
182
 
183
+
181
184
  %%{
182
185
  machine JSON_value;
183
186
  include JSON_common;
@@ -208,13 +211,13 @@ static const char *JSON_parse_object(JSON_Parser *json, const char *p, const cha
208
211
  }
209
212
  }
210
213
  action parse_string {
211
- const char *np = JSON_parse_string(json, fpc, pe, result);
214
+ char *np = JSON_parse_string(json, fpc, pe, result);
212
215
  if (np == NULL) { fhold; fbreak; } else fexec np;
213
216
  }
214
217
 
215
218
  action parse_number {
216
- const char *np;
217
- if(pe > fpc + 9 && !strncmp(MinusInfinity, fpc, 9)) {
219
+ char *np;
220
+ if(pe > fpc + 9 - json->quirks_mode && !strncmp(MinusInfinity, fpc, 9)) {
218
221
  if (json->allow_nan) {
219
222
  *result = CMinusInfinity;
220
223
  fexec p + 10;
@@ -231,7 +234,7 @@ static const char *JSON_parse_object(JSON_Parser *json, const char *p, const cha
231
234
  }
232
235
 
233
236
  action parse_array {
234
- const char *np;
237
+ char *np;
235
238
  json->current_nesting++;
236
239
  np = JSON_parse_array(json, fpc, pe, result);
237
240
  json->current_nesting--;
@@ -239,7 +242,7 @@ static const char *JSON_parse_object(JSON_Parser *json, const char *p, const cha
239
242
  }
240
243
 
241
244
  action parse_object {
242
- const char *np;
245
+ char *np;
243
246
  json->current_nesting++;
244
247
  np = JSON_parse_object(json, fpc, pe, result);
245
248
  json->current_nesting--;
@@ -261,7 +264,7 @@ main := (
261
264
  ) %*exit;
262
265
  }%%
263
266
 
264
- static const char *JSON_parse_value(JSON_Parser *json, const char *p, const char *pe, VALUE *result)
267
+ static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *result)
265
268
  {
266
269
  int cs = EVIL;
267
270
 
@@ -282,10 +285,10 @@ static const char *JSON_parse_value(JSON_Parser *json, const char *p, const char
282
285
 
283
286
  action exit { fhold; fbreak; }
284
287
 
285
- main := '-'? ('0' | [1-9][0-9]*) (^[0-9] @exit);
288
+ main := '-'? ('0' | [1-9][0-9]*) (^[0-9]? @exit);
286
289
  }%%
287
290
 
288
- static const char *JSON_parse_integer(JSON_Parser *json, const char *p, const char *pe, VALUE *result)
291
+ static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *result)
289
292
  {
290
293
  int cs = EVIL;
291
294
 
@@ -313,10 +316,10 @@ static const char *JSON_parse_integer(JSON_Parser *json, const char *p, const ch
313
316
  main := '-'? (
314
317
  (('0' | [1-9][0-9]*) '.' [0-9]+ ([Ee] [+\-]?[0-9]+)?)
315
318
  | (('0' | [1-9][0-9]*) ([Ee] [+\-]?[0-9]+))
316
- ) (^[0-9Ee.\-] @exit );
319
+ ) (^[0-9Ee.\-]? @exit );
317
320
  }%%
318
321
 
319
- static const char *JSON_parse_float(JSON_Parser *json, const char *p, const char *pe, VALUE *result)
322
+ static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *result)
320
323
  {
321
324
  int cs = EVIL;
322
325
 
@@ -342,7 +345,7 @@ static const char *JSON_parse_float(JSON_Parser *json, const char *p, const char
342
345
 
343
346
  action parse_value {
344
347
  VALUE v = Qnil;
345
- const char *np = JSON_parse_value(json, fpc, pe, &v);
348
+ char *np = JSON_parse_value(json, fpc, pe, &v);
346
349
  if (np == NULL) {
347
350
  fhold; fbreak;
348
351
  } else {
@@ -365,7 +368,7 @@ static const char *JSON_parse_float(JSON_Parser *json, const char *p, const char
365
368
  end_array @exit;
366
369
  }%%
367
370
 
368
- static const char *JSON_parse_array(JSON_Parser *json, const char *p, const char *pe, VALUE *result)
371
+ static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *result)
369
372
  {
370
373
  int cs = EVIL;
371
374
  VALUE array_class = json->array_class;
@@ -386,9 +389,9 @@ static const char *JSON_parse_array(JSON_Parser *json, const char *p, const char
386
389
  }
387
390
  }
388
391
 
389
- static VALUE json_string_unescape(VALUE result, const char *string, const char *stringEnd)
392
+ static VALUE json_string_unescape(VALUE result, char *string, char *stringEnd)
390
393
  {
391
- const char *p = string, *pe = string, *unescape;
394
+ char *p = string, *pe = string, *unescape;
392
395
  int unescape_len;
393
396
 
394
397
  while (pe < stringEnd) {
@@ -490,17 +493,17 @@ match_i(VALUE regexp, VALUE klass, VALUE memo)
490
493
  return ST_CONTINUE;
491
494
  }
492
495
 
493
- static const char *JSON_parse_string(JSON_Parser *json, const char *p, const char *pe, VALUE *result)
496
+ static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *result)
494
497
  {
495
498
  int cs = EVIL;
499
+ VALUE match_string;
500
+
496
501
  *result = rb_str_buf_new(0);
497
502
  %% write init;
498
503
  json->memo = p;
499
504
  %% write exec;
500
505
 
501
- if (json->create_additions) {
502
- VALUE match_string = json->match_string;
503
- if (RTEST(match_string)) {
506
+ if (json->create_additions && RTEST(match_string = json->match_string)) {
504
507
  VALUE klass;
505
508
  VALUE memo = rb_ary_new2(2);
506
509
  rb_ary_push(memo, *result);
@@ -509,7 +512,6 @@ static const char *JSON_parse_string(JSON_Parser *json, const char *p, const cha
509
512
  if (RTEST(klass)) {
510
513
  *result = rb_funcall(klass, i_json_create, 1, *result);
511
514
  }
512
- }
513
515
  }
514
516
 
515
517
  if (json->symbolize_names && json->parsing_name) {
@@ -522,34 +524,6 @@ static const char *JSON_parse_string(JSON_Parser *json, const char *p, const cha
522
524
  }
523
525
  }
524
526
 
525
-
526
- %%{
527
- machine JSON;
528
-
529
- write data;
530
-
531
- include JSON_common;
532
-
533
- action parse_object {
534
- const char *np;
535
- json->current_nesting = 1;
536
- np = JSON_parse_object(json, fpc, pe, &result);
537
- if (np == NULL) { fhold; fbreak; } else fexec np;
538
- }
539
-
540
- action parse_array {
541
- const char *np;
542
- json->current_nesting = 1;
543
- np = JSON_parse_array(json, fpc, pe, &result);
544
- if (np == NULL) { fhold; fbreak; } else fexec np;
545
- }
546
-
547
- main := ignore* (
548
- begin_object >parse_object |
549
- begin_array >parse_array
550
- ) ignore*;
551
- }%%
552
-
553
527
  /*
554
528
  * Document-class: JSON::Ext::Parser
555
529
  *
@@ -564,7 +538,7 @@ static const char *JSON_parse_string(JSON_Parser *json, const char *p, const cha
564
538
 
565
539
  static VALUE convert_encoding(VALUE source)
566
540
  {
567
- const char *ptr = RSTRING_PTR(source);
541
+ char *ptr = RSTRING_PTR(source);
568
542
  long len = RSTRING_LEN(source);
569
543
  if (len < 2) {
570
544
  rb_raise(eParserError, "A JSON text must at least contain two octets!");
@@ -603,12 +577,15 @@ static VALUE convert_encoding(VALUE source)
603
577
  return source;
604
578
  }
605
579
 
606
- static inline void parser_iv_set(JSON_Parser *json, const char* iv_name, VALUE v)
607
- {
608
- // store reference to v in a Ruby instVar to keep v alive
609
- // without using a gc_mark function in Data_Wrap_Struct calls
610
- rb_iv_set(json->dwrapped_parser, iv_name, v);
611
- }
580
+ #if defined MAGLEV
581
+ // Maglev doesn't support the mark function, keep a reference in the object
582
+ #define QUOTE(x) #x
583
+ #define PARSER_SET_REFERENCE(json, field, val) \
584
+ (json)->field = (val); \
585
+ rb_iv_set(json->dwrapped_parser, QUOTE(@field), (json)->field);
586
+ #else
587
+ #define PARSER_SET_REFERENCE(json, field, val) (json)->field = (val);
588
+ #endif
612
589
 
613
590
  /*
614
591
  * call-seq: new(source, opts => {})
@@ -636,26 +613,15 @@ static inline void parser_iv_set(JSON_Parser *json, const char* iv_name, VALUE v
636
613
  * * *object_class*: Defaults to Hash
637
614
  * * *array_class*: Defaults to Array
638
615
  */
639
-
640
- static int init_count = 0;
641
616
  static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
642
617
  {
643
- const char *ptr;
644
- long len;
645
618
  VALUE source, opts;
646
-
647
619
  GET_PARSER_INIT;
648
- init_count += 1;
649
620
 
650
- #ifndef MAGLEV
651
- if (json->Vsource) {
621
+ if (RTEST(json->Vsource)) {
652
622
  rb_raise(rb_eTypeError, "already initialized instance");
653
623
  }
654
- #endif
655
624
  rb_scan_args(argc, argv, "11", &source, &opts);
656
- source = convert_encoding(StringValue(source));
657
- ptr = RSTRING_PTR(source);
658
- len = RSTRING_LEN(source);
659
625
  if (!NIL_P(opts)) {
660
626
  opts = rb_convert_type(opts, T_HASH, "Hash", "to_hash");
661
627
  if (NIL_P(opts)) {
@@ -685,6 +651,13 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
685
651
  } else {
686
652
  json->symbolize_names = 0;
687
653
  }
654
+ tmp = ID2SYM(i_quirks_mode);
655
+ if (option_given_p(opts, tmp)) {
656
+ VALUE quirks_mode = rb_hash_aref(opts, tmp);
657
+ json->quirks_mode = RTEST(quirks_mode) ? 1 : 0;
658
+ } else {
659
+ json->quirks_mode = 0;
660
+ }
688
661
  tmp = ID2SYM(i_create_additions);
689
662
  if (option_given_p(opts, tmp)) {
690
663
  json->create_additions = RTEST(rb_hash_aref(opts, tmp));
@@ -693,52 +666,78 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
693
666
  }
694
667
  tmp = ID2SYM(i_create_id);
695
668
  if (option_given_p(opts, tmp)) {
696
- json->create_id = rb_hash_aref(opts, tmp);
669
+ PARSER_SET_REFERENCE(json, create_id, rb_hash_aref(opts, tmp));
697
670
  } else {
698
- json->create_id = rb_funcall(mJSON, i_create_id, 0);
671
+ PARSER_SET_REFERENCE(json, create_id, rb_funcall(mJSON, i_create_id, 0));
699
672
  }
700
- parser_iv_set(json, "@create_id", json->create_id);
701
673
  tmp = ID2SYM(i_object_class);
702
674
  if (option_given_p(opts, tmp)) {
703
- json->object_class = rb_hash_aref(opts, tmp);
704
- parser_iv_set(json, "@object_class", json->object_class);
675
+ PARSER_SET_REFERENCE(json, object_class, rb_hash_aref(opts, tmp));
676
+ } else {
677
+ PARSER_SET_REFERENCE(json, object_class, Qnil);
705
678
  }
706
679
  tmp = ID2SYM(i_array_class);
707
680
  if (option_given_p(opts, tmp)) {
708
- json->array_class = rb_hash_aref(opts, tmp);
709
- parser_iv_set(json, "@array_class", json->array_class);
681
+ PARSER_SET_REFERENCE(json, array_class, rb_hash_aref(opts, tmp));
682
+ } else {
683
+ PARSER_SET_REFERENCE(json, array_class, Qnil);
710
684
  }
711
685
  tmp = ID2SYM(i_match_string);
712
686
  if (option_given_p(opts, tmp)) {
713
687
  VALUE match_string = rb_hash_aref(opts, tmp);
714
- json->match_string = RTEST(match_string) ? match_string : Qnil;
715
- parser_iv_set(json, "@match_string", json->match_string);
688
+ PARSER_SET_REFERENCE(json, match_string, RTEST(match_string) ? match_string : Qnil);
689
+ } else {
690
+ PARSER_SET_REFERENCE(json, match_string, Qnil);
716
691
  }
717
692
  }
718
693
  } else {
719
694
  json->max_nesting = 19;
720
695
  json->allow_nan = 0;
721
696
  json->create_additions = 1;
722
- json->create_id = rb_funcall(mJSON, i_create_id, 0);
723
- parser_iv_set(json, "@create_id", json->create_id);
697
+ PARSER_SET_REFERENCE(json, create_id, rb_funcall(mJSON, i_create_id, 0));
698
+ json->object_class = Qnil;
699
+ json->array_class = Qnil;
700
+ }
701
+ if (!json->quirks_mode) {
702
+ source = convert_encoding(StringValue(source));
724
703
  }
725
704
  json->current_nesting = 0;
726
- json->len = len;
727
- json->source = ptr;
728
- json->Vsource = source;
729
- parser_iv_set(json, "@vsource", json->Vsource);
705
+ json->len = RSTRING_LEN(source);
706
+ json->source = RSTRING_PTR(source);;
707
+ PARSER_SET_REFERENCE(json, Vsource, source);
730
708
  return self;
731
709
  }
732
710
 
733
- /*
734
- * call-seq: parse()
735
- *
736
- * Parses the current JSON text _source_ and returns the complete data
737
- * structure as a result.
738
- */
739
- static VALUE cParser_parse(VALUE self)
711
+ %%{
712
+ machine JSON;
713
+
714
+ write data;
715
+
716
+ include JSON_common;
717
+
718
+ action parse_object {
719
+ char *np;
720
+ json->current_nesting = 1;
721
+ np = JSON_parse_object(json, fpc, pe, &result);
722
+ if (np == NULL) { fhold; fbreak; } else fexec np;
723
+ }
724
+
725
+ action parse_array {
726
+ char *np;
727
+ json->current_nesting = 1;
728
+ np = JSON_parse_array(json, fpc, pe, &result);
729
+ if (np == NULL) { fhold; fbreak; } else fexec np;
730
+ }
731
+
732
+ main := ignore* (
733
+ begin_object >parse_object |
734
+ begin_array >parse_array
735
+ ) ignore*;
736
+ }%%
737
+
738
+ static VALUE cParser_parse_strict(VALUE self)
740
739
  {
741
- const char *p, *pe;
740
+ char *p, *pe;
742
741
  int cs = EVIL;
743
742
  VALUE result = Qnil;
744
743
  GET_PARSER;
@@ -756,6 +755,62 @@ static VALUE cParser_parse(VALUE self)
756
755
  }
757
756
  }
758
757
 
758
+
759
+ %%{
760
+ machine JSON_quirks_mode;
761
+
762
+ write data;
763
+
764
+ include JSON_common;
765
+
766
+ action parse_value {
767
+ char *np = JSON_parse_value(json, fpc, pe, &result);
768
+ if (np == NULL) { fhold; fbreak; } else fexec np;
769
+ }
770
+
771
+ main := ignore* (
772
+ begin_value >parse_value
773
+ ) ignore*;
774
+ }%%
775
+
776
+ static VALUE cParser_parse_quirks_mode(VALUE self)
777
+ {
778
+ char *p, *pe;
779
+ int cs = EVIL;
780
+ VALUE result = Qnil;
781
+ GET_PARSER;
782
+
783
+ %% write init;
784
+ p = json->source;
785
+ pe = p + json->len;
786
+ %% write exec;
787
+
788
+ if (cs >= JSON_quirks_mode_first_final && p == pe) {
789
+ return result;
790
+ } else {
791
+ rb_raise(eParserError, "%u: unexpected token at '%s'", __LINE__, p);
792
+ return Qnil;
793
+ }
794
+ }
795
+
796
+ /*
797
+ * call-seq: parse()
798
+ *
799
+ * Parses the current JSON text _source_ and returns the complete data
800
+ * structure as a result.
801
+ */
802
+ static VALUE cParser_parse(VALUE self)
803
+ {
804
+ GET_PARSER;
805
+
806
+ if (json->quirks_mode) {
807
+ return cParser_parse_quirks_mode(self);
808
+ } else {
809
+ return cParser_parse_strict(self);
810
+ }
811
+ }
812
+
813
+
759
814
  static JSON_Parser *JSON_allocate()
760
815
  {
761
816
  JSON_Parser *json = ALLOC(JSON_Parser);
@@ -770,7 +825,14 @@ static JSON_Parser *JSON_allocate()
770
825
  return json;
771
826
  }
772
827
 
773
- /* deleted JSON_mark function */
828
+ static void JSON_mark(JSON_Parser *json)
829
+ {
830
+ rb_gc_mark_maybe(json->Vsource);
831
+ rb_gc_mark_maybe(json->create_id);
832
+ rb_gc_mark_maybe(json->object_class);
833
+ rb_gc_mark_maybe(json->array_class);
834
+ rb_gc_mark_maybe(json->match_string);
835
+ }
774
836
 
775
837
  static void JSON_free(JSON_Parser *json)
776
838
  {
@@ -780,9 +842,7 @@ static void JSON_free(JSON_Parser *json)
780
842
  static VALUE cJSON_parser_s_allocate(VALUE klass)
781
843
  {
782
844
  JSON_Parser *json = JSON_allocate();
783
- VALUE data_obj = Data_Wrap_Struct(klass, NULL, JSON_free, json);
784
- json->dwrapped_parser = data_obj;
785
- return data_obj;
845
+ return json->dwrapped_parser = Data_Wrap_Struct(klass, JSON_mark, JSON_free, json);
786
846
  }
787
847
 
788
848
  /*
@@ -797,6 +857,18 @@ static VALUE cParser_source(VALUE self)
797
857
  return rb_str_dup(json->Vsource);
798
858
  }
799
859
 
860
+ /*
861
+ * call-seq: quirks_mode?()
862
+ *
863
+ * Returns a true, if this parser is in quirks_mode, false otherwise.
864
+ */
865
+ static VALUE cParser_quirks_mode_p(VALUE self)
866
+ {
867
+ GET_PARSER;
868
+ return json->quirks_mode ? Qtrue : Qfalse;
869
+ }
870
+
871
+
800
872
  void Init_parser()
801
873
  {
802
874
  rb_require("json/common");
@@ -809,6 +881,7 @@ void Init_parser()
809
881
  rb_define_method(cParser, "initialize", cParser_initialize, -1);
810
882
  rb_define_method(cParser, "parse", cParser_parse, 0);
811
883
  rb_define_method(cParser, "source", cParser_source, 0);
884
+ rb_define_method(cParser, "quirks_mode?", cParser_quirks_mode_p, 0);
812
885
 
813
886
  CNaN = rb_const_get(mJSON, rb_intern("NaN"));
814
887
  CInfinity = rb_const_get(mJSON, rb_intern("Infinity"));
@@ -822,6 +895,7 @@ void Init_parser()
822
895
  i_max_nesting = rb_intern("max_nesting");
823
896
  i_allow_nan = rb_intern("allow_nan");
824
897
  i_symbolize_names = rb_intern("symbolize_names");
898
+ i_quirks_mode = rb_intern("quirks_mode");
825
899
  i_object_class = rb_intern("object_class");
826
900
  i_array_class = rb_intern("array_class");
827
901
  i_match = rb_intern("match");