ox 2.14.4 → 2.14.8

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.
data/ext/ox/ox.c CHANGED
@@ -3,214 +3,209 @@
3
3
  * All rights reserved.
4
4
  */
5
5
 
6
- #include <stdlib.h>
6
+ #include "ox.h"
7
+
7
8
  #include <errno.h>
8
- #include <stdint.h>
9
9
  #include <stdbool.h>
10
+ #include <stdint.h>
10
11
  #include <stdio.h>
12
+ #include <stdlib.h>
11
13
  #include <string.h>
12
14
 
15
+ #include "intern.h"
13
16
  #include "ruby.h"
14
- #include "ox.h"
15
17
  #include "sax.h"
16
18
 
17
19
  /* maximum to allocate on the stack, arbitrary limit */
18
- #define SMALL_XML 4096
19
- #define WITH_CACHE_TESTS 0
20
+ #define SMALL_XML 4096
21
+ #define WITH_CACHE_TESTS 0
20
22
 
21
23
  typedef struct _yesNoOpt {
22
- VALUE sym;
23
- char *attr;
24
- } *YesNoOpt;
24
+ VALUE sym;
25
+ char *attr;
26
+ } * YesNoOpt;
25
27
 
26
28
  void Init_ox();
27
29
 
28
- VALUE Ox = Qnil;
29
-
30
- ID ox_abort_id;
31
- ID ox_at_column_id;
32
- ID ox_at_content_id;
33
- ID ox_at_id;
34
- ID ox_at_line_id;
35
- ID ox_at_pos_id;
36
- ID ox_at_value_id;
37
- ID ox_attr_id;
38
- ID ox_attr_value_id;
39
- ID ox_attributes_id;
40
- ID ox_attrs_done_id;
41
- ID ox_beg_id;
42
- ID ox_bigdecimal_id;
43
- ID ox_call_id;
44
- ID ox_cdata_id;
45
- ID ox_comment_id;
46
- ID ox_den_id;
47
- ID ox_doctype_id;
48
- ID ox_end_element_id;
49
- ID ox_end_id;
50
- ID ox_end_instruct_id;
51
- ID ox_error_id;
52
- ID ox_excl_id;
53
- ID ox_external_encoding_id;
54
- ID ox_fileno_id;
55
- ID ox_force_encoding_id;
56
- ID ox_inspect_id;
57
- ID ox_instruct_id;
58
- ID ox_jd_id;
59
- ID ox_keys_id;
60
- ID ox_local_id;
61
- ID ox_mesg_id;
62
- ID ox_message_id;
63
- ID ox_new_id;
64
- ID ox_nodes_id;
65
- ID ox_num_id;
66
- ID ox_parse_id;
67
- ID ox_pos_id;
68
- ID ox_read_id;
69
- ID ox_readpartial_id;
70
- ID ox_start_element_id;
71
- ID ox_string_id;
72
- ID ox_text_id;
73
- ID ox_to_c_id;
74
- ID ox_to_s_id;
75
- ID ox_to_sym_id;
76
- ID ox_tv_nsec_id;
77
- ID ox_tv_sec_id;
78
- ID ox_tv_usec_id;
79
- ID ox_value_id;
80
-
81
- VALUE ox_encoding_sym;
82
- VALUE ox_version_sym;
83
- VALUE ox_standalone_sym;
84
- VALUE ox_indent_sym;
85
- VALUE ox_size_sym;
86
-
87
- VALUE ox_empty_string;
88
- VALUE ox_zero_fixnum;
89
- VALUE ox_sym_bank; // Array
90
-
91
- VALUE ox_arg_error_class;
92
- VALUE ox_bag_clas;
93
- VALUE ox_bigdecimal_class;
94
- VALUE ox_cdata_clas;
95
- VALUE ox_comment_clas;
96
- VALUE ox_raw_clas;
97
- VALUE ox_date_class;
98
- VALUE ox_doctype_clas;
99
- VALUE ox_document_clas;
100
- VALUE ox_element_clas;
101
- VALUE ox_instruct_clas;
102
- VALUE ox_parse_error_class;
103
- VALUE ox_stringio_class;
104
- VALUE ox_struct_class;
105
- VALUE ox_syntax_error_class;
106
- VALUE ox_time_class;
107
-
108
- Cache ox_symbol_cache = 0;
109
- Cache ox_class_cache = 0;
110
- Cache ox_attr_cache = 0;
111
-
112
- static VALUE abort_sym;
113
- static VALUE active_sym;
114
- static VALUE attr_key_mod_sym;
115
- static VALUE auto_define_sym;
116
- static VALUE auto_sym;
117
- static VALUE block_sym;
118
- static VALUE circular_sym;
119
- static VALUE convert_special_sym;
120
- static VALUE effort_sym;
121
- static VALUE generic_sym;
122
- static VALUE hash_no_attrs_sym;
123
- static VALUE hash_sym;
124
- static VALUE inactive_sym;
125
- static VALUE invalid_replace_sym;
126
- static VALUE limited_sym;
127
- static VALUE margin_sym;
128
- static VALUE mode_sym;
129
- static VALUE nest_ok_sym;
130
- static VALUE no_empty_sym;
131
- static VALUE object_sym;
132
- static VALUE off_sym;
133
- static VALUE opt_format_sym;
134
- static VALUE optimized_sym;
135
- static VALUE overlay_sym;
136
- static VALUE skip_none_sym;
137
- static VALUE skip_off_sym;
138
- static VALUE skip_return_sym;
139
- static VALUE skip_sym;
140
- static VALUE skip_white_sym;
141
- static VALUE smart_sym;
142
- static VALUE strict_sym;
143
- static VALUE strip_namespace_sym;
144
- static VALUE symbolize_keys_sym;
145
- static VALUE symbolize_sym;
146
- static VALUE tolerant_sym;
147
- static VALUE trace_sym;
148
- static VALUE with_cdata_sym;
149
- static VALUE with_dtd_sym;
150
- static VALUE with_instruct_sym;
151
- static VALUE with_xml_sym;
152
- static VALUE xsd_date_sym;
153
- static VALUE element_key_mod_sym;
154
-
155
- static ID encoding_id;
156
- static ID has_key_id;
157
-
158
- #if HAVE_RB_ENC_ASSOCIATE
159
- rb_encoding *ox_utf8_encoding = 0;
160
- #else
161
- void *ox_utf8_encoding = 0;
162
- #endif
163
-
164
- struct _options ox_default_options = {
165
- { '\0' }, // encoding
166
- { '\0' }, // margin
167
- 2, // indent
168
- 0, // trace
169
- 0, // margin_len
170
- No, // with_dtd
171
- No, // with_xml
172
- No, // with_instruct
173
- No, // circular
174
- No, // xsd_date
175
- NoMode, // mode
176
- StrictEffort, // effort
177
- Yes, // sym_keys
178
- SpcSkip, // skip
179
- No, // smart
180
- true, // convert_special
181
- No, // allow_invalid
182
- false, // no_empty
183
- false, // with_cdata
184
- { '\0' }, // inv_repl
185
- { '\0' }, // strip_ns
186
- NULL, // html_hints
187
- Qnil, // attr_key_mod;
188
- Qnil, // element_key_mod;
189
- 0 // rb_enc
30
+ VALUE Ox = Qnil;
31
+
32
+ ID ox_abort_id;
33
+ ID ox_at_column_id;
34
+ ID ox_at_content_id;
35
+ ID ox_at_id;
36
+ ID ox_at_line_id;
37
+ ID ox_at_pos_id;
38
+ ID ox_at_value_id;
39
+ ID ox_attr_id;
40
+ ID ox_attr_value_id;
41
+ ID ox_attributes_id;
42
+ ID ox_attrs_done_id;
43
+ ID ox_beg_id;
44
+ ID ox_bigdecimal_id;
45
+ ID ox_call_id;
46
+ ID ox_cdata_id;
47
+ ID ox_comment_id;
48
+ ID ox_den_id;
49
+ ID ox_doctype_id;
50
+ ID ox_end_element_id;
51
+ ID ox_end_id;
52
+ ID ox_end_instruct_id;
53
+ ID ox_error_id;
54
+ ID ox_excl_id;
55
+ ID ox_external_encoding_id;
56
+ ID ox_fileno_id;
57
+ ID ox_force_encoding_id;
58
+ ID ox_inspect_id;
59
+ ID ox_instruct_id;
60
+ ID ox_jd_id;
61
+ ID ox_keys_id;
62
+ ID ox_local_id;
63
+ ID ox_mesg_id;
64
+ ID ox_message_id;
65
+ ID ox_new_id;
66
+ ID ox_nodes_id;
67
+ ID ox_num_id;
68
+ ID ox_parse_id;
69
+ ID ox_pos_id;
70
+ ID ox_read_id;
71
+ ID ox_readpartial_id;
72
+ ID ox_start_element_id;
73
+ ID ox_string_id;
74
+ ID ox_text_id;
75
+ ID ox_to_c_id;
76
+ ID ox_to_s_id;
77
+ ID ox_to_sym_id;
78
+ ID ox_tv_nsec_id;
79
+ ID ox_tv_sec_id;
80
+ ID ox_tv_usec_id;
81
+ ID ox_value_id;
82
+
83
+ VALUE ox_encoding_sym;
84
+ VALUE ox_version_sym;
85
+ VALUE ox_standalone_sym;
86
+ VALUE ox_indent_sym;
87
+ VALUE ox_size_sym;
88
+
89
+ VALUE ox_empty_string;
90
+ VALUE ox_zero_fixnum;
91
+ VALUE ox_sym_bank; // Array
92
+
93
+ VALUE ox_arg_error_class;
94
+ VALUE ox_bag_clas;
95
+ VALUE ox_bigdecimal_class;
96
+ VALUE ox_cdata_clas;
97
+ VALUE ox_comment_clas;
98
+ VALUE ox_raw_clas;
99
+ VALUE ox_date_class;
100
+ VALUE ox_doctype_clas;
101
+ VALUE ox_document_clas;
102
+ VALUE ox_element_clas;
103
+ VALUE ox_instruct_clas;
104
+ VALUE ox_parse_error_class;
105
+ VALUE ox_stringio_class;
106
+ VALUE ox_struct_class;
107
+ VALUE ox_syntax_error_class;
108
+ VALUE ox_time_class;
109
+
110
+ SlotCache ox_class_cache = 0;
111
+
112
+ static VALUE abort_sym;
113
+ static VALUE active_sym;
114
+ static VALUE attr_key_mod_sym;
115
+ static VALUE auto_define_sym;
116
+ static VALUE auto_sym;
117
+ static VALUE block_sym;
118
+ static VALUE circular_sym;
119
+ static VALUE convert_special_sym;
120
+ static VALUE effort_sym;
121
+ static VALUE generic_sym;
122
+ static VALUE hash_no_attrs_sym;
123
+ static VALUE hash_sym;
124
+ static VALUE inactive_sym;
125
+ static VALUE invalid_replace_sym;
126
+ static VALUE limited_sym;
127
+ static VALUE margin_sym;
128
+ static VALUE mode_sym;
129
+ static VALUE nest_ok_sym;
130
+ static VALUE no_empty_sym;
131
+ static VALUE object_sym;
132
+ static VALUE off_sym;
133
+ static VALUE opt_format_sym;
134
+ static VALUE optimized_sym;
135
+ static VALUE overlay_sym;
136
+ static VALUE skip_none_sym;
137
+ static VALUE skip_off_sym;
138
+ static VALUE skip_return_sym;
139
+ static VALUE skip_sym;
140
+ static VALUE skip_white_sym;
141
+ static VALUE smart_sym;
142
+ static VALUE strict_sym;
143
+ static VALUE strip_namespace_sym;
144
+ static VALUE symbolize_keys_sym;
145
+ static VALUE symbolize_sym;
146
+ static VALUE tolerant_sym;
147
+ static VALUE trace_sym;
148
+ static VALUE with_cdata_sym;
149
+ static VALUE with_dtd_sym;
150
+ static VALUE with_instruct_sym;
151
+ static VALUE with_xml_sym;
152
+ static VALUE xsd_date_sym;
153
+ static VALUE element_key_mod_sym;
154
+
155
+ static ID encoding_id;
156
+ static ID has_key_id;
157
+
158
+ rb_encoding *ox_utf8_encoding = 0;
159
+
160
+ struct _options ox_default_options = {
161
+ {'\0'}, // encoding
162
+ {'\0'}, // margin
163
+ 2, // indent
164
+ 0, // trace
165
+ 0, // margin_len
166
+ No, // with_dtd
167
+ No, // with_xml
168
+ No, // with_instruct
169
+ No, // circular
170
+ No, // xsd_date
171
+ NoMode, // mode
172
+ StrictEffort, // effort
173
+ Yes, // sym_keys
174
+ SpcSkip, // skip
175
+ No, // smart
176
+ true, // convert_special
177
+ No, // allow_invalid
178
+ false, // no_empty
179
+ false, // with_cdata
180
+ {'\0'}, // inv_repl
181
+ {'\0'}, // strip_ns
182
+ NULL, // html_hints
183
+ Qnil, // attr_key_mod;
184
+ Qnil, // element_key_mod;
185
+ 0 // rb_enc
190
186
  };
191
187
 
192
- extern ParseCallbacks ox_obj_callbacks;
193
- extern ParseCallbacks ox_gen_callbacks;
194
- extern ParseCallbacks ox_limited_callbacks;
195
- extern ParseCallbacks ox_nomode_callbacks;
196
- extern ParseCallbacks ox_hash_callbacks;
197
- extern ParseCallbacks ox_hash_cdata_callbacks;
198
- extern ParseCallbacks ox_hash_no_attrs_callbacks;
199
- extern ParseCallbacks ox_hash_no_attrs_cdata_callbacks;
188
+ extern ParseCallbacks ox_obj_callbacks;
189
+ extern ParseCallbacks ox_gen_callbacks;
190
+ extern ParseCallbacks ox_limited_callbacks;
191
+ extern ParseCallbacks ox_nomode_callbacks;
192
+ extern ParseCallbacks ox_hash_callbacks;
193
+ extern ParseCallbacks ox_hash_cdata_callbacks;
194
+ extern ParseCallbacks ox_hash_no_attrs_callbacks;
195
+ extern ParseCallbacks ox_hash_no_attrs_cdata_callbacks;
200
196
 
201
- static void parse_dump_options(VALUE ropts, Options copts);
197
+ static void parse_dump_options(VALUE ropts, Options copts);
202
198
 
203
- static char*
204
- defuse_bom(char *xml, Options options) {
199
+ static char *defuse_bom(char *xml, Options options) {
205
200
  switch ((uint8_t)*xml) {
206
- case 0xEF: // UTF-8
207
- if (0xBB == (uint8_t)xml[1] && 0xBF == (uint8_t)xml[2]) {
208
- options->rb_enc = ox_utf8_encoding;
209
- xml += 3;
210
- } else {
211
- rb_raise(ox_parse_error_class, "Invalid BOM in XML string.\n");
212
- }
213
- break;
201
+ case 0xEF: // UTF-8
202
+ if (0xBB == (uint8_t)xml[1] && 0xBF == (uint8_t)xml[2]) {
203
+ options->rb_enc = ox_utf8_encoding;
204
+ xml += 3;
205
+ } else {
206
+ rb_raise(ox_parse_error_class, "Invalid BOM in XML string.\n");
207
+ }
208
+ break;
214
209
  #if 0
215
210
  case 0xFE: // UTF-16BE
216
211
  if (0xFF == (uint8_t)xml[1]) {
@@ -243,31 +238,30 @@ defuse_bom(char *xml, Options options) {
243
238
  break;
244
239
  #endif
245
240
  default:
246
- // Let it fail if there is a BOM that is not UTF-8. Other BOM options
247
- // are not ASCII compatible.
248
- break;
241
+ // Let it fail if there is a BOM that is not UTF-8. Other BOM options
242
+ // are not ASCII compatible.
243
+ break;
249
244
  }
250
245
  return xml;
251
246
  }
252
247
 
253
- static VALUE
254
- hints_to_overlay(Hints hints) {
255
- volatile VALUE overlay = rb_hash_new();
256
- Hint h;
257
- int i;
258
- VALUE ov;
248
+ static VALUE hints_to_overlay(Hints hints) {
249
+ volatile VALUE overlay = rb_hash_new();
250
+ Hint h;
251
+ int i;
252
+ VALUE ov;
259
253
 
260
254
  for (i = hints->size, h = hints->hints; 0 < i; i--, h++) {
261
- switch (h->overlay) {
262
- case InactiveOverlay: ov = inactive_sym; break;
263
- case BlockOverlay: ov = block_sym; break;
264
- case OffOverlay: ov = off_sym; break;
265
- case AbortOverlay: ov = abort_sym; break;
266
- case NestOverlay: ov = nest_ok_sym; break;
267
- case ActiveOverlay:
268
- default: ov = active_sym; break;
269
- }
270
- rb_hash_aset(overlay, rb_str_new2(h->name), ov);
255
+ switch (h->overlay) {
256
+ case InactiveOverlay: ov = inactive_sym; break;
257
+ case BlockOverlay: ov = block_sym; break;
258
+ case OffOverlay: ov = off_sym; break;
259
+ case AbortOverlay: ov = abort_sym; break;
260
+ case NestOverlay: ov = nest_ok_sym; break;
261
+ case ActiveOverlay:
262
+ default: ov = active_sym; break;
263
+ }
264
+ rb_hash_aset(overlay, rb_str_new2(h->name), ov);
271
265
  }
272
266
  return overlay;
273
267
  }
@@ -292,10 +286,12 @@ hints_to_overlay(Hints hints) {
292
286
  * - _:skip_ [:skip_none|:skip_return|:skip_white|:skip_off] determines how to handle white space in text
293
287
  * - _:smart_ [true|false|nil] flag indicating the SAX parser uses hints if available (use with html)
294
288
  * - _:convert_special_ [true|false|nil] flag indicating special characters like &lt; are converted with the SAX parser
295
- * - _:invalid_replace_ [nil|String] replacement string for invalid XML characters on dump. nil indicates include anyway as hex. A string, limited to 10 characters will replace the invalid character with the replace.
289
+ * - _:invalid_replace_ [nil|String] replacement string for invalid XML characters on dump. nil indicates include anyway
290
+ * as hex. A string, limited to 10 characters will replace the invalid character with the replace.
296
291
  * - _:no_empty_ [true|false|nil] flag indicating there should be no empty elements in a dump
297
292
  * - _:with_cdata_ [true|false] includes cdata in hash_load results
298
- * - _:strip_namespace_ [String|true|false] false or "" results in no namespace stripping. A string of "*" or true will strip all namespaces. Any other non-empty string indicates that matching namespaces will be stripped.
293
+ * - _:strip_namespace_ [String|true|false] false or "" results in no namespace stripping. A string of "*" or true will
294
+ * strip all namespaces. Any other non-empty string indicates that matching namespaces will be stripped.
299
295
  * - _:overlay_ [Hash] a Hash of keys that match html element names and values that are one of
300
296
  * - _:active_ - make the normal callback for the element
301
297
  * - _:nest_ok_ - active but the nesting check is ignored
@@ -309,90 +305,107 @@ hints_to_overlay(Hints hints) {
309
305
  * Note that an indent of less than zero will result in a tight one line output
310
306
  * unless the text in the XML fields contain new line characters.
311
307
  */
312
- static VALUE
313
- get_def_opts(VALUE self) {
314
- VALUE opts = rb_hash_new();
315
- int elen = (int)strlen(ox_default_options.encoding);
308
+ static VALUE get_def_opts(VALUE self) {
309
+ VALUE opts = rb_hash_new();
310
+ int elen = (int)strlen(ox_default_options.encoding);
316
311
 
317
312
  rb_hash_aset(opts, ox_encoding_sym, (0 == elen) ? Qnil : rb_str_new(ox_default_options.encoding, elen));
318
313
  rb_hash_aset(opts, margin_sym, rb_str_new(ox_default_options.margin, ox_default_options.margin_len));
319
314
  rb_hash_aset(opts, ox_indent_sym, INT2FIX(ox_default_options.indent));
320
315
  rb_hash_aset(opts, trace_sym, INT2FIX(ox_default_options.trace));
321
- rb_hash_aset(opts, with_dtd_sym, (Yes == ox_default_options.with_dtd) ? Qtrue : ((No == ox_default_options.with_dtd) ? Qfalse : Qnil));
322
- rb_hash_aset(opts, with_xml_sym, (Yes == ox_default_options.with_xml) ? Qtrue : ((No == ox_default_options.with_xml) ? Qfalse : Qnil));
323
- rb_hash_aset(opts, with_instruct_sym, (Yes == ox_default_options.with_instruct) ? Qtrue : ((No == ox_default_options.with_instruct) ? Qfalse : Qnil));
324
- rb_hash_aset(opts, circular_sym, (Yes == ox_default_options.circular) ? Qtrue : ((No == ox_default_options.circular) ? Qfalse : Qnil));
325
- rb_hash_aset(opts, xsd_date_sym, (Yes == ox_default_options.xsd_date) ? Qtrue : ((No == ox_default_options.xsd_date) ? Qfalse : Qnil));
326
- rb_hash_aset(opts, symbolize_keys_sym, (Yes == ox_default_options.sym_keys) ? Qtrue : ((No == ox_default_options.sym_keys) ? Qfalse : Qnil));
316
+ rb_hash_aset(opts,
317
+ with_dtd_sym,
318
+ (Yes == ox_default_options.with_dtd) ? Qtrue : ((No == ox_default_options.with_dtd) ? Qfalse : Qnil));
319
+ rb_hash_aset(opts,
320
+ with_xml_sym,
321
+ (Yes == ox_default_options.with_xml) ? Qtrue : ((No == ox_default_options.with_xml) ? Qfalse : Qnil));
322
+ rb_hash_aset(
323
+ opts,
324
+ with_instruct_sym,
325
+ (Yes == ox_default_options.with_instruct) ? Qtrue : ((No == ox_default_options.with_instruct) ? Qfalse : Qnil));
326
+ rb_hash_aset(opts,
327
+ circular_sym,
328
+ (Yes == ox_default_options.circular) ? Qtrue : ((No == ox_default_options.circular) ? Qfalse : Qnil));
329
+ rb_hash_aset(opts,
330
+ xsd_date_sym,
331
+ (Yes == ox_default_options.xsd_date) ? Qtrue : ((No == ox_default_options.xsd_date) ? Qfalse : Qnil));
332
+ rb_hash_aset(opts,
333
+ symbolize_keys_sym,
334
+ (Yes == ox_default_options.sym_keys) ? Qtrue : ((No == ox_default_options.sym_keys) ? Qfalse : Qnil));
327
335
  rb_hash_aset(opts, attr_key_mod_sym, ox_default_options.attr_key_mod);
328
336
  rb_hash_aset(opts, element_key_mod_sym, ox_default_options.element_key_mod);
329
- rb_hash_aset(opts, smart_sym, (Yes == ox_default_options.smart) ? Qtrue : ((No == ox_default_options.smart) ? Qfalse : Qnil));
337
+ rb_hash_aset(opts,
338
+ smart_sym,
339
+ (Yes == ox_default_options.smart) ? Qtrue : ((No == ox_default_options.smart) ? Qfalse : Qnil));
330
340
  rb_hash_aset(opts, convert_special_sym, (ox_default_options.convert_special) ? Qtrue : Qfalse);
331
341
  rb_hash_aset(opts, no_empty_sym, (ox_default_options.no_empty) ? Qtrue : Qfalse);
332
342
  rb_hash_aset(opts, with_cdata_sym, (ox_default_options.with_cdata) ? Qtrue : Qfalse);
333
343
  switch (ox_default_options.mode) {
334
- case ObjMode: rb_hash_aset(opts, mode_sym, object_sym); break;
335
- case GenMode: rb_hash_aset(opts, mode_sym, generic_sym); break;
336
- case LimMode: rb_hash_aset(opts, mode_sym, limited_sym); break;
337
- case HashMode: rb_hash_aset(opts, mode_sym, hash_sym); break;
338
- case HashNoAttrMode: rb_hash_aset(opts, mode_sym, hash_no_attrs_sym); break;
344
+ case ObjMode: rb_hash_aset(opts, mode_sym, object_sym); break;
345
+ case GenMode: rb_hash_aset(opts, mode_sym, generic_sym); break;
346
+ case LimMode: rb_hash_aset(opts, mode_sym, limited_sym); break;
347
+ case HashMode: rb_hash_aset(opts, mode_sym, hash_sym); break;
348
+ case HashNoAttrMode: rb_hash_aset(opts, mode_sym, hash_no_attrs_sym); break;
339
349
  case NoMode:
340
- default: rb_hash_aset(opts, mode_sym, Qnil); break;
350
+ default: rb_hash_aset(opts, mode_sym, Qnil); break;
341
351
  }
342
352
  switch (ox_default_options.effort) {
343
- case StrictEffort: rb_hash_aset(opts, effort_sym, strict_sym); break;
344
- case TolerantEffort: rb_hash_aset(opts, effort_sym, tolerant_sym); break;
345
- case AutoEffort: rb_hash_aset(opts, effort_sym, auto_define_sym); break;
353
+ case StrictEffort: rb_hash_aset(opts, effort_sym, strict_sym); break;
354
+ case TolerantEffort: rb_hash_aset(opts, effort_sym, tolerant_sym); break;
355
+ case AutoEffort: rb_hash_aset(opts, effort_sym, auto_define_sym); break;
346
356
  case NoEffort:
347
- default: rb_hash_aset(opts, effort_sym, Qnil); break;
357
+ default: rb_hash_aset(opts, effort_sym, Qnil); break;
348
358
  }
349
359
  switch (ox_default_options.skip) {
350
- case OffSkip: rb_hash_aset(opts, skip_sym, skip_off_sym); break;
351
- case NoSkip: rb_hash_aset(opts, skip_sym, skip_none_sym); break;
352
- case CrSkip: rb_hash_aset(opts, skip_sym, skip_return_sym); break;
353
- case SpcSkip: rb_hash_aset(opts, skip_sym, skip_white_sym); break;
354
- default: rb_hash_aset(opts, skip_sym, Qnil); break;
360
+ case OffSkip: rb_hash_aset(opts, skip_sym, skip_off_sym); break;
361
+ case NoSkip: rb_hash_aset(opts, skip_sym, skip_none_sym); break;
362
+ case CrSkip: rb_hash_aset(opts, skip_sym, skip_return_sym); break;
363
+ case SpcSkip: rb_hash_aset(opts, skip_sym, skip_white_sym); break;
364
+ default: rb_hash_aset(opts, skip_sym, Qnil); break;
355
365
  }
356
366
  if (Yes == ox_default_options.allow_invalid) {
357
- rb_hash_aset(opts, invalid_replace_sym, Qnil);
367
+ rb_hash_aset(opts, invalid_replace_sym, Qnil);
358
368
  } else {
359
- rb_hash_aset(opts, invalid_replace_sym, rb_str_new(ox_default_options.inv_repl + 1, (int)*ox_default_options.inv_repl));
369
+ rb_hash_aset(opts,
370
+ invalid_replace_sym,
371
+ rb_str_new(ox_default_options.inv_repl + 1, (int)*ox_default_options.inv_repl));
360
372
  }
361
373
  if ('\0' == *ox_default_options.strip_ns) {
362
- rb_hash_aset(opts, strip_namespace_sym, Qfalse);
374
+ rb_hash_aset(opts, strip_namespace_sym, Qfalse);
363
375
  } else if ('*' == *ox_default_options.strip_ns && '\0' == ox_default_options.strip_ns[1]) {
364
- rb_hash_aset(opts, strip_namespace_sym, Qtrue);
376
+ rb_hash_aset(opts, strip_namespace_sym, Qtrue);
365
377
  } else {
366
- rb_hash_aset(opts, strip_namespace_sym, rb_str_new(ox_default_options.strip_ns, strlen(ox_default_options.strip_ns)));
378
+ rb_hash_aset(opts,
379
+ strip_namespace_sym,
380
+ rb_str_new(ox_default_options.strip_ns, strlen(ox_default_options.strip_ns)));
367
381
  }
368
382
  if (NULL == ox_default_options.html_hints) {
369
- //rb_hash_aset(opts, overlay_sym, hints_to_overlay(ox_hints_html()));
370
- rb_hash_aset(opts, overlay_sym, Qnil);
383
+ // rb_hash_aset(opts, overlay_sym, hints_to_overlay(ox_hints_html()));
384
+ rb_hash_aset(opts, overlay_sym, Qnil);
371
385
  } else {
372
- rb_hash_aset(opts, overlay_sym, hints_to_overlay(ox_default_options.html_hints));
386
+ rb_hash_aset(opts, overlay_sym, hints_to_overlay(ox_default_options.html_hints));
373
387
  }
374
388
  return opts;
375
389
  }
376
390
 
377
- static int
378
- set_overlay(VALUE key, VALUE value, VALUE ctx) {
379
- Hints hints = (Hints)ctx;
380
- Hint hint;
391
+ static int set_overlay(VALUE key, VALUE value, VALUE ctx) {
392
+ Hints hints = (Hints)ctx;
393
+ Hint hint;
381
394
 
382
395
  if (NULL != (hint = ox_hint_find(hints, StringValuePtr(key)))) {
383
- if (active_sym == value) {
384
- hint->overlay = ActiveOverlay;
385
- } else if (inactive_sym == value) {
386
- hint->overlay = InactiveOverlay;
387
- } else if (block_sym == value) {
388
- hint->overlay = BlockOverlay;
389
- } else if (nest_ok_sym == value) {
390
- hint->overlay = NestOverlay;
391
- } else if (off_sym == value) {
392
- hint->overlay = OffOverlay;
393
- } else if (abort_sym == value) {
394
- hint->overlay = AbortOverlay;
395
- }
396
+ if (active_sym == value) {
397
+ hint->overlay = ActiveOverlay;
398
+ } else if (inactive_sym == value) {
399
+ hint->overlay = InactiveOverlay;
400
+ } else if (block_sym == value) {
401
+ hint->overlay = BlockOverlay;
402
+ } else if (nest_ok_sym == value) {
403
+ hint->overlay = NestOverlay;
404
+ } else if (off_sym == value) {
405
+ hint->overlay = OffOverlay;
406
+ } else if (abort_sym == value) {
407
+ hint->overlay = AbortOverlay;
408
+ }
396
409
  }
397
410
  return ST_CONTINUE;
398
411
  }
@@ -410,8 +423,7 @@ set_overlay(VALUE key, VALUE value, VALUE ctx) {
410
423
  *
411
424
  * *return* [Hash] default SAX HTML settings
412
425
  */
413
- static VALUE
414
- sax_html_overlay(VALUE self) {
426
+ static VALUE sax_html_overlay(VALUE self) {
415
427
  return hints_to_overlay(ox_hints_html());
416
428
  }
417
429
 
@@ -435,8 +447,10 @@ sax_html_overlay(VALUE self) {
435
447
  * - _:attr_key_mod_ [Proc|nil] converts attribute keys on parse if not nil
436
448
  * - _:skip_ [:skip_none|:skip_return|:skip_white|:skip_off] determines how to handle white space in text
437
449
  * - _:smart_ [true|false|nil] flag indicating the SAX parser uses hints if available (use with html)
438
- * - _:invalid_replace_ [nil|String] replacement string for invalid XML characters on dump. nil indicates include anyway as hex. A string, limited to 10 characters will replace the invalid character with the replace.
439
- * - _:strip_namespace_ [nil|String|true|false] "" or false result in no namespace stripping. A string of "*" or true will strip all namespaces. Any other non-empty string indicates that matching namespaces will be stripped.
450
+ * - _:invalid_replace_ [nil|String] replacement string for invalid XML characters on dump. nil indicates include
451
+ * anyway as hex. A string, limited to 10 characters will replace the invalid character with the replace.
452
+ * - _:strip_namespace_ [nil|String|true|false] "" or false result in no namespace stripping. A string of "*" or true
453
+ * will strip all namespaces. Any other non-empty string indicates that matching namespaces will be stripped.
440
454
  * - _:with_cdata_ [true|false] includes cdata in hash_load results
441
455
  * - _:overlay_ [Hash] a Hash of keys that match html element names and values that are one of
442
456
  * - _:active_ - make the normal callback for the element
@@ -448,201 +462,199 @@ sax_html_overlay(VALUE self) {
448
462
  *
449
463
  * *return* [nil]
450
464
  */
451
- static VALUE
452
- set_def_opts(VALUE self, VALUE opts) {
453
- struct _yesNoOpt ynos[] = {
454
- { with_xml_sym, &ox_default_options.with_xml },
455
- { with_dtd_sym, &ox_default_options.with_dtd },
456
- { with_instruct_sym, &ox_default_options.with_instruct },
457
- { xsd_date_sym, &ox_default_options.xsd_date },
458
- { circular_sym, &ox_default_options.circular },
459
- { symbolize_keys_sym, &ox_default_options.sym_keys },
460
- { smart_sym, &ox_default_options.smart },
461
- { Qnil, 0 }
462
- };
463
- YesNoOpt o;
464
- VALUE v;
465
+ static VALUE set_def_opts(VALUE self, VALUE opts) {
466
+ struct _yesNoOpt ynos[] = {{with_xml_sym, &ox_default_options.with_xml},
467
+ {with_dtd_sym, &ox_default_options.with_dtd},
468
+ {with_instruct_sym, &ox_default_options.with_instruct},
469
+ {xsd_date_sym, &ox_default_options.xsd_date},
470
+ {circular_sym, &ox_default_options.circular},
471
+ {symbolize_keys_sym, &ox_default_options.sym_keys},
472
+ {smart_sym, &ox_default_options.smart},
473
+ {Qnil, 0}};
474
+ YesNoOpt o;
475
+ VALUE v;
465
476
 
466
477
  Check_Type(opts, T_HASH);
467
478
 
468
479
  v = rb_hash_aref(opts, ox_encoding_sym);
469
480
  if (Qnil == v) {
470
- *ox_default_options.encoding = '\0';
481
+ *ox_default_options.encoding = '\0';
471
482
  } else {
472
- Check_Type(v, T_STRING);
473
- strncpy(ox_default_options.encoding, StringValuePtr(v), sizeof(ox_default_options.encoding) - 1);
474
- #if HAVE_RB_ENC_FIND
475
- ox_default_options.rb_enc = rb_enc_find(ox_default_options.encoding);
476
- #endif
483
+ Check_Type(v, T_STRING);
484
+ strncpy(ox_default_options.encoding, StringValuePtr(v), sizeof(ox_default_options.encoding) - 1);
485
+ ox_default_options.rb_enc = rb_enc_find(ox_default_options.encoding);
477
486
  }
478
487
 
479
488
  v = rb_hash_aref(opts, ox_indent_sym);
480
489
  if (Qnil != v) {
481
- Check_Type(v, T_FIXNUM);
482
- ox_default_options.indent = FIX2INT(v);
490
+ Check_Type(v, T_FIXNUM);
491
+ ox_default_options.indent = FIX2INT(v);
483
492
  }
484
493
 
485
494
  v = rb_hash_aref(opts, trace_sym);
486
495
  if (Qnil != v) {
487
- Check_Type(v, T_FIXNUM);
488
- ox_default_options.trace = FIX2INT(v);
496
+ Check_Type(v, T_FIXNUM);
497
+ ox_default_options.trace = FIX2INT(v);
489
498
  }
490
499
 
491
500
  v = rb_hash_aref(opts, mode_sym);
492
501
  if (Qnil == v) {
493
- ox_default_options.mode = NoMode;
502
+ ox_default_options.mode = NoMode;
494
503
  } else if (object_sym == v) {
495
- ox_default_options.mode = ObjMode;
504
+ ox_default_options.mode = ObjMode;
496
505
  } else if (generic_sym == v) {
497
- ox_default_options.mode = GenMode;
506
+ ox_default_options.mode = GenMode;
498
507
  } else if (limited_sym == v) {
499
- ox_default_options.mode = LimMode;
508
+ ox_default_options.mode = LimMode;
500
509
  } else if (hash_sym == v) {
501
- ox_default_options.mode = HashMode;
510
+ ox_default_options.mode = HashMode;
502
511
  } else if (hash_no_attrs_sym == v) {
503
- ox_default_options.mode = HashNoAttrMode;
512
+ ox_default_options.mode = HashNoAttrMode;
504
513
  } else {
505
- rb_raise(ox_parse_error_class, ":mode must be :object, :generic, :limited, :hash, :hash_no_attrs, or nil.\n");
514
+ rb_raise(ox_parse_error_class, ":mode must be :object, :generic, :limited, :hash, :hash_no_attrs, or nil.\n");
506
515
  }
507
516
 
508
517
  v = rb_hash_aref(opts, effort_sym);
509
518
  if (Qnil == v) {
510
- ox_default_options.effort = NoEffort;
519
+ ox_default_options.effort = NoEffort;
511
520
  } else if (strict_sym == v) {
512
- ox_default_options.effort = StrictEffort;
521
+ ox_default_options.effort = StrictEffort;
513
522
  } else if (tolerant_sym == v) {
514
- ox_default_options.effort = TolerantEffort;
523
+ ox_default_options.effort = TolerantEffort;
515
524
  } else if (auto_define_sym == v) {
516
- ox_default_options.effort = AutoEffort;
525
+ ox_default_options.effort = AutoEffort;
517
526
  } else {
518
- rb_raise(ox_parse_error_class, ":effort must be :strict, :tolerant, :auto_define, or nil.\n");
527
+ rb_raise(ox_parse_error_class, ":effort must be :strict, :tolerant, :auto_define, or nil.\n");
519
528
  }
520
529
 
521
530
  v = rb_hash_aref(opts, skip_sym);
522
531
  if (Qnil == v) {
523
- ox_default_options.skip = NoSkip;
532
+ ox_default_options.skip = NoSkip;
524
533
  } else if (skip_off_sym == v) {
525
- ox_default_options.skip = OffSkip;
534
+ ox_default_options.skip = OffSkip;
526
535
  } else if (skip_none_sym == v) {
527
- ox_default_options.skip = NoSkip;
536
+ ox_default_options.skip = NoSkip;
528
537
  } else if (skip_return_sym == v) {
529
- ox_default_options.skip = CrSkip;
538
+ ox_default_options.skip = CrSkip;
530
539
  } else if (skip_white_sym == v) {
531
- ox_default_options.skip = SpcSkip;
540
+ ox_default_options.skip = SpcSkip;
532
541
  } else {
533
- rb_raise(ox_parse_error_class, ":skip must be :skip_none, :skip_return, :skip_white, :skip_off, or nil.\n");
542
+ rb_raise(ox_parse_error_class, ":skip must be :skip_none, :skip_return, :skip_white, :skip_off, or nil.\n");
534
543
  }
535
544
 
536
545
  v = rb_hash_lookup(opts, convert_special_sym);
537
546
  if (Qnil == v) {
538
- // no change
547
+ // no change
539
548
  } else if (Qtrue == v) {
540
- ox_default_options.convert_special = 1;
549
+ ox_default_options.convert_special = 1;
541
550
  } else if (Qfalse == v) {
542
- ox_default_options.convert_special = 0;
551
+ ox_default_options.convert_special = 0;
543
552
  } else {
544
- rb_raise(ox_parse_error_class, ":convert_special must be true or false.\n");
553
+ rb_raise(ox_parse_error_class, ":convert_special must be true or false.\n");
545
554
  }
546
555
 
547
556
  v = rb_hash_lookup(opts, no_empty_sym);
548
557
  if (Qnil == v) {
549
- // no change
558
+ // no change
550
559
  } else if (Qtrue == v) {
551
- ox_default_options.no_empty = 1;
560
+ ox_default_options.no_empty = 1;
552
561
  } else if (Qfalse == v) {
553
- ox_default_options.no_empty = 0;
562
+ ox_default_options.no_empty = 0;
554
563
  } else {
555
- rb_raise(ox_parse_error_class, ":no_empty must be true or false.\n");
564
+ rb_raise(ox_parse_error_class, ":no_empty must be true or false.\n");
556
565
  }
557
566
 
558
567
  v = rb_hash_aref(opts, invalid_replace_sym);
559
568
  if (Qnil == v) {
560
- ox_default_options.allow_invalid = Yes;
569
+ ox_default_options.allow_invalid = Yes;
561
570
  } else {
562
- long slen;
563
-
564
- Check_Type(v, T_STRING);
565
- slen = RSTRING_LEN(v);
566
- if (sizeof(ox_default_options.inv_repl) - 2 < (size_t)slen) {
567
- rb_raise(ox_parse_error_class, ":invalid_replace can be no longer than %d characters.",
568
- (int)sizeof(ox_default_options.inv_repl) - 2);
569
- }
570
- strncpy(ox_default_options.inv_repl + 1, StringValuePtr(v), sizeof(ox_default_options.inv_repl) - 1);
571
- ox_default_options.inv_repl[sizeof(ox_default_options.inv_repl) - 1] = '\0';
572
- *ox_default_options.inv_repl = (char)slen;
573
- ox_default_options.allow_invalid = No;
571
+ long slen;
572
+
573
+ Check_Type(v, T_STRING);
574
+ slen = RSTRING_LEN(v);
575
+ if (sizeof(ox_default_options.inv_repl) - 2 < (size_t)slen) {
576
+ rb_raise(ox_parse_error_class,
577
+ ":invalid_replace can be no longer than %d characters.",
578
+ (int)sizeof(ox_default_options.inv_repl) - 2);
579
+ }
580
+ strncpy(ox_default_options.inv_repl + 1, StringValuePtr(v), sizeof(ox_default_options.inv_repl) - 1);
581
+ ox_default_options.inv_repl[sizeof(ox_default_options.inv_repl) - 1] = '\0';
582
+ *ox_default_options.inv_repl = (char)slen;
583
+ ox_default_options.allow_invalid = No;
574
584
  }
575
585
 
576
586
  v = rb_hash_aref(opts, strip_namespace_sym);
577
587
  if (Qfalse == v) {
578
- *ox_default_options.strip_ns = '\0';
588
+ *ox_default_options.strip_ns = '\0';
579
589
  } else if (Qtrue == v) {
580
- *ox_default_options.strip_ns = '*';
581
- ox_default_options.strip_ns[1] = '\0';
590
+ *ox_default_options.strip_ns = '*';
591
+ ox_default_options.strip_ns[1] = '\0';
582
592
  } else if (Qnil != v) {
583
- long slen;
584
-
585
- Check_Type(v, T_STRING);
586
- slen = RSTRING_LEN(v);
587
- if (sizeof(ox_default_options.strip_ns) - 1 < (size_t)slen) {
588
- rb_raise(ox_parse_error_class, ":strip_namespace can be no longer than %d characters.",
589
- (int)sizeof(ox_default_options.strip_ns) - 1);
590
- }
591
- strncpy(ox_default_options.strip_ns, StringValuePtr(v), sizeof(ox_default_options.strip_ns) - 1);
592
- ox_default_options.strip_ns[sizeof(ox_default_options.strip_ns) - 1] = '\0';
593
+ long slen;
594
+
595
+ Check_Type(v, T_STRING);
596
+ slen = RSTRING_LEN(v);
597
+ if (sizeof(ox_default_options.strip_ns) - 1 < (size_t)slen) {
598
+ rb_raise(ox_parse_error_class,
599
+ ":strip_namespace can be no longer than %d characters.",
600
+ (int)sizeof(ox_default_options.strip_ns) - 1);
601
+ }
602
+ strncpy(ox_default_options.strip_ns, StringValuePtr(v), sizeof(ox_default_options.strip_ns) - 1);
603
+ ox_default_options.strip_ns[sizeof(ox_default_options.strip_ns) - 1] = '\0';
593
604
  }
594
605
 
595
606
  v = rb_hash_aref(opts, margin_sym);
596
607
  if (Qnil != v) {
597
- long slen;
598
-
599
- Check_Type(v, T_STRING);
600
- slen = RSTRING_LEN(v);
601
- if (sizeof(ox_default_options.margin) - 1 < (size_t)slen) {
602
- rb_raise(ox_parse_error_class, ":margin can be no longer than %d characters.",
603
- (int)sizeof(ox_default_options.margin) - 1);
604
- }
605
- strncpy(ox_default_options.margin, StringValuePtr(v), sizeof(ox_default_options.margin) - 1);
606
- ox_default_options.margin[sizeof(ox_default_options.margin) - 1] = '\0';
607
- ox_default_options.margin_len = strlen(ox_default_options.margin);
608
+ long slen;
609
+
610
+ Check_Type(v, T_STRING);
611
+ slen = RSTRING_LEN(v);
612
+ if (sizeof(ox_default_options.margin) - 1 < (size_t)slen) {
613
+ rb_raise(ox_parse_error_class,
614
+ ":margin can be no longer than %d characters.",
615
+ (int)sizeof(ox_default_options.margin) - 1);
616
+ }
617
+ strncpy(ox_default_options.margin, StringValuePtr(v), sizeof(ox_default_options.margin) - 1);
618
+ ox_default_options.margin[sizeof(ox_default_options.margin) - 1] = '\0';
619
+ ox_default_options.margin_len = strlen(ox_default_options.margin);
608
620
  }
609
621
 
610
622
  for (o = ynos; 0 != o->attr; o++) {
611
- v = rb_hash_lookup(opts, o->sym);
612
- if (Qnil == v) {
613
- *o->attr = NotSet;
614
- } else if (Qtrue == v) {
615
- *o->attr = Yes;
616
- } else if (Qfalse == v) {
617
- *o->attr = No;
618
- } else {
619
- rb_raise(ox_parse_error_class, "%s must be true or false.\n", rb_id2name(SYM2ID(o->sym)));
620
- }
623
+ v = rb_hash_lookup(opts, o->sym);
624
+ if (Qnil == v) {
625
+ *o->attr = NotSet;
626
+ } else if (Qtrue == v) {
627
+ *o->attr = Yes;
628
+ } else if (Qfalse == v) {
629
+ *o->attr = No;
630
+ } else {
631
+ rb_raise(ox_parse_error_class, "%s must be true or false.\n", rb_id2name(SYM2ID(o->sym)));
632
+ }
621
633
  }
622
634
  v = rb_hash_aref(opts, overlay_sym);
623
635
  if (Qnil == v) {
624
- ox_hints_destroy(ox_default_options.html_hints);
625
- ox_default_options.html_hints = NULL;
636
+ ox_hints_destroy(ox_default_options.html_hints);
637
+ ox_default_options.html_hints = NULL;
626
638
  } else {
627
- int cnt;
628
-
629
- Check_Type(v, T_HASH);
630
- cnt = (int)RHASH_SIZE(v);
631
- if (0 == cnt) {
632
- ox_hints_destroy(ox_default_options.html_hints);
633
- ox_default_options.html_hints = NULL;
634
- } else {
635
- ox_hints_destroy(ox_default_options.html_hints);
636
- ox_default_options.html_hints = ox_hints_dup(ox_hints_html());
637
- rb_hash_foreach(v, set_overlay, (VALUE)ox_default_options.html_hints);
638
- }
639
+ int cnt;
640
+
641
+ Check_Type(v, T_HASH);
642
+ cnt = (int)RHASH_SIZE(v);
643
+ if (0 == cnt) {
644
+ ox_hints_destroy(ox_default_options.html_hints);
645
+ ox_default_options.html_hints = NULL;
646
+ } else {
647
+ ox_hints_destroy(ox_default_options.html_hints);
648
+ ox_default_options.html_hints = ox_hints_dup(ox_hints_html());
649
+ rb_hash_foreach(v, set_overlay, (VALUE)ox_default_options.html_hints);
650
+ }
639
651
  }
640
652
  if (Qnil != (v = rb_hash_lookup(opts, with_cdata_sym))) {
641
- ox_default_options.with_cdata = (Qtrue == v);
653
+ ox_default_options.with_cdata = (Qtrue == v);
642
654
  }
643
655
 
644
656
  ox_default_options.element_key_mod = rb_hash_lookup2(opts, element_key_mod_sym, ox_default_options.element_key_mod);
645
- ox_default_options.attr_key_mod = rb_hash_lookup2(opts, attr_key_mod_sym, ox_default_options.attr_key_mod);
657
+ ox_default_options.attr_key_mod = rb_hash_lookup2(opts, attr_key_mod_sym, ox_default_options.attr_key_mod);
646
658
 
647
659
  return Qnil;
648
660
  }
@@ -657,23 +669,22 @@ set_def_opts(VALUE self, VALUE opts) {
657
669
  * - +xml+ [String] XML String in optimized Object format.
658
670
  * *return* [Object] deserialized Object.
659
671
  */
660
- static VALUE
661
- to_obj(VALUE self, VALUE ruby_xml) {
662
- char *xml, *x;
663
- size_t len;
664
- VALUE obj;
665
- struct _options options = ox_default_options;
666
- struct _err err;
672
+ static VALUE to_obj(VALUE self, VALUE ruby_xml) {
673
+ char *xml, *x;
674
+ size_t len;
675
+ VALUE obj;
676
+ struct _options options = ox_default_options;
677
+ struct _err err;
667
678
 
668
679
  err_init(&err);
669
680
  Check_Type(ruby_xml, T_STRING);
670
681
  /* the xml string gets modified so make a copy of it */
671
682
  len = RSTRING_LEN(ruby_xml) + 1;
672
- x = defuse_bom(StringValuePtr(ruby_xml), &options);
683
+ x = defuse_bom(StringValuePtr(ruby_xml), &options);
673
684
  if (SMALL_XML < len) {
674
- xml = ALLOC_N(char, len);
685
+ xml = ALLOC_N(char, len);
675
686
  } else {
676
- xml = ALLOCA_N(char, len);
687
+ xml = ALLOCA_N(char, len);
677
688
  }
678
689
  memcpy(xml, x, len);
679
690
  #ifdef RB_GC_GUARD
@@ -681,14 +692,14 @@ to_obj(VALUE self, VALUE ruby_xml) {
681
692
  #endif
682
693
  obj = ox_parse(xml, len - 1, ox_obj_callbacks, 0, &options, &err);
683
694
  if (SMALL_XML < len) {
684
- xfree(xml);
695
+ xfree(xml);
685
696
  }
686
697
  #ifdef RB_GC_GUARD
687
698
  RB_GC_GUARD(obj);
688
699
  rb_gc_enable();
689
700
  #endif
690
701
  if (err_has(&err)) {
691
- ox_err_raise(&err);
702
+ ox_err_raise(&err);
692
703
  }
693
704
  return obj;
694
705
  }
@@ -701,207 +712,198 @@ to_obj(VALUE self, VALUE ruby_xml) {
701
712
  *
702
713
  * _raise_ [Exception] if the XML is malformed.
703
714
  */
704
- static VALUE
705
- to_gen(VALUE self, VALUE ruby_xml) {
706
- char *xml, *x;
707
- size_t len;
708
- VALUE obj;
709
- struct _options options = ox_default_options;
710
- struct _err err;
715
+ static VALUE to_gen(VALUE self, VALUE ruby_xml) {
716
+ char *xml, *x;
717
+ size_t len;
718
+ VALUE obj;
719
+ struct _options options = ox_default_options;
720
+ struct _err err;
711
721
 
712
722
  err_init(&err);
713
723
  Check_Type(ruby_xml, T_STRING);
714
724
  /* the xml string gets modified so make a copy of it */
715
725
  len = RSTRING_LEN(ruby_xml) + 1;
716
- x = defuse_bom(StringValuePtr(ruby_xml), &options);
726
+ x = defuse_bom(StringValuePtr(ruby_xml), &options);
717
727
  if (SMALL_XML < len) {
718
- xml = ALLOC_N(char, len);
728
+ xml = ALLOC_N(char, len);
719
729
  } else {
720
- xml = ALLOCA_N(char, len);
730
+ xml = ALLOCA_N(char, len);
721
731
  }
722
732
  memcpy(xml, x, len);
723
733
  obj = ox_parse(xml, len - 1, ox_gen_callbacks, 0, &options, &err);
724
734
  if (SMALL_XML < len) {
725
- xfree(xml);
735
+ xfree(xml);
726
736
  }
727
737
  if (err_has(&err)) {
728
- ox_err_raise(&err);
738
+ ox_err_raise(&err);
729
739
  }
730
740
  return obj;
731
741
  }
732
742
 
733
- static VALUE
734
- load(char *xml, size_t len, int argc, VALUE *argv, VALUE self, VALUE encoding, Err err) {
735
- VALUE obj;
736
- struct _options options = ox_default_options;
743
+ static VALUE load(char *xml, size_t len, int argc, VALUE *argv, VALUE self, VALUE encoding, Err err) {
744
+ VALUE obj;
745
+ struct _options options = ox_default_options;
737
746
 
738
747
  if (1 == argc && rb_cHash == rb_obj_class(*argv)) {
739
- VALUE h = *argv;
740
- VALUE v;
741
-
742
- if (Qnil != (v = rb_hash_lookup(h, mode_sym))) {
743
- if (object_sym == v) {
744
- options.mode = ObjMode;
745
- } else if (optimized_sym == v) {
746
- options.mode = ObjMode;
747
- } else if (generic_sym == v) {
748
- options.mode = GenMode;
749
- } else if (limited_sym == v) {
750
- options.mode = LimMode;
751
- } else if (hash_sym == v) {
752
- options.mode = HashMode;
753
- } else if (hash_no_attrs_sym == v) {
754
- options.mode = HashNoAttrMode;
755
- } else {
756
- rb_raise(ox_parse_error_class, ":mode must be :generic, :object, :limited, :hash, :hash_no_attrs.\n");
757
- }
758
- }
759
- if (Qnil != (v = rb_hash_lookup(h, effort_sym))) {
760
- if (auto_define_sym == v) {
761
- options.effort = AutoEffort;
762
- } else if (tolerant_sym == v) {
763
- options.effort = TolerantEffort;
764
- } else if (strict_sym == v) {
765
- options.effort = StrictEffort;
766
- } else {
767
- rb_raise(ox_parse_error_class, ":effort must be :strict, :tolerant, or :auto_define.\n");
768
- }
769
- }
770
- if (Qnil != (v = rb_hash_lookup(h, skip_sym))) {
771
- if (skip_none_sym == v) {
772
- options.skip = NoSkip;
773
- } else if (skip_off_sym == v) {
774
- options.skip = OffSkip;
775
- } else if (skip_return_sym == v) {
776
- options.skip = CrSkip;
777
- } else if (skip_white_sym == v) {
778
- options.skip = SpcSkip;
779
- } else {
780
- rb_raise(ox_parse_error_class, ":skip must be :skip_none, :skip_return, :skip_white, or :skip_off.\n");
781
- }
782
- }
783
-
784
- if (Qnil != (v = rb_hash_lookup(h, trace_sym))) {
785
- Check_Type(v, T_FIXNUM);
786
- options.trace = FIX2INT(v);
787
- }
788
- if (Qnil != (v = rb_hash_lookup(h, symbolize_keys_sym))) {
789
- options.sym_keys = (Qfalse == v) ? No : Yes;
790
- }
791
- options.element_key_mod = rb_hash_lookup2(h, element_key_mod_sym, options.element_key_mod);
792
- options.attr_key_mod = rb_hash_lookup2(h, attr_key_mod_sym, options.attr_key_mod);
793
-
794
- if (Qnil != (v = rb_hash_lookup(h, convert_special_sym))) {
795
- options.convert_special = (Qfalse != v);
796
- }
797
- if (Qnil != (v = rb_hash_lookup(h, no_empty_sym))) {
798
- options.no_empty = (Qfalse != v);
799
- }
800
-
801
- v = rb_hash_lookup(h, invalid_replace_sym);
802
- if (Qnil == v) {
803
- if (Qtrue == rb_funcall(h, has_key_id, 1, invalid_replace_sym)) {
804
- options.allow_invalid = Yes;
805
- }
806
- } else {
807
- long slen;
808
-
809
- Check_Type(v, T_STRING);
810
- slen = RSTRING_LEN(v);
811
- if (sizeof(options.inv_repl) - 2 < (size_t)slen) {
812
- rb_raise(ox_parse_error_class, ":invalid_replace can be no longer than %d characters.",
813
- (int)sizeof(options.inv_repl) - 2);
814
- }
815
- strncpy(options.inv_repl + 1, StringValuePtr(v), sizeof(options.inv_repl) - 1);
816
- options.inv_repl[sizeof(options.inv_repl) - 1] = '\0';
817
- *options.inv_repl = (char)slen;
818
- options.allow_invalid = No;
819
- }
820
- v = rb_hash_lookup(h, strip_namespace_sym);
821
- if (Qfalse == v) {
822
- *options.strip_ns = '\0';
823
- } else if (Qtrue == v) {
824
- *options.strip_ns = '*';
825
- options.strip_ns[1] = '\0';
826
- } else if (Qnil != v) {
827
- long slen;
828
-
829
- Check_Type(v, T_STRING);
830
- slen = RSTRING_LEN(v);
831
- if (sizeof(options.strip_ns) - 1 < (size_t)slen) {
832
- rb_raise(ox_parse_error_class, ":strip_namespace can be no longer than %d characters.",
833
- (int)sizeof(options.strip_ns) - 1);
834
- }
835
- strncpy(options.strip_ns, StringValuePtr(v), sizeof(options.strip_ns) - 1);
836
- options.strip_ns[sizeof(options.strip_ns) - 1] = '\0';
837
- }
838
- v = rb_hash_lookup(h, margin_sym);
839
- if (Qnil != v) {
840
- long slen;
841
-
842
- Check_Type(v, T_STRING);
843
- slen = RSTRING_LEN(v);
844
- if (sizeof(options.margin) - 1 < (size_t)slen) {
845
- rb_raise(ox_parse_error_class, ":margin can be no longer than %d characters.",
846
- (int)sizeof(options.margin) - 1);
847
- }
848
- strncpy(options.margin, StringValuePtr(v), sizeof(options.margin) - 1);
849
- options.margin[sizeof(options.margin) - 1] = '\0';
850
- options.margin_len = strlen(options.margin);
851
- }
852
- if (Qnil != (v = rb_hash_lookup(h, with_cdata_sym))) {
853
- options.with_cdata = (Qtrue == v);
854
- }
748
+ VALUE h = *argv;
749
+ VALUE v;
750
+
751
+ if (Qnil != (v = rb_hash_lookup(h, mode_sym))) {
752
+ if (object_sym == v) {
753
+ options.mode = ObjMode;
754
+ } else if (optimized_sym == v) {
755
+ options.mode = ObjMode;
756
+ } else if (generic_sym == v) {
757
+ options.mode = GenMode;
758
+ } else if (limited_sym == v) {
759
+ options.mode = LimMode;
760
+ } else if (hash_sym == v) {
761
+ options.mode = HashMode;
762
+ } else if (hash_no_attrs_sym == v) {
763
+ options.mode = HashNoAttrMode;
764
+ } else {
765
+ rb_raise(ox_parse_error_class, ":mode must be :generic, :object, :limited, :hash, :hash_no_attrs.\n");
766
+ }
767
+ }
768
+ if (Qnil != (v = rb_hash_lookup(h, effort_sym))) {
769
+ if (auto_define_sym == v) {
770
+ options.effort = AutoEffort;
771
+ } else if (tolerant_sym == v) {
772
+ options.effort = TolerantEffort;
773
+ } else if (strict_sym == v) {
774
+ options.effort = StrictEffort;
775
+ } else {
776
+ rb_raise(ox_parse_error_class, ":effort must be :strict, :tolerant, or :auto_define.\n");
777
+ }
778
+ }
779
+ if (Qnil != (v = rb_hash_lookup(h, skip_sym))) {
780
+ if (skip_none_sym == v) {
781
+ options.skip = NoSkip;
782
+ } else if (skip_off_sym == v) {
783
+ options.skip = OffSkip;
784
+ } else if (skip_return_sym == v) {
785
+ options.skip = CrSkip;
786
+ } else if (skip_white_sym == v) {
787
+ options.skip = SpcSkip;
788
+ } else {
789
+ rb_raise(ox_parse_error_class, ":skip must be :skip_none, :skip_return, :skip_white, or :skip_off.\n");
790
+ }
791
+ }
792
+
793
+ if (Qnil != (v = rb_hash_lookup(h, trace_sym))) {
794
+ Check_Type(v, T_FIXNUM);
795
+ options.trace = FIX2INT(v);
796
+ }
797
+ if (Qnil != (v = rb_hash_lookup(h, symbolize_keys_sym))) {
798
+ options.sym_keys = (Qfalse == v) ? No : Yes;
799
+ }
800
+ options.element_key_mod = rb_hash_lookup2(h, element_key_mod_sym, options.element_key_mod);
801
+ options.attr_key_mod = rb_hash_lookup2(h, attr_key_mod_sym, options.attr_key_mod);
802
+
803
+ if (Qnil != (v = rb_hash_lookup(h, convert_special_sym))) {
804
+ options.convert_special = (Qfalse != v);
805
+ }
806
+ if (Qnil != (v = rb_hash_lookup(h, no_empty_sym))) {
807
+ options.no_empty = (Qfalse != v);
808
+ }
809
+
810
+ v = rb_hash_lookup(h, invalid_replace_sym);
811
+ if (Qnil == v) {
812
+ if (Qtrue == rb_funcall(h, has_key_id, 1, invalid_replace_sym)) {
813
+ options.allow_invalid = Yes;
814
+ }
815
+ } else {
816
+ long slen;
817
+
818
+ Check_Type(v, T_STRING);
819
+ slen = RSTRING_LEN(v);
820
+ if (sizeof(options.inv_repl) - 2 < (size_t)slen) {
821
+ rb_raise(ox_parse_error_class,
822
+ ":invalid_replace can be no longer than %d characters.",
823
+ (int)sizeof(options.inv_repl) - 2);
824
+ }
825
+ strncpy(options.inv_repl + 1, StringValuePtr(v), sizeof(options.inv_repl) - 1);
826
+ options.inv_repl[sizeof(options.inv_repl) - 1] = '\0';
827
+ *options.inv_repl = (char)slen;
828
+ options.allow_invalid = No;
829
+ }
830
+ v = rb_hash_lookup(h, strip_namespace_sym);
831
+ if (Qfalse == v) {
832
+ *options.strip_ns = '\0';
833
+ } else if (Qtrue == v) {
834
+ *options.strip_ns = '*';
835
+ options.strip_ns[1] = '\0';
836
+ } else if (Qnil != v) {
837
+ long slen;
838
+
839
+ Check_Type(v, T_STRING);
840
+ slen = RSTRING_LEN(v);
841
+ if (sizeof(options.strip_ns) - 1 < (size_t)slen) {
842
+ rb_raise(ox_parse_error_class,
843
+ ":strip_namespace can be no longer than %d characters.",
844
+ (int)sizeof(options.strip_ns) - 1);
845
+ }
846
+ strncpy(options.strip_ns, StringValuePtr(v), sizeof(options.strip_ns) - 1);
847
+ options.strip_ns[sizeof(options.strip_ns) - 1] = '\0';
848
+ }
849
+ v = rb_hash_lookup(h, margin_sym);
850
+ if (Qnil != v) {
851
+ long slen;
852
+
853
+ Check_Type(v, T_STRING);
854
+ slen = RSTRING_LEN(v);
855
+ if (sizeof(options.margin) - 1 < (size_t)slen) {
856
+ rb_raise(ox_parse_error_class,
857
+ ":margin can be no longer than %d characters.",
858
+ (int)sizeof(options.margin) - 1);
859
+ }
860
+ strncpy(options.margin, StringValuePtr(v), sizeof(options.margin) - 1);
861
+ options.margin[sizeof(options.margin) - 1] = '\0';
862
+ options.margin_len = strlen(options.margin);
863
+ }
864
+ if (Qnil != (v = rb_hash_lookup(h, with_cdata_sym))) {
865
+ options.with_cdata = (Qtrue == v);
866
+ }
855
867
  }
856
- #if HAVE_RB_ENC_FIND
857
868
  if ('\0' == *options.encoding) {
858
- if (Qnil != encoding) {
859
- options.rb_enc = rb_enc_from_index(rb_enc_get_index(encoding));
860
- } else {
861
- options.rb_enc = 0;
862
- }
869
+ if (Qnil != encoding) {
870
+ options.rb_enc = rb_enc_from_index(rb_enc_get_index(encoding));
871
+ } else {
872
+ options.rb_enc = 0;
873
+ }
863
874
  } else if (0 == options.rb_enc) {
864
- options.rb_enc = rb_enc_find(options.encoding);
875
+ options.rb_enc = rb_enc_find(options.encoding);
865
876
  }
866
- #endif
867
877
  xml = defuse_bom(xml, &options);
868
878
  switch (options.mode) {
869
879
  case ObjMode:
870
880
  #ifdef RB_GC_GUARD
871
- rb_gc_disable();
881
+ rb_gc_disable();
872
882
  #endif
873
- obj = ox_parse(xml, len, ox_obj_callbacks, 0, &options, err);
883
+ obj = ox_parse(xml, len, ox_obj_callbacks, 0, &options, err);
874
884
  #ifdef RB_GC_GUARD
875
- RB_GC_GUARD(obj);
876
- rb_gc_enable();
885
+ RB_GC_GUARD(obj);
886
+ rb_gc_enable();
877
887
  #endif
878
- break;
879
- case GenMode:
880
- obj = ox_parse(xml, len, ox_gen_callbacks, 0, &options, err);
881
- break;
882
- case LimMode:
883
- obj = ox_parse(xml, len, ox_limited_callbacks, 0, &options, err);
884
- break;
888
+ break;
889
+ case GenMode: obj = ox_parse(xml, len, ox_gen_callbacks, 0, &options, err); break;
890
+ case LimMode: obj = ox_parse(xml, len, ox_limited_callbacks, 0, &options, err); break;
885
891
  case HashMode:
886
- if (options.with_cdata) {
887
- obj = ox_parse(xml, len, ox_hash_cdata_callbacks, 0, &options, err);
888
- } else {
889
- obj = ox_parse(xml, len, ox_hash_callbacks, 0, &options, err);
890
- }
891
- break;
892
+ if (options.with_cdata) {
893
+ obj = ox_parse(xml, len, ox_hash_cdata_callbacks, 0, &options, err);
894
+ } else {
895
+ obj = ox_parse(xml, len, ox_hash_callbacks, 0, &options, err);
896
+ }
897
+ break;
892
898
  case HashNoAttrMode:
893
- if (options.with_cdata) {
894
- obj = ox_parse(xml, len, ox_hash_no_attrs_cdata_callbacks, 0, &options, err);
895
- } else {
896
- obj = ox_parse(xml, len, ox_hash_no_attrs_callbacks, 0, &options, err);
897
- }
898
- break;
899
- case NoMode:
900
- obj = ox_parse(xml, len, ox_nomode_callbacks, 0, &options, err);
901
- break;
902
- default:
903
- obj = ox_parse(xml, len, ox_gen_callbacks, 0, &options, err);
904
- break;
899
+ if (options.with_cdata) {
900
+ obj = ox_parse(xml, len, ox_hash_no_attrs_cdata_callbacks, 0, &options, err);
901
+ } else {
902
+ obj = ox_parse(xml, len, ox_hash_no_attrs_callbacks, 0, &options, err);
903
+ }
904
+ break;
905
+ case NoMode: obj = ox_parse(xml, len, ox_nomode_callbacks, 0, &options, err); break;
906
+ default: obj = ox_parse(xml, len, ox_gen_callbacks, 0, &options, err); break;
905
907
  }
906
908
  return obj;
907
909
  }
@@ -928,26 +930,27 @@ load(char *xml, size_t len, int argc, VALUE *argv, VALUE self, VALUE encoding, E
928
930
  * - _:auto_define_ - auto define missing classes and modules
929
931
  * - *:trace* [Fixnum] trace level as a Fixnum, default: 0 (silent)
930
932
  * - *:symbolize_keys* [true|false|nil] symbolize element attribute keys or leave as Strings
931
- * - *:invalid_replace* [nil|String] replacement string for invalid XML characters on dump. nil indicates include anyway as hex. A string, limited to 10 characters will replace the invalid character with the replace.
932
- * - *:strip_namespace* [String|true|false] "" or false result in no namespace stripping. A string of "*" or true will strip all namespaces. Any other non-empty string indicates that matching namespaces will be stripped.
933
+ * - *:invalid_replace* [nil|String] replacement string for invalid XML characters on dump. nil indicates include
934
+ * anyway as hex. A string, limited to 10 characters will replace the invalid character with the replace.
935
+ * - *:strip_namespace* [String|true|false] "" or false result in no namespace stripping. A string of "*" or true will
936
+ * strip all namespaces. Any other non-empty string indicates that matching namespaces will be stripped.
933
937
  * - *:with_cdata* [true|false] if true cdata is included in hash_load output otherwise it is not.
934
938
  */
935
- static VALUE
936
- load_str(int argc, VALUE *argv, VALUE self) {
937
- char *xml;
938
- size_t len;
939
- VALUE obj;
940
- VALUE encoding;
941
- struct _err err;
939
+ static VALUE load_str(int argc, VALUE *argv, VALUE self) {
940
+ char *xml;
941
+ size_t len;
942
+ VALUE obj;
943
+ VALUE encoding;
944
+ struct _err err;
942
945
 
943
946
  err_init(&err);
944
947
  Check_Type(*argv, T_STRING);
945
948
  /* the xml string gets modified so make a copy of it */
946
949
  len = RSTRING_LEN(*argv) + 1;
947
950
  if (SMALL_XML < len) {
948
- xml = ALLOC_N(char, len);
951
+ xml = ALLOC_N(char, len);
949
952
  } else {
950
- xml = ALLOCA_N(char, len);
953
+ xml = ALLOCA_N(char, len);
951
954
  }
952
955
  #if HAVE_RB_OBJ_ENCODING
953
956
  encoding = rb_obj_encoding(*argv);
@@ -956,12 +959,12 @@ load_str(int argc, VALUE *argv, VALUE self) {
956
959
  #endif
957
960
  memcpy(xml, StringValuePtr(*argv), len);
958
961
  xml[len - 1] = '\0';
959
- obj = load(xml, len - 1, argc - 1, argv + 1, self, encoding, &err);
962
+ obj = load(xml, len - 1, argc - 1, argv + 1, self, encoding, &err);
960
963
  if (SMALL_XML < len) {
961
- xfree(xml);
964
+ xfree(xml);
962
965
  }
963
966
  if (err_has(&err)) {
964
- ox_err_raise(&err);
967
+ ox_err_raise(&err);
965
968
  }
966
969
  return obj;
967
970
  }
@@ -985,45 +988,46 @@ load_str(int argc, VALUE *argv, VALUE self) {
985
988
  * - _:auto_define_ - auto define missing classes and modules
986
989
  * - *:trace* [Fixnum] trace level as a Fixnum, default: 0 (silent)
987
990
  * - *:symbolize_keys* [true|false|nil] symbolize element attribute keys or leave as Strings
988
- * - *:invalid_replace* [nil|String] replacement string for invalid XML characters on dump. nil indicates include anyway as hex. A string, limited to 10 characters will replace the invalid character with the replace.
989
- * - *:strip_namespace* [String|true|false] "" or false result in no namespace stripping. A string of "*" or true will strip all namespaces. Any other non-empty string indicates that matching namespaces will be stripped.
991
+ * - *:invalid_replace* [nil|String] replacement string for invalid XML characters on dump. nil indicates include
992
+ * anyway as hex. A string, limited to 10 characters will replace the invalid character with the replace.
993
+ * - *:strip_namespace* [String|true|false] "" or false result in no namespace stripping. A string of "*" or true will
994
+ * strip all namespaces. Any other non-empty string indicates that matching namespaces will be stripped.
990
995
  */
991
- static VALUE
992
- load_file(int argc, VALUE *argv, VALUE self) {
993
- char *path;
994
- char *xml;
995
- FILE *f;
996
- off_t len;
997
- VALUE obj;
998
- struct _err err;
996
+ static VALUE load_file(int argc, VALUE *argv, VALUE self) {
997
+ char *path;
998
+ char *xml;
999
+ FILE *f;
1000
+ off_t len;
1001
+ VALUE obj;
1002
+ struct _err err;
999
1003
 
1000
1004
  err_init(&err);
1001
1005
  Check_Type(*argv, T_STRING);
1002
1006
  path = StringValuePtr(*argv);
1003
1007
  if (0 == (f = fopen(path, "r"))) {
1004
- rb_raise(rb_eIOError, "%s\n", strerror(errno));
1008
+ rb_raise(rb_eIOError, "%s\n", strerror(errno));
1005
1009
  }
1006
1010
  fseek(f, 0, SEEK_END);
1007
1011
  len = ftello(f);
1008
1012
  if (SMALL_XML < len) {
1009
- xml = ALLOC_N(char, len + 1);
1013
+ xml = ALLOC_N(char, len + 1);
1010
1014
  } else {
1011
- xml = ALLOCA_N(char, len + 1);
1015
+ xml = ALLOCA_N(char, len + 1);
1012
1016
  }
1013
1017
  fseek(f, 0, SEEK_SET);
1014
1018
  if ((size_t)len != fread(xml, 1, len, f)) {
1015
- ox_err_set(&err, rb_eLoadError, "Failed to read %ld bytes from %s.\n", (long)len, path);
1016
- obj = Qnil;
1019
+ ox_err_set(&err, rb_eLoadError, "Failed to read %ld bytes from %s.\n", (long)len, path);
1020
+ obj = Qnil;
1017
1021
  } else {
1018
- xml[len] = '\0';
1019
- obj = load(xml, len, argc - 1, argv + 1, self, Qnil, &err);
1022
+ xml[len] = '\0';
1023
+ obj = load(xml, len, argc - 1, argv + 1, self, Qnil, &err);
1020
1024
  }
1021
1025
  fclose(f);
1022
1026
  if (SMALL_XML < len) {
1023
- xfree(xml);
1027
+ xfree(xml);
1024
1028
  }
1025
1029
  if (err_has(&err)) {
1026
- ox_err_raise(&err);
1030
+ ox_err_raise(&err);
1027
1031
  }
1028
1032
  return obj;
1029
1033
  }
@@ -1038,66 +1042,68 @@ load_file(int argc, VALUE *argv, VALUE self) {
1038
1042
  * - *:convert_special* [true|false] flag indicating special characters like &lt; are converted
1039
1043
  * - *:symbolize* [true|false] flag indicating the parser symbolize element and attribute names
1040
1044
  * - *:smart* [true|false] flag indicating the parser uses hints if available (use with html)
1041
- * - *:skip* [:skip_none|:skip_return|:skip_white|:skip_off] flag indicating the parser skips \\r or collpase white space into a single space. Default (skip space)
1042
- * - *:strip_namespace* [nil|String|true|false] "" or false result in no namespace stripping. A string of "*" or true will strip all namespaces. Any other non-empty string indicates that matching namespaces will be stripped.
1045
+ * - *:skip* [:skip_none|:skip_return|:skip_white|:skip_off] flag indicating the parser skips \\r or collpase white
1046
+ * space into a single space. Default (skip space)
1047
+ * - *:strip_namespace* [nil|String|true|false] "" or false result in no namespace stripping. A string of "*" or true
1048
+ * will strip all namespaces. Any other non-empty string indicates that matching namespaces will be stripped.
1043
1049
  */
1044
- static VALUE
1045
- sax_parse(int argc, VALUE *argv, VALUE self) {
1046
- struct _saxOptions options;
1050
+ static VALUE sax_parse(int argc, VALUE *argv, VALUE self) {
1051
+ struct _saxOptions options;
1047
1052
 
1048
- options.symbolize = (No != ox_default_options.sym_keys);
1053
+ options.symbolize = (No != ox_default_options.sym_keys);
1049
1054
  options.convert_special = ox_default_options.convert_special;
1050
- options.smart = (Yes == ox_default_options.smart);
1051
- options.skip = ox_default_options.skip;
1052
- options.hints = NULL;
1055
+ options.smart = (Yes == ox_default_options.smart);
1056
+ options.skip = ox_default_options.skip;
1057
+ options.hints = NULL;
1053
1058
  strcpy(options.strip_ns, ox_default_options.strip_ns);
1054
1059
 
1055
1060
  if (argc < 2) {
1056
- rb_raise(ox_parse_error_class, "Wrong number of arguments to sax_parse.\n");
1061
+ rb_raise(ox_parse_error_class, "Wrong number of arguments to sax_parse.\n");
1057
1062
  }
1058
1063
  if (3 <= argc && rb_cHash == rb_obj_class(argv[2])) {
1059
- VALUE h = argv[2];
1060
- VALUE v;
1061
-
1062
- if (Qnil != (v = rb_hash_lookup(h, convert_special_sym))) {
1063
- options.convert_special = (Qtrue == v);
1064
- }
1065
- if (Qnil != (v = rb_hash_lookup(h, smart_sym))) {
1066
- options.smart = (Qtrue == v);
1067
- }
1068
- if (Qnil != (v = rb_hash_lookup(h, symbolize_sym))) {
1069
- options.symbolize = (Qtrue == v);
1070
- }
1071
- if (Qnil != (v = rb_hash_lookup(h, skip_sym))) {
1072
- if (skip_return_sym == v) {
1073
- options.skip = CrSkip;
1074
- } else if (skip_white_sym == v) {
1075
- options.skip = SpcSkip;
1076
- } else if (skip_none_sym == v) {
1077
- options.skip = NoSkip;
1078
- } else if (skip_off_sym == v) {
1079
- options.skip = OffSkip;
1080
- }
1081
- }
1082
- if (Qnil != (v = rb_hash_lookup(h, strip_namespace_sym))) {
1083
- if (Qfalse == v) {
1084
- *options.strip_ns = '\0';
1085
- } else if (Qtrue == v) {
1086
- *options.strip_ns = '*';
1087
- options.strip_ns[1] = '\0';
1088
- } else {
1089
- long slen;
1090
-
1091
- Check_Type(v, T_STRING);
1092
- slen = RSTRING_LEN(v);
1093
- if (sizeof(options.strip_ns) - 1 < (size_t)slen) {
1094
- rb_raise(ox_parse_error_class, ":strip_namespace can be no longer than %d characters.",
1095
- (int)sizeof(options.strip_ns) - 1);
1096
- }
1097
- strncpy(options.strip_ns, StringValuePtr(v), sizeof(options.strip_ns) - 1);
1098
- options.strip_ns[sizeof(options.strip_ns) - 1] = '\0';
1099
- }
1100
- }
1064
+ VALUE h = argv[2];
1065
+ VALUE v;
1066
+
1067
+ if (Qnil != (v = rb_hash_lookup(h, convert_special_sym))) {
1068
+ options.convert_special = (Qtrue == v);
1069
+ }
1070
+ if (Qnil != (v = rb_hash_lookup(h, smart_sym))) {
1071
+ options.smart = (Qtrue == v);
1072
+ }
1073
+ if (Qnil != (v = rb_hash_lookup(h, symbolize_sym))) {
1074
+ options.symbolize = (Qtrue == v);
1075
+ }
1076
+ if (Qnil != (v = rb_hash_lookup(h, skip_sym))) {
1077
+ if (skip_return_sym == v) {
1078
+ options.skip = CrSkip;
1079
+ } else if (skip_white_sym == v) {
1080
+ options.skip = SpcSkip;
1081
+ } else if (skip_none_sym == v) {
1082
+ options.skip = NoSkip;
1083
+ } else if (skip_off_sym == v) {
1084
+ options.skip = OffSkip;
1085
+ }
1086
+ }
1087
+ if (Qnil != (v = rb_hash_lookup(h, strip_namespace_sym))) {
1088
+ if (Qfalse == v) {
1089
+ *options.strip_ns = '\0';
1090
+ } else if (Qtrue == v) {
1091
+ *options.strip_ns = '*';
1092
+ options.strip_ns[1] = '\0';
1093
+ } else {
1094
+ long slen;
1095
+
1096
+ Check_Type(v, T_STRING);
1097
+ slen = RSTRING_LEN(v);
1098
+ if (sizeof(options.strip_ns) - 1 < (size_t)slen) {
1099
+ rb_raise(ox_parse_error_class,
1100
+ ":strip_namespace can be no longer than %d characters.",
1101
+ (int)sizeof(options.strip_ns) - 1);
1102
+ }
1103
+ strncpy(options.strip_ns, StringValuePtr(v), sizeof(options.strip_ns) - 1);
1104
+ options.strip_ns[sizeof(options.strip_ns) - 1] = '\0';
1105
+ }
1106
+ }
1101
1107
  }
1102
1108
  ox_sax_parse(argv[0], argv[1], &options);
1103
1109
 
@@ -1113,7 +1119,8 @@ sax_parse(int argc, VALUE *argv, VALUE self) {
1113
1119
  * - +options+ [Hash] options parse options
1114
1120
  * - *:convert_special* [true|false] flag indicating special characters like &lt; are converted
1115
1121
  * - *:symbolize* [true|false] flag indicating the parser symbolize element and attribute names
1116
- * - *:skip* [:skip_none|:skip_return|:skip_white|:skip_off] flag indicating the parser skips \\r or collapse white space into a single space. Default (skip space)
1122
+ * - *:skip* [:skip_none|:skip_return|:skip_white|:skip_off] flag indicating the parser skips \\r or collapse white
1123
+ * space into a single space. Default (skip space)
1117
1124
  * - *:overlay* [Hash] a Hash of keys that match html element names and values that are one of
1118
1125
  * - _:active_ - make the normal callback for the element
1119
1126
  * - _:nest_ok_ - active but ignore nest check
@@ -1122,168 +1129,166 @@ sax_parse(int argc, VALUE *argv, VALUE self) {
1122
1129
  * - _:off_ - block this element and it's children unless the child element is active
1123
1130
  * - _:abort_ - abort the html processing and return
1124
1131
  */
1125
- static VALUE
1126
- sax_html(int argc, VALUE *argv, VALUE self) {
1127
- struct _saxOptions options;
1128
- bool free_hints = false;
1132
+ static VALUE sax_html(int argc, VALUE *argv, VALUE self) {
1133
+ struct _saxOptions options;
1134
+ bool free_hints = false;
1129
1135
 
1130
- options.symbolize = (No != ox_default_options.sym_keys);
1136
+ options.symbolize = (No != ox_default_options.sym_keys);
1131
1137
  options.convert_special = ox_default_options.convert_special;
1132
- options.smart = true;
1133
- options.skip = ox_default_options.skip;
1134
- options.hints = ox_default_options.html_hints;
1138
+ options.smart = true;
1139
+ options.skip = ox_default_options.skip;
1140
+ options.hints = ox_default_options.html_hints;
1135
1141
  if (NULL == options.hints) {
1136
- options.hints = ox_hints_html();
1142
+ options.hints = ox_hints_html();
1137
1143
  }
1138
1144
  *options.strip_ns = '\0';
1139
1145
 
1140
1146
  if (argc < 2) {
1141
- rb_raise(ox_parse_error_class, "Wrong number of arguments to sax_html.\n");
1147
+ rb_raise(ox_parse_error_class, "Wrong number of arguments to sax_html.\n");
1142
1148
  }
1143
1149
  if (3 <= argc && rb_cHash == rb_obj_class(argv[2])) {
1144
- volatile VALUE h = argv[2];
1145
- volatile VALUE v;
1146
-
1147
- if (Qnil != (v = rb_hash_lookup(h, convert_special_sym))) {
1148
- options.convert_special = (Qtrue == v);
1149
- }
1150
- if (Qnil != (v = rb_hash_lookup(h, symbolize_sym))) {
1151
- options.symbolize = (Qtrue == v);
1152
- }
1153
- if (Qnil != (v = rb_hash_lookup(h, skip_sym))) {
1154
- if (skip_return_sym == v) {
1155
- options.skip = CrSkip;
1156
- } else if (skip_white_sym == v) {
1157
- options.skip = SpcSkip;
1158
- } else if (skip_none_sym == v) {
1159
- options.skip = NoSkip;
1160
- } else if (skip_off_sym == v) {
1161
- options.skip = OffSkip;
1162
- }
1163
- }
1164
- if (Qnil != (v = rb_hash_lookup(h, overlay_sym))) {
1165
- int cnt;
1166
-
1167
- Check_Type(v, T_HASH);
1168
- cnt = (int)RHASH_SIZE(v);
1169
- if (0 == cnt) {
1170
- options.hints = ox_hints_html();
1171
- } else {
1172
- options.hints = ox_hints_dup(options.hints);
1173
- free_hints = true;
1174
- rb_hash_foreach(v, set_overlay, (VALUE)options.hints);
1175
- }
1176
- }
1150
+ volatile VALUE h = argv[2];
1151
+ volatile VALUE v;
1152
+
1153
+ if (Qnil != (v = rb_hash_lookup(h, convert_special_sym))) {
1154
+ options.convert_special = (Qtrue == v);
1155
+ }
1156
+ if (Qnil != (v = rb_hash_lookup(h, symbolize_sym))) {
1157
+ options.symbolize = (Qtrue == v);
1158
+ }
1159
+ if (Qnil != (v = rb_hash_lookup(h, skip_sym))) {
1160
+ if (skip_return_sym == v) {
1161
+ options.skip = CrSkip;
1162
+ } else if (skip_white_sym == v) {
1163
+ options.skip = SpcSkip;
1164
+ } else if (skip_none_sym == v) {
1165
+ options.skip = NoSkip;
1166
+ } else if (skip_off_sym == v) {
1167
+ options.skip = OffSkip;
1168
+ }
1169
+ }
1170
+ if (Qnil != (v = rb_hash_lookup(h, overlay_sym))) {
1171
+ int cnt;
1172
+
1173
+ Check_Type(v, T_HASH);
1174
+ cnt = (int)RHASH_SIZE(v);
1175
+ if (0 == cnt) {
1176
+ options.hints = ox_hints_html();
1177
+ } else {
1178
+ options.hints = ox_hints_dup(options.hints);
1179
+ free_hints = true;
1180
+ rb_hash_foreach(v, set_overlay, (VALUE)options.hints);
1181
+ }
1182
+ }
1177
1183
  }
1178
1184
  ox_sax_parse(argv[0], argv[1], &options);
1179
1185
  if (free_hints) {
1180
- ox_hints_destroy(options.hints);
1186
+ ox_hints_destroy(options.hints);
1181
1187
  }
1182
1188
  return Qnil;
1183
1189
  }
1184
1190
 
1185
- static void
1186
- parse_dump_options(VALUE ropts, Options copts) {
1187
- struct _yesNoOpt ynos[] = {
1188
- { with_xml_sym, &copts->with_xml },
1189
- { with_dtd_sym, &copts->with_dtd },
1190
- { with_instruct_sym, &copts->with_instruct },
1191
- { xsd_date_sym, &copts->xsd_date },
1192
- { circular_sym, &copts->circular },
1193
- { Qnil, 0 }
1194
- };
1195
- YesNoOpt o;
1191
+ static void parse_dump_options(VALUE ropts, Options copts) {
1192
+ struct _yesNoOpt ynos[] = {{with_xml_sym, &copts->with_xml},
1193
+ {with_dtd_sym, &copts->with_dtd},
1194
+ {with_instruct_sym, &copts->with_instruct},
1195
+ {xsd_date_sym, &copts->xsd_date},
1196
+ {circular_sym, &copts->circular},
1197
+ {Qnil, 0}};
1198
+ YesNoOpt o;
1196
1199
 
1197
1200
  if (rb_cHash == rb_obj_class(ropts)) {
1198
- VALUE v;
1201
+ VALUE v;
1199
1202
 
1200
- if (Qnil != (v = rb_hash_lookup(ropts, ox_indent_sym))) {
1203
+ if (Qnil != (v = rb_hash_lookup(ropts, ox_indent_sym))) {
1201
1204
  #ifdef RUBY_INTEGER_UNIFICATION
1202
- if (rb_cInteger != rb_obj_class(v) && T_FIXNUM != rb_type(v)) {
1205
+ if (rb_cInteger != rb_obj_class(v) && T_FIXNUM != rb_type(v)) {
1203
1206
  #else
1204
- if (rb_cFixnum != rb_obj_class(v)) {
1207
+ if (rb_cFixnum != rb_obj_class(v)) {
1205
1208
  #endif
1206
- rb_raise(ox_parse_error_class, ":indent must be a Fixnum.\n");
1207
- }
1208
- copts->indent = NUM2INT(v);
1209
- }
1210
- if (Qnil != (v = rb_hash_lookup(ropts, trace_sym))) {
1209
+ rb_raise(ox_parse_error_class, ":indent must be a Fixnum.\n");
1210
+ }
1211
+ copts->indent = NUM2INT(v);
1212
+ }
1213
+ if (Qnil != (v = rb_hash_lookup(ropts, trace_sym))) {
1211
1214
  #ifdef RUBY_INTEGER_UNIFICATION
1212
- if (rb_cInteger != rb_obj_class(v) && T_FIXNUM != rb_type(v)) {
1215
+ if (rb_cInteger != rb_obj_class(v) && T_FIXNUM != rb_type(v)) {
1213
1216
  #else
1214
- if (rb_cFixnum != rb_obj_class(v)) {
1217
+ if (rb_cFixnum != rb_obj_class(v)) {
1215
1218
  #endif
1216
- rb_raise(ox_parse_error_class, ":trace must be a Fixnum.\n");
1217
- }
1218
- copts->trace = NUM2INT(v);
1219
- }
1220
- if (Qnil != (v = rb_hash_lookup(ropts, ox_encoding_sym))) {
1221
- if (rb_cString != rb_obj_class(v)) {
1222
- rb_raise(ox_parse_error_class, ":encoding must be a String.\n");
1223
- }
1224
- strncpy(copts->encoding, StringValuePtr(v), sizeof(copts->encoding) - 1);
1225
- }
1226
- if (Qnil != (v = rb_hash_lookup(ropts, no_empty_sym))) {
1227
- copts->no_empty = (v == Qtrue);
1228
- }
1229
- if (Qnil != (v = rb_hash_lookup(ropts, effort_sym))) {
1230
- if (auto_define_sym == v) {
1231
- copts->effort = AutoEffort;
1232
- } else if (tolerant_sym == v) {
1233
- copts->effort = TolerantEffort;
1234
- } else if (strict_sym == v) {
1235
- copts->effort = StrictEffort;
1236
- } else {
1237
- rb_raise(ox_parse_error_class, ":effort must be :strict, :tolerant, or :auto_define.\n");
1238
- }
1239
- }
1240
- v = rb_hash_lookup(ropts, invalid_replace_sym);
1241
- if (Qnil == v) {
1242
- if (Qtrue == rb_funcall(ropts, has_key_id, 1, invalid_replace_sym)) {
1243
- copts->allow_invalid = Yes;
1244
- }
1245
- } else {
1246
- long slen;
1247
-
1248
- Check_Type(v, T_STRING);
1249
- slen = RSTRING_LEN(v);
1250
- if (sizeof(copts->inv_repl) - 2 < (size_t)slen) {
1251
- rb_raise(ox_parse_error_class, ":invalid_replace can be no longer than %d characters.",
1252
- (int)sizeof(copts->inv_repl) - 2);
1253
- }
1254
- strncpy(copts->inv_repl + 1, StringValuePtr(v), sizeof(copts->inv_repl) - 1);
1255
- copts->inv_repl[sizeof(copts->inv_repl) - 1] = '\0';
1256
- *copts->inv_repl = (char)slen;
1257
- copts->allow_invalid = No;
1258
- }
1259
- v = rb_hash_lookup(ropts, margin_sym);
1260
- if (Qnil != v) {
1261
- long slen;
1262
-
1263
- Check_Type(v, T_STRING);
1264
- slen = RSTRING_LEN(v);
1265
- if (sizeof(copts->margin) - 2 < (size_t)slen) {
1266
- rb_raise(ox_parse_error_class, ":margin can be no longer than %d characters.",
1267
- (int)sizeof(copts->margin) - 2);
1268
- }
1269
- strncpy(copts->margin, StringValuePtr(v), sizeof(copts->margin) - 1);
1270
- copts->margin[sizeof(copts->margin) - 1] = '\0';
1271
- copts->margin_len = (char)slen;
1272
- }
1273
-
1274
- for (o = ynos; 0 != o->attr; o++) {
1275
- if (Qnil != (v = rb_hash_lookup(ropts, o->sym))) {
1276
- VALUE c = rb_obj_class(v);
1277
-
1278
- if (rb_cTrueClass == c) {
1279
- *o->attr = Yes;
1280
- } else if (rb_cFalseClass == c) {
1281
- *o->attr = No;
1282
- } else {
1283
- rb_raise(ox_parse_error_class, "%s must be true or false.\n", rb_id2name(SYM2ID(o->sym)));
1284
- }
1285
- }
1286
- }
1219
+ rb_raise(ox_parse_error_class, ":trace must be a Fixnum.\n");
1220
+ }
1221
+ copts->trace = NUM2INT(v);
1222
+ }
1223
+ if (Qnil != (v = rb_hash_lookup(ropts, ox_encoding_sym))) {
1224
+ if (rb_cString != rb_obj_class(v)) {
1225
+ rb_raise(ox_parse_error_class, ":encoding must be a String.\n");
1226
+ }
1227
+ strncpy(copts->encoding, StringValuePtr(v), sizeof(copts->encoding) - 1);
1228
+ }
1229
+ if (Qnil != (v = rb_hash_lookup(ropts, no_empty_sym))) {
1230
+ copts->no_empty = (v == Qtrue);
1231
+ }
1232
+ if (Qnil != (v = rb_hash_lookup(ropts, effort_sym))) {
1233
+ if (auto_define_sym == v) {
1234
+ copts->effort = AutoEffort;
1235
+ } else if (tolerant_sym == v) {
1236
+ copts->effort = TolerantEffort;
1237
+ } else if (strict_sym == v) {
1238
+ copts->effort = StrictEffort;
1239
+ } else {
1240
+ rb_raise(ox_parse_error_class, ":effort must be :strict, :tolerant, or :auto_define.\n");
1241
+ }
1242
+ }
1243
+ v = rb_hash_lookup(ropts, invalid_replace_sym);
1244
+ if (Qnil == v) {
1245
+ if (Qtrue == rb_funcall(ropts, has_key_id, 1, invalid_replace_sym)) {
1246
+ copts->allow_invalid = Yes;
1247
+ }
1248
+ } else {
1249
+ long slen;
1250
+
1251
+ Check_Type(v, T_STRING);
1252
+ slen = RSTRING_LEN(v);
1253
+ if (sizeof(copts->inv_repl) - 2 < (size_t)slen) {
1254
+ rb_raise(ox_parse_error_class,
1255
+ ":invalid_replace can be no longer than %d characters.",
1256
+ (int)sizeof(copts->inv_repl) - 2);
1257
+ }
1258
+ strncpy(copts->inv_repl + 1, StringValuePtr(v), sizeof(copts->inv_repl) - 1);
1259
+ copts->inv_repl[sizeof(copts->inv_repl) - 1] = '\0';
1260
+ *copts->inv_repl = (char)slen;
1261
+ copts->allow_invalid = No;
1262
+ }
1263
+ v = rb_hash_lookup(ropts, margin_sym);
1264
+ if (Qnil != v) {
1265
+ long slen;
1266
+
1267
+ Check_Type(v, T_STRING);
1268
+ slen = RSTRING_LEN(v);
1269
+ if (sizeof(copts->margin) - 2 < (size_t)slen) {
1270
+ rb_raise(ox_parse_error_class,
1271
+ ":margin can be no longer than %d characters.",
1272
+ (int)sizeof(copts->margin) - 2);
1273
+ }
1274
+ strncpy(copts->margin, StringValuePtr(v), sizeof(copts->margin) - 1);
1275
+ copts->margin[sizeof(copts->margin) - 1] = '\0';
1276
+ copts->margin_len = (char)slen;
1277
+ }
1278
+
1279
+ for (o = ynos; 0 != o->attr; o++) {
1280
+ if (Qnil != (v = rb_hash_lookup(ropts, o->sym))) {
1281
+ VALUE c = rb_obj_class(v);
1282
+
1283
+ if (rb_cTrueClass == c) {
1284
+ *o->attr = Yes;
1285
+ } else if (rb_cFalseClass == c) {
1286
+ *o->attr = No;
1287
+ } else {
1288
+ rb_raise(ox_parse_error_class, "%s must be true or false.\n", rb_id2name(SYM2ID(o->sym)));
1289
+ }
1290
+ }
1291
+ }
1287
1292
  }
1288
1293
  }
1289
1294
 
@@ -1296,31 +1301,29 @@ parse_dump_options(VALUE ropts, Options copts) {
1296
1301
  * - *:no_empty* [true|false] if true don't output empty elements
1297
1302
  * - *:xsd_date* [true|false] use XSD date format if true, default: false
1298
1303
  * - *:circular* [true|false] allow circular references, default: false
1299
- * - *:strict|:tolerant]* [ :effort effort to use when an undumpable object (e.g., IO) is encountered, default: :strict
1304
+ * - *:strict|:tolerant]* [ :effort effort to use when an undumpable object (e.g., IO) is encountered, default:
1305
+ * :strict
1300
1306
  * - _:strict_ - raise an NotImplementedError if an undumpable object is encountered
1301
1307
  * - _:tolerant_ - replaces undumplable objects with nil
1302
1308
  *
1303
1309
  * Note that an indent of less than zero will result in a tight one line output
1304
1310
  * unless the text in the XML fields contain new line characters.
1305
1311
  */
1306
- static VALUE
1307
- dump(int argc, VALUE *argv, VALUE self) {
1308
- char *xml;
1309
- struct _options copts = ox_default_options;
1310
- VALUE rstr;
1312
+ static VALUE dump(int argc, VALUE *argv, VALUE self) {
1313
+ char *xml;
1314
+ struct _options copts = ox_default_options;
1315
+ VALUE rstr;
1311
1316
 
1312
1317
  if (2 == argc) {
1313
- parse_dump_options(argv[1], &copts);
1318
+ parse_dump_options(argv[1], &copts);
1314
1319
  }
1315
1320
  if (0 == (xml = ox_write_obj_to_str(*argv, &copts))) {
1316
- rb_raise(rb_eNoMemError, "Not enough memory.\n");
1321
+ rb_raise(rb_eNoMemError, "Not enough memory.\n");
1317
1322
  }
1318
1323
  rstr = rb_str_new2(xml);
1319
- #if HAVE_RB_ENC_ASSOCIATE
1320
1324
  if ('\0' != *copts.encoding) {
1321
- rb_enc_associate(rstr, rb_enc_find(copts.encoding));
1325
+ rb_enc_associate(rstr, rb_enc_find(copts.encoding));
1322
1326
  }
1323
- #endif
1324
1327
  xfree(xml);
1325
1328
 
1326
1329
  return rstr;
@@ -1335,15 +1338,15 @@ dump(int argc, VALUE *argv, VALUE self) {
1335
1338
  * - *:no_empty* [true|false] if true don't output empty elements
1336
1339
  * - *:xsd_date* [true|false] use XSD date format if true, default: false
1337
1340
  * - *:circular* [true|false] allow circular references, default: false
1338
- * - *:strict|:tolerant]* [ :effort effort to use when an undumpable object (e.g., IO) is encountered, default: :strict
1341
+ * - *:strict|:tolerant]* [ :effort effort to use when an undumpable object (e.g., IO) is encountered, default:
1342
+ * :strict
1339
1343
  * - _:strict_ - raise an NotImplementedError if an undumpable object is encountered
1340
1344
  * - _:tolerant_ - replaces undumplable objects with nil
1341
1345
  *
1342
1346
  * Note that an indent of less than zero will result in a tight one line output
1343
1347
  * unless the text in the XML fields contain new line characters.
1344
1348
  */
1345
- static VALUE
1346
- to_xml(int argc, VALUE *argv, VALUE self) {
1349
+ static VALUE to_xml(int argc, VALUE *argv, VALUE self) {
1347
1350
  return dump(argc, argv, self);
1348
1351
  }
1349
1352
 
@@ -1356,19 +1359,19 @@ to_xml(int argc, VALUE *argv, VALUE self) {
1356
1359
  * - *:indent* [Fixnum] format expected
1357
1360
  * - *:xsd_date* [true|false] use XSD date format if true, default: false
1358
1361
  * - *:circular* [true|false] allow circular references, default: false
1359
- * - *:strict|:tolerant]* [ :effort effort to use when an undumpable object (e.g., IO) is encountered, default: :strict
1362
+ * - *:strict|:tolerant]* [ :effort effort to use when an undumpable object (e.g., IO) is encountered, default:
1363
+ * :strict
1360
1364
  * - _:strict_ - raise an NotImplementedError if an undumpable object is encountered
1361
1365
  * - _:tolerant_ - replaces undumplable objects with nil
1362
1366
  *
1363
1367
  * Note that an indent of less than zero will result in a tight one line output
1364
1368
  * unless the text in the XML fields contain new line characters.
1365
1369
  */
1366
- static VALUE
1367
- to_file(int argc, VALUE *argv, VALUE self) {
1368
- struct _options copts = ox_default_options;
1370
+ static VALUE to_file(int argc, VALUE *argv, VALUE self) {
1371
+ struct _options copts = ox_default_options;
1369
1372
 
1370
1373
  if (3 == argc) {
1371
- parse_dump_options(argv[2], &copts);
1374
+ parse_dump_options(argv[2], &copts);
1372
1375
  }
1373
1376
  Check_Type(*argv, T_STRING);
1374
1377
  ox_write_obj_to_file(argv[1], StringValuePtr(*argv), &copts);
@@ -1377,24 +1380,25 @@ to_file(int argc, VALUE *argv, VALUE self) {
1377
1380
  }
1378
1381
 
1379
1382
  #if WITH_CACHE_TESTS
1380
- extern void ox_cache_test(void);
1383
+ extern void ox_cache_test(void);
1381
1384
 
1382
- static VALUE
1383
- cache_test(VALUE self) {
1385
+ static VALUE cache_test(VALUE self) {
1384
1386
  ox_cache_test();
1385
1387
  return Qnil;
1386
1388
  }
1387
1389
 
1388
- extern void ox_cache8_test(void);
1390
+ extern void ox_cache8_test(void);
1389
1391
 
1390
- static VALUE
1391
- cache8_test(VALUE self) {
1392
+ static VALUE cache8_test(VALUE self) {
1392
1393
  ox_cache8_test();
1393
1394
  return Qnil;
1394
1395
  }
1395
1396
  #endif
1396
1397
 
1397
1398
  void Init_ox() {
1399
+ #if HAVE_RB_EXT_RACTOR_SAFE
1400
+ rb_ext_ractor_safe(true);
1401
+ #endif
1398
1402
  Ox = rb_define_module("Ox");
1399
1403
 
1400
1404
  rb_define_module_function(Ox, "default_options", get_def_opts, 0);
@@ -1421,59 +1425,59 @@ void Init_ox() {
1421
1425
  rb_require("bigdecimal");
1422
1426
  rb_require("stringio");
1423
1427
 
1424
- ox_abort_id = rb_intern("abort");
1425
- ox_at_column_id = rb_intern("@column");
1426
- ox_at_content_id = rb_intern("@content");
1427
- ox_at_id = rb_intern("at");
1428
- ox_at_line_id = rb_intern("@line");
1429
- ox_at_pos_id = rb_intern("@pos");
1430
- ox_at_value_id = rb_intern("@value");
1431
- ox_attr_id = rb_intern("attr");
1432
- ox_attr_value_id = rb_intern("attr_value");
1433
- ox_attributes_id = rb_intern("@attributes");
1434
- ox_attrs_done_id = rb_intern("attrs_done");
1435
- ox_beg_id = rb_intern("@beg");
1436
- ox_bigdecimal_id = rb_intern("BigDecimal");
1437
- ox_call_id = rb_intern("call");
1438
- ox_cdata_id = rb_intern("cdata");
1439
- ox_comment_id = rb_intern("comment");
1440
- ox_den_id = rb_intern("@den");
1441
- ox_doctype_id = rb_intern("doctype");
1442
- ox_end_element_id = rb_intern("end_element");
1443
- ox_end_id = rb_intern("@end");
1444
- ox_end_instruct_id = rb_intern("end_instruct");
1445
- ox_error_id = rb_intern("error");
1446
- ox_excl_id = rb_intern("@excl");
1428
+ ox_abort_id = rb_intern("abort");
1429
+ ox_at_column_id = rb_intern("@column");
1430
+ ox_at_content_id = rb_intern("@content");
1431
+ ox_at_id = rb_intern("at");
1432
+ ox_at_line_id = rb_intern("@line");
1433
+ ox_at_pos_id = rb_intern("@pos");
1434
+ ox_at_value_id = rb_intern("@value");
1435
+ ox_attr_id = rb_intern("attr");
1436
+ ox_attr_value_id = rb_intern("attr_value");
1437
+ ox_attributes_id = rb_intern("@attributes");
1438
+ ox_attrs_done_id = rb_intern("attrs_done");
1439
+ ox_beg_id = rb_intern("@beg");
1440
+ ox_bigdecimal_id = rb_intern("BigDecimal");
1441
+ ox_call_id = rb_intern("call");
1442
+ ox_cdata_id = rb_intern("cdata");
1443
+ ox_comment_id = rb_intern("comment");
1444
+ ox_den_id = rb_intern("@den");
1445
+ ox_doctype_id = rb_intern("doctype");
1446
+ ox_end_element_id = rb_intern("end_element");
1447
+ ox_end_id = rb_intern("@end");
1448
+ ox_end_instruct_id = rb_intern("end_instruct");
1449
+ ox_error_id = rb_intern("error");
1450
+ ox_excl_id = rb_intern("@excl");
1447
1451
  ox_external_encoding_id = rb_intern("external_encoding");
1448
- ox_fileno_id = rb_intern("fileno");
1449
- ox_force_encoding_id = rb_intern("force_encoding");
1450
- ox_inspect_id = rb_intern("inspect");
1451
- ox_instruct_id = rb_intern("instruct");
1452
- ox_jd_id = rb_intern("jd");
1453
- ox_keys_id = rb_intern("keys");
1454
- ox_local_id = rb_intern("local");
1455
- ox_mesg_id = rb_intern("mesg");
1456
- ox_message_id = rb_intern("message");
1457
- ox_nodes_id = rb_intern("@nodes");
1458
- ox_new_id = rb_intern("new");
1459
- ox_num_id = rb_intern("@num");
1460
- ox_parse_id = rb_intern("parse");
1461
- ox_pos_id = rb_intern("pos");
1462
- ox_read_id = rb_intern("read");
1463
- ox_readpartial_id = rb_intern("readpartial");
1464
- ox_start_element_id = rb_intern("start_element");
1465
- ox_string_id = rb_intern("string");
1466
- ox_text_id = rb_intern("text");
1467
- ox_to_c_id = rb_intern("to_c");
1468
- ox_to_s_id = rb_intern("to_s");
1469
- ox_to_sym_id = rb_intern("to_sym");
1470
- ox_tv_nsec_id = rb_intern("tv_nsec");
1471
- ox_tv_sec_id = rb_intern("tv_sec");
1472
- ox_tv_usec_id = rb_intern("tv_usec");
1473
- ox_value_id = rb_intern("value");
1452
+ ox_fileno_id = rb_intern("fileno");
1453
+ ox_force_encoding_id = rb_intern("force_encoding");
1454
+ ox_inspect_id = rb_intern("inspect");
1455
+ ox_instruct_id = rb_intern("instruct");
1456
+ ox_jd_id = rb_intern("jd");
1457
+ ox_keys_id = rb_intern("keys");
1458
+ ox_local_id = rb_intern("local");
1459
+ ox_mesg_id = rb_intern("mesg");
1460
+ ox_message_id = rb_intern("message");
1461
+ ox_nodes_id = rb_intern("@nodes");
1462
+ ox_new_id = rb_intern("new");
1463
+ ox_num_id = rb_intern("@num");
1464
+ ox_parse_id = rb_intern("parse");
1465
+ ox_pos_id = rb_intern("pos");
1466
+ ox_read_id = rb_intern("read");
1467
+ ox_readpartial_id = rb_intern("readpartial");
1468
+ ox_start_element_id = rb_intern("start_element");
1469
+ ox_string_id = rb_intern("string");
1470
+ ox_text_id = rb_intern("text");
1471
+ ox_to_c_id = rb_intern("to_c");
1472
+ ox_to_s_id = rb_intern("to_s");
1473
+ ox_to_sym_id = rb_intern("to_sym");
1474
+ ox_tv_nsec_id = rb_intern("tv_nsec");
1475
+ ox_tv_sec_id = rb_intern("tv_sec");
1476
+ ox_tv_usec_id = rb_intern("tv_usec");
1477
+ ox_value_id = rb_intern("value");
1474
1478
 
1475
1479
  encoding_id = rb_intern("encoding");
1476
- has_key_id = rb_intern("has_key?");
1480
+ has_key_id = rb_intern("has_key?");
1477
1481
 
1478
1482
  rb_require("ox/version");
1479
1483
  rb_require("ox/error");
@@ -1488,81 +1492,162 @@ void Init_ox() {
1488
1492
  rb_require("ox/bag");
1489
1493
  rb_require("ox/sax");
1490
1494
 
1491
- ox_time_class = rb_const_get(rb_cObject, rb_intern("Time"));
1492
- ox_date_class = rb_const_get(rb_cObject, rb_intern("Date"));
1493
- ox_parse_error_class = rb_const_get_at(Ox, rb_intern("ParseError"));
1495
+ ox_time_class = rb_const_get(rb_cObject, rb_intern("Time"));
1496
+ ox_date_class = rb_const_get(rb_cObject, rb_intern("Date"));
1497
+ ox_parse_error_class = rb_const_get_at(Ox, rb_intern("ParseError"));
1494
1498
  ox_syntax_error_class = rb_const_get_at(Ox, rb_intern("SyntaxError"));
1495
- ox_arg_error_class = rb_const_get_at(Ox, rb_intern("ArgError"));
1496
- ox_struct_class = rb_const_get(rb_cObject, rb_intern("Struct"));
1497
- ox_stringio_class = rb_const_get(rb_cObject, rb_intern("StringIO"));
1498
- ox_bigdecimal_class = rb_const_get(rb_cObject, rb_intern("BigDecimal"));
1499
-
1500
- abort_sym = ID2SYM(rb_intern("abort")); rb_gc_register_address(&abort_sym);
1501
- active_sym = ID2SYM(rb_intern("active")); rb_gc_register_address(&active_sym);
1502
- attr_key_mod_sym = ID2SYM(rb_intern("attr_key_mod")); rb_gc_register_address(&attr_key_mod_sym);
1503
- auto_define_sym = ID2SYM(rb_intern("auto_define")); rb_gc_register_address(&auto_define_sym);
1504
- auto_sym = ID2SYM(rb_intern("auto")); rb_gc_register_address(&auto_sym);
1505
- block_sym = ID2SYM(rb_intern("block")); rb_gc_register_address(&block_sym);
1506
- circular_sym = ID2SYM(rb_intern("circular")); rb_gc_register_address(&circular_sym);
1507
- convert_special_sym = ID2SYM(rb_intern("convert_special")); rb_gc_register_address(&convert_special_sym);
1508
- effort_sym = ID2SYM(rb_intern("effort")); rb_gc_register_address(&effort_sym);
1509
- element_key_mod_sym = ID2SYM(rb_intern("element_key_mod")); rb_gc_register_address(&element_key_mod_sym);
1510
- generic_sym = ID2SYM(rb_intern("generic")); rb_gc_register_address(&generic_sym);
1511
- hash_no_attrs_sym = ID2SYM(rb_intern("hash_no_attrs")); rb_gc_register_address(&hash_no_attrs_sym);
1512
- hash_sym = ID2SYM(rb_intern("hash")); rb_gc_register_address(&hash_sym);
1513
- inactive_sym = ID2SYM(rb_intern("inactive")); rb_gc_register_address(&inactive_sym);
1514
- invalid_replace_sym = ID2SYM(rb_intern("invalid_replace")); rb_gc_register_address(&invalid_replace_sym);
1515
- limited_sym = ID2SYM(rb_intern("limited")); rb_gc_register_address(&limited_sym);
1516
- margin_sym = ID2SYM(rb_intern("margin")); rb_gc_register_address(&margin_sym);
1517
- mode_sym = ID2SYM(rb_intern("mode")); rb_gc_register_address(&mode_sym);
1518
- nest_ok_sym = ID2SYM(rb_intern("nest_ok")); rb_gc_register_address(&nest_ok_sym);
1519
- no_empty_sym = ID2SYM(rb_intern("no_empty")); rb_gc_register_address(&no_empty_sym);
1520
- object_sym = ID2SYM(rb_intern("object")); rb_gc_register_address(&object_sym);
1521
- off_sym = ID2SYM(rb_intern("off")); rb_gc_register_address(&off_sym);
1522
- opt_format_sym = ID2SYM(rb_intern("opt_format")); rb_gc_register_address(&opt_format_sym);
1523
- optimized_sym = ID2SYM(rb_intern("optimized")); rb_gc_register_address(&optimized_sym);
1524
- overlay_sym = ID2SYM(rb_intern("overlay")); rb_gc_register_address(&overlay_sym);
1525
- ox_encoding_sym = ID2SYM(rb_intern("encoding")); rb_gc_register_address(&ox_encoding_sym);
1526
- ox_indent_sym = ID2SYM(rb_intern("indent")); rb_gc_register_address(&ox_indent_sym);
1527
- ox_size_sym = ID2SYM(rb_intern("size")); rb_gc_register_address(&ox_size_sym);
1528
- ox_standalone_sym = ID2SYM(rb_intern("standalone")); rb_gc_register_address(&ox_standalone_sym);
1529
- ox_version_sym = ID2SYM(rb_intern("version")); rb_gc_register_address(&ox_version_sym);
1530
- skip_none_sym = ID2SYM(rb_intern("skip_none")); rb_gc_register_address(&skip_none_sym);
1531
- skip_off_sym = ID2SYM(rb_intern("skip_off")); rb_gc_register_address(&skip_off_sym);
1532
- skip_return_sym = ID2SYM(rb_intern("skip_return")); rb_gc_register_address(&skip_return_sym);
1533
- skip_sym = ID2SYM(rb_intern("skip")); rb_gc_register_address(&skip_sym);
1534
- skip_white_sym = ID2SYM(rb_intern("skip_white")); rb_gc_register_address(&skip_white_sym);
1535
- smart_sym = ID2SYM(rb_intern("smart")); rb_gc_register_address(&smart_sym);
1536
- strict_sym = ID2SYM(rb_intern("strict")); rb_gc_register_address(&strict_sym);
1537
- strip_namespace_sym = ID2SYM(rb_intern("strip_namespace")); rb_gc_register_address(&strip_namespace_sym);
1538
- symbolize_keys_sym = ID2SYM(rb_intern("symbolize_keys")); rb_gc_register_address(&symbolize_keys_sym);
1539
- symbolize_sym = ID2SYM(rb_intern("symbolize")); rb_gc_register_address(&symbolize_sym);
1540
- tolerant_sym = ID2SYM(rb_intern("tolerant")); rb_gc_register_address(&tolerant_sym);
1541
- trace_sym = ID2SYM(rb_intern("trace")); rb_gc_register_address(&trace_sym);
1542
- with_cdata_sym = ID2SYM(rb_intern("with_cdata")); rb_gc_register_address(&with_cdata_sym);
1543
- with_dtd_sym = ID2SYM(rb_intern("with_dtd")); rb_gc_register_address(&with_dtd_sym);
1544
- with_instruct_sym = ID2SYM(rb_intern("with_instructions")); rb_gc_register_address(&with_instruct_sym);
1545
- with_xml_sym = ID2SYM(rb_intern("with_xml")); rb_gc_register_address(&with_xml_sym);
1546
- xsd_date_sym = ID2SYM(rb_intern("xsd_date")); rb_gc_register_address(&xsd_date_sym);
1547
-
1548
- ox_empty_string = rb_str_new2(""); rb_gc_register_address(&ox_empty_string);
1549
- ox_zero_fixnum = INT2NUM(0); rb_gc_register_address(&ox_zero_fixnum);
1550
- ox_sym_bank = rb_ary_new(); rb_gc_register_address(&ox_sym_bank);
1499
+ ox_arg_error_class = rb_const_get_at(Ox, rb_intern("ArgError"));
1500
+ ox_struct_class = rb_const_get(rb_cObject, rb_intern("Struct"));
1501
+ ox_stringio_class = rb_const_get(rb_cObject, rb_intern("StringIO"));
1502
+ ox_bigdecimal_class = rb_const_get(rb_cObject, rb_intern("BigDecimal"));
1503
+
1504
+ abort_sym = ID2SYM(rb_intern("abort"));
1505
+ rb_gc_register_address(&abort_sym);
1506
+ active_sym = ID2SYM(rb_intern("active"));
1507
+ rb_gc_register_address(&active_sym);
1508
+ attr_key_mod_sym = ID2SYM(rb_intern("attr_key_mod"));
1509
+ rb_gc_register_address(&attr_key_mod_sym);
1510
+ auto_define_sym = ID2SYM(rb_intern("auto_define"));
1511
+ rb_gc_register_address(&auto_define_sym);
1512
+ auto_sym = ID2SYM(rb_intern("auto"));
1513
+ rb_gc_register_address(&auto_sym);
1514
+ block_sym = ID2SYM(rb_intern("block"));
1515
+ rb_gc_register_address(&block_sym);
1516
+ circular_sym = ID2SYM(rb_intern("circular"));
1517
+ rb_gc_register_address(&circular_sym);
1518
+ convert_special_sym = ID2SYM(rb_intern("convert_special"));
1519
+ rb_gc_register_address(&convert_special_sym);
1520
+ effort_sym = ID2SYM(rb_intern("effort"));
1521
+ rb_gc_register_address(&effort_sym);
1522
+ element_key_mod_sym = ID2SYM(rb_intern("element_key_mod"));
1523
+ rb_gc_register_address(&element_key_mod_sym);
1524
+ generic_sym = ID2SYM(rb_intern("generic"));
1525
+ rb_gc_register_address(&generic_sym);
1526
+ hash_no_attrs_sym = ID2SYM(rb_intern("hash_no_attrs"));
1527
+ rb_gc_register_address(&hash_no_attrs_sym);
1528
+ hash_sym = ID2SYM(rb_intern("hash"));
1529
+ rb_gc_register_address(&hash_sym);
1530
+ inactive_sym = ID2SYM(rb_intern("inactive"));
1531
+ rb_gc_register_address(&inactive_sym);
1532
+ invalid_replace_sym = ID2SYM(rb_intern("invalid_replace"));
1533
+ rb_gc_register_address(&invalid_replace_sym);
1534
+ limited_sym = ID2SYM(rb_intern("limited"));
1535
+ rb_gc_register_address(&limited_sym);
1536
+ margin_sym = ID2SYM(rb_intern("margin"));
1537
+ rb_gc_register_address(&margin_sym);
1538
+ mode_sym = ID2SYM(rb_intern("mode"));
1539
+ rb_gc_register_address(&mode_sym);
1540
+ nest_ok_sym = ID2SYM(rb_intern("nest_ok"));
1541
+ rb_gc_register_address(&nest_ok_sym);
1542
+ no_empty_sym = ID2SYM(rb_intern("no_empty"));
1543
+ rb_gc_register_address(&no_empty_sym);
1544
+ object_sym = ID2SYM(rb_intern("object"));
1545
+ rb_gc_register_address(&object_sym);
1546
+ off_sym = ID2SYM(rb_intern("off"));
1547
+ rb_gc_register_address(&off_sym);
1548
+ opt_format_sym = ID2SYM(rb_intern("opt_format"));
1549
+ rb_gc_register_address(&opt_format_sym);
1550
+ optimized_sym = ID2SYM(rb_intern("optimized"));
1551
+ rb_gc_register_address(&optimized_sym);
1552
+ overlay_sym = ID2SYM(rb_intern("overlay"));
1553
+ rb_gc_register_address(&overlay_sym);
1554
+ ox_encoding_sym = ID2SYM(rb_intern("encoding"));
1555
+ rb_gc_register_address(&ox_encoding_sym);
1556
+ ox_indent_sym = ID2SYM(rb_intern("indent"));
1557
+ rb_gc_register_address(&ox_indent_sym);
1558
+ ox_size_sym = ID2SYM(rb_intern("size"));
1559
+ rb_gc_register_address(&ox_size_sym);
1560
+ ox_standalone_sym = ID2SYM(rb_intern("standalone"));
1561
+ rb_gc_register_address(&ox_standalone_sym);
1562
+ ox_version_sym = ID2SYM(rb_intern("version"));
1563
+ rb_gc_register_address(&ox_version_sym);
1564
+ skip_none_sym = ID2SYM(rb_intern("skip_none"));
1565
+ rb_gc_register_address(&skip_none_sym);
1566
+ skip_off_sym = ID2SYM(rb_intern("skip_off"));
1567
+ rb_gc_register_address(&skip_off_sym);
1568
+ skip_return_sym = ID2SYM(rb_intern("skip_return"));
1569
+ rb_gc_register_address(&skip_return_sym);
1570
+ skip_sym = ID2SYM(rb_intern("skip"));
1571
+ rb_gc_register_address(&skip_sym);
1572
+ skip_white_sym = ID2SYM(rb_intern("skip_white"));
1573
+ rb_gc_register_address(&skip_white_sym);
1574
+ smart_sym = ID2SYM(rb_intern("smart"));
1575
+ rb_gc_register_address(&smart_sym);
1576
+ strict_sym = ID2SYM(rb_intern("strict"));
1577
+ rb_gc_register_address(&strict_sym);
1578
+ strip_namespace_sym = ID2SYM(rb_intern("strip_namespace"));
1579
+ rb_gc_register_address(&strip_namespace_sym);
1580
+ symbolize_keys_sym = ID2SYM(rb_intern("symbolize_keys"));
1581
+ rb_gc_register_address(&symbolize_keys_sym);
1582
+ symbolize_sym = ID2SYM(rb_intern("symbolize"));
1583
+ rb_gc_register_address(&symbolize_sym);
1584
+ tolerant_sym = ID2SYM(rb_intern("tolerant"));
1585
+ rb_gc_register_address(&tolerant_sym);
1586
+ trace_sym = ID2SYM(rb_intern("trace"));
1587
+ rb_gc_register_address(&trace_sym);
1588
+ with_cdata_sym = ID2SYM(rb_intern("with_cdata"));
1589
+ rb_gc_register_address(&with_cdata_sym);
1590
+ with_dtd_sym = ID2SYM(rb_intern("with_dtd"));
1591
+ rb_gc_register_address(&with_dtd_sym);
1592
+ with_instruct_sym = ID2SYM(rb_intern("with_instructions"));
1593
+ rb_gc_register_address(&with_instruct_sym);
1594
+ with_xml_sym = ID2SYM(rb_intern("with_xml"));
1595
+ rb_gc_register_address(&with_xml_sym);
1596
+ xsd_date_sym = ID2SYM(rb_intern("xsd_date"));
1597
+ rb_gc_register_address(&xsd_date_sym);
1598
+
1599
+ ox_empty_string = rb_str_new2("");
1600
+ rb_gc_register_address(&ox_empty_string);
1601
+ ox_zero_fixnum = INT2NUM(0);
1602
+ rb_gc_register_address(&ox_zero_fixnum);
1603
+ ox_sym_bank = rb_ary_new();
1604
+ rb_gc_register_address(&ox_sym_bank);
1551
1605
 
1552
1606
  ox_document_clas = rb_const_get_at(Ox, rb_intern("Document"));
1553
- ox_element_clas = rb_const_get_at(Ox, rb_intern("Element"));
1607
+ ox_element_clas = rb_const_get_at(Ox, rb_intern("Element"));
1554
1608
  ox_instruct_clas = rb_const_get_at(Ox, rb_intern("Instruct"));
1555
- ox_comment_clas = rb_const_get_at(Ox, rb_intern("Comment"));
1556
- ox_raw_clas = rb_const_get_at(Ox, rb_intern("Raw"));
1557
- ox_doctype_clas = rb_const_get_at(Ox, rb_intern("DocType"));
1558
- ox_cdata_clas = rb_const_get_at(Ox, rb_intern("CData"));
1559
- ox_bag_clas = rb_const_get_at(Ox, rb_intern("Bag"));
1560
-
1561
- ox_cache_new(&ox_symbol_cache);
1562
- ox_cache_new(&ox_class_cache);
1563
- ox_cache_new(&ox_attr_cache);
1609
+ ox_comment_clas = rb_const_get_at(Ox, rb_intern("Comment"));
1610
+ ox_raw_clas = rb_const_get_at(Ox, rb_intern("Raw"));
1611
+ ox_doctype_clas = rb_const_get_at(Ox, rb_intern("DocType"));
1612
+ ox_cdata_clas = rb_const_get_at(Ox, rb_intern("CData"));
1613
+ ox_bag_clas = rb_const_get_at(Ox, rb_intern("Bag"));
1614
+
1615
+ // Classes can move in more recent versions so register them all.
1616
+ rb_gc_register_address(&Ox);
1617
+ rb_gc_register_address(&ox_arg_error_class);
1618
+ rb_gc_register_address(&ox_bag_clas);
1619
+ rb_gc_register_address(&ox_bag_clas);
1620
+ rb_gc_register_address(&ox_bigdecimal_class);
1621
+ rb_gc_register_address(&ox_cdata_clas);
1622
+ rb_gc_register_address(&ox_cdata_clas);
1623
+ rb_gc_register_address(&ox_comment_clas);
1624
+ rb_gc_register_address(&ox_comment_clas);
1625
+ rb_gc_register_address(&ox_date_class);
1626
+ rb_gc_register_address(&ox_doctype_clas);
1627
+ rb_gc_register_address(&ox_doctype_clas);
1628
+ rb_gc_register_address(&ox_document_clas);
1629
+ rb_gc_register_address(&ox_document_clas);
1630
+ rb_gc_register_address(&ox_element_clas);
1631
+ rb_gc_register_address(&ox_element_clas);
1632
+ rb_gc_register_address(&ox_encoding_sym);
1633
+ rb_gc_register_address(&ox_indent_sym);
1634
+ rb_gc_register_address(&ox_instruct_clas);
1635
+ rb_gc_register_address(&ox_instruct_clas);
1636
+ rb_gc_register_address(&ox_parse_error_class);
1637
+ rb_gc_register_address(&ox_raw_clas);
1638
+ rb_gc_register_address(&ox_raw_clas);
1639
+ rb_gc_register_address(&ox_size_sym);
1640
+ rb_gc_register_address(&ox_standalone_sym);
1641
+ rb_gc_register_address(&ox_stringio_class);
1642
+ rb_gc_register_address(&ox_struct_class);
1643
+ rb_gc_register_address(&ox_syntax_error_class);
1644
+ rb_gc_register_address(&ox_time_class);
1645
+ rb_gc_register_address(&ox_version_sym);
1646
+
1647
+ slot_cache_new(&ox_class_cache);
1564
1648
 
1565
1649
  ox_sax_define();
1650
+ ox_hash_init();
1566
1651
 
1567
1652
  #if WITH_CACHE_TESTS
1568
1653
  // space added to stop yardoc from trying to document
@@ -1570,9 +1655,7 @@ void Init_ox() {
1570
1655
  rb_define _module_function(Ox, "cache8_test", cache8_test, 0);
1571
1656
  #endif
1572
1657
 
1573
- #if HAVE_RB_ENC_FIND
1574
1658
  ox_utf8_encoding = rb_enc_find("UTF-8");
1575
- #endif
1576
1659
  }
1577
1660
 
1578
1661
  #if __GNUC__ > 4
@@ -1580,17 +1663,17 @@ _Noreturn void
1580
1663
  #else
1581
1664
  void
1582
1665
  #endif
1583
- _ox_raise_error(const char *msg, const char *xml, const char *current, const char* file, int line) {
1584
- int xline = 1;
1585
- int col = 1;
1666
+ _ox_raise_error(const char *msg, const char *xml, const char *current, const char *file, int line) {
1667
+ int xline = 1;
1668
+ int col = 1;
1586
1669
 
1587
1670
  for (; xml < current && '\n' != *current; current--) {
1588
- col++;
1671
+ col++;
1589
1672
  }
1590
1673
  for (; xml < current; current--) {
1591
- if ('\n' == *current) {
1592
- xline++;
1593
- }
1674
+ if ('\n' == *current) {
1675
+ xline++;
1676
+ }
1594
1677
  }
1595
1678
  #ifdef RB_GC_GUARD
1596
1679
  rb_gc_enable();