oj 3.13.23 → 3.16.10

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 (178) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +86 -0
  3. data/README.md +2 -2
  4. data/ext/oj/buf.h +7 -6
  5. data/ext/oj/cache.c +29 -26
  6. data/ext/oj/cache.h +3 -2
  7. data/ext/oj/cache8.c +10 -9
  8. data/ext/oj/circarray.c +7 -5
  9. data/ext/oj/circarray.h +2 -2
  10. data/ext/oj/code.c +5 -12
  11. data/ext/oj/code.h +2 -2
  12. data/ext/oj/compat.c +20 -60
  13. data/ext/oj/custom.c +26 -59
  14. data/ext/oj/debug.c +3 -9
  15. data/ext/oj/dump.c +103 -53
  16. data/ext/oj/dump.h +1 -4
  17. data/ext/oj/dump_compat.c +557 -592
  18. data/ext/oj/dump_leaf.c +3 -5
  19. data/ext/oj/dump_object.c +42 -48
  20. data/ext/oj/dump_strict.c +10 -22
  21. data/ext/oj/encoder.c +1 -1
  22. data/ext/oj/err.c +2 -13
  23. data/ext/oj/err.h +9 -12
  24. data/ext/oj/extconf.rb +16 -7
  25. data/ext/oj/fast.c +63 -98
  26. data/ext/oj/intern.c +62 -47
  27. data/ext/oj/intern.h +3 -7
  28. data/ext/oj/mem.c +318 -0
  29. data/ext/oj/mem.h +53 -0
  30. data/ext/oj/mimic_json.c +54 -38
  31. data/ext/oj/object.c +33 -43
  32. data/ext/oj/odd.c +8 -6
  33. data/ext/oj/odd.h +4 -4
  34. data/ext/oj/oj.c +245 -216
  35. data/ext/oj/oj.h +83 -81
  36. data/ext/oj/parse.c +109 -153
  37. data/ext/oj/parse.h +21 -24
  38. data/ext/oj/parser.c +80 -67
  39. data/ext/oj/parser.h +9 -8
  40. data/ext/oj/rails.c +71 -94
  41. data/ext/oj/reader.c +9 -14
  42. data/ext/oj/reader.h +4 -2
  43. data/ext/oj/resolve.c +3 -4
  44. data/ext/oj/rxclass.c +6 -5
  45. data/ext/oj/rxclass.h +1 -1
  46. data/ext/oj/saj.c +13 -15
  47. data/ext/oj/saj2.c +37 -49
  48. data/ext/oj/saj2.h +1 -1
  49. data/ext/oj/scp.c +6 -20
  50. data/ext/oj/sparse.c +22 -70
  51. data/ext/oj/stream_writer.c +46 -48
  52. data/ext/oj/strict.c +22 -56
  53. data/ext/oj/string_writer.c +64 -40
  54. data/ext/oj/trace.h +31 -4
  55. data/ext/oj/usual.c +125 -114
  56. data/ext/oj/usual.h +7 -6
  57. data/ext/oj/util.h +1 -1
  58. data/ext/oj/val_stack.c +13 -2
  59. data/ext/oj/val_stack.h +8 -7
  60. data/ext/oj/wab.c +25 -57
  61. data/lib/oj/active_support_helper.rb +1 -3
  62. data/lib/oj/bag.rb +7 -1
  63. data/lib/oj/easy_hash.rb +4 -5
  64. data/lib/oj/error.rb +0 -1
  65. data/lib/oj/json.rb +162 -150
  66. data/lib/oj/mimic.rb +7 -7
  67. data/lib/oj/schandler.rb +5 -4
  68. data/lib/oj/state.rb +8 -5
  69. data/lib/oj/version.rb +1 -2
  70. data/lib/oj.rb +2 -0
  71. data/pages/InstallOptions.md +20 -0
  72. data/pages/Options.md +4 -0
  73. metadata +46 -121
  74. data/test/_test_active.rb +0 -76
  75. data/test/_test_active_mimic.rb +0 -96
  76. data/test/_test_mimic_rails.rb +0 -126
  77. data/test/activerecord/result_test.rb +0 -32
  78. data/test/activesupport4/decoding_test.rb +0 -108
  79. data/test/activesupport4/encoding_test.rb +0 -531
  80. data/test/activesupport4/test_helper.rb +0 -41
  81. data/test/activesupport5/abstract_unit.rb +0 -45
  82. data/test/activesupport5/decoding_test.rb +0 -133
  83. data/test/activesupport5/encoding_test.rb +0 -500
  84. data/test/activesupport5/encoding_test_cases.rb +0 -98
  85. data/test/activesupport5/test_helper.rb +0 -72
  86. data/test/activesupport5/time_zone_test_helpers.rb +0 -39
  87. data/test/activesupport6/abstract_unit.rb +0 -44
  88. data/test/activesupport6/decoding_test.rb +0 -133
  89. data/test/activesupport6/encoding_test.rb +0 -507
  90. data/test/activesupport6/encoding_test_cases.rb +0 -98
  91. data/test/activesupport6/test_common.rb +0 -17
  92. data/test/activesupport6/test_helper.rb +0 -163
  93. data/test/activesupport6/time_zone_test_helpers.rb +0 -39
  94. data/test/activesupport7/abstract_unit.rb +0 -49
  95. data/test/activesupport7/decoding_test.rb +0 -125
  96. data/test/activesupport7/encoding_test.rb +0 -486
  97. data/test/activesupport7/encoding_test_cases.rb +0 -104
  98. data/test/activesupport7/time_zone_test_helpers.rb +0 -47
  99. data/test/bar.rb +0 -11
  100. data/test/baz.rb +0 -16
  101. data/test/bug.rb +0 -16
  102. data/test/files.rb +0 -29
  103. data/test/foo.rb +0 -77
  104. data/test/helper.rb +0 -42
  105. data/test/isolated/shared.rb +0 -308
  106. data/test/isolated/test_mimic_after.rb +0 -13
  107. data/test/isolated/test_mimic_alone.rb +0 -12
  108. data/test/isolated/test_mimic_as_json.rb +0 -45
  109. data/test/isolated/test_mimic_before.rb +0 -13
  110. data/test/isolated/test_mimic_define.rb +0 -28
  111. data/test/isolated/test_mimic_rails_after.rb +0 -22
  112. data/test/isolated/test_mimic_rails_before.rb +0 -21
  113. data/test/isolated/test_mimic_redefine.rb +0 -15
  114. data/test/json_gem/json_addition_test.rb +0 -216
  115. data/test/json_gem/json_common_interface_test.rb +0 -153
  116. data/test/json_gem/json_encoding_test.rb +0 -107
  117. data/test/json_gem/json_ext_parser_test.rb +0 -20
  118. data/test/json_gem/json_fixtures_test.rb +0 -35
  119. data/test/json_gem/json_generator_test.rb +0 -396
  120. data/test/json_gem/json_generic_object_test.rb +0 -90
  121. data/test/json_gem/json_parser_test.rb +0 -477
  122. data/test/json_gem/json_string_matching_test.rb +0 -42
  123. data/test/json_gem/test_helper.rb +0 -30
  124. data/test/mem.rb +0 -33
  125. data/test/perf.rb +0 -107
  126. data/test/perf_compat.rb +0 -130
  127. data/test/perf_dump.rb +0 -50
  128. data/test/perf_fast.rb +0 -164
  129. data/test/perf_file.rb +0 -64
  130. data/test/perf_object.rb +0 -138
  131. data/test/perf_once.rb +0 -58
  132. data/test/perf_parser.rb +0 -189
  133. data/test/perf_saj.rb +0 -109
  134. data/test/perf_scp.rb +0 -152
  135. data/test/perf_simple.rb +0 -287
  136. data/test/perf_strict.rb +0 -139
  137. data/test/perf_wab.rb +0 -131
  138. data/test/prec.rb +0 -23
  139. data/test/sample/change.rb +0 -14
  140. data/test/sample/dir.rb +0 -19
  141. data/test/sample/doc.rb +0 -36
  142. data/test/sample/file.rb +0 -48
  143. data/test/sample/group.rb +0 -16
  144. data/test/sample/hasprops.rb +0 -16
  145. data/test/sample/layer.rb +0 -12
  146. data/test/sample/line.rb +0 -20
  147. data/test/sample/oval.rb +0 -10
  148. data/test/sample/rect.rb +0 -10
  149. data/test/sample/shape.rb +0 -35
  150. data/test/sample/text.rb +0 -20
  151. data/test/sample.rb +0 -54
  152. data/test/sample_json.rb +0 -37
  153. data/test/test_compat.rb +0 -540
  154. data/test/test_custom.rb +0 -544
  155. data/test/test_debian.rb +0 -53
  156. data/test/test_fast.rb +0 -530
  157. data/test/test_file.rb +0 -255
  158. data/test/test_gc.rb +0 -60
  159. data/test/test_generate.rb +0 -21
  160. data/test/test_hash.rb +0 -39
  161. data/test/test_integer_range.rb +0 -72
  162. data/test/test_null.rb +0 -376
  163. data/test/test_object.rb +0 -1025
  164. data/test/test_parser.rb +0 -11
  165. data/test/test_parser_debug.rb +0 -27
  166. data/test/test_parser_saj.rb +0 -335
  167. data/test/test_parser_usual.rb +0 -217
  168. data/test/test_rails.rb +0 -35
  169. data/test/test_saj.rb +0 -186
  170. data/test/test_scp.rb +0 -431
  171. data/test/test_strict.rb +0 -435
  172. data/test/test_various.rb +0 -752
  173. data/test/test_wab.rb +0 -309
  174. data/test/test_writer.rb +0 -380
  175. data/test/tests.rb +0 -33
  176. data/test/tests_mimic.rb +0 -23
  177. data/test/tests_mimic_addition.rb +0 -16
  178. data/test/zoo.rb +0 -13
data/ext/oj/object.c CHANGED
@@ -83,8 +83,9 @@ static int parse_num(const char *str, const char *end, int cnt) {
83
83
 
84
84
  VALUE
85
85
  oj_parse_xml_time(const char *str, int len) {
86
- VALUE args[8];
87
- const char *end = str + len;
86
+ VALUE args[7];
87
+ const char *end = str + len;
88
+ const char *orig = str;
88
89
  int n;
89
90
 
90
91
  // year
@@ -144,7 +145,9 @@ oj_parse_xml_time(const char *str, int len) {
144
145
  char c = *str++;
145
146
 
146
147
  if ('.' == c) {
147
- long long nsec = 0;
148
+ unsigned long long num = 0;
149
+ unsigned long long den = 1;
150
+ const unsigned long long last_den_limit = ULLONG_MAX / 10;
148
151
 
149
152
  for (; str < end; str++) {
150
153
  c = *str;
@@ -152,9 +155,14 @@ oj_parse_xml_time(const char *str, int len) {
152
155
  str++;
153
156
  break;
154
157
  }
155
- nsec = nsec * 10 + (c - '0');
158
+ if (den > last_den_limit) {
159
+ // bail to Time.parse if there are more fractional digits than a ULLONG rational can hold
160
+ return rb_funcall(rb_cTime, oj_parse_id, 1, rb_str_new(orig, len));
161
+ }
162
+ num = num * 10 + (c - '0');
163
+ den *= 10;
156
164
  }
157
- args[5] = rb_float_new((double)n + ((double)nsec + 0.5) / 1000000000.0);
165
+ args[5] = rb_funcall(INT2NUM(n), oj_plus_id, 1, rb_rational_new(ULL2NUM(num), ULL2NUM(den)));
158
166
  } else {
159
167
  args[5] = rb_ll2inum(n);
160
168
  }
@@ -270,8 +278,8 @@ static int hat_num(ParseInfo pi, Val parent, Val kval, NumInfo ni) {
270
278
  parent->val = rb_funcall2(parent->val, oj_utc_id, 0, 0);
271
279
  } else if (ni->has_exp) {
272
280
  struct timespec ts;
273
- ts.tv_sec = ni->i;
274
- ts.tv_nsec = nsec;
281
+ ts.tv_sec = ni->i;
282
+ ts.tv_nsec = nsec;
275
283
  parent->val = rb_time_timespec_new(&ts, (int)ni->exp);
276
284
  } else {
277
285
  parent->val = rb_time_nano_new(ni->i, (long)nsec);
@@ -308,7 +316,7 @@ static int hat_value(ParseInfo pi, Val parent, const char *key, size_t klen, vol
308
316
  oj_set_error_at(pi, oj_parse_error_class, __FILE__, __LINE__, "Invalid struct data");
309
317
  return 1;
310
318
  }
311
- e1 = *RARRAY_PTR(value);
319
+ e1 = *RARRAY_CONST_PTR(value);
312
320
  // check for anonymous Struct
313
321
  if (T_ARRAY == rb_type(e1)) {
314
322
  VALUE args[1024];
@@ -322,17 +330,17 @@ static int hat_value(ParseInfo pi, Val parent, const char *key, size_t klen, vol
322
330
  sc = rb_funcall2(rb_cStruct, oj_new_id, cnt, args);
323
331
  } else {
324
332
  // If struct is not defined then we let this fail and raise an exception.
325
- sc = oj_name2struct(pi, *RARRAY_PTR(value), rb_eArgError);
333
+ sc = oj_name2struct(pi, *RARRAY_CONST_PTR(value), rb_eArgError);
326
334
  }
327
335
  if (sc == rb_cRange) {
328
- parent->val = rb_class_new_instance(len - 1, RARRAY_PTR(value) + 1, rb_cRange);
336
+ parent->val = rb_class_new_instance(len - 1, RARRAY_CONST_PTR(value) + 1, rb_cRange);
329
337
  } else {
330
338
  // Create a properly initialized struct instance without calling the initialize method.
331
339
  parent->val = rb_obj_alloc(sc);
332
340
  // If the JSON array has more entries than the struct class allows, we record an error.
333
341
  #ifdef RSTRUCT_LEN
334
342
  #if RSTRUCT_LEN_RETURNS_INTEGER_OBJECT
335
- slen = (int)NUM2LONG(RSTRUCT_LEN(parent->val));
343
+ slen = (int)NUM2LONG(RSTRUCT_LEN(parent->val));
336
344
  #else // RSTRUCT_LEN_RETURNS_INTEGER_OBJECT
337
345
  slen = (int)RSTRUCT_LEN(parent->val);
338
346
  #endif // RSTRUCT_LEN_RETURNS_INTEGER_OBJECT
@@ -346,20 +354,20 @@ static int hat_value(ParseInfo pi, Val parent, const char *key, size_t klen, vol
346
354
  int i;
347
355
 
348
356
  for (i = 0; i < len - 1; i++) {
349
- rb_struct_aset(parent->val, INT2FIX(i), RARRAY_PTR(value)[i + 1]);
357
+ rb_struct_aset(parent->val, INT2FIX(i), RARRAY_CONST_PTR(value)[i + 1]);
350
358
  }
351
359
  }
352
360
  }
353
361
  return 1;
354
362
  } else if (3 <= klen && '#' == key[1]) {
355
- volatile VALUE *a;
363
+ volatile const VALUE *a;
356
364
 
357
365
  if (2 != len) {
358
366
  oj_set_error_at(pi, oj_parse_error_class, __FILE__, __LINE__, "invalid hash pair");
359
367
  return 1;
360
368
  }
361
369
  parent->val = rb_hash_new();
362
- a = RARRAY_PTR(value);
370
+ a = RARRAY_CONST_PTR(value);
363
371
  rb_hash_aset(parent->val, *a, a[1]);
364
372
 
365
373
  return 1;
@@ -446,9 +454,7 @@ WHICH_TYPE:
446
454
  rb_class2name(rb_obj_class(parent->val)));
447
455
  return;
448
456
  }
449
- if (RB_UNLIKELY(Yes == pi->options.trace)) {
450
- oj_trace_parse_call("set_string", pi, __FILE__, __LINE__, rval);
451
- }
457
+ TRACE_PARSE_CALL(pi->options.trace, "set_string", pi, rval);
452
458
  }
453
459
 
454
460
  static void hash_set_num(ParseInfo pi, Val kval, NumInfo ni) {
@@ -517,9 +523,7 @@ WHICH_TYPE:
517
523
  rb_class2name(rb_obj_class(parent->val)));
518
524
  return;
519
525
  }
520
- if (RB_UNLIKELY(Yes == pi->options.trace)) {
521
- oj_trace_parse_call("add_number", pi, __FILE__, __LINE__, rval);
522
- }
526
+ TRACE_PARSE_CALL(pi->options.trace, "add_number", pi, rval);
523
527
  }
524
528
 
525
529
  static void hash_set_value(ParseInfo pi, Val kval, VALUE value) {
@@ -545,8 +549,8 @@ WHICH_TYPE:
545
549
  }
546
550
  } else {
547
551
  if (3 <= klen && '^' == *key && '#' == key[1] && T_ARRAY == rb_type(value)) {
548
- long len = RARRAY_LEN(value);
549
- volatile VALUE *a = RARRAY_PTR(value);
552
+ long len = RARRAY_LEN(value);
553
+ volatile const VALUE *a = RARRAY_CONST_PTR(value);
550
554
 
551
555
  if (2 != len) {
552
556
  oj_set_error_at(pi, oj_parse_error_class, __FILE__, __LINE__, "invalid hash pair");
@@ -603,15 +607,11 @@ WHICH_TYPE:
603
607
  rb_class2name(rb_obj_class(parent->val)));
604
608
  return;
605
609
  }
606
- if (RB_UNLIKELY(Yes == pi->options.trace)) {
607
- oj_trace_parse_call("add_value", pi, __FILE__, __LINE__, value);
608
- }
610
+ TRACE_PARSE_CALL(pi->options.trace, "add_value", pi, value);
609
611
  }
610
612
 
611
613
  static VALUE start_hash(ParseInfo pi) {
612
- if (RB_UNLIKELY(Yes == pi->options.trace)) {
613
- oj_trace_parse_in("start_hash", pi, __FILE__, __LINE__);
614
- }
614
+ TRACE_PARSE_IN(pi->options.trace, "start_hash", pi);
615
615
  return Qnil;
616
616
  }
617
617
 
@@ -627,9 +627,7 @@ static void end_hash(ParseInfo pi) {
627
627
  oj_odd_free(oa);
628
628
  parent->odd_args = NULL;
629
629
  }
630
- if (RB_UNLIKELY(Yes == pi->options.trace)) {
631
- oj_trace_parse_hash_end(pi, __FILE__, __LINE__);
632
- }
630
+ TRACE_PARSE_HASH_END(pi->options.trace, pi);
633
631
  }
634
632
 
635
633
  static void array_append_cstr(ParseInfo pi, const char *str, size_t len, const char *orig) {
@@ -655,32 +653,24 @@ static void array_append_cstr(ParseInfo pi, const char *str, size_t len, const c
655
653
  }
656
654
  rval = str_to_value(pi, str, len, orig);
657
655
  rb_ary_push(stack_peek(&pi->stack)->val, rval);
658
- if (RB_UNLIKELY(Yes == pi->options.trace)) {
659
- oj_trace_parse_call("append_string", pi, __FILE__, __LINE__, rval);
660
- }
656
+ TRACE_PARSE_CALL(pi->options.trace, "append_string", pi, rval);
661
657
  }
662
658
 
663
659
  static void array_append_num(ParseInfo pi, NumInfo ni) {
664
660
  volatile VALUE rval = oj_num_as_value(ni);
665
661
 
666
662
  rb_ary_push(stack_peek(&pi->stack)->val, rval);
667
- if (RB_UNLIKELY(Yes == pi->options.trace)) {
668
- oj_trace_parse_call("append_number", pi, __FILE__, __LINE__, rval);
669
- }
663
+ TRACE_PARSE_CALL(pi->options.trace, "append_number", pi, rval);
670
664
  }
671
665
 
672
666
  static void add_cstr(ParseInfo pi, const char *str, size_t len, const char *orig) {
673
667
  pi->stack.head->val = str_to_value(pi, str, len, orig);
674
- if (RB_UNLIKELY(Yes == pi->options.trace)) {
675
- oj_trace_parse_call("add_string", pi, __FILE__, __LINE__, pi->stack.head->val);
676
- }
668
+ TRACE_PARSE_CALL(pi->options.trace, "add_string", pi, pi->stack.head->val);
677
669
  }
678
670
 
679
671
  static void add_num(ParseInfo pi, NumInfo ni) {
680
672
  pi->stack.head->val = oj_num_as_value(ni);
681
- if (RB_UNLIKELY(Yes == pi->options.trace)) {
682
- oj_trace_parse_call("add_num", pi, __FILE__, __LINE__, pi->stack.head->val);
683
- }
673
+ TRACE_PARSE_CALL(pi->options.trace, "add_num", pi, pi->stack.head->val);
684
674
  }
685
675
 
686
676
  void oj_set_object_callbacks(ParseInfo pi) {
data/ext/oj/odd.c CHANGED
@@ -5,6 +5,8 @@
5
5
 
6
6
  #include <string.h>
7
7
 
8
+ #include "mem.h"
9
+
8
10
  static Odd odds = NULL;
9
11
  static ID sec_id;
10
12
  static ID sec_fraction_id;
@@ -68,7 +70,7 @@ void print_all_odds(const char *label) {
68
70
  }
69
71
 
70
72
  static Odd odd_create(void) {
71
- Odd odd = ALLOC(struct _odd);
73
+ Odd odd = OJ_R_ALLOC(struct _odd);
72
74
 
73
75
  memset(odd, 0, sizeof(struct _odd));
74
76
  odd->next = odds;
@@ -172,7 +174,7 @@ Odd oj_get_oddc(const char *classname, size_t len) {
172
174
  }
173
175
 
174
176
  OddArgs oj_odd_alloc_args(Odd odd) {
175
- OddArgs oa = ALLOC_N(struct _oddArgs, 1);
177
+ OddArgs oa = OJ_R_ALLOC_N(struct _oddArgs, 1);
176
178
  VALUE *a;
177
179
  int i;
178
180
 
@@ -184,7 +186,7 @@ OddArgs oj_odd_alloc_args(Odd odd) {
184
186
  }
185
187
 
186
188
  void oj_odd_free(OddArgs args) {
187
- xfree(args);
189
+ OJ_R_FREE(args);
188
190
  }
189
191
 
190
192
  int oj_odd_set_arg(OddArgs args, const char *key, size_t klen, VALUE value) {
@@ -210,7 +212,7 @@ void oj_reg_odd(VALUE clas, VALUE create_object, VALUE create_method, int mcnt,
210
212
  odd = odd_create();
211
213
  odd->clas = clas;
212
214
  rb_gc_register_mark_object(odd->clas);
213
- if (NULL == (odd->classname = strdup(rb_class2name(clas)))) {
215
+ if (NULL == (odd->classname = OJ_STRDUP(rb_class2name(clas)))) {
214
216
  rb_raise(rb_eNoMemError, "for class name.");
215
217
  }
216
218
  odd->clen = strlen(odd->classname);
@@ -224,13 +226,13 @@ void oj_reg_odd(VALUE clas, VALUE create_object, VALUE create_method, int mcnt,
224
226
  *fp = 0;
225
227
  switch (rb_type(*members)) {
226
228
  case T_STRING:
227
- if (NULL == (*np = strdup(RSTRING_PTR(*members)))) {
229
+ if (NULL == (*np = OJ_STRDUP(RSTRING_PTR(*members)))) {
228
230
  rb_raise(rb_eNoMemError, "for attribute name.");
229
231
  }
230
232
  break;
231
233
  case T_SYMBOL:
232
234
  // The symbol can move and invalidate the name so make a copy.
233
- if (NULL == (*np = strdup(rb_id2name(SYM2ID(*members))))) {
235
+ if (NULL == (*np = OJ_STRDUP(rb_id2name(SYM2ID(*members))))) {
234
236
  rb_raise(rb_eNoMemError, "for attribute name.");
235
237
  }
236
238
  break;
data/ext/oj/odd.h CHANGED
@@ -14,7 +14,7 @@ typedef VALUE (*AttrGetFunc)(VALUE obj);
14
14
 
15
15
  typedef struct _odd {
16
16
  struct _odd *next;
17
- const char * classname;
17
+ const char *classname;
18
18
  size_t clen;
19
19
  VALUE clas; // Ruby class or module
20
20
  VALUE create_obj;
@@ -22,15 +22,15 @@ typedef struct _odd {
22
22
  int attr_cnt;
23
23
  bool is_module;
24
24
  bool raw;
25
- const char * attr_names[MAX_ODD_ARGS]; // NULL terminated attr names
25
+ const char *attr_names[MAX_ODD_ARGS]; // NULL terminated attr names
26
26
  ID attrs[MAX_ODD_ARGS]; // 0 terminated attr IDs
27
27
  AttrGetFunc attrFuncs[MAX_ODD_ARGS];
28
- } * Odd;
28
+ } *Odd;
29
29
 
30
30
  typedef struct _oddArgs {
31
31
  Odd odd;
32
32
  VALUE args[MAX_ODD_ARGS];
33
- } * OddArgs;
33
+ } *OddArgs;
34
34
 
35
35
  extern void oj_odd_init(void);
36
36
  extern Odd oj_get_odd(VALUE clas);