ox 2.4.0 → 2.4.1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of ox might be problematic. Click here for more details.
- data/README.md +25 -0
- data/ext/ox/dump.c +4 -4
- data/ext/ox/ox.c +200 -7
- data/ext/ox/ox.h +22 -20
- data/ext/ox/sax.c +200 -156
- data/ext/ox/sax.h +5 -1
- data/ext/ox/sax_hint.c +144 -121
- data/ext/ox/sax_hint.h +13 -0
- data/lib/ox/element.rb +8 -1
- data/lib/ox/sax.rb +4 -0
- data/lib/ox/version.rb +1 -1
- metadata +2 -2
data/ext/ox/sax.c
CHANGED
@@ -50,11 +50,11 @@ static char read_element_start(SaxDrive dr);
|
|
50
50
|
static char read_element_end(SaxDrive dr);
|
51
51
|
static char read_text(SaxDrive dr);
|
52
52
|
static char read_jump(SaxDrive dr, const char *pat);
|
53
|
-
static char read_attrs(SaxDrive dr, char c, char termc, char term2, int is_xml, int eq_req);
|
53
|
+
static char read_attrs(SaxDrive dr, char c, char termc, char term2, int is_xml, int eq_req, Hint h);
|
54
54
|
static char read_name_token(SaxDrive dr);
|
55
55
|
static char read_quoted_value(SaxDrive dr);
|
56
56
|
|
57
|
-
static void end_element_cb(SaxDrive dr, VALUE name, int pos, int line, int col);
|
57
|
+
static void end_element_cb(SaxDrive dr, VALUE name, int pos, int line, int col, Hint h);
|
58
58
|
|
59
59
|
static void hint_clear_empty(SaxDrive dr);
|
60
60
|
static Nv hint_try_close(SaxDrive dr, const char *name);
|
@@ -181,8 +181,9 @@ sax_drive_init(SaxDrive dr, VALUE handler, VALUE io, SaxOptions options) {
|
|
181
181
|
#endif
|
182
182
|
rb_gc_register_address(&dr->value_obj);
|
183
183
|
dr->options = *options;
|
184
|
-
dr->hints = 0;
|
185
184
|
dr->err = 0;
|
185
|
+
dr->blocked = 0;
|
186
|
+
dr->abort = false;
|
186
187
|
has_init(&dr->has, handler);
|
187
188
|
#if HAS_ENCODING_SUPPORT
|
188
189
|
if ('\0' == *ox_default_options.encoding) {
|
@@ -355,7 +356,7 @@ parse(SaxDrive dr) {
|
|
355
356
|
break;
|
356
357
|
case '/': /* element end */
|
357
358
|
parent = stack_peek(&dr->stack);
|
358
|
-
if (0 != parent && 0 == parent->childCnt && dr->has.text) {
|
359
|
+
if (0 != parent && 0 == parent->childCnt && dr->has.text && !dr->blocked) {
|
359
360
|
VALUE args[1];
|
360
361
|
int pos = dr->buf.pos;
|
361
362
|
int line = dr->buf.line;
|
@@ -407,6 +408,9 @@ parse(SaxDrive dr) {
|
|
407
408
|
}
|
408
409
|
}
|
409
410
|
DONE:
|
411
|
+
if (dr->abort) {
|
412
|
+
return;
|
413
|
+
}
|
410
414
|
if (dr->stack.head < dr->stack.tail) {
|
411
415
|
char msg[256];
|
412
416
|
Nv sp;
|
@@ -423,12 +427,15 @@ parse(SaxDrive dr) {
|
|
423
427
|
for (sp = dr->stack.tail - 1; dr->stack.head <= sp; sp--) {
|
424
428
|
snprintf(msg, sizeof(msg) - 1, "%selement '%s' not closed", EL_MISMATCH, sp->name);
|
425
429
|
ox_sax_drive_error_at(dr, msg, dr->buf.pos, dr->buf.line, dr->buf.col);
|
426
|
-
if (dr->has.end_element) {
|
430
|
+
if (dr->has.end_element && 0 >= dr->blocked && (NULL == sp->hint || ActiveOverlay == sp->hint->overlay)) {
|
427
431
|
VALUE args[1];
|
428
432
|
|
429
433
|
args[0] = sp->val;
|
430
434
|
rb_funcall2(dr->handler, ox_end_element_id, 1, args);
|
431
435
|
}
|
436
|
+
if (dr->blocked && NULL != sp->hint && BlockOverlay == sp->hint->overlay) {
|
437
|
+
dr->blocked--;
|
438
|
+
}
|
432
439
|
}
|
433
440
|
}
|
434
441
|
}
|
@@ -504,7 +511,7 @@ read_instruction(SaxDrive dr) {
|
|
504
511
|
cend = dr->buf.tail;
|
505
512
|
buf_reset(&dr->buf);
|
506
513
|
dr->err = 0;
|
507
|
-
c = read_attrs(dr, c, '?', '?', is_xml, 1);
|
514
|
+
c = read_attrs(dr, c, '?', '?', is_xml, 1, NULL);
|
508
515
|
if (dr->has.attrs_done) {
|
509
516
|
rb_funcall(dr->handler, ox_attrs_done_id, 0);
|
510
517
|
}
|
@@ -626,10 +633,10 @@ read_doctype(SaxDrive dr) {
|
|
626
633
|
buf_backup(&dr->buf); /* back up to the start in case the doctype is empty */
|
627
634
|
buf_protect(&dr->buf);
|
628
635
|
read_delimited(dr, '>');
|
629
|
-
if (dr->options.smart && 0 == dr->hints) {
|
636
|
+
if (dr->options.smart && 0 == dr->options.hints) {
|
630
637
|
for (s = dr->buf.str; is_white(*s); s++) { }
|
631
638
|
if (0 == strncasecmp("HTML", s, 4)) {
|
632
|
-
dr->hints = ox_hints_html();
|
639
|
+
dr->options.hints = ox_hints_html();
|
633
640
|
}
|
634
641
|
}
|
635
642
|
*(dr->buf.tail - 1) = '\0';
|
@@ -669,6 +676,7 @@ read_cdata(SaxDrive dr) {
|
|
669
676
|
struct _CheckPt cp = CHECK_PT_INIT;
|
670
677
|
Nv parent = stack_peek(&dr->stack);
|
671
678
|
|
679
|
+
// TBD check parent overlay
|
672
680
|
if (0 != parent) {
|
673
681
|
parent->childCnt++;
|
674
682
|
}
|
@@ -716,29 +724,31 @@ read_cdata(SaxDrive dr) {
|
|
716
724
|
}
|
717
725
|
}
|
718
726
|
CB:
|
719
|
-
if (dr->
|
720
|
-
|
727
|
+
if (!dr->blocked && (NULL == parent || NULL == parent->hint || OffOverlay != parent->hint->overlay)) {
|
728
|
+
if (dr->has.cdata) {
|
729
|
+
VALUE args[1];
|
721
730
|
|
722
|
-
|
731
|
+
args[0] = rb_str_new2(dr->buf.str);
|
723
732
|
#if HAS_ENCODING_SUPPORT
|
724
|
-
|
725
|
-
|
726
|
-
|
733
|
+
if (0 != dr->encoding) {
|
734
|
+
rb_enc_associate(args[0], dr->encoding);
|
735
|
+
}
|
727
736
|
#elif HAS_PRIVATE_ENCODING
|
728
|
-
|
729
|
-
|
730
|
-
|
737
|
+
if (Qnil != dr->encoding) {
|
738
|
+
rb_funcall(args[0], ox_force_encoding_id, 1, dr->encoding);
|
739
|
+
}
|
731
740
|
#endif
|
732
|
-
|
733
|
-
|
734
|
-
|
735
|
-
|
736
|
-
|
737
|
-
|
738
|
-
|
739
|
-
|
741
|
+
if (dr->has.pos) {
|
742
|
+
rb_ivar_set(dr->handler, ox_at_pos_id, LONG2NUM(pos));
|
743
|
+
}
|
744
|
+
if (dr->has.line) {
|
745
|
+
rb_ivar_set(dr->handler, ox_at_line_id, LONG2NUM(line));
|
746
|
+
}
|
747
|
+
if (dr->has.column) {
|
748
|
+
rb_ivar_set(dr->handler, ox_at_column_id, LONG2NUM(col));
|
749
|
+
}
|
750
|
+
rb_funcall2(dr->handler, ox_cdata_id, 1, args);
|
740
751
|
}
|
741
|
-
rb_funcall2(dr->handler, ox_cdata_id, 1, args);
|
742
752
|
}
|
743
753
|
if ('\0' != zero) {
|
744
754
|
*(dr->buf.tail - 1) = zero;
|
@@ -804,29 +814,33 @@ read_comment(SaxDrive dr) {
|
|
804
814
|
}
|
805
815
|
}
|
806
816
|
CB:
|
807
|
-
|
808
|
-
|
817
|
+
// TBD check parent overlay
|
818
|
+
if (dr->has.comment && !dr->blocked) {
|
819
|
+
VALUE args[1];
|
820
|
+
Nv parent = stack_peek(&dr->stack);
|
809
821
|
|
810
|
-
|
822
|
+
if (NULL == parent || NULL == parent->hint || OffOverlay != parent->hint->overlay) {
|
823
|
+
args[0] = rb_str_new2(dr->buf.str);
|
811
824
|
#if HAS_ENCODING_SUPPORT
|
812
|
-
|
813
|
-
|
814
|
-
|
825
|
+
if (0 != dr->encoding) {
|
826
|
+
rb_enc_associate(args[0], dr->encoding);
|
827
|
+
}
|
815
828
|
#elif HAS_PRIVATE_ENCODING
|
816
|
-
|
817
|
-
|
818
|
-
|
829
|
+
if (Qnil != dr->encoding) {
|
830
|
+
rb_funcall(args[0], ox_force_encoding_id, 1, dr->encoding);
|
831
|
+
}
|
819
832
|
#endif
|
820
|
-
|
821
|
-
|
822
|
-
|
823
|
-
|
824
|
-
|
825
|
-
|
826
|
-
|
827
|
-
|
833
|
+
if (dr->has.pos) {
|
834
|
+
rb_ivar_set(dr->handler, ox_at_pos_id, LONG2NUM(pos));
|
835
|
+
}
|
836
|
+
if (dr->has.line) {
|
837
|
+
rb_ivar_set(dr->handler, ox_at_line_id, LONG2NUM(line));
|
838
|
+
}
|
839
|
+
if (dr->has.column) {
|
840
|
+
rb_ivar_set(dr->handler, ox_at_column_id, LONG2NUM(col));
|
841
|
+
}
|
842
|
+
rb_funcall2(dr->handler, ox_comment_id, 1, args);
|
828
843
|
}
|
829
|
-
rb_funcall2(dr->handler, ox_comment_id, 1, args);
|
830
844
|
}
|
831
845
|
if ('\0' != zero) {
|
832
846
|
*(dr->buf.tail - 1) = zero;
|
@@ -848,7 +862,7 @@ read_element_start(SaxDrive dr) {
|
|
848
862
|
int pos = dr->buf.pos;
|
849
863
|
int line = dr->buf.line;
|
850
864
|
int col = dr->buf.col;
|
851
|
-
Hint h =
|
865
|
+
Hint h = NULL;
|
852
866
|
int stackless = 0;
|
853
867
|
Nv parent = stack_peek(&dr->stack);
|
854
868
|
|
@@ -866,32 +880,45 @@ read_element_start(SaxDrive dr) {
|
|
866
880
|
if (0 != parent) {
|
867
881
|
parent->childCnt++;
|
868
882
|
}
|
869
|
-
if (dr->options.smart && 0 == dr->hints && stack_empty(&dr->stack) && 0 == strcasecmp("html", dr->buf.str)) {
|
870
|
-
dr->hints = ox_hints_html();
|
883
|
+
if (dr->options.smart && 0 == dr->options.hints && stack_empty(&dr->stack) && 0 == strcasecmp("html", dr->buf.str)) {
|
884
|
+
dr->options.hints = ox_hints_html();
|
871
885
|
}
|
872
|
-
if (
|
886
|
+
if (NULL != dr->options.hints) {
|
873
887
|
hint_clear_empty(dr);
|
874
|
-
h = ox_hint_find(dr->hints, dr->buf.str);
|
875
|
-
if (
|
876
|
-
char msg[
|
888
|
+
h = ox_hint_find(dr->options.hints, dr->buf.str);
|
889
|
+
if (NULL == h) {
|
890
|
+
char msg[256];
|
877
891
|
|
878
|
-
|
892
|
+
snprintf(msg, sizeof(msg), "%s%s is not a valid element type for a %s document type.", INV_ELEMENT, dr->buf.str, dr->options.hints->name);
|
879
893
|
ox_sax_drive_error(dr, msg);
|
880
894
|
} else {
|
881
895
|
Nv top_nv = stack_peek(&dr->stack);
|
882
896
|
|
897
|
+
if (AbortOverlay == h->overlay) {
|
898
|
+
if (rb_respond_to(dr->handler, ox_abort_id)) {
|
899
|
+
VALUE args[1];
|
900
|
+
|
901
|
+
args[0] = str2sym(dr, dr->buf.str, NULL);
|
902
|
+
rb_funcall2(dr->handler, ox_abort_id, 1, args);
|
903
|
+
}
|
904
|
+
dr->abort = true;
|
905
|
+
return '\0';
|
906
|
+
}
|
907
|
+
if (BlockOverlay == h->overlay) {
|
908
|
+
dr->blocked++;
|
909
|
+
}
|
883
910
|
if (h->empty) {
|
884
911
|
stackless = 1;
|
885
912
|
}
|
886
913
|
if (0 != top_nv) {
|
887
914
|
char msg[256];
|
888
|
-
|
915
|
+
|
889
916
|
if (!h->nest && 0 == strcasecmp(top_nv->name, h->name)) {
|
890
917
|
snprintf(msg, sizeof(msg) - 1, "%s%s can not be nested in a %s document, closing previous.",
|
891
|
-
INV_ELEMENT, dr->buf.str, dr->hints->name);
|
918
|
+
INV_ELEMENT, dr->buf.str, dr->options.hints->name);
|
892
919
|
ox_sax_drive_error(dr, msg);
|
893
920
|
stack_pop(&dr->stack);
|
894
|
-
end_element_cb(dr, top_nv->val, pos, line, col);
|
921
|
+
end_element_cb(dr, top_nv->val, pos, line, col, top_nv->hint);
|
895
922
|
top_nv = stack_peek(&dr->stack);
|
896
923
|
}
|
897
924
|
if (0 != h->parents) {
|
@@ -906,7 +933,7 @@ read_element_start(SaxDrive dr) {
|
|
906
933
|
}
|
907
934
|
if (!ok) {
|
908
935
|
snprintf(msg, sizeof(msg) - 1, "%s%s can not be a child of a %s in a %s document.",
|
909
|
-
INV_ELEMENT, h->name, top_nv->name, dr->hints->name);
|
936
|
+
INV_ELEMENT, h->name, top_nv->name, dr->options.hints->name);
|
910
937
|
ox_sax_drive_error(dr, msg);
|
911
938
|
}
|
912
939
|
}
|
@@ -914,7 +941,7 @@ read_element_start(SaxDrive dr) {
|
|
914
941
|
}
|
915
942
|
}
|
916
943
|
name = str2sym(dr, dr->buf.str, &ename);
|
917
|
-
if (dr->has.start_element) {
|
944
|
+
if (dr->has.start_element && 0 >= dr->blocked && (NULL == h || ActiveOverlay == h->overlay)) {
|
918
945
|
VALUE args[1];
|
919
946
|
|
920
947
|
if (dr->has.pos) {
|
@@ -935,13 +962,13 @@ read_element_start(SaxDrive dr) {
|
|
935
962
|
closed = 0;
|
936
963
|
} else {
|
937
964
|
buf_protect(&dr->buf);
|
938
|
-
c = read_attrs(dr, c, '/', '>', 0, 0);
|
965
|
+
c = read_attrs(dr, c, '/', '>', 0, 0, h);
|
939
966
|
if (is_white(c)) {
|
940
967
|
c = buf_next_non_white(&dr->buf);
|
941
968
|
}
|
942
969
|
closed = ('/' == c);
|
943
970
|
}
|
944
|
-
if (dr->has.attrs_done) {
|
971
|
+
if (dr->has.attrs_done && 0 >= dr->blocked && (NULL == h || ActiveOverlay == h->overlay)) {
|
945
972
|
rb_funcall(dr->handler, ox_attrs_done_id, 0);
|
946
973
|
}
|
947
974
|
if (closed) {
|
@@ -949,9 +976,9 @@ read_element_start(SaxDrive dr) {
|
|
949
976
|
pos = dr->buf.pos;
|
950
977
|
line = dr->buf.line;
|
951
978
|
col = dr->buf.col;
|
952
|
-
end_element_cb(dr, name, pos, line, col);
|
979
|
+
end_element_cb(dr, name, pos, line, col, h);
|
953
980
|
} else if (stackless) {
|
954
|
-
end_element_cb(dr, name, pos, line, col);
|
981
|
+
end_element_cb(dr, name, pos, line, col, h);
|
955
982
|
} else if (0 != h && h->jump) {
|
956
983
|
stack_push(&dr->stack, ename, name, h);
|
957
984
|
if ('>' != c) {
|
@@ -992,7 +1019,8 @@ read_element_end(SaxDrive dr) {
|
|
992
1019
|
int line = dr->buf.line;
|
993
1020
|
int col = dr->buf.col - 1;
|
994
1021
|
Nv nv;
|
995
|
-
|
1022
|
+
Hint h = NULL;
|
1023
|
+
|
996
1024
|
if ('\0' == (c = read_name_token(dr))) {
|
997
1025
|
return '\0';
|
998
1026
|
}
|
@@ -1004,6 +1032,7 @@ read_element_end(SaxDrive dr) {
|
|
1004
1032
|
nv = stack_peek(&dr->stack);
|
1005
1033
|
if (0 != nv && 0 == strcmp(dr->buf.str, nv->name)) {
|
1006
1034
|
name = nv->val;
|
1035
|
+
h = nv->hint;
|
1007
1036
|
stack_pop(&dr->stack);
|
1008
1037
|
} else {
|
1009
1038
|
// Mismatched start and end
|
@@ -1012,9 +1041,8 @@ read_element_end(SaxDrive dr) {
|
|
1012
1041
|
|
1013
1042
|
if (0 == match) {
|
1014
1043
|
// Not found so open and close element.
|
1015
|
-
|
1016
|
-
|
1017
|
-
if (0 != h && h->empty) {
|
1044
|
+
h = ox_hint_find(dr->options.hints, dr->buf.str);
|
1045
|
+
if (NULL != h && h->empty) {
|
1018
1046
|
// Just close normally
|
1019
1047
|
name = str2sym(dr, dr->buf.str, 0);
|
1020
1048
|
snprintf(msg, sizeof(msg) - 1, "%selement '%s' should not have a separate close element", EL_MISMATCH, dr->buf.str);
|
@@ -1024,7 +1052,7 @@ read_element_end(SaxDrive dr) {
|
|
1024
1052
|
snprintf(msg, sizeof(msg) - 1, "%selement '%s' closed but not opened", EL_MISMATCH, dr->buf.str);
|
1025
1053
|
ox_sax_drive_error_at(dr, msg, pos, line, col);
|
1026
1054
|
name = str2sym(dr, dr->buf.str, 0);
|
1027
|
-
if (dr->has.start_element) {
|
1055
|
+
if (dr->has.start_element && 0 >= dr->blocked && (NULL == h || ActiveOverlay == h->overlay)) {
|
1028
1056
|
VALUE args[1];
|
1029
1057
|
|
1030
1058
|
if (dr->has.pos) {
|
@@ -1039,6 +1067,9 @@ read_element_end(SaxDrive dr) {
|
|
1039
1067
|
args[0] = name;
|
1040
1068
|
rb_funcall2(dr->handler, ox_start_element_id, 1, args);
|
1041
1069
|
}
|
1070
|
+
if (NULL != h && BlockOverlay == h->overlay && 0 < dr->blocked) {
|
1071
|
+
dr->blocked--;
|
1072
|
+
}
|
1042
1073
|
}
|
1043
1074
|
} else {
|
1044
1075
|
// Found a match so close all up to the found element in stack.
|
@@ -1046,6 +1077,7 @@ read_element_end(SaxDrive dr) {
|
|
1046
1077
|
|
1047
1078
|
if (0 != (n2 = hint_try_close(dr, dr->buf.str))) {
|
1048
1079
|
name = n2->val;
|
1080
|
+
h = n2->hint;
|
1049
1081
|
} else {
|
1050
1082
|
snprintf(msg, sizeof(msg) - 1, "%selement '%s' close does not match '%s' open", EL_MISMATCH, dr->buf.str, nv->name);
|
1051
1083
|
ox_sax_drive_error_at(dr, msg, pos, line, col);
|
@@ -1059,15 +1091,19 @@ read_element_end(SaxDrive dr) {
|
|
1059
1091
|
rb_ivar_set(dr->handler, ox_at_column_id, LONG2NUM(col));
|
1060
1092
|
}
|
1061
1093
|
for (nv = stack_pop(&dr->stack); match < nv; nv = stack_pop(&dr->stack)) {
|
1062
|
-
if (dr->has.end_element) {
|
1094
|
+
if (dr->has.end_element && 0 >= dr->blocked && (NULL == nv->hint || ActiveOverlay == nv->hint->overlay)) {
|
1063
1095
|
rb_funcall(dr->handler, ox_end_element_id, 1, nv->val);
|
1064
1096
|
}
|
1097
|
+
if (NULL != nv->hint && BlockOverlay == nv->hint->overlay && 0 < dr->blocked) {
|
1098
|
+
dr->blocked--;
|
1099
|
+
}
|
1065
1100
|
}
|
1066
1101
|
name = nv->val;
|
1102
|
+
h = nv->hint;
|
1067
1103
|
}
|
1068
1104
|
}
|
1069
1105
|
}
|
1070
|
-
end_element_cb(dr, name, pos, line, col);
|
1106
|
+
end_element_cb(dr, name, pos, line, col, h);
|
1071
1107
|
|
1072
1108
|
return c;
|
1073
1109
|
}
|
@@ -1119,52 +1155,54 @@ read_text(SaxDrive dr) {
|
|
1119
1155
|
if (0 != parent) {
|
1120
1156
|
parent->childCnt++;
|
1121
1157
|
}
|
1122
|
-
if (dr->
|
1123
|
-
if (dr->has.
|
1124
|
-
|
1125
|
-
|
1126
|
-
|
1127
|
-
|
1128
|
-
|
1129
|
-
|
1130
|
-
|
1131
|
-
|
1132
|
-
|
1133
|
-
|
1134
|
-
|
1135
|
-
|
1136
|
-
|
1137
|
-
|
1138
|
-
|
1139
|
-
|
1140
|
-
|
1141
|
-
|
1142
|
-
|
1143
|
-
|
1144
|
-
|
1145
|
-
|
1146
|
-
|
1147
|
-
|
1148
|
-
|
1158
|
+
if (!dr->blocked && (NULL == parent || NULL == parent->hint || OffOverlay != parent->hint->overlay)) {
|
1159
|
+
if (dr->has.value) {
|
1160
|
+
if (dr->has.pos) {
|
1161
|
+
rb_ivar_set(dr->handler, ox_at_pos_id, LONG2NUM(pos));
|
1162
|
+
}
|
1163
|
+
if (dr->has.line) {
|
1164
|
+
rb_ivar_set(dr->handler, ox_at_line_id, LONG2NUM(line));
|
1165
|
+
}
|
1166
|
+
if (dr->has.column) {
|
1167
|
+
rb_ivar_set(dr->handler, ox_at_column_id, LONG2NUM(col));
|
1168
|
+
}
|
1169
|
+
*args = dr->value_obj;
|
1170
|
+
rb_funcall2(dr->handler, ox_value_id, 1, args);
|
1171
|
+
} else if (dr->has.text) {
|
1172
|
+
if (dr->options.convert_special) {
|
1173
|
+
ox_sax_collapse_special(dr, dr->buf.str, pos, line, col);
|
1174
|
+
}
|
1175
|
+
switch (dr->options.skip) {
|
1176
|
+
case CrSkip:
|
1177
|
+
buf_collapse_return(dr->buf.str);
|
1178
|
+
break;
|
1179
|
+
case SpcSkip:
|
1180
|
+
buf_collapse_white(dr->buf.str);
|
1181
|
+
break;
|
1182
|
+
default:
|
1183
|
+
break;
|
1184
|
+
}
|
1185
|
+
args[0] = rb_str_new2(dr->buf.str);
|
1149
1186
|
#if HAS_ENCODING_SUPPORT
|
1150
|
-
|
1151
|
-
|
1152
|
-
|
1187
|
+
if (0 != dr->encoding) {
|
1188
|
+
rb_enc_associate(args[0], dr->encoding);
|
1189
|
+
}
|
1153
1190
|
#elif HAS_PRIVATE_ENCODING
|
1154
|
-
|
1155
|
-
|
1156
|
-
|
1191
|
+
if (Qnil != dr->encoding) {
|
1192
|
+
rb_funcall(args[0], ox_force_encoding_id, 1, dr->encoding);
|
1193
|
+
}
|
1157
1194
|
#endif
|
1158
|
-
|
1159
|
-
|
1160
|
-
|
1161
|
-
|
1162
|
-
|
1163
|
-
|
1164
|
-
|
1165
|
-
|
1195
|
+
if (dr->has.pos) {
|
1196
|
+
rb_ivar_set(dr->handler, ox_at_pos_id, LONG2NUM(pos));
|
1197
|
+
}
|
1198
|
+
if (dr->has.line) {
|
1199
|
+
rb_ivar_set(dr->handler, ox_at_line_id, LONG2NUM(line));
|
1200
|
+
}
|
1201
|
+
if (dr->has.column) {
|
1202
|
+
rb_ivar_set(dr->handler, ox_at_column_id, LONG2NUM(col));
|
1203
|
+
}
|
1204
|
+
rb_funcall2(dr->handler, ox_text_id, 1, args);
|
1166
1205
|
}
|
1167
|
-
rb_funcall2(dr->handler, ox_text_id, 1, args);
|
1168
1206
|
}
|
1169
1207
|
dr->buf.str = 0;
|
1170
1208
|
|
@@ -1228,7 +1266,8 @@ read_jump(SaxDrive dr, const char *pat) {
|
|
1228
1266
|
if (0 != parent) {
|
1229
1267
|
parent->childCnt++;
|
1230
1268
|
}
|
1231
|
-
|
1269
|
+
// TBD check parent overlay
|
1270
|
+
if (dr->has.text && !dr->blocked) {
|
1232
1271
|
args[0] = rb_str_new2(dr->buf.str);
|
1233
1272
|
#if HAS_ENCODING_SUPPORT
|
1234
1273
|
if (0 != dr->encoding) {
|
@@ -1258,7 +1297,7 @@ read_jump(SaxDrive dr, const char *pat) {
|
|
1258
1297
|
}
|
1259
1298
|
|
1260
1299
|
static char
|
1261
|
-
read_attrs(SaxDrive dr, char c, char termc, char term2, int is_xml, int eq_req) {
|
1300
|
+
read_attrs(SaxDrive dr, char c, char termc, char term2, int is_xml, int eq_req, Hint h) {
|
1262
1301
|
VALUE name = Qnil;
|
1263
1302
|
int is_encoding = 0;
|
1264
1303
|
int pos;
|
@@ -1318,49 +1357,51 @@ read_attrs(SaxDrive dr, char c, char termc, char term2, int is_xml, int eq_req)
|
|
1318
1357
|
is_encoding = 0;
|
1319
1358
|
}
|
1320
1359
|
}
|
1321
|
-
|
1322
|
-
|
1323
|
-
|
1324
|
-
if (dr->has.pos) {
|
1325
|
-
rb_ivar_set(dr->handler, ox_at_pos_id, LONG2NUM(pos));
|
1326
|
-
}
|
1327
|
-
if (dr->has.line) {
|
1328
|
-
rb_ivar_set(dr->handler, ox_at_line_id, LONG2NUM(line));
|
1329
|
-
}
|
1330
|
-
if (dr->has.column) {
|
1331
|
-
rb_ivar_set(dr->handler, ox_at_column_id, LONG2NUM(col));
|
1332
|
-
}
|
1333
|
-
args[0] = name;
|
1334
|
-
args[1] = dr->value_obj;
|
1335
|
-
rb_funcall2(dr->handler, ox_attr_value_id, 2, args);
|
1336
|
-
} else if (dr->has.attr) {
|
1337
|
-
VALUE args[2];
|
1360
|
+
if (0 >= dr->blocked && (NULL == h || ActiveOverlay == h->overlay)) {
|
1361
|
+
if (dr->has.attr_value) {
|
1362
|
+
VALUE args[2];
|
1338
1363
|
|
1339
|
-
|
1340
|
-
|
1341
|
-
|
1342
|
-
|
1343
|
-
|
1364
|
+
if (dr->has.pos) {
|
1365
|
+
rb_ivar_set(dr->handler, ox_at_pos_id, LONG2NUM(pos));
|
1366
|
+
}
|
1367
|
+
if (dr->has.line) {
|
1368
|
+
rb_ivar_set(dr->handler, ox_at_line_id, LONG2NUM(line));
|
1369
|
+
}
|
1370
|
+
if (dr->has.column) {
|
1371
|
+
rb_ivar_set(dr->handler, ox_at_column_id, LONG2NUM(col));
|
1372
|
+
}
|
1373
|
+
args[0] = name;
|
1374
|
+
args[1] = dr->value_obj;
|
1375
|
+
rb_funcall2(dr->handler, ox_attr_value_id, 2, args);
|
1376
|
+
} else if (dr->has.attr) {
|
1377
|
+
VALUE args[2];
|
1378
|
+
|
1379
|
+
args[0] = name;
|
1380
|
+
if (dr->options.convert_special) {
|
1381
|
+
ox_sax_collapse_special(dr, dr->buf.str, pos, line, col);
|
1382
|
+
}
|
1383
|
+
args[1] = rb_str_new2(attr_value);
|
1344
1384
|
#if HAS_ENCODING_SUPPORT
|
1345
|
-
|
1346
|
-
|
1347
|
-
|
1385
|
+
if (0 != dr->encoding) {
|
1386
|
+
rb_enc_associate(args[1], dr->encoding);
|
1387
|
+
}
|
1348
1388
|
#elif HAS_PRIVATE_ENCODING
|
1349
|
-
|
1350
|
-
|
1351
|
-
|
1389
|
+
if (Qnil != dr->encoding) {
|
1390
|
+
rb_funcall(args[1], ox_force_encoding_id, 1, dr->encoding);
|
1391
|
+
}
|
1352
1392
|
#endif
|
1353
|
-
|
1354
|
-
|
1355
|
-
|
1356
|
-
|
1357
|
-
|
1358
|
-
|
1359
|
-
|
1360
|
-
|
1393
|
+
if (dr->has.pos) {
|
1394
|
+
rb_ivar_set(dr->handler, ox_at_pos_id, LONG2NUM(pos));
|
1395
|
+
}
|
1396
|
+
if (dr->has.line) {
|
1397
|
+
rb_ivar_set(dr->handler, ox_at_line_id, LONG2NUM(line));
|
1398
|
+
}
|
1399
|
+
if (dr->has.column) {
|
1400
|
+
rb_ivar_set(dr->handler, ox_at_column_id, LONG2NUM(col));
|
1401
|
+
}
|
1402
|
+
rb_funcall2(dr->handler, ox_attr_id, 2, args);
|
1361
1403
|
}
|
1362
|
-
|
1363
|
-
}
|
1404
|
+
}
|
1364
1405
|
if (is_white(c)) {
|
1365
1406
|
c = buf_next_non_white(&dr->buf);
|
1366
1407
|
}
|
@@ -1450,7 +1491,7 @@ read_quoted_value(SaxDrive dr) {
|
|
1450
1491
|
while ('\0' != (c = buf_get(&dr->buf))) {
|
1451
1492
|
switch (c) {
|
1452
1493
|
case ' ':
|
1453
|
-
|
1494
|
+
//case '/':
|
1454
1495
|
case '>':
|
1455
1496
|
case '?': // for instructions
|
1456
1497
|
case '\t':
|
@@ -1623,7 +1664,7 @@ hint_clear_empty(SaxDrive dr) {
|
|
1623
1664
|
break;
|
1624
1665
|
}
|
1625
1666
|
if (nv->hint->empty) {
|
1626
|
-
end_element_cb(dr, nv->val, dr->buf.pos, dr->buf.line, dr->buf.col);
|
1667
|
+
end_element_cb(dr, nv->val, dr->buf.pos, dr->buf.line, dr->buf.col, nv->hint);
|
1627
1668
|
stack_pop(&dr->stack);
|
1628
1669
|
} else {
|
1629
1670
|
break;
|
@@ -1633,7 +1674,7 @@ hint_clear_empty(SaxDrive dr) {
|
|
1633
1674
|
|
1634
1675
|
static Nv
|
1635
1676
|
hint_try_close(SaxDrive dr, const char *name) {
|
1636
|
-
Hint h = ox_hint_find(dr->hints, name);
|
1677
|
+
Hint h = ox_hint_find(dr->options.hints, name);
|
1637
1678
|
Nv nv;
|
1638
1679
|
|
1639
1680
|
if (0 == h) {
|
@@ -1648,7 +1689,7 @@ hint_try_close(SaxDrive dr, const char *name) {
|
|
1648
1689
|
break;
|
1649
1690
|
}
|
1650
1691
|
if (nv->hint->empty) {
|
1651
|
-
end_element_cb(dr, nv->val, dr->buf.pos, dr->buf.line, dr->buf.col);
|
1692
|
+
end_element_cb(dr, nv->val, dr->buf.pos, dr->buf.line, dr->buf.col, nv->hint);
|
1652
1693
|
dr->stack.tail = nv;
|
1653
1694
|
} else {
|
1654
1695
|
break;
|
@@ -1658,8 +1699,8 @@ hint_try_close(SaxDrive dr, const char *name) {
|
|
1658
1699
|
}
|
1659
1700
|
|
1660
1701
|
static void
|
1661
|
-
end_element_cb(SaxDrive dr, VALUE name, int pos, int line, int col) {
|
1662
|
-
if (dr->has.end_element) {
|
1702
|
+
end_element_cb(SaxDrive dr, VALUE name, int pos, int line, int col, Hint h) {
|
1703
|
+
if (dr->has.end_element && 0 >= dr->blocked && (NULL == h || ActiveOverlay == h->overlay)) {
|
1663
1704
|
if (dr->has.pos) {
|
1664
1705
|
rb_ivar_set(dr->handler, ox_at_pos_id, LONG2NUM(pos));
|
1665
1706
|
}
|
@@ -1671,4 +1712,7 @@ end_element_cb(SaxDrive dr, VALUE name, int pos, int line, int col) {
|
|
1671
1712
|
}
|
1672
1713
|
rb_funcall(dr->handler, ox_end_element_id, 1, name);
|
1673
1714
|
}
|
1715
|
+
if (NULL != h && BlockOverlay == h->overlay && 0 < dr->blocked) {
|
1716
|
+
dr->blocked--;
|
1717
|
+
}
|
1674
1718
|
}
|