ox 2.11.0 → 2.13.3
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.
- 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));
|