ox 2.11.0 → 2.13.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +46 -0
- data/README.md +55 -7
- data/ext/ox/builder.c +13 -7
- data/ext/ox/dump.c +31 -25
- data/ext/ox/extconf.rb +16 -34
- data/ext/ox/gen_load.c +18 -96
- data/ext/ox/hash_load.c +62 -26
- data/ext/ox/obj_load.c +8 -45
- data/ext/ox/ox.c +59 -48
- data/ext/ox/ox.h +33 -38
- data/ext/ox/parse.c +59 -67
- data/ext/ox/sax.c +84 -134
- data/ext/ox/sax.h +2 -4
- data/ext/ox/sax_as.c +2 -6
- data/ext/ox/sax_buf.c +1 -1
- data/ext/ox/special.c +346 -0
- data/ext/ox/special.h +1 -0
- data/lib/ox/element.rb +1 -0
- data/lib/ox/version.rb +1 -1
- metadata +7 -8
- data/ext/ox/encode.h +0 -26
data/ext/ox/gen_load.c
CHANGED
@@ -10,6 +10,9 @@
|
|
10
10
|
#include <stdarg.h>
|
11
11
|
|
12
12
|
#include "ruby.h"
|
13
|
+
#if HAVE_RB_ENC_ASSOCIATE
|
14
|
+
#include "ruby/encoding.h"
|
15
|
+
#endif
|
13
16
|
#include "ox.h"
|
14
17
|
|
15
18
|
static void instruct(PInfo pi, const char *target, Attr attrs, const char *content);
|
@@ -72,7 +75,7 @@ create_doc(PInfo pi) {
|
|
72
75
|
|
73
76
|
helper_stack_init(&pi->helpers);
|
74
77
|
doc = rb_obj_alloc(ox_document_clas);
|
75
|
-
#
|
78
|
+
#ifdef RB_GC_GUARD
|
76
79
|
RB_GC_GUARD(doc);
|
77
80
|
#endif
|
78
81
|
nodes = rb_ary_new();
|
@@ -100,7 +103,7 @@ create_prolog_doc(PInfo pi, const char *target, Attr attrs) {
|
|
100
103
|
sym = rb_funcall(pi->options->attr_key_mod, ox_call_id, 1, rb_str_new2(attrs->name));
|
101
104
|
rb_hash_aset(ah, sym, rb_str_new2(attrs->value));
|
102
105
|
} else if (Yes == pi->options->sym_keys) {
|
103
|
-
#if
|
106
|
+
#if HAVE_RB_ENC_ASSOCIATE
|
104
107
|
if (0 != pi->options->rb_enc) {
|
105
108
|
VALUE rstr = rb_str_new2(attrs->name);
|
106
109
|
|
@@ -109,41 +112,21 @@ create_prolog_doc(PInfo pi, const char *target, Attr attrs) {
|
|
109
112
|
} else {
|
110
113
|
sym = ID2SYM(rb_intern(attrs->name));
|
111
114
|
}
|
112
|
-
#elif HAS_PRIVATE_ENCODING
|
113
|
-
if (Qnil != pi->options->rb_enc) {
|
114
|
-
VALUE rstr = rb_str_new2(attrs->name);
|
115
|
-
|
116
|
-
rb_funcall(rstr, ox_force_encoding_id, 1, pi->options->rb_enc);
|
117
|
-
sym = rb_funcall(rstr, ox_to_sym_id, 0);
|
118
|
-
} else {
|
119
|
-
sym = ID2SYM(rb_intern(attrs->name));
|
120
|
-
}
|
121
|
-
#else
|
122
115
|
sym = ID2SYM(rb_intern(attrs->name));
|
123
116
|
#endif
|
124
117
|
rb_hash_aset(ah, sym, rb_str_new2(attrs->value));
|
125
118
|
} else {
|
126
119
|
volatile VALUE rstr = rb_str_new2(attrs->name);
|
127
120
|
|
128
|
-
#if
|
121
|
+
#if HAVE_RB_ENC_ASSOCIATE
|
129
122
|
if (0 != pi->options->rb_enc) {
|
130
123
|
rb_enc_associate(rstr, pi->options->rb_enc);
|
131
124
|
}
|
132
|
-
#elif HAS_PRIVATE_ENCODING
|
133
|
-
if (Qnil != pi->options->rb_enc) {
|
134
|
-
rb_funcall(rstr, ox_force_encoding_id, 1, pi->options->rb_enc);
|
135
|
-
}
|
136
|
-
#endif
|
137
125
|
rb_hash_aset(ah, rstr, rb_str_new2(attrs->value));
|
138
126
|
}
|
139
|
-
#if HAS_ENCODING_SUPPORT
|
140
127
|
if (0 == strcmp("encoding", attrs->name)) {
|
141
128
|
pi->options->rb_enc = rb_enc_find(attrs->value);
|
142
129
|
}
|
143
|
-
#elif HAS_PRIVATE_ENCODING
|
144
|
-
if (0 == strcmp("encoding", attrs->name)) {
|
145
|
-
pi->options->rb_enc = rb_str_new2(attrs->value);
|
146
|
-
}
|
147
130
|
#endif
|
148
131
|
}
|
149
132
|
nodes = rb_ary_new();
|
@@ -212,14 +195,10 @@ add_doctype(PInfo pi, const char *docType) {
|
|
212
195
|
VALUE n = rb_obj_alloc(ox_doctype_clas);
|
213
196
|
VALUE s = rb_str_new2(docType);
|
214
197
|
|
215
|
-
#if
|
198
|
+
#if HAVE_RB_ENC_ASSOCIATE
|
216
199
|
if (0 != pi->options->rb_enc) {
|
217
200
|
rb_enc_associate(s, pi->options->rb_enc);
|
218
201
|
}
|
219
|
-
#elif HAS_PRIVATE_ENCODING
|
220
|
-
if (Qnil != pi->options->rb_enc) {
|
221
|
-
rb_funcall(s, ox_force_encoding_id, 1, pi->options->rb_enc);
|
222
|
-
}
|
223
202
|
#endif
|
224
203
|
rb_ivar_set(n, ox_at_value_id, s);
|
225
204
|
if (helper_stack_empty(&pi->helpers)) { /* top level object */
|
@@ -233,14 +212,10 @@ add_comment(PInfo pi, const char *comment) {
|
|
233
212
|
VALUE n = rb_obj_alloc(ox_comment_clas);
|
234
213
|
VALUE s = rb_str_new2(comment);
|
235
214
|
|
236
|
-
#if
|
215
|
+
#if HAVE_RB_ENC_ASSOCIATE
|
237
216
|
if (0 != pi->options->rb_enc) {
|
238
217
|
rb_enc_associate(s, pi->options->rb_enc);
|
239
218
|
}
|
240
|
-
#elif HAS_PRIVATE_ENCODING
|
241
|
-
if (Qnil != pi->options->rb_enc) {
|
242
|
-
rb_funcall(s, ox_force_encoding_id, 1, pi->options->rb_enc);
|
243
|
-
}
|
244
219
|
#endif
|
245
220
|
rb_ivar_set(n, ox_at_value_id, s);
|
246
221
|
if (helper_stack_empty(&pi->helpers)) { /* top level object */
|
@@ -254,14 +229,10 @@ add_cdata(PInfo pi, const char *cdata, size_t len) {
|
|
254
229
|
VALUE n = rb_obj_alloc(ox_cdata_clas);
|
255
230
|
VALUE s = rb_str_new2(cdata);
|
256
231
|
|
257
|
-
#if
|
232
|
+
#if HAVE_RB_ENC_ASSOCIATE
|
258
233
|
if (0 != pi->options->rb_enc) {
|
259
234
|
rb_enc_associate(s, pi->options->rb_enc);
|
260
235
|
}
|
261
|
-
#elif HAS_PRIVATE_ENCODING
|
262
|
-
if (Qnil != pi->options->rb_enc) {
|
263
|
-
rb_funcall(s, ox_force_encoding_id, 1, pi->options->rb_enc);
|
264
|
-
}
|
265
236
|
#endif
|
266
237
|
rb_ivar_set(n, ox_at_value_id, s);
|
267
238
|
if (helper_stack_empty(&pi->helpers)) { /* top level object */
|
@@ -274,14 +245,10 @@ static void
|
|
274
245
|
add_text(PInfo pi, char *text, int closed) {
|
275
246
|
VALUE s = rb_str_new2(text);
|
276
247
|
|
277
|
-
#if
|
248
|
+
#if HAVE_RB_ENC_ASSOCIATE
|
278
249
|
if (0 != pi->options->rb_enc) {
|
279
250
|
rb_enc_associate(s, pi->options->rb_enc);
|
280
251
|
}
|
281
|
-
#elif HAS_PRIVATE_ENCODING
|
282
|
-
if (Qnil != pi->options->rb_enc) {
|
283
|
-
rb_funcall(s, ox_force_encoding_id, 1, pi->options->rb_enc);
|
284
|
-
}
|
285
252
|
#endif
|
286
253
|
if (helper_stack_empty(&pi->helpers)) { /* top level object */
|
287
254
|
create_doc(pi);
|
@@ -297,14 +264,10 @@ add_element(PInfo pi, const char *ename, Attr attrs, int hasChildren) {
|
|
297
264
|
if (Qnil != pi->options->element_key_mod) {
|
298
265
|
s = rb_funcall(pi->options->element_key_mod, ox_call_id, 1, s);
|
299
266
|
}
|
300
|
-
#if
|
267
|
+
#if HAVE_RB_ENC_ASSOCIATE
|
301
268
|
if (0 != pi->options->rb_enc) {
|
302
269
|
rb_enc_associate(s, pi->options->rb_enc);
|
303
270
|
}
|
304
|
-
#elif HAS_PRIVATE_ENCODING
|
305
|
-
if (Qnil != pi->options->rb_enc) {
|
306
|
-
rb_funcall(s, ox_force_encoding_id, 1, pi->options->rb_enc);
|
307
|
-
}
|
308
271
|
#endif
|
309
272
|
e = rb_obj_alloc(ox_element_clas);
|
310
273
|
rb_ivar_set(e, ox_at_value_id, s);
|
@@ -320,7 +283,7 @@ add_element(PInfo pi, const char *ename, Attr attrs, int hasChildren) {
|
|
320
283
|
VALUE *slot;
|
321
284
|
|
322
285
|
if (Qundef == (sym = ox_cache_get(ox_symbol_cache, attrs->name, &slot, 0))) {
|
323
|
-
#if
|
286
|
+
#if HAVE_RB_ENC_ASSOCIATE
|
324
287
|
if (0 != pi->options->rb_enc) {
|
325
288
|
VALUE rstr = rb_str_new2(attrs->name);
|
326
289
|
|
@@ -329,15 +292,6 @@ add_element(PInfo pi, const char *ename, Attr attrs, int hasChildren) {
|
|
329
292
|
} else {
|
330
293
|
sym = ID2SYM(rb_intern(attrs->name));
|
331
294
|
}
|
332
|
-
#elif HAS_PRIVATE_ENCODING
|
333
|
-
if (Qnil != pi->options->rb_enc) {
|
334
|
-
VALUE rstr = rb_str_new2(attrs->name);
|
335
|
-
|
336
|
-
rb_funcall(rstr, ox_force_encoding_id, 1, pi->options->rb_enc);
|
337
|
-
sym = rb_funcall(rstr, ox_to_sym_id, 0);
|
338
|
-
} else {
|
339
|
-
sym = ID2SYM(rb_intern(attrs->name));
|
340
|
-
}
|
341
295
|
#else
|
342
296
|
sym = ID2SYM(rb_intern(attrs->name));
|
343
297
|
#endif
|
@@ -348,25 +302,17 @@ add_element(PInfo pi, const char *ename, Attr attrs, int hasChildren) {
|
|
348
302
|
}
|
349
303
|
} else {
|
350
304
|
sym = rb_str_new2(attrs->name);
|
351
|
-
#if
|
305
|
+
#if HAVE_RB_ENC_ASSOCIATE
|
352
306
|
if (0 != pi->options->rb_enc) {
|
353
307
|
rb_enc_associate(sym, pi->options->rb_enc);
|
354
308
|
}
|
355
|
-
#elif HAS_PRIVATE_ENCODING
|
356
|
-
if (Qnil != pi->options->rb_enc) {
|
357
|
-
rb_funcall(sym, ox_force_encoding_id, 1, pi->options->rb_enc);
|
358
|
-
}
|
359
309
|
#endif
|
360
310
|
}
|
361
311
|
s = rb_str_new2(attrs->value);
|
362
|
-
#if
|
312
|
+
#if HAVE_RB_ENC_ASSOCIATE
|
363
313
|
if (0 != pi->options->rb_enc) {
|
364
314
|
rb_enc_associate(s, pi->options->rb_enc);
|
365
315
|
}
|
366
|
-
#elif HAS_PRIVATE_ENCODING
|
367
|
-
if (Qnil != pi->options->rb_enc) {
|
368
|
-
rb_funcall(s, ox_force_encoding_id, 1, pi->options->rb_enc);
|
369
|
-
}
|
370
316
|
#endif
|
371
317
|
rb_hash_aset(ah, sym, s);
|
372
318
|
}
|
@@ -403,20 +349,13 @@ add_instruct(PInfo pi, const char *name, Attr attrs, const char *content) {
|
|
403
349
|
if (0 != content) {
|
404
350
|
c = rb_str_new2(content);
|
405
351
|
}
|
406
|
-
#if
|
352
|
+
#if HAVE_RB_ENC_ASSOCIATE
|
407
353
|
if (0 != pi->options->rb_enc) {
|
408
354
|
rb_enc_associate(s, pi->options->rb_enc);
|
409
355
|
if (0 != content) {
|
410
356
|
rb_enc_associate(c, pi->options->rb_enc);
|
411
357
|
}
|
412
358
|
}
|
413
|
-
#elif HAS_PRIVATE_ENCODING
|
414
|
-
if (Qnil != pi->options->rb_enc) {
|
415
|
-
rb_funcall(s, ox_force_encoding_id, 1, pi->options->rb_enc);
|
416
|
-
if (0 != content) {
|
417
|
-
rb_funcall(c, ox_force_encoding_id, 1, pi->options->rb_enc);
|
418
|
-
}
|
419
|
-
}
|
420
359
|
#endif
|
421
360
|
inst = rb_obj_alloc(ox_instruct_clas);
|
422
361
|
rb_ivar_set(inst, ox_at_value_id, s);
|
@@ -433,7 +372,7 @@ add_instruct(PInfo pi, const char *name, Attr attrs, const char *content) {
|
|
433
372
|
sym = rb_funcall(pi->options->attr_key_mod, ox_call_id, 1, rb_str_new2(attrs->name));
|
434
373
|
} else if (Yes == pi->options->sym_keys) {
|
435
374
|
if (Qundef == (sym = ox_cache_get(ox_symbol_cache, attrs->name, &slot, 0))) {
|
436
|
-
#if
|
375
|
+
#if HAVE_RB_ENC_ASSOCIATE
|
437
376
|
if (0 != pi->options->rb_enc) {
|
438
377
|
VALUE rstr = rb_str_new2(attrs->name);
|
439
378
|
|
@@ -442,15 +381,6 @@ add_instruct(PInfo pi, const char *name, Attr attrs, const char *content) {
|
|
442
381
|
} else {
|
443
382
|
sym = ID2SYM(rb_intern(attrs->name));
|
444
383
|
}
|
445
|
-
#elif HAS_PRIVATE_ENCODING
|
446
|
-
if (Qnil != pi->options->rb_enc) {
|
447
|
-
VALUE rstr = rb_str_new2(attrs->name);
|
448
|
-
|
449
|
-
rb_funcall(rstr, ox_force_encoding_id, 1, pi->options->rb_enc);
|
450
|
-
sym = rb_funcall(rstr, ox_to_sym_id, 0);
|
451
|
-
} else {
|
452
|
-
sym = ID2SYM(rb_intern(attrs->name));
|
453
|
-
}
|
454
384
|
#else
|
455
385
|
sym = ID2SYM(rb_intern(attrs->name));
|
456
386
|
#endif
|
@@ -461,25 +391,17 @@ add_instruct(PInfo pi, const char *name, Attr attrs, const char *content) {
|
|
461
391
|
}
|
462
392
|
} else {
|
463
393
|
sym = rb_str_new2(attrs->name);
|
464
|
-
#if
|
394
|
+
#if HAVE_RB_ENC_ASSOCIATE
|
465
395
|
if (0 != pi->options->rb_enc) {
|
466
396
|
rb_enc_associate(sym, pi->options->rb_enc);
|
467
397
|
}
|
468
|
-
#elif HAS_PRIVATE_ENCODING
|
469
|
-
if (Qnil != pi->options->rb_enc) {
|
470
|
-
rb_funcall(sym, ox_force_encoding_id, 1, pi->options->rb_enc);
|
471
|
-
}
|
472
398
|
#endif
|
473
399
|
}
|
474
400
|
s = rb_str_new2(attrs->value);
|
475
|
-
#if
|
401
|
+
#if HAVE_RB_ENC_ASSOCIATE
|
476
402
|
if (0 != pi->options->rb_enc) {
|
477
403
|
rb_enc_associate(s, pi->options->rb_enc);
|
478
404
|
}
|
479
|
-
#elif HAS_PRIVATE_ENCODING
|
480
|
-
if (Qnil != pi->options->rb_enc) {
|
481
|
-
rb_funcall(s, ox_force_encoding_id, 1, pi->options->rb_enc);
|
482
|
-
}
|
483
405
|
#endif
|
484
406
|
rb_hash_aset(ah, sym, s);
|
485
407
|
}
|
data/ext/ox/hash_load.c
CHANGED
@@ -13,12 +13,14 @@
|
|
13
13
|
#include "ruby.h"
|
14
14
|
#include "ox.h"
|
15
15
|
|
16
|
+
#define MARK_INC 256
|
17
|
+
|
16
18
|
// The approach taken for the hash and has_no_attrs parsing is to push just
|
17
19
|
// the key on to the stack and then decide what to do on the way up/out.
|
18
20
|
|
19
21
|
static VALUE
|
20
22
|
create_top(PInfo pi) {
|
21
|
-
volatile VALUE top = rb_hash_new()
|
23
|
+
volatile VALUE top = rb_hash_new();
|
22
24
|
|
23
25
|
helper_stack_push(&pi->helpers, 0, top, HashCode);
|
24
26
|
pi->obj = top;
|
@@ -26,20 +28,61 @@ create_top(PInfo pi) {
|
|
26
28
|
return top;
|
27
29
|
}
|
28
30
|
|
31
|
+
static void
|
32
|
+
mark_value(PInfo pi, VALUE val) {
|
33
|
+
if (NULL == pi->marked) {
|
34
|
+
pi->marked = ALLOC_N(VALUE, MARK_INC);
|
35
|
+
pi->mark_size = MARK_INC;
|
36
|
+
} else if (pi->mark_size <= pi->mark_cnt) {
|
37
|
+
pi->mark_size += MARK_INC;
|
38
|
+
pi->marked = REALLOC_N(pi->marked, VALUE, pi->mark_size);
|
39
|
+
}
|
40
|
+
pi->marked[pi->mark_cnt] = val;
|
41
|
+
pi->mark_cnt++;
|
42
|
+
}
|
43
|
+
|
44
|
+
static bool
|
45
|
+
marked(PInfo pi, VALUE val) {
|
46
|
+
if (NULL != pi->marked) {
|
47
|
+
VALUE *vp = pi->marked + pi->mark_cnt - 1;
|
48
|
+
|
49
|
+
for (; pi->marked <= vp; vp--) {
|
50
|
+
if (val == *vp) {
|
51
|
+
return true;
|
52
|
+
}
|
53
|
+
}
|
54
|
+
}
|
55
|
+
return false;
|
56
|
+
}
|
57
|
+
|
58
|
+
static void
|
59
|
+
unmark(PInfo pi, VALUE val) {
|
60
|
+
if (NULL != pi->marked) {
|
61
|
+
VALUE *vp = pi->marked + pi->mark_cnt - 1;
|
62
|
+
int i;
|
63
|
+
|
64
|
+
for (i = 0; pi->marked <= vp; vp--, i++) {
|
65
|
+
if (val == *vp) {
|
66
|
+
for (; 0 < i; i--, vp++) {
|
67
|
+
*vp = *(vp + 1);
|
68
|
+
}
|
69
|
+
pi->mark_cnt--;
|
70
|
+
break;
|
71
|
+
}
|
72
|
+
}
|
73
|
+
}
|
74
|
+
}
|
75
|
+
|
29
76
|
static void
|
30
77
|
add_text(PInfo pi, char *text, int closed) {
|
31
78
|
Helper parent = helper_stack_peek(&pi->helpers);
|
32
79
|
volatile VALUE s = rb_str_new2(text);
|
33
80
|
volatile VALUE a;
|
34
81
|
|
35
|
-
#if
|
82
|
+
#if HAVE_RB_ENC_ASSOCIATE
|
36
83
|
if (0 != pi->options->rb_enc) {
|
37
84
|
rb_enc_associate(s, pi->options->rb_enc);
|
38
85
|
}
|
39
|
-
#elif HAS_PRIVATE_ENCODING
|
40
|
-
if (Qnil != pi->options->rb_enc) {
|
41
|
-
rb_funcall(s, ox_force_encoding_id, 1, pi->options->rb_enc);
|
42
|
-
}
|
43
86
|
#endif
|
44
87
|
switch (parent->type) {
|
45
88
|
case NoCode:
|
@@ -79,20 +122,16 @@ add_element(PInfo pi, const char *ename, Attr attrs, int hasChildren) {
|
|
79
122
|
key = rb_str_new2(attrs->name);
|
80
123
|
}
|
81
124
|
val = rb_str_new2(attrs->value);
|
82
|
-
#if
|
125
|
+
#if HAVE_RB_ENC_ASSOCIATE
|
83
126
|
if (0 != pi->options->rb_enc) {
|
84
127
|
rb_enc_associate(val, pi->options->rb_enc);
|
85
128
|
}
|
86
|
-
#elif HAS_PRIVATE_ENCODING
|
87
|
-
if (Qnil != pi->options->rb_enc) {
|
88
|
-
rb_funcall(val, ox_force_encoding_id, 1, pi->options->rb_enc);
|
89
|
-
}
|
90
129
|
#endif
|
91
130
|
rb_hash_aset(h, key, val);
|
92
131
|
}
|
93
132
|
a = rb_ary_new();
|
94
133
|
rb_ary_push(a, h);
|
95
|
-
|
134
|
+
mark_value(pi, a);
|
96
135
|
helper_stack_push(&pi->helpers, rb_intern(ename), a, ArrayCode);
|
97
136
|
} else {
|
98
137
|
helper_stack_push(&pi->helpers, rb_intern(ename), Qnil, NoCode);
|
@@ -108,15 +147,14 @@ add_element_no_attrs(PInfo pi, const char *ename, Attr attrs, int hasChildren) {
|
|
108
147
|
}
|
109
148
|
|
110
149
|
static int
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
}
|
150
|
+
umark_hash_cb(VALUE key, VALUE value, VALUE x) {
|
151
|
+
unmark((PInfo)x, value);
|
152
|
+
|
115
153
|
return ST_CONTINUE;
|
116
154
|
}
|
117
155
|
|
118
156
|
static void
|
119
|
-
end_element_core(PInfo pi, const char *ename, bool
|
157
|
+
end_element_core(PInfo pi, const char *ename, bool check_marked) {
|
120
158
|
Helper e = helper_stack_pop(&pi->helpers);
|
121
159
|
Helper parent = helper_stack_peek(&pi->helpers);
|
122
160
|
volatile VALUE pobj = parent->obj;
|
@@ -161,8 +199,8 @@ end_element_core(PInfo pi, const char *ename, bool check_taint) {
|
|
161
199
|
if (Qundef == found) {
|
162
200
|
rb_hash_aset(pobj, key, e->obj);
|
163
201
|
} else if (RUBY_T_ARRAY == rb_type(found)) {
|
164
|
-
if (
|
165
|
-
|
202
|
+
if (check_marked && marked(pi, found)) {
|
203
|
+
unmark(pi, found);
|
166
204
|
a = rb_ary_new();
|
167
205
|
rb_ary_push(a, found);
|
168
206
|
rb_ary_push(a, e->obj);
|
@@ -171,16 +209,16 @@ end_element_core(PInfo pi, const char *ename, bool check_taint) {
|
|
171
209
|
rb_ary_push(found, e->obj);
|
172
210
|
}
|
173
211
|
} else { // something there other than an array
|
174
|
-
if (
|
175
|
-
|
212
|
+
if (check_marked && marked(pi, e->obj)) {
|
213
|
+
unmark(pi, e->obj);
|
176
214
|
}
|
177
215
|
a = rb_ary_new();
|
178
216
|
rb_ary_push(a, found);
|
179
217
|
rb_ary_push(a, e->obj);
|
180
218
|
rb_hash_aset(pobj, key, a);
|
181
219
|
}
|
182
|
-
if (
|
183
|
-
rb_hash_foreach(e->obj,
|
220
|
+
if (check_marked && NULL != pi->marked && RUBY_T_HASH == rb_type(e->obj)) {
|
221
|
+
rb_hash_foreach(e->obj, umark_hash_cb, (VALUE)pi);
|
184
222
|
}
|
185
223
|
}
|
186
224
|
|
@@ -196,9 +234,7 @@ end_element_no_attrs(PInfo pi, const char *ename) {
|
|
196
234
|
|
197
235
|
static void
|
198
236
|
finish(PInfo pi) {
|
199
|
-
|
200
|
-
rb_hash_foreach(pi->obj, untaint_hash_cb, Qnil);
|
201
|
-
}
|
237
|
+
xfree(pi->marked);
|
202
238
|
}
|
203
239
|
|
204
240
|
struct _parseCallbacks _ox_hash_callbacks = {
|
data/ext/ox/obj_load.c
CHANGED
@@ -11,6 +11,9 @@
|
|
11
11
|
#include <time.h>
|
12
12
|
|
13
13
|
#include "ruby.h"
|
14
|
+
#if HAVE_RB_ENC_ASSOCIATE
|
15
|
+
#include "ruby/encoding.h"
|
16
|
+
#endif
|
14
17
|
#include "base64.h"
|
15
18
|
#include "ox.h"
|
16
19
|
|
@@ -143,7 +146,6 @@ classname2obj(const char *name, PInfo pi, VALUE base_class) {
|
|
143
146
|
}
|
144
147
|
}
|
145
148
|
|
146
|
-
#if HAS_RSTRUCT
|
147
149
|
inline static VALUE
|
148
150
|
structname2obj(const char *name) {
|
149
151
|
VALUE ost;
|
@@ -159,16 +161,12 @@ structname2obj(const char *name) {
|
|
159
161
|
}
|
160
162
|
}
|
161
163
|
ost = rb_const_get(ox_struct_class, rb_intern(s));
|
162
|
-
|
163
|
-
#if HAS_ENCODING_SUPPORT
|
164
|
-
return rb_struct_alloc_noinit(ost);
|
165
|
-
#elif HAS_PRIVATE_ENCODING
|
164
|
+
#if HAVE_RB_STRUCT_ALLOC_NOINIT
|
166
165
|
return rb_struct_alloc_noinit(ost);
|
167
166
|
#else
|
168
167
|
return rb_struct_new(ost);
|
169
168
|
#endif
|
170
169
|
}
|
171
|
-
#endif
|
172
170
|
|
173
171
|
inline static VALUE
|
174
172
|
parse_ulong(const char *s, PInfo pi) {
|
@@ -255,7 +253,6 @@ get_obj_from_attrs(Attr a, PInfo pi, VALUE base_class) {
|
|
255
253
|
return Qundef;
|
256
254
|
}
|
257
255
|
|
258
|
-
#if HAS_RSTRUCT
|
259
256
|
static VALUE
|
260
257
|
get_struct_from_attrs(Attr a) {
|
261
258
|
for (; 0 != a->name; a++) {
|
@@ -265,7 +262,6 @@ get_struct_from_attrs(Attr a) {
|
|
265
262
|
}
|
266
263
|
return Qundef;
|
267
264
|
}
|
268
|
-
#endif
|
269
265
|
|
270
266
|
static VALUE
|
271
267
|
get_class_from_attrs(Attr a, PInfo pi, VALUE base_class) {
|
@@ -363,7 +359,7 @@ parse_regexp(const char *text) {
|
|
363
359
|
int options = 0;
|
364
360
|
|
365
361
|
te = text + strlen(text) - 1;
|
366
|
-
#
|
362
|
+
#ifdef ONIG_OPTION_IGNORECASE
|
367
363
|
for (; text < te && '/' != *te; te--) {
|
368
364
|
switch (*te) {
|
369
365
|
case 'i': options |= ONIG_OPTION_IGNORECASE; break;
|
@@ -379,18 +375,12 @@ parse_regexp(const char *text) {
|
|
379
375
|
static void
|
380
376
|
instruct(PInfo pi, const char *target, Attr attrs, const char *content) {
|
381
377
|
if (0 == strcmp("xml", target)) {
|
382
|
-
#if
|
378
|
+
#if HAVE_RB_ENC_FIND
|
383
379
|
for (; 0 != attrs->name; attrs++) {
|
384
380
|
if (0 == strcmp("encoding", attrs->name)) {
|
385
381
|
pi->options->rb_enc = rb_enc_find(attrs->value);
|
386
382
|
}
|
387
383
|
}
|
388
|
-
#elif HAS_PRIVATE_ENCODING
|
389
|
-
for (; 0 != attrs->name; attrs++) {
|
390
|
-
if (0 == strcmp("encoding", attrs->name)) {
|
391
|
-
pi->options->rb_enc = rb_str_new2(attrs->value);
|
392
|
-
}
|
393
|
-
}
|
394
384
|
#endif
|
395
385
|
}
|
396
386
|
}
|
@@ -417,14 +407,10 @@ add_text(PInfo pi, char *text, int closed) {
|
|
417
407
|
case NoCode:
|
418
408
|
case StringCode:
|
419
409
|
h->obj = rb_str_new2(text);
|
420
|
-
#if
|
410
|
+
#if HAVE_RB_ENC_ASSOCIATE
|
421
411
|
if (0 != pi->options->rb_enc) {
|
422
412
|
rb_enc_associate(h->obj, pi->options->rb_enc);
|
423
413
|
}
|
424
|
-
#elif HAS_PRIVATE_ENCODING
|
425
|
-
if (Qnil != pi->options->rb_enc) {
|
426
|
-
rb_funcall(h->obj, ox_force_encoding_id, 1, pi->options->rb_enc);
|
427
|
-
}
|
428
414
|
#endif
|
429
415
|
if (0 != pi->circ_array) {
|
430
416
|
circ_array_set(pi->circ_array, h->obj, (unsigned long)pi->id);
|
@@ -494,14 +480,10 @@ add_text(PInfo pi, char *text, int closed) {
|
|
494
480
|
|
495
481
|
from_base64(text, (uchar*)str);
|
496
482
|
v = rb_str_new(str, str_size);
|
497
|
-
#if
|
483
|
+
#if HAVE_RB_ENC_ASSOCIATE
|
498
484
|
if (0 != pi->options->rb_enc) {
|
499
485
|
rb_enc_associate(v, pi->options->rb_enc);
|
500
486
|
}
|
501
|
-
#elif HAS_PRIVATE_ENCODING
|
502
|
-
if (0 != pi->options->rb_enc) {
|
503
|
-
rb_funcall(v, ox_force_encoding_id, 1, pi->options->rb_enc);
|
504
|
-
}
|
505
487
|
#endif
|
506
488
|
if (0 != pi->circ_array) {
|
507
489
|
circ_array_set(pi->circ_array, v, (unsigned long)h->obj);
|
@@ -542,11 +524,7 @@ add_text(PInfo pi, char *text, int closed) {
|
|
542
524
|
h->obj = rb_cstr_to_inum(text, 10, 1);
|
543
525
|
break;
|
544
526
|
case BigDecimalCode:
|
545
|
-
#if HAS_BIGDECIMAL
|
546
527
|
h->obj = rb_funcall(rb_cObject, ox_bigdecimal_id, 1, rb_str_new2(text));
|
547
|
-
#else
|
548
|
-
h->obj = Qnil;
|
549
|
-
#endif
|
550
528
|
break;
|
551
529
|
default:
|
552
530
|
h->obj = Qnil;
|
@@ -670,15 +648,10 @@ add_element(PInfo pi, const char *ename, Attr attrs, int hasChildren) {
|
|
670
648
|
}
|
671
649
|
break;
|
672
650
|
case StructCode:
|
673
|
-
#if HAS_RSTRUCT
|
674
651
|
h->obj = get_struct_from_attrs(attrs);
|
675
652
|
if (0 != pi->circ_array) {
|
676
653
|
circ_array_set(pi->circ_array, h->obj, get_id_from_attrs(pi, attrs));
|
677
654
|
}
|
678
|
-
#else
|
679
|
-
set_error(&pi->err, "Ruby structs not supported with this verion of Ruby", pi->str, pi->s);
|
680
|
-
return;
|
681
|
-
#endif
|
682
655
|
break;
|
683
656
|
case ClassCode:
|
684
657
|
if (Qundef == (h->obj = get_class_from_attrs(attrs, pi, ox_bag_clas))) {
|
@@ -750,23 +723,17 @@ end_element(PInfo pi, const char *ename) {
|
|
750
723
|
}
|
751
724
|
break;
|
752
725
|
case StructCode:
|
753
|
-
#if HAS_RSTRUCT
|
754
726
|
if (0 == h->var) {
|
755
727
|
set_error(&pi->err, "Invalid element for object mode", pi->str, pi->s);
|
756
728
|
return;
|
757
729
|
}
|
758
730
|
rb_struct_aset(ph->obj, h->var, h->obj);
|
759
|
-
#else
|
760
|
-
set_error(&pi->err, "Ruby structs not supported with this verion of Ruby", pi->str, pi->s);
|
761
|
-
return;
|
762
|
-
#endif
|
763
731
|
break;
|
764
732
|
case HashCode:
|
765
733
|
// put back h
|
766
734
|
helper_stack_push(&pi->helpers, h->var, h->obj, KeyCode);
|
767
735
|
break;
|
768
736
|
case RangeCode:
|
769
|
-
#if HAS_RSTRUCT
|
770
737
|
if (ox_beg_id == h->var) {
|
771
738
|
RSTRUCT_SET(ph->obj, 0, h->obj);
|
772
739
|
} else if (ox_end_id == h->var) {
|
@@ -777,10 +744,6 @@ end_element(PInfo pi, const char *ename) {
|
|
777
744
|
set_error(&pi->err, "Invalid range attribute", pi->str, pi->s);
|
778
745
|
return;
|
779
746
|
}
|
780
|
-
#else
|
781
|
-
set_error(&pi->err, "Ruby structs not supported with this verion of Ruby", pi->str, pi->s);
|
782
|
-
return;
|
783
|
-
#endif
|
784
747
|
break;
|
785
748
|
case KeyCode:
|
786
749
|
{
|