ox 2.14.3 → 2.14.7

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