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/sax.c
CHANGED
@@ -9,13 +9,16 @@
|
|
9
9
|
#include <stdio.h>
|
10
10
|
#include <strings.h>
|
11
11
|
#include <sys/types.h>
|
12
|
-
#if
|
12
|
+
#if HAVE_SYS_UIO_H
|
13
13
|
#include <sys/uio.h>
|
14
14
|
#endif
|
15
15
|
#include <unistd.h>
|
16
16
|
#include <time.h>
|
17
17
|
|
18
18
|
#include "ruby.h"
|
19
|
+
#if HAVE_RB_ENC_ASSOCIATE
|
20
|
+
#include "ruby/encoding.h"
|
21
|
+
#endif
|
19
22
|
#include "ox.h"
|
20
23
|
#include "sax.h"
|
21
24
|
#include "sax_stack.h"
|
@@ -55,7 +58,7 @@ static char read_attrs(SaxDrive dr, char c, char termc, char term2, int is_xml,
|
|
55
58
|
static char read_name_token(SaxDrive dr);
|
56
59
|
static char read_quoted_value(SaxDrive dr);
|
57
60
|
|
58
|
-
static void end_element_cb(SaxDrive dr, VALUE name,
|
61
|
+
static void end_element_cb(SaxDrive dr, VALUE name, long pos, long line, long col, Hint h);
|
59
62
|
|
60
63
|
static void hint_clear_empty(SaxDrive dr);
|
61
64
|
static Nv hint_try_close(SaxDrive dr, const char *name);
|
@@ -68,9 +71,9 @@ static VALUE protect_parse(VALUE drp) {
|
|
68
71
|
return Qnil;
|
69
72
|
}
|
70
73
|
|
71
|
-
#if
|
74
|
+
#if HAVE_RB_ENC_ASSOCIATE
|
72
75
|
static int
|
73
|
-
|
76
|
+
str_is_ascii(const char *s) {
|
74
77
|
for (; '\0' != *s; s++) {
|
75
78
|
if (*s < ' ' || '~' < *s) {
|
76
79
|
return 0;
|
@@ -87,8 +90,8 @@ str2sym(SaxDrive dr, const char *str, const char **strp) {
|
|
87
90
|
|
88
91
|
if (dr->options.symbolize) {
|
89
92
|
if (Qundef == (sym = ox_cache_get(ox_symbol_cache, str, &slot, strp))) {
|
90
|
-
#if
|
91
|
-
if (0 != dr->encoding && !
|
93
|
+
#if HAVE_RB_ENC_ASSOCIATE
|
94
|
+
if (0 != dr->encoding && !str_is_ascii(str)) {
|
92
95
|
VALUE rstr = rb_str_new2(str);
|
93
96
|
|
94
97
|
// TBD if sym can be pinned down then use this all the time
|
@@ -99,20 +102,6 @@ str2sym(SaxDrive dr, const char *str, const char **strp) {
|
|
99
102
|
sym = ID2SYM(rb_intern(str));
|
100
103
|
*slot = sym;
|
101
104
|
}
|
102
|
-
#elif HAS_PRIVATE_ENCODING
|
103
|
-
if (Qnil != dr->encoding && !strIsAscii(str)) {
|
104
|
-
VALUE rstr = rb_str_new2(str);
|
105
|
-
|
106
|
-
rb_funcall(rstr, ox_force_encoding_id, 1, dr->encoding);
|
107
|
-
sym = rb_funcall(rstr, ox_to_sym_id, 0);
|
108
|
-
// Needed for Ruby 2.2 to get around the GC of symbols created
|
109
|
-
// with to_sym which is needed for encoded symbols.
|
110
|
-
rb_ary_push(ox_sym_bank, sym);
|
111
|
-
*slot = Qundef;
|
112
|
-
} else {
|
113
|
-
sym = ID2SYM(rb_intern(str));
|
114
|
-
*slot = sym;
|
115
|
-
}
|
116
105
|
#else
|
117
106
|
sym = ID2SYM(rb_intern(str));
|
118
107
|
*slot = sym;
|
@@ -120,14 +109,10 @@ str2sym(SaxDrive dr, const char *str, const char **strp) {
|
|
120
109
|
}
|
121
110
|
} else {
|
122
111
|
sym = rb_str_new2(str);
|
123
|
-
#if
|
112
|
+
#if HAVE_RB_ENC_ASSOCIATE
|
124
113
|
if (0 != dr->encoding) {
|
125
114
|
rb_enc_associate(sym, dr->encoding);
|
126
115
|
}
|
127
|
-
#elif HAS_PRIVATE_ENCODING
|
128
|
-
if (Qnil != dr->encoding) {
|
129
|
-
rb_funcall(sym, ox_force_encoding_id, 1, dr->encoding);
|
130
|
-
}
|
131
116
|
#endif
|
132
117
|
if (0 != strp) {
|
133
118
|
*strp = StringValuePtr(sym);
|
@@ -182,7 +167,7 @@ sax_drive_init(SaxDrive dr, VALUE handler, VALUE io, SaxOptions options) {
|
|
182
167
|
dr->blocked = 0;
|
183
168
|
dr->abort = false;
|
184
169
|
has_init(&dr->has, handler);
|
185
|
-
#if
|
170
|
+
#if HAVE_RB_ENC_FIND
|
186
171
|
if ('\0' == *ox_default_options.encoding) {
|
187
172
|
VALUE encoding;
|
188
173
|
|
@@ -196,18 +181,6 @@ sax_drive_init(SaxDrive dr, VALUE handler, VALUE io, SaxOptions options) {
|
|
196
181
|
} else {
|
197
182
|
dr->encoding = rb_enc_find(ox_default_options.encoding);
|
198
183
|
}
|
199
|
-
#elif HAS_PRIVATE_ENCODING
|
200
|
-
if ('\0' == *ox_default_options.encoding) {
|
201
|
-
VALUE encoding;
|
202
|
-
|
203
|
-
if (rb_respond_to(io, ox_external_encoding_id) && Qnil != (encoding = rb_funcall(io, ox_external_encoding_id, 0))) {
|
204
|
-
dr->encoding = encoding;
|
205
|
-
} else {
|
206
|
-
dr->encoding = Qnil;
|
207
|
-
}
|
208
|
-
} else {
|
209
|
-
dr->encoding = rb_str_new2(ox_default_options.encoding);
|
210
|
-
}
|
211
184
|
#else
|
212
185
|
dr->encoding = 0;
|
213
186
|
#endif
|
@@ -221,7 +194,7 @@ ox_sax_drive_cleanup(SaxDrive dr) {
|
|
221
194
|
}
|
222
195
|
|
223
196
|
static void
|
224
|
-
ox_sax_drive_error_at(SaxDrive dr, const char *msg,
|
197
|
+
ox_sax_drive_error_at(SaxDrive dr, const char *msg, off_t pos, off_t line, off_t col) {
|
225
198
|
if (dr->has.error) {
|
226
199
|
VALUE args[3];
|
227
200
|
|
@@ -255,9 +228,7 @@ skipBOM(SaxDrive dr) {
|
|
255
228
|
|
256
229
|
if (0xEF == (uint8_t)c) { /* only UTF8 is supported */
|
257
230
|
if (0xBB == (uint8_t)buf_get(&dr->buf) && 0xBF == (uint8_t)buf_get(&dr->buf)) {
|
258
|
-
#if
|
259
|
-
dr->encoding = ox_utf8_encoding;
|
260
|
-
#elif HAS_PRIVATE_ENCODING
|
231
|
+
#if HAVE_RB_ENC_FIND
|
261
232
|
dr->encoding = ox_utf8_encoding;
|
262
233
|
#else
|
263
234
|
dr->encoding = UTF8_STR;
|
@@ -301,11 +272,11 @@ parse(SaxDrive dr) {
|
|
301
272
|
}
|
302
273
|
c = read_comment(dr);
|
303
274
|
} else {
|
304
|
-
int
|
305
|
-
int
|
306
|
-
|
307
|
-
|
308
|
-
|
275
|
+
int i;
|
276
|
+
int spaced = 0;
|
277
|
+
off_t pos = dr->buf.pos + 1;
|
278
|
+
off_t line = dr->buf.line;
|
279
|
+
off_t col = dr->buf.col + 1;
|
309
280
|
|
310
281
|
if (is_white(c)) {
|
311
282
|
spaced = 1;
|
@@ -359,19 +330,15 @@ parse(SaxDrive dr) {
|
|
359
330
|
parent = stack_peek(&dr->stack);
|
360
331
|
if (0 != parent && 0 == parent->childCnt && dr->has.text && !dr->blocked) {
|
361
332
|
VALUE args[1];
|
362
|
-
|
363
|
-
|
364
|
-
|
333
|
+
off_t pos = dr->buf.pos;
|
334
|
+
off_t line = dr->buf.line;
|
335
|
+
off_t col = dr->buf.col - 1;
|
365
336
|
|
366
337
|
args[0] = rb_str_new2("");
|
367
|
-
#if
|
338
|
+
#if HAVE_RB_ENC_ASSOCIATE
|
368
339
|
if (0 != dr->encoding) {
|
369
340
|
rb_enc_associate(args[0], dr->encoding);
|
370
341
|
}
|
371
|
-
#elif HAS_PRIVATE_ENCODING
|
372
|
-
if (Qnil != dr->encoding) {
|
373
|
-
rb_funcall(args[0], ox_force_encoding_id, 1, dr->encoding);
|
374
|
-
}
|
375
342
|
#endif
|
376
343
|
if (dr->has.pos) {
|
377
344
|
rb_ivar_set(dr->handler, ox_at_pos_id, LONG2NUM(pos));
|
@@ -479,9 +446,9 @@ read_instruction(SaxDrive dr) {
|
|
479
446
|
int coff;
|
480
447
|
VALUE target = Qnil;
|
481
448
|
int is_xml;
|
482
|
-
|
483
|
-
|
484
|
-
|
449
|
+
off_t pos = dr->buf.pos - 1;
|
450
|
+
off_t line = dr->buf.line;
|
451
|
+
off_t col = dr->buf.col - 1;
|
485
452
|
|
486
453
|
buf_protect(&dr->buf);
|
487
454
|
if ('\0' == (c = read_name_token(dr))) {
|
@@ -511,7 +478,7 @@ read_instruction(SaxDrive dr) {
|
|
511
478
|
line = dr->buf.line;
|
512
479
|
col = dr->buf.col;
|
513
480
|
read_content(dr, content, sizeof(content) - 1);
|
514
|
-
coff = dr->buf.tail - dr->buf.head;
|
481
|
+
coff = (int)(dr->buf.tail - dr->buf.head);
|
515
482
|
buf_reset(&dr->buf);
|
516
483
|
dr->err = 0;
|
517
484
|
c = read_attrs(dr, c, '?', '?', is_xml, 1, NULL);
|
@@ -523,17 +490,13 @@ read_instruction(SaxDrive dr) {
|
|
523
490
|
VALUE args[1];
|
524
491
|
|
525
492
|
if (dr->options.convert_special) {
|
526
|
-
ox_sax_collapse_special(dr, content, pos, line, col);
|
493
|
+
ox_sax_collapse_special(dr, content, (int)pos, (int)line, (int)col);
|
527
494
|
}
|
528
495
|
args[0] = rb_str_new2(content);
|
529
|
-
#if
|
496
|
+
#if HAVE_RB_ENC_ASSOCIATE
|
530
497
|
if (0 != dr->encoding) {
|
531
498
|
rb_enc_associate(args[0], dr->encoding);
|
532
499
|
}
|
533
|
-
#elif HAS_PRIVATE_ENCODING
|
534
|
-
if (Qnil != dr->encoding) {
|
535
|
-
rb_funcall(args[0], ox_force_encoding_id, 1, dr->encoding);
|
536
|
-
}
|
537
500
|
#endif
|
538
501
|
if (dr->has.line) {
|
539
502
|
rb_ivar_set(dr->handler, ox_at_line_id, LONG2NUM(line));
|
@@ -627,9 +590,9 @@ read_delimited(SaxDrive dr, char end) {
|
|
627
590
|
*/
|
628
591
|
static char
|
629
592
|
read_doctype(SaxDrive dr) {
|
630
|
-
|
631
|
-
|
632
|
-
|
593
|
+
long pos = (long)(dr->buf.pos - 9);
|
594
|
+
long line = (long)(dr->buf.line);
|
595
|
+
long col = (long)(dr->buf.col - 9);
|
633
596
|
char *s;
|
634
597
|
Nv parent = stack_peek(&dr->stack);
|
635
598
|
|
@@ -673,9 +636,9 @@ read_cdata(SaxDrive dr) {
|
|
673
636
|
char c;
|
674
637
|
char zero = '\0';
|
675
638
|
int end = 0;
|
676
|
-
|
677
|
-
|
678
|
-
|
639
|
+
long pos = (long)(dr->buf.pos - 9);
|
640
|
+
long line = (long)(dr->buf.line);
|
641
|
+
long col = (long)(dr->buf.col - 9);
|
679
642
|
struct _checkPt cp = CHECK_PT_INIT;
|
680
643
|
Nv parent = stack_peek(&dr->stack);
|
681
644
|
|
@@ -732,14 +695,10 @@ read_cdata(SaxDrive dr) {
|
|
732
695
|
VALUE args[1];
|
733
696
|
|
734
697
|
args[0] = rb_str_new2(dr->buf.str);
|
735
|
-
#if
|
698
|
+
#if HAVE_RB_ENC_ASSOCIATE
|
736
699
|
if (0 != dr->encoding) {
|
737
700
|
rb_enc_associate(args[0], dr->encoding);
|
738
701
|
}
|
739
|
-
#elif HAS_PRIVATE_ENCODING
|
740
|
-
if (Qnil != dr->encoding) {
|
741
|
-
rb_funcall(args[0], ox_force_encoding_id, 1, dr->encoding);
|
742
|
-
}
|
743
702
|
#endif
|
744
703
|
if (dr->has.pos) {
|
745
704
|
rb_ivar_set(dr->handler, ox_at_pos_id, LONG2NUM(pos));
|
@@ -768,9 +727,9 @@ read_comment(SaxDrive dr) {
|
|
768
727
|
char c;
|
769
728
|
char zero = '\0';
|
770
729
|
int end = 0;
|
771
|
-
|
772
|
-
|
773
|
-
|
730
|
+
long pos = (long)(dr->buf.pos - 4);
|
731
|
+
long line = (long)(dr->buf.line);
|
732
|
+
long col = (long)(dr->buf.col - 4);
|
774
733
|
struct _checkPt cp = CHECK_PT_INIT;
|
775
734
|
|
776
735
|
buf_backup(&dr->buf); /* back up to the start in case the cdata is empty */
|
@@ -826,14 +785,10 @@ read_comment(SaxDrive dr) {
|
|
826
785
|
(NULL != h && (ActiveOverlay == h->overlay || ActiveOverlay == h->overlay))) {
|
827
786
|
|
828
787
|
args[0] = rb_str_new2(dr->buf.str);
|
829
|
-
#if
|
788
|
+
#if HAVE_RB_ENC_ASSOCIATE
|
830
789
|
if (0 != dr->encoding) {
|
831
790
|
rb_enc_associate(args[0], dr->encoding);
|
832
791
|
}
|
833
|
-
#elif HAS_PRIVATE_ENCODING
|
834
|
-
if (Qnil != dr->encoding) {
|
835
|
-
rb_funcall(args[0], ox_force_encoding_id, 1, dr->encoding);
|
836
|
-
}
|
837
792
|
#endif
|
838
793
|
if (dr->has.pos) {
|
839
794
|
rb_ivar_set(dr->handler, ox_at_pos_id, LONG2NUM(pos));
|
@@ -864,9 +819,9 @@ read_element_start(SaxDrive dr) {
|
|
864
819
|
volatile VALUE name = Qnil;
|
865
820
|
char c;
|
866
821
|
int closed;
|
867
|
-
|
868
|
-
|
869
|
-
|
822
|
+
long pos = (long)(dr->buf.pos);
|
823
|
+
long line = (long)(dr->buf.line);
|
824
|
+
long col = (long)(dr->buf.col);
|
870
825
|
Hint h = NULL;
|
871
826
|
int stackless = 0;
|
872
827
|
Nv parent = stack_peek(&dr->stack);
|
@@ -1020,9 +975,9 @@ static char
|
|
1020
975
|
read_element_end(SaxDrive dr) {
|
1021
976
|
VALUE name = Qnil;
|
1022
977
|
char c;
|
1023
|
-
|
1024
|
-
|
1025
|
-
|
978
|
+
long pos = (long)(dr->buf.pos - 1);
|
979
|
+
long line = (long)(dr->buf.line);
|
980
|
+
long col = (long)(dr->buf.col - 1);
|
1026
981
|
Nv nv;
|
1027
982
|
Hint h = NULL;
|
1028
983
|
|
@@ -1118,9 +1073,9 @@ static char
|
|
1118
1073
|
read_text(SaxDrive dr) {
|
1119
1074
|
VALUE args[1];
|
1120
1075
|
char c;
|
1121
|
-
|
1122
|
-
|
1123
|
-
|
1076
|
+
long pos = (long)(dr->buf.pos);
|
1077
|
+
long line = (long)(dr->buf.line);
|
1078
|
+
long col = (long)(dr->buf.col - 1);
|
1124
1079
|
Nv parent = stack_peek(&dr->stack);
|
1125
1080
|
int allWhite = 1;
|
1126
1081
|
|
@@ -1158,14 +1113,10 @@ read_text(SaxDrive dr) {
|
|
1158
1113
|
((NoSkip == dr->options.skip && !isEnd) ||
|
1159
1114
|
(OffSkip == dr->options.skip))) {
|
1160
1115
|
args[0] = rb_str_new2(dr->buf.str);
|
1161
|
-
#if
|
1116
|
+
#if HAVE_RB_ENC_ASSOCIATE
|
1162
1117
|
if (0 != dr->encoding) {
|
1163
1118
|
rb_enc_associate(args[0], dr->encoding);
|
1164
1119
|
}
|
1165
|
-
#elif HAS_PRIVATE_ENCODING
|
1166
|
-
if (Qnil != dr->encoding) {
|
1167
|
-
rb_funcall(args[0], ox_force_encoding_id, 1, dr->encoding);
|
1168
|
-
}
|
1169
1120
|
#endif
|
1170
1121
|
if (dr->has.pos) {
|
1171
1122
|
rb_ivar_set(dr->handler, ox_at_pos_id, LONG2NUM(pos));
|
@@ -1213,14 +1164,10 @@ read_text(SaxDrive dr) {
|
|
1213
1164
|
break;
|
1214
1165
|
}
|
1215
1166
|
args[0] = rb_str_new2(dr->buf.str);
|
1216
|
-
#if
|
1167
|
+
#if HAVE_RB_ENC_ASSOCIATE
|
1217
1168
|
if (0 != dr->encoding) {
|
1218
1169
|
rb_enc_associate(args[0], dr->encoding);
|
1219
1170
|
}
|
1220
|
-
#elif HAS_PRIVATE_ENCODING
|
1221
|
-
if (Qnil != dr->encoding) {
|
1222
|
-
rb_funcall(args[0], ox_force_encoding_id, 1, dr->encoding);
|
1223
|
-
}
|
1224
1171
|
#endif
|
1225
1172
|
if (dr->has.pos) {
|
1226
1173
|
rb_ivar_set(dr->handler, ox_at_pos_id, LONG2NUM(pos));
|
@@ -1266,9 +1213,9 @@ static char
|
|
1266
1213
|
read_jump(SaxDrive dr, const char *pat) {
|
1267
1214
|
VALUE args[1];
|
1268
1215
|
char c;
|
1269
|
-
|
1270
|
-
|
1271
|
-
|
1216
|
+
long pos = (long)(dr->buf.pos);
|
1217
|
+
long line = (long)(dr->buf.line);
|
1218
|
+
long col = (long)(dr->buf.col - 1);
|
1272
1219
|
Nv parent = stack_peek(&dr->stack);
|
1273
1220
|
|
1274
1221
|
buf_protect(&dr->buf);
|
@@ -1299,14 +1246,10 @@ read_jump(SaxDrive dr, const char *pat) {
|
|
1299
1246
|
// TBD check parent overlay
|
1300
1247
|
if (dr->has.text && !dr->blocked) {
|
1301
1248
|
args[0] = rb_str_new2(dr->buf.str);
|
1302
|
-
#if
|
1249
|
+
#if HAVE_RB_ENC_ASSOCIATE
|
1303
1250
|
if (0 != dr->encoding) {
|
1304
1251
|
rb_enc_associate(args[0], dr->encoding);
|
1305
1252
|
}
|
1306
|
-
#elif HAS_PRIVATE_ENCODING
|
1307
|
-
if (Qnil != dr->encoding) {
|
1308
|
-
rb_funcall(args[0], ox_force_encoding_id, 1, dr->encoding);
|
1309
|
-
}
|
1310
1253
|
#endif
|
1311
1254
|
if (dr->has.pos) {
|
1312
1255
|
rb_ivar_set(dr->handler, ox_at_pos_id, LONG2NUM(pos));
|
@@ -1330,9 +1273,9 @@ static char
|
|
1330
1273
|
read_attrs(SaxDrive dr, char c, char termc, char term2, int is_xml, int eq_req, Hint h) {
|
1331
1274
|
VALUE name = Qnil;
|
1332
1275
|
int is_encoding = 0;
|
1333
|
-
|
1334
|
-
|
1335
|
-
|
1276
|
+
off_t pos;
|
1277
|
+
off_t line;
|
1278
|
+
off_t col;
|
1336
1279
|
char *attr_value;
|
1337
1280
|
|
1338
1281
|
// already protected by caller
|
@@ -1377,10 +1320,8 @@ read_attrs(SaxDrive dr, char c, char termc, char term2, int is_xml, int eq_req,
|
|
1377
1320
|
c = read_quoted_value(dr);
|
1378
1321
|
attr_value = dr->buf.str;
|
1379
1322
|
if (is_encoding) {
|
1380
|
-
#if
|
1323
|
+
#if HAVE_RB_ENC_FIND
|
1381
1324
|
dr->encoding = rb_enc_find(dr->buf.str);
|
1382
|
-
#elif HAS_PRIVATE_ENCODING
|
1383
|
-
dr->encoding = rb_str_new2(dr->buf.str);
|
1384
1325
|
#else
|
1385
1326
|
dr->encoding = dr->buf.str;
|
1386
1327
|
#endif
|
@@ -1411,14 +1352,10 @@ read_attrs(SaxDrive dr, char c, char termc, char term2, int is_xml, int eq_req,
|
|
1411
1352
|
ox_sax_collapse_special(dr, dr->buf.str, pos, line, col);
|
1412
1353
|
}
|
1413
1354
|
args[1] = rb_str_new2(attr_value);
|
1414
|
-
#if
|
1355
|
+
#if HAVE_RB_ENC_ASSOCIATE
|
1415
1356
|
if (0 != dr->encoding) {
|
1416
1357
|
rb_enc_associate(args[1], dr->encoding);
|
1417
1358
|
}
|
1418
|
-
#elif HAS_PRIVATE_ENCODING
|
1419
|
-
if (Qnil != dr->encoding) {
|
1420
|
-
rb_funcall(args[1], ox_force_encoding_id, 1, dr->encoding);
|
1421
|
-
}
|
1422
1359
|
#endif
|
1423
1360
|
if (dr->has.pos) {
|
1424
1361
|
rb_ivar_set(dr->handler, ox_at_pos_id, LONG2NUM(pos));
|
@@ -1580,7 +1517,7 @@ read_10_uint64(char *b, uint64_t *up) {
|
|
1580
1517
|
}
|
1581
1518
|
|
1582
1519
|
int
|
1583
|
-
ox_sax_collapse_special(SaxDrive dr, char *str,
|
1520
|
+
ox_sax_collapse_special(SaxDrive dr, char *str, long pos, long line, long col) {
|
1584
1521
|
char *s = str;
|
1585
1522
|
char *b = str;
|
1586
1523
|
|
@@ -1614,19 +1551,12 @@ ox_sax_collapse_special(SaxDrive dr, char *str, int pos, int line, int col) {
|
|
1614
1551
|
}
|
1615
1552
|
if (u <= 0x000000000000007FULL) {
|
1616
1553
|
*b++ = (char)u;
|
1617
|
-
#if
|
1554
|
+
#if HAVE_RB_ENC_FIND
|
1618
1555
|
} else if (ox_utf8_encoding == dr->encoding) {
|
1619
1556
|
b = ox_ucs_to_utf8_chars(b, u);
|
1620
1557
|
} else if (0 == dr->encoding) {
|
1621
1558
|
dr->encoding = ox_utf8_encoding;
|
1622
1559
|
b = ox_ucs_to_utf8_chars(b, u);
|
1623
|
-
#elif HAS_PRIVATE_ENCODING
|
1624
|
-
} else if (ox_utf8_encoding == dr->encoding ||
|
1625
|
-
0 == strcasecmp(rb_str_ptr(rb_String(ox_utf8_encoding)), rb_str_ptr(rb_String(dr->encoding)))) {
|
1626
|
-
b = ox_ucs_to_utf8_chars(b, u);
|
1627
|
-
} else if (Qnil == dr->encoding) {
|
1628
|
-
dr->encoding = ox_utf8_encoding;
|
1629
|
-
b = ox_ucs_to_utf8_chars(b, u);
|
1630
1560
|
#else
|
1631
1561
|
} else if (0 == dr->encoding) {
|
1632
1562
|
dr->encoding = UTF8_STR;
|
@@ -1668,8 +1598,28 @@ ox_sax_collapse_special(SaxDrive dr, char *str, int pos, int line, int col) {
|
|
1668
1598
|
c = '\'';
|
1669
1599
|
s += 5;
|
1670
1600
|
} else {
|
1671
|
-
|
1672
|
-
|
1601
|
+
char key[16];
|
1602
|
+
char *k = key;
|
1603
|
+
char *kend = key + sizeof(key) - 1;
|
1604
|
+
char *bn;
|
1605
|
+
char *s2 = s;
|
1606
|
+
|
1607
|
+
for (; ';' != *s2 && '\0' != *s2; s2++, k++) {
|
1608
|
+
if (kend <= k) {
|
1609
|
+
k = key;
|
1610
|
+
break;
|
1611
|
+
}
|
1612
|
+
*k = *s2;
|
1613
|
+
}
|
1614
|
+
*k = '\0';
|
1615
|
+
if ('\0' == *key || NULL == (bn = ox_entity_lookup(b, key))) {
|
1616
|
+
ox_sax_drive_error_at(dr, INVALID_FORMAT "Invalid special character sequence", pos, line, col);
|
1617
|
+
c = '&';
|
1618
|
+
} else {
|
1619
|
+
b = bn;
|
1620
|
+
s = s2 + 1;
|
1621
|
+
continue;
|
1622
|
+
}
|
1673
1623
|
}
|
1674
1624
|
*b++ = (char)c;
|
1675
1625
|
col++;
|
@@ -1731,7 +1681,7 @@ hint_try_close(SaxDrive dr, const char *name) {
|
|
1731
1681
|
}
|
1732
1682
|
|
1733
1683
|
static void
|
1734
|
-
end_element_cb(SaxDrive dr, VALUE name,
|
1684
|
+
end_element_cb(SaxDrive dr, VALUE name, long pos, long line, long col, Hint h) {
|
1735
1685
|
if (dr->has.end_element && 0 >= dr->blocked && (NULL == h || ActiveOverlay == h->overlay || NestOverlay == h->overlay)) {
|
1736
1686
|
if (dr->has.pos) {
|
1737
1687
|
rb_ivar_set(dr->handler, ox_at_pos_id, LONG2NUM(pos));
|