OLD | NEW |
1 /* | 1 /* |
2 * xpointer.c : Code to handle XML Pointer | 2 * xpointer.c : Code to handle XML Pointer |
3 * | 3 * |
4 * Base implementation was made accordingly to | 4 * Base implementation was made accordingly to |
5 * W3C Candidate Recommendation 7 June 2000 | 5 * W3C Candidate Recommendation 7 June 2000 |
6 * http://www.w3.org/TR/2000/CR-xptr-20000607 | 6 * http://www.w3.org/TR/2000/CR-xptr-20000607 |
7 * | 7 * |
8 * Added support for the element() scheme described in: | 8 * Added support for the element() scheme described in: |
9 * W3C Proposed Recommendation 13 November 2002 | 9 * W3C Proposed Recommendation 13 November 2002 |
10 * http://www.w3.org/TR/2002/PR-xptr-element-20021113/ | 10 * http://www.w3.org/TR/2002/PR-xptr-element-20021113/ |
11 * | 11 * |
12 * See Copyright for the status of this software. | 12 * See Copyright for the status of this software. |
13 * | 13 * |
14 * daniel@veillard.com | 14 * daniel@veillard.com |
15 */ | 15 */ |
16 | 16 |
17 #define IN_LIBXML | 17 #define IN_LIBXML |
18 #include "libxml.h" | 18 #include "libxml.h" |
19 | 19 |
20 /* | 20 /* |
(...skipping 19 matching lines...) Expand all Loading... |
40 /* Add support of the xmlns() xpointer scheme to initialize the namespaces */ | 40 /* Add support of the xmlns() xpointer scheme to initialize the namespaces */ |
41 #define XPTR_XMLNS_SCHEME | 41 #define XPTR_XMLNS_SCHEME |
42 | 42 |
43 /* #define DEBUG_RANGES */ | 43 /* #define DEBUG_RANGES */ |
44 #ifdef DEBUG_RANGES | 44 #ifdef DEBUG_RANGES |
45 #ifdef LIBXML_DEBUG_ENABLED | 45 #ifdef LIBXML_DEBUG_ENABLED |
46 #include <libxml/debugXML.h> | 46 #include <libxml/debugXML.h> |
47 #endif | 47 #endif |
48 #endif | 48 #endif |
49 | 49 |
50 #define TODO » » » » » » » » \ | 50 #define TODO» » » » » » » » \ |
51 xmlGenericError(xmlGenericErrorContext, \ | 51 xmlGenericError(xmlGenericErrorContext, \ |
52 "Unimplemented block at %s:%d\n", \ | 52 "Unimplemented block at %s:%d\n", \ |
53 __FILE__, __LINE__); | 53 __FILE__, __LINE__); |
54 | 54 |
55 #define STRANGE » » » » » » » \ | 55 #define STRANGE»» » » » » » \ |
56 xmlGenericError(xmlGenericErrorContext, \ | 56 xmlGenericError(xmlGenericErrorContext, \ |
57 "Internal error at %s:%d\n", \ | 57 "Internal error at %s:%d\n", \ |
58 __FILE__, __LINE__); | 58 __FILE__, __LINE__); |
59 | 59 |
60 /************************************************************************ | 60 /************************************************************************ |
61 * * | 61 * * |
62 * » » Some factorized error routines» » » » * | 62 *» » Some factorized error routines» » » » * |
63 * * | 63 * * |
64 ************************************************************************/ | 64 ************************************************************************/ |
65 | 65 |
66 /** | 66 /** |
67 * xmlXPtrErrMemory: | 67 * xmlXPtrErrMemory: |
68 * @extra: extra informations | 68 * @extra: extra informations |
69 * | 69 * |
70 * Handle a redefinition of attribute error | 70 * Handle a redefinition of attribute error |
71 */ | 71 */ |
72 static void | 72 static void |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
127 xmlNodePtr xmlXPtrAdvanceNode(xmlNodePtr cur, int *level); | 127 xmlNodePtr xmlXPtrAdvanceNode(xmlNodePtr cur, int *level); |
128 /** | 128 /** |
129 * xmlXPtrGetArity: | 129 * xmlXPtrGetArity: |
130 * @cur: the node | 130 * @cur: the node |
131 * | 131 * |
132 * Returns the number of child for an element, -1 in case of error | 132 * Returns the number of child for an element, -1 in case of error |
133 */ | 133 */ |
134 static int | 134 static int |
135 xmlXPtrGetArity(xmlNodePtr cur) { | 135 xmlXPtrGetArity(xmlNodePtr cur) { |
136 int i; | 136 int i; |
137 if (cur == NULL) | 137 if ((cur == NULL) || (cur->type == XML_NAMESPACE_DECL)) |
138 return(-1); | 138 return(-1); |
139 cur = cur->children; | 139 cur = cur->children; |
140 for (i = 0;cur != NULL;cur = cur->next) { | 140 for (i = 0;cur != NULL;cur = cur->next) { |
141 if ((cur->type == XML_ELEMENT_NODE) || | 141 if ((cur->type == XML_ELEMENT_NODE) || |
142 (cur->type == XML_DOCUMENT_NODE) || | 142 (cur->type == XML_DOCUMENT_NODE) || |
143 (cur->type == XML_HTML_DOCUMENT_NODE)) { | 143 (cur->type == XML_HTML_DOCUMENT_NODE)) { |
144 i++; | 144 i++; |
145 } | 145 } |
146 } | 146 } |
147 return(i); | 147 return(i); |
148 } | 148 } |
149 | 149 |
150 /** | 150 /** |
151 * xmlXPtrGetIndex: | 151 * xmlXPtrGetIndex: |
152 * @cur: the node | 152 * @cur: the node |
153 * | 153 * |
154 * Returns the index of the node in its parent children list, -1 | 154 * Returns the index of the node in its parent children list, -1 |
155 * in case of error | 155 * in case of error |
156 */ | 156 */ |
157 static int | 157 static int |
158 xmlXPtrGetIndex(xmlNodePtr cur) { | 158 xmlXPtrGetIndex(xmlNodePtr cur) { |
159 int i; | 159 int i; |
160 if (cur == NULL) | 160 if ((cur == NULL) || (cur->type == XML_NAMESPACE_DECL)) |
161 return(-1); | 161 return(-1); |
162 for (i = 1;cur != NULL;cur = cur->prev) { | 162 for (i = 1;cur != NULL;cur = cur->prev) { |
163 if ((cur->type == XML_ELEMENT_NODE) || | 163 if ((cur->type == XML_ELEMENT_NODE) || |
164 (cur->type == XML_DOCUMENT_NODE) || | 164 (cur->type == XML_DOCUMENT_NODE) || |
165 (cur->type == XML_HTML_DOCUMENT_NODE)) { | 165 (cur->type == XML_HTML_DOCUMENT_NODE)) { |
166 i++; | 166 i++; |
167 } | 167 } |
168 } | 168 } |
169 return(i); | 169 return(i); |
170 } | 170 } |
171 | 171 |
172 /** | 172 /** |
173 * xmlXPtrGetNthChild: | 173 * xmlXPtrGetNthChild: |
174 * @cur: the node | 174 * @cur: the node |
175 * @no: the child number | 175 * @no: the child number |
176 * | 176 * |
177 * Returns the @no'th element child of @cur or NULL | 177 * Returns the @no'th element child of @cur or NULL |
178 */ | 178 */ |
179 static xmlNodePtr | 179 static xmlNodePtr |
180 xmlXPtrGetNthChild(xmlNodePtr cur, int no) { | 180 xmlXPtrGetNthChild(xmlNodePtr cur, int no) { |
181 int i; | 181 int i; |
182 if (cur == NULL) | 182 if ((cur == NULL) || (cur->type == XML_NAMESPACE_DECL)) |
183 return(cur); | 183 return(cur); |
184 cur = cur->children; | 184 cur = cur->children; |
185 for (i = 0;i <= no;cur = cur->next) { | 185 for (i = 0;i <= no;cur = cur->next) { |
186 » if (cur == NULL) | 186 » if (cur == NULL) |
187 return(cur); | 187 return(cur); |
188 if ((cur->type == XML_ELEMENT_NODE) || | 188 if ((cur->type == XML_ELEMENT_NODE) || |
189 (cur->type == XML_DOCUMENT_NODE) || | 189 (cur->type == XML_DOCUMENT_NODE) || |
190 (cur->type == XML_HTML_DOCUMENT_NODE)) { | 190 (cur->type == XML_HTML_DOCUMENT_NODE)) { |
191 i++; | 191 i++; |
192 if (i == no) | 192 if (i == no) |
193 break; | 193 break; |
194 } | 194 } |
195 } | 195 } |
196 return(cur); | 196 return(cur); |
(...skipping 349 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
546 if (start == NULL) | 546 if (start == NULL) |
547 return(NULL); | 547 return(NULL); |
548 if (end == NULL) | 548 if (end == NULL) |
549 return(NULL); | 549 return(NULL); |
550 switch (end->type) { | 550 switch (end->type) { |
551 case XPATH_POINT: | 551 case XPATH_POINT: |
552 case XPATH_RANGE: | 552 case XPATH_RANGE: |
553 break; | 553 break; |
554 case XPATH_NODESET: | 554 case XPATH_NODESET: |
555 /* | 555 /* |
556 » * Empty set ... | 556 » * Empty set ... |
557 */ | 557 */ |
558 if (end->nodesetval->nodeNr <= 0) | 558 if (end->nodesetval->nodeNr <= 0) |
559 return(NULL); | 559 return(NULL); |
560 break; | 560 break; |
561 default: | 561 default: |
562 /* TODO */ | 562 /* TODO */ |
563 return(NULL); | 563 return(NULL); |
564 } | 564 } |
565 | 565 |
566 ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject)); | 566 ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject)); |
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
724 if (val == NULL) return; | 724 if (val == NULL) return; |
725 | 725 |
726 /* | 726 /* |
727 * check against doublons | 727 * check against doublons |
728 */ | 728 */ |
729 for (i = 0;i < cur->locNr;i++) | 729 for (i = 0;i < cur->locNr;i++) |
730 if (cur->locTab[i] == val) break; | 730 if (cur->locTab[i] == val) break; |
731 | 731 |
732 if (i >= cur->locNr) { | 732 if (i >= cur->locNr) { |
733 #ifdef DEBUG | 733 #ifdef DEBUG |
734 xmlGenericError(xmlGenericErrorContext, | 734 xmlGenericError(xmlGenericErrorContext, |
735 "xmlXPtrLocationSetDel: Range wasn't found in RangeList\n"); | 735 "xmlXPtrLocationSetDel: Range wasn't found in RangeList\n"); |
736 #endif | 736 #endif |
737 return; | 737 return; |
738 } | 738 } |
739 cur->locNr--; | 739 cur->locNr--; |
740 for (;i < cur->locNr;i++) | 740 for (;i < cur->locNr;i++) |
741 cur->locTab[i] = cur->locTab[i + 1]; | 741 cur->locTab[i] = cur->locTab[i + 1]; |
742 cur->locTab[cur->locNr] = NULL; | 742 cur->locTab[cur->locNr] = NULL; |
743 } | 743 } |
744 | 744 |
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
896 * NEXT Skip to the next character, this does the proper decoding | 896 * NEXT Skip to the next character, this does the proper decoding |
897 * in UTF-8 mode. It also pop-up unfinished entities on the fly. | 897 * in UTF-8 mode. It also pop-up unfinished entities on the fly. |
898 * It returns the pointer to the current xmlChar. | 898 * It returns the pointer to the current xmlChar. |
899 */ | 899 */ |
900 | 900 |
901 #define CUR (*ctxt->cur) | 901 #define CUR (*ctxt->cur) |
902 #define SKIP(val) ctxt->cur += (val) | 902 #define SKIP(val) ctxt->cur += (val) |
903 #define NXT(val) ctxt->cur[(val)] | 903 #define NXT(val) ctxt->cur[(val)] |
904 #define CUR_PTR ctxt->cur | 904 #define CUR_PTR ctxt->cur |
905 | 905 |
906 #define SKIP_BLANKS » » » » » » » \ | 906 #define SKIP_BLANKS» » » » » » » \ |
907 while (IS_BLANK_CH(*(ctxt->cur))) NEXT | 907 while (IS_BLANK_CH(*(ctxt->cur))) NEXT |
908 | 908 |
909 #define CURRENT (*ctxt->cur) | 909 #define CURRENT (*ctxt->cur) |
910 #define NEXT ((*ctxt->cur) ? ctxt->cur++: ctxt->cur) | 910 #define NEXT ((*ctxt->cur) ? ctxt->cur++: ctxt->cur) |
911 | 911 |
912 /* | 912 /* |
913 * xmlXPtrGetChildNo: | 913 * xmlXPtrGetChildNo: |
914 * @ctxt: the XPointer Parser context | 914 * @ctxt: the XPointer Parser context |
915 * @index: the child number | 915 * @index: the child number |
916 * | 916 * |
(...skipping 21 matching lines...) Expand all Loading... |
938 return; | 938 return; |
939 } | 939 } |
940 oldset->nodeTab[0] = cur; | 940 oldset->nodeTab[0] = cur; |
941 valuePush(ctxt, obj); | 941 valuePush(ctxt, obj); |
942 } | 942 } |
943 | 943 |
944 /** | 944 /** |
945 * xmlXPtrEvalXPtrPart: | 945 * xmlXPtrEvalXPtrPart: |
946 * @ctxt: the XPointer Parser context | 946 * @ctxt: the XPointer Parser context |
947 * @name: the preparsed Scheme for the XPtrPart | 947 * @name: the preparsed Scheme for the XPtrPart |
948 * | 948 * |
949 * XPtrPart ::= 'xpointer' '(' XPtrExpr ')' | 949 * XPtrPart ::= 'xpointer' '(' XPtrExpr ')' |
950 * | Scheme '(' SchemeSpecificExpr ')' | 950 * | Scheme '(' SchemeSpecificExpr ')' |
951 * | 951 * |
952 * Scheme ::= NCName - 'xpointer' [VC: Non-XPointer schemes] | 952 * Scheme ::= NCName - 'xpointer' [VC: Non-XPointer schemes] |
953 * | 953 * |
954 * SchemeSpecificExpr ::= StringWithBalancedParens | 954 * SchemeSpecificExpr ::= StringWithBalancedParens |
955 * | 955 * |
956 * StringWithBalancedParens ::= | 956 * StringWithBalancedParens ::= |
957 * [^()]* ('(' StringWithBalancedParens ')' [^()]*)* | 957 * [^()]* ('(' StringWithBalancedParens ')' [^()]*)* |
958 * [VC: Parenthesis escaping] | 958 * [VC: Parenthesis escaping] |
959 * | 959 * |
960 * XPtrExpr ::= Expr [VC: Parenthesis escaping] | 960 * XPtrExpr ::= Expr [VC: Parenthesis escaping] |
961 * | 961 * |
962 * VC: Parenthesis escaping: | 962 * VC: Parenthesis escaping: |
963 * The end of an XPointer part is signaled by the right parenthesis ")" | 963 * The end of an XPointer part is signaled by the right parenthesis ")" |
964 * character that is balanced with the left parenthesis "(" character | 964 * character that is balanced with the left parenthesis "(" character |
965 * that began the part. Any unbalanced parenthesis character inside the | 965 * that began the part. Any unbalanced parenthesis character inside the |
966 * expression, even within literals, must be escaped with a circumflex (^) | 966 * expression, even within literals, must be escaped with a circumflex (^) |
967 * character preceding it. If the expression contains any literal | 967 * character preceding it. If the expression contains any literal |
968 * occurrences of the circumflex, each must be escaped with an additional | 968 * occurrences of the circumflex, each must be escaped with an additional |
969 * circumflex (that is, ^^). If the unescaped parentheses in the expression | 969 * circumflex (that is, ^^). If the unescaped parentheses in the expression |
970 * are not balanced, a syntax error results. | 970 * are not balanced, a syntax error results. |
971 * | 971 * |
972 * Parse and evaluate an XPtrPart. Basically it generates the unescaped | 972 * Parse and evaluate an XPtrPart. Basically it generates the unescaped |
973 * string and if the scheme is 'xpointer' it will call the XPath interpreter. | 973 * string and if the scheme is 'xpointer' it will call the XPath interpreter. |
974 * | 974 * |
975 * TODO: there is no new scheme registration mechanism | 975 * TODO: there is no new scheme registration mechanism |
976 */ | 976 */ |
977 | 977 |
978 static void | 978 static void |
979 xmlXPtrEvalXPtrPart(xmlXPathParserContextPtr ctxt, xmlChar *name) { | 979 xmlXPtrEvalXPtrPart(xmlXPathParserContextPtr ctxt, xmlChar *name) { |
980 xmlChar *buffer, *cur; | 980 xmlChar *buffer, *cur; |
981 int len; | 981 int len; |
982 int level; | 982 int level; |
983 | 983 |
984 if (name == NULL) | 984 if (name == NULL) |
(...skipping 18 matching lines...) Expand all Loading... |
1003 while (CUR != 0) { | 1003 while (CUR != 0) { |
1004 if (CUR == ')') { | 1004 if (CUR == ')') { |
1005 level--; | 1005 level--; |
1006 if (level == 0) { | 1006 if (level == 0) { |
1007 NEXT; | 1007 NEXT; |
1008 break; | 1008 break; |
1009 } | 1009 } |
1010 } else if (CUR == '(') { | 1010 } else if (CUR == '(') { |
1011 level++; | 1011 level++; |
1012 } else if (CUR == '^') { | 1012 } else if (CUR == '^') { |
1013 » if ((NXT(1) == ')') || (NXT(1) == '(') || (NXT(1) == '^')) { | 1013 if ((NXT(1) == ')') || (NXT(1) == '(') || (NXT(1) == '^')) { |
1014 » NEXT; | 1014 NEXT; |
1015 » } | 1015 } |
1016 } | 1016 } |
1017 » *cur++ = CUR; | 1017 *cur++ = CUR; |
1018 NEXT; | 1018 NEXT; |
1019 } | 1019 } |
1020 *cur = 0; | 1020 *cur = 0; |
1021 | 1021 |
1022 if ((level != 0) && (CUR == 0)) { | 1022 if ((level != 0) && (CUR == 0)) { |
1023 xmlFree(buffer); | 1023 xmlFree(buffer); |
1024 XP_ERROR(XPTR_SYNTAX_ERROR); | 1024 XP_ERROR(XPTR_SYNTAX_ERROR); |
1025 } | 1025 } |
1026 | 1026 |
1027 if (xmlStrEqual(name, (xmlChar *) "xpointer")) { | 1027 if (xmlStrEqual(name, (xmlChar *) "xpointer")) { |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1090 XP_ERROR(XPTR_SYNTAX_ERROR); | 1090 XP_ERROR(XPTR_SYNTAX_ERROR); |
1091 } | 1091 } |
1092 URI = xmlSaveUri(value); | 1092 URI = xmlSaveUri(value); |
1093 xmlFreeURI(value); | 1093 xmlFreeURI(value); |
1094 if (URI == NULL) { | 1094 if (URI == NULL) { |
1095 xmlFree(prefix); | 1095 xmlFree(prefix); |
1096 xmlFree(buffer); | 1096 xmlFree(buffer); |
1097 xmlFree(name); | 1097 xmlFree(name); |
1098 XP_ERROR(XPATH_MEMORY_ERROR); | 1098 XP_ERROR(XPATH_MEMORY_ERROR); |
1099 } | 1099 } |
1100 » | 1100 |
1101 xmlXPathRegisterNs(ctxt->context, prefix, URI); | 1101 xmlXPathRegisterNs(ctxt->context, prefix, URI); |
1102 CUR_PTR = left; | 1102 CUR_PTR = left; |
1103 xmlFree(URI); | 1103 xmlFree(URI); |
1104 xmlFree(prefix); | 1104 xmlFree(prefix); |
1105 #endif /* XPTR_XMLNS_SCHEME */ | 1105 #endif /* XPTR_XMLNS_SCHEME */ |
1106 } else { | 1106 } else { |
1107 xmlXPtrErr(ctxt, XML_XPTR_UNKNOWN_SCHEME, | 1107 xmlXPtrErr(ctxt, XML_XPTR_UNKNOWN_SCHEME, |
1108 "unsupported scheme '%s'\n", name); | 1108 "unsupported scheme '%s'\n", name); |
1109 } | 1109 } |
1110 xmlFree(buffer); | 1110 xmlFree(buffer); |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1222 if (name != NULL) { | 1222 if (name != NULL) { |
1223 valuePush(ctxt, xmlXPathNewString(name)); | 1223 valuePush(ctxt, xmlXPathNewString(name)); |
1224 xmlFree(name); | 1224 xmlFree(name); |
1225 xmlXPathIdFunction(ctxt, 1); | 1225 xmlXPathIdFunction(ctxt, 1); |
1226 CHECK_ERROR; | 1226 CHECK_ERROR; |
1227 } | 1227 } |
1228 | 1228 |
1229 while (CUR == '/') { | 1229 while (CUR == '/') { |
1230 int child = 0; | 1230 int child = 0; |
1231 NEXT; | 1231 NEXT; |
1232 | 1232 |
1233 while ((CUR >= '0') && (CUR <= '9')) { | 1233 while ((CUR >= '0') && (CUR <= '9')) { |
1234 child = child * 10 + (CUR - '0'); | 1234 child = child * 10 + (CUR - '0'); |
1235 NEXT; | 1235 NEXT; |
1236 } | 1236 } |
1237 xmlXPtrGetChildNo(ctxt, child); | 1237 xmlXPtrGetChildNo(ctxt, child); |
1238 } | 1238 } |
1239 } | 1239 } |
1240 | 1240 |
1241 | 1241 |
1242 /** | 1242 /** |
1243 * xmlXPtrEvalXPointer: | 1243 * xmlXPtrEvalXPointer: |
1244 * @ctxt: the XPointer Parser context | 1244 * @ctxt: the XPointer Parser context |
1245 * | 1245 * |
1246 * XPointer ::= Name | 1246 * XPointer ::= Name |
1247 * | ChildSeq | 1247 * | ChildSeq |
1248 * | FullXPtr | 1248 * | FullXPtr |
1249 * | 1249 * |
1250 * Parse and evaluate an XPointer | 1250 * Parse and evaluate an XPointer |
1251 */ | 1251 */ |
1252 static void | 1252 static void |
1253 xmlXPtrEvalXPointer(xmlXPathParserContextPtr ctxt) { | 1253 xmlXPtrEvalXPointer(xmlXPathParserContextPtr ctxt) { |
1254 if (ctxt->valueTab == NULL) { | 1254 if (ctxt->valueTab == NULL) { |
1255 /* Allocate the value stack */ | 1255 /* Allocate the value stack */ |
1256 » ctxt->valueTab = (xmlXPathObjectPtr *) | 1256 » ctxt->valueTab = (xmlXPathObjectPtr *) |
1257 xmlMalloc(10 * sizeof(xmlXPathObjectPtr)); | 1257 xmlMalloc(10 * sizeof(xmlXPathObjectPtr)); |
1258 if (ctxt->valueTab == NULL) { | 1258 if (ctxt->valueTab == NULL) { |
1259 xmlXPtrErrMemory("allocating evaluation context"); | 1259 xmlXPtrErrMemory("allocating evaluation context"); |
1260 return; | 1260 return; |
1261 } | 1261 } |
1262 ctxt->valueNr = 0; | 1262 ctxt->valueNr = 0; |
1263 ctxt->valueMax = 10; | 1263 ctxt->valueMax = 10; |
1264 ctxt->value = NULL; | 1264 ctxt->value = NULL; |
| 1265 ctxt->valueFrame = 0; |
1265 } | 1266 } |
1266 SKIP_BLANKS; | 1267 SKIP_BLANKS; |
1267 if (CUR == '/') { | 1268 if (CUR == '/') { |
1268 xmlXPathRoot(ctxt); | 1269 xmlXPathRoot(ctxt); |
1269 xmlXPtrEvalChildSeq(ctxt, NULL); | 1270 xmlXPtrEvalChildSeq(ctxt, NULL); |
1270 } else { | 1271 } else { |
1271 xmlChar *name; | 1272 xmlChar *name; |
1272 | 1273 |
1273 name = xmlXPathParseName(ctxt); | 1274 name = xmlXPathParseName(ctxt); |
1274 if (name == NULL) | 1275 if (name == NULL) |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1367 xmlXPathObjectPtr res = NULL, tmp; | 1368 xmlXPathObjectPtr res = NULL, tmp; |
1368 xmlXPathObjectPtr init = NULL; | 1369 xmlXPathObjectPtr init = NULL; |
1369 int stack = 0; | 1370 int stack = 0; |
1370 | 1371 |
1371 xmlXPathInit(); | 1372 xmlXPathInit(); |
1372 | 1373 |
1373 if ((ctx == NULL) || (str == NULL)) | 1374 if ((ctx == NULL) || (str == NULL)) |
1374 return(NULL); | 1375 return(NULL); |
1375 | 1376 |
1376 ctxt = xmlXPathNewParserContext(str, ctx); | 1377 ctxt = xmlXPathNewParserContext(str, ctx); |
| 1378 if (ctxt == NULL) |
| 1379 return(NULL); |
1377 ctxt->xptr = 1; | 1380 ctxt->xptr = 1; |
1378 xmlXPtrEvalXPointer(ctxt); | 1381 xmlXPtrEvalXPointer(ctxt); |
1379 | 1382 |
1380 if ((ctxt->value != NULL) && | 1383 if ((ctxt->value != NULL) && |
1381 (ctxt->value->type != XPATH_NODESET) && | 1384 (ctxt->value->type != XPATH_NODESET) && |
1382 (ctxt->value->type != XPATH_LOCATIONSET)) { | 1385 (ctxt->value->type != XPATH_LOCATIONSET)) { |
1383 xmlXPtrErr(ctxt, XML_XPTR_EVAL_FAILED, | 1386 xmlXPtrErr(ctxt, XML_XPTR_EVAL_FAILED, |
1384 "xmlXPtrEval: evaluation failed to return a node set\n", | 1387 "xmlXPtrEval: evaluation failed to return a node set\n", |
1385 NULL); | 1388 NULL); |
1386 } else { | 1389 } else { |
1387 res = valuePop(ctxt); | 1390 res = valuePop(ctxt); |
1388 } | 1391 } |
1389 | 1392 |
1390 do { | 1393 do { |
1391 tmp = valuePop(ctxt); | 1394 tmp = valuePop(ctxt); |
1392 if (tmp != NULL) { | 1395 if (tmp != NULL) { |
1393 if (tmp != init) { | 1396 if (tmp != init) { |
1394 if (tmp->type == XPATH_NODESET) { | 1397 if (tmp->type == XPATH_NODESET) { |
1395 /* | 1398 /* |
1396 * Evaluation may push a root nodeset which is unused | 1399 * Evaluation may push a root nodeset which is unused |
1397 */ | 1400 */ |
1398 » » xmlNodeSetPtr set; | 1401 » » xmlNodeSetPtr set; |
1399 set = tmp->nodesetval; | 1402 set = tmp->nodesetval; |
1400 if ((set->nodeNr != 1) || | 1403 if ((set->nodeNr != 1) || |
1401 (set->nodeTab[0] != (xmlNodePtr) ctx->doc)) | 1404 (set->nodeTab[0] != (xmlNodePtr) ctx->doc)) |
1402 stack++; | 1405 stack++; |
1403 } else | 1406 } else |
1404 » » stack++; | 1407 » » stack++; |
1405 } | 1408 } |
1406 xmlXPathFreeObject(tmp); | 1409 xmlXPathFreeObject(tmp); |
1407 } | 1410 } |
1408 } while (tmp != NULL); | 1411 } while (tmp != NULL); |
1409 if (stack != 0) { | 1412 if (stack != 0) { |
1410 xmlXPtrErr(ctxt, XML_XPTR_EXTRA_OBJECTS, | 1413 xmlXPtrErr(ctxt, XML_XPTR_EXTRA_OBJECTS, |
1411 "xmlXPtrEval: object(s) left on the eval stack\n", | 1414 "xmlXPtrEval: object(s) left on the eval stack\n", |
1412 NULL); | 1415 NULL); |
1413 } | 1416 } |
1414 if (ctxt->error != XPATH_EXPRESSION_OK) { | 1417 if (ctxt->error != XPATH_EXPRESSION_OK) { |
1415 xmlXPathFreeObject(res); | 1418 xmlXPathFreeObject(res); |
1416 res = NULL; | 1419 res = NULL; |
1417 } | 1420 } |
1418 | 1421 |
1419 xmlXPathFreeParserContext(ctxt); | 1422 xmlXPathFreeParserContext(ctxt); |
1420 return(res); | 1423 return(res); |
1421 } | 1424 } |
1422 | 1425 |
1423 /** | 1426 /** |
1424 * xmlXPtrBuildRangeNodeList: | 1427 * xmlXPtrBuildRangeNodeList: |
1425 * @range: a range object | 1428 * @range: a range object |
1426 * | 1429 * |
1427 * Build a node list tree copy of the range | 1430 * Build a node list tree copy of the range |
1428 * | 1431 * |
1429 * Returns an xmlNodePtr list or NULL. | 1432 * Returns an xmlNodePtr list or NULL. |
1430 * the caller has to free the node tree. | 1433 * the caller has to free the node tree. |
1431 */ | 1434 */ |
1432 static xmlNodePtr | 1435 static xmlNodePtr |
1433 xmlXPtrBuildRangeNodeList(xmlXPathObjectPtr range) { | 1436 xmlXPtrBuildRangeNodeList(xmlXPathObjectPtr range) { |
1434 /* pointers to generated nodes */ | 1437 /* pointers to generated nodes */ |
1435 xmlNodePtr list = NULL, last = NULL, parent = NULL, tmp; | 1438 xmlNodePtr list = NULL, last = NULL, parent = NULL, tmp; |
1436 /* pointers to traversal nodes */ | 1439 /* pointers to traversal nodes */ |
1437 xmlNodePtr start, cur, end; | 1440 xmlNodePtr start, cur, end; |
1438 int index1, index2; | 1441 int index1, index2; |
1439 | 1442 |
1440 if (range == NULL) | 1443 if (range == NULL) |
1441 return(NULL); | 1444 return(NULL); |
1442 if (range->type != XPATH_RANGE) | 1445 if (range->type != XPATH_RANGE) |
1443 return(NULL); | 1446 return(NULL); |
1444 start = (xmlNodePtr) range->user; | 1447 start = (xmlNodePtr) range->user; |
1445 | 1448 |
1446 if (start == NULL) | 1449 if ((start == NULL) || (start->type == XML_NAMESPACE_DECL)) |
1447 return(NULL); | 1450 return(NULL); |
1448 end = range->user2; | 1451 end = range->user2; |
1449 if (end == NULL) | 1452 if (end == NULL) |
1450 return(xmlCopyNode(start, 1)); | 1453 return(xmlCopyNode(start, 1)); |
| 1454 if (end->type == XML_NAMESPACE_DECL) |
| 1455 return(NULL); |
1451 | 1456 |
1452 cur = start; | 1457 cur = start; |
1453 index1 = range->index; | 1458 index1 = range->index; |
1454 index2 = range->index2; | 1459 index2 = range->index2; |
1455 while (cur != NULL) { | 1460 while (cur != NULL) { |
1456 if (cur == end) { | 1461 if (cur == end) { |
1457 if (cur->type == XML_TEXT_NODE) { | 1462 if (cur->type == XML_TEXT_NODE) { |
1458 const xmlChar *content = cur->content; | 1463 const xmlChar *content = cur->content; |
1459 int len; | 1464 int len; |
1460 | 1465 |
1461 if (content == NULL) { | 1466 if (content == NULL) { |
1462 tmp = xmlNewTextLen(NULL, 0); | 1467 tmp = xmlNewTextLen(NULL, 0); |
1463 } else { | 1468 } else { |
1464 len = index2; | 1469 len = index2; |
1465 if ((cur == start) && (index1 > 1)) { | 1470 if ((cur == start) && (index1 > 1)) { |
1466 content += (index1 - 1); | 1471 content += (index1 - 1); |
1467 len -= (index1 - 1); | 1472 len -= (index1 - 1); |
1468 index1 = 0; | 1473 index1 = 0; |
1469 } else { | 1474 } else { |
1470 len = index2; | 1475 len = index2; |
1471 } | 1476 } |
1472 tmp = xmlNewTextLen(content, len); | 1477 tmp = xmlNewTextLen(content, len); |
1473 } | 1478 } |
1474 /* single sub text node selection */ | 1479 /* single sub text node selection */ |
1475 if (list == NULL) | 1480 if (list == NULL) |
1476 return(tmp); | 1481 return(tmp); |
1477 /* prune and return full set */ | 1482 /* prune and return full set */ |
1478 if (last != NULL) | 1483 if (last != NULL) |
1479 xmlAddNextSibling(last, tmp); | 1484 xmlAddNextSibling(last, tmp); |
1480 » » else | 1485 » » else |
1481 xmlAddChild(parent, tmp); | 1486 xmlAddChild(parent, tmp); |
1482 return(list); | 1487 return(list); |
1483 } else { | 1488 } else { |
1484 tmp = xmlCopyNode(cur, 0); | 1489 tmp = xmlCopyNode(cur, 0); |
1485 if (list == NULL) | 1490 if (list == NULL) |
1486 list = tmp; | 1491 list = tmp; |
1487 else { | 1492 else { |
1488 if (last != NULL) | 1493 if (last != NULL) |
1489 xmlAddNextSibling(last, tmp); | 1494 xmlAddNextSibling(last, tmp); |
1490 else | 1495 else |
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1724 return(-1); | 1729 return(-1); |
1725 } | 1730 } |
1726 return(ret); | 1731 return(ret); |
1727 } | 1732 } |
1728 | 1733 |
1729 /** | 1734 /** |
1730 * xmlXPtrHereFunction: | 1735 * xmlXPtrHereFunction: |
1731 * @ctxt: the XPointer Parser context | 1736 * @ctxt: the XPointer Parser context |
1732 * @nargs: the number of args | 1737 * @nargs: the number of args |
1733 * | 1738 * |
1734 * Function implementing here() operation | 1739 * Function implementing here() operation |
1735 * as described in 5.4.3 | 1740 * as described in 5.4.3 |
1736 */ | 1741 */ |
1737 static void | 1742 static void |
1738 xmlXPtrHereFunction(xmlXPathParserContextPtr ctxt, int nargs) { | 1743 xmlXPtrHereFunction(xmlXPathParserContextPtr ctxt, int nargs) { |
1739 CHECK_ARITY(0); | 1744 CHECK_ARITY(0); |
1740 | 1745 |
1741 if (ctxt->context->here == NULL) | 1746 if (ctxt->context->here == NULL) |
1742 XP_ERROR(XPTR_SYNTAX_ERROR); | 1747 XP_ERROR(XPTR_SYNTAX_ERROR); |
1743 | 1748 |
1744 valuePush(ctxt, xmlXPtrNewLocationSetNodes(ctxt->context->here, NULL)); | 1749 valuePush(ctxt, xmlXPtrNewLocationSetNodes(ctxt->context->here, NULL)); |
1745 } | 1750 } |
1746 | 1751 |
1747 /** | 1752 /** |
1748 * xmlXPtrOriginFunction: | 1753 * xmlXPtrOriginFunction: |
1749 * @ctxt: the XPointer Parser context | 1754 * @ctxt: the XPointer Parser context |
1750 * @nargs: the number of args | 1755 * @nargs: the number of args |
1751 * | 1756 * |
1752 * Function implementing origin() operation | 1757 * Function implementing origin() operation |
1753 * as described in 5.4.3 | 1758 * as described in 5.4.3 |
1754 */ | 1759 */ |
1755 static void | 1760 static void |
1756 xmlXPtrOriginFunction(xmlXPathParserContextPtr ctxt, int nargs) { | 1761 xmlXPtrOriginFunction(xmlXPathParserContextPtr ctxt, int nargs) { |
1757 CHECK_ARITY(0); | 1762 CHECK_ARITY(0); |
1758 | 1763 |
1759 if (ctxt->context->origin == NULL) | 1764 if (ctxt->context->origin == NULL) |
1760 XP_ERROR(XPTR_SYNTAX_ERROR); | 1765 XP_ERROR(XPTR_SYNTAX_ERROR); |
1761 | 1766 |
1762 valuePush(ctxt, xmlXPtrNewLocationSetNodes(ctxt->context->origin, NULL)); | 1767 valuePush(ctxt, xmlXPtrNewLocationSetNodes(ctxt->context->origin, NULL)); |
1763 } | 1768 } |
1764 | 1769 |
1765 /** | 1770 /** |
1766 * xmlXPtrStartPointFunction: | 1771 * xmlXPtrStartPointFunction: |
1767 * @ctxt: the XPointer Parser context | 1772 * @ctxt: the XPointer Parser context |
1768 * @nargs: the number of args | 1773 * @nargs: the number of args |
1769 * | 1774 * |
1770 * Function implementing start-point() operation | 1775 * Function implementing start-point() operation |
1771 * as described in 5.4.3 | 1776 * as described in 5.4.3 |
1772 * ---------------- | 1777 * ---------------- |
1773 * location-set start-point(location-set) | 1778 * location-set start-point(location-set) |
1774 * | 1779 * |
1775 * For each location x in the argument location-set, start-point adds a | 1780 * For each location x in the argument location-set, start-point adds a |
1776 * location of type point to the result location-set. That point represents | 1781 * location of type point to the result location-set. That point represents |
1777 * the start point of location x and is determined by the following rules: | 1782 * the start point of location x and is determined by the following rules: |
1778 * | 1783 * |
1779 * - If x is of type point, the start point is x. | 1784 * - If x is of type point, the start point is x. |
1780 * - If x is of type range, the start point is the start point of x. | 1785 * - If x is of type range, the start point is the start point of x. |
(...skipping 16 matching lines...) Expand all Loading... |
1797 (ctxt->value->type != XPATH_NODESET))) | 1802 (ctxt->value->type != XPATH_NODESET))) |
1798 XP_ERROR(XPATH_INVALID_TYPE) | 1803 XP_ERROR(XPATH_INVALID_TYPE) |
1799 | 1804 |
1800 obj = valuePop(ctxt); | 1805 obj = valuePop(ctxt); |
1801 if (obj->type == XPATH_NODESET) { | 1806 if (obj->type == XPATH_NODESET) { |
1802 /* | 1807 /* |
1803 * First convert to a location set | 1808 * First convert to a location set |
1804 */ | 1809 */ |
1805 tmp = xmlXPtrNewLocationSetNodeSet(obj->nodesetval); | 1810 tmp = xmlXPtrNewLocationSetNodeSet(obj->nodesetval); |
1806 xmlXPathFreeObject(obj); | 1811 xmlXPathFreeObject(obj); |
| 1812 if (tmp == NULL) |
| 1813 XP_ERROR(XPATH_MEMORY_ERROR) |
1807 obj = tmp; | 1814 obj = tmp; |
1808 } | 1815 } |
1809 | 1816 |
1810 newset = xmlXPtrLocationSetCreate(NULL); | 1817 newset = xmlXPtrLocationSetCreate(NULL); |
1811 if (newset == NULL) { | 1818 if (newset == NULL) { |
1812 xmlXPathFreeObject(obj); | 1819 xmlXPathFreeObject(obj); |
1813 XP_ERROR(XPATH_MEMORY_ERROR); | 1820 XP_ERROR(XPATH_MEMORY_ERROR); |
1814 } | 1821 } |
1815 oldset = (xmlLocationSetPtr) obj->user; | 1822 oldset = (xmlLocationSetPtr) obj->user; |
1816 if (oldset != NULL) { | 1823 if (oldset != NULL) { |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1852 } | 1859 } |
1853 xmlXPathFreeObject(obj); | 1860 xmlXPathFreeObject(obj); |
1854 valuePush(ctxt, xmlXPtrWrapLocationSet(newset)); | 1861 valuePush(ctxt, xmlXPtrWrapLocationSet(newset)); |
1855 } | 1862 } |
1856 | 1863 |
1857 /** | 1864 /** |
1858 * xmlXPtrEndPointFunction: | 1865 * xmlXPtrEndPointFunction: |
1859 * @ctxt: the XPointer Parser context | 1866 * @ctxt: the XPointer Parser context |
1860 * @nargs: the number of args | 1867 * @nargs: the number of args |
1861 * | 1868 * |
1862 * Function implementing end-point() operation | 1869 * Function implementing end-point() operation |
1863 * as described in 5.4.3 | 1870 * as described in 5.4.3 |
1864 * ---------------------------- | 1871 * ---------------------------- |
1865 * location-set end-point(location-set) | 1872 * location-set end-point(location-set) |
1866 * | 1873 * |
1867 * For each location x in the argument location-set, end-point adds a | 1874 * For each location x in the argument location-set, end-point adds a |
1868 * location of type point to the result location-set. That point represents | 1875 * location of type point to the result location-set. That point represents |
1869 * the end point of location x and is determined by the following rules: | 1876 * the end point of location x and is determined by the following rules: |
1870 * | 1877 * |
1871 * - If x is of type point, the resulting point is x. | 1878 * - If x is of type point, the resulting point is x. |
1872 * - If x is of type range, the resulting point is the end point of x. | 1879 * - If x is of type range, the resulting point is the end point of x. |
(...skipping 18 matching lines...) Expand all Loading... |
1891 (ctxt->value->type != XPATH_NODESET))) | 1898 (ctxt->value->type != XPATH_NODESET))) |
1892 XP_ERROR(XPATH_INVALID_TYPE) | 1899 XP_ERROR(XPATH_INVALID_TYPE) |
1893 | 1900 |
1894 obj = valuePop(ctxt); | 1901 obj = valuePop(ctxt); |
1895 if (obj->type == XPATH_NODESET) { | 1902 if (obj->type == XPATH_NODESET) { |
1896 /* | 1903 /* |
1897 * First convert to a location set | 1904 * First convert to a location set |
1898 */ | 1905 */ |
1899 tmp = xmlXPtrNewLocationSetNodeSet(obj->nodesetval); | 1906 tmp = xmlXPtrNewLocationSetNodeSet(obj->nodesetval); |
1900 xmlXPathFreeObject(obj); | 1907 xmlXPathFreeObject(obj); |
| 1908 if (tmp == NULL) |
| 1909 XP_ERROR(XPATH_MEMORY_ERROR) |
1901 obj = tmp; | 1910 obj = tmp; |
1902 } | 1911 } |
1903 | 1912 |
1904 newset = xmlXPtrLocationSetCreate(NULL); | 1913 newset = xmlXPtrLocationSetCreate(NULL); |
| 1914 if (newset == NULL) { |
| 1915 xmlXPathFreeObject(obj); |
| 1916 XP_ERROR(XPATH_MEMORY_ERROR); |
| 1917 } |
1905 oldset = (xmlLocationSetPtr) obj->user; | 1918 oldset = (xmlLocationSetPtr) obj->user; |
1906 if (oldset != NULL) { | 1919 if (oldset != NULL) { |
1907 int i; | 1920 int i; |
1908 | 1921 |
1909 for (i = 0; i < oldset->locNr; i++) { | 1922 for (i = 0; i < oldset->locNr; i++) { |
1910 tmp = oldset->locTab[i]; | 1923 tmp = oldset->locTab[i]; |
1911 if (tmp == NULL) | 1924 if (tmp == NULL) |
1912 continue; | 1925 continue; |
1913 point = NULL; | 1926 point = NULL; |
1914 switch (tmp->type) { | 1927 switch (tmp->type) { |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1988 case XML_ELEMENT_NODE: | 2001 case XML_ELEMENT_NODE: |
1989 case XML_TEXT_NODE: | 2002 case XML_TEXT_NODE: |
1990 case XML_CDATA_SECTION_NODE: | 2003 case XML_CDATA_SECTION_NODE: |
1991 case XML_ENTITY_REF_NODE: | 2004 case XML_ENTITY_REF_NODE: |
1992 case XML_PI_NODE: | 2005 case XML_PI_NODE: |
1993 case XML_COMMENT_NODE: | 2006 case XML_COMMENT_NODE: |
1994 case XML_DOCUMENT_NODE: | 2007 case XML_DOCUMENT_NODE: |
1995 case XML_NOTATION_NODE: | 2008 case XML_NOTATION_NODE: |
1996 case XML_HTML_DOCUMENT_NODE: { | 2009 case XML_HTML_DOCUMENT_NODE: { |
1997 int indx = xmlXPtrGetIndex(node); | 2010 int indx = xmlXPtrGetIndex(node); |
1998 » » » | 2011 |
1999 node = node->parent; | 2012 node = node->parent; |
2000 return(xmlXPtrNewRange(node, indx - 1, | 2013 return(xmlXPtrNewRange(node, indx - 1, |
2001 node, indx + 1)); | 2014 node, indx + 1)); |
2002 } | 2015 } |
2003 default: | 2016 default: |
2004 return(NULL); | 2017 return(NULL); |
2005 } | 2018 } |
2006 } | 2019 } |
2007 } | 2020 } |
2008 default: | 2021 default: |
(...skipping 30 matching lines...) Expand all Loading... |
2039 | 2052 |
2040 set = valuePop(ctxt); | 2053 set = valuePop(ctxt); |
2041 if (set->type == XPATH_NODESET) { | 2054 if (set->type == XPATH_NODESET) { |
2042 xmlXPathObjectPtr tmp; | 2055 xmlXPathObjectPtr tmp; |
2043 | 2056 |
2044 /* | 2057 /* |
2045 * First convert to a location set | 2058 * First convert to a location set |
2046 */ | 2059 */ |
2047 tmp = xmlXPtrNewLocationSetNodeSet(set->nodesetval); | 2060 tmp = xmlXPtrNewLocationSetNodeSet(set->nodesetval); |
2048 xmlXPathFreeObject(set); | 2061 xmlXPathFreeObject(set); |
| 2062 if (tmp == NULL) |
| 2063 XP_ERROR(XPATH_MEMORY_ERROR) |
2049 set = tmp; | 2064 set = tmp; |
2050 } | 2065 } |
2051 oldset = (xmlLocationSetPtr) set->user; | 2066 oldset = (xmlLocationSetPtr) set->user; |
2052 | 2067 |
2053 /* | 2068 /* |
2054 * The loop is to compute the covering range for each item and add it | 2069 * The loop is to compute the covering range for each item and add it |
2055 */ | 2070 */ |
2056 newset = xmlXPtrLocationSetCreate(NULL); | 2071 newset = xmlXPtrLocationSetCreate(NULL); |
| 2072 if (newset == NULL) { |
| 2073 xmlXPathFreeObject(set); |
| 2074 XP_ERROR(XPATH_MEMORY_ERROR); |
| 2075 } |
2057 for (i = 0;i < oldset->locNr;i++) { | 2076 for (i = 0;i < oldset->locNr;i++) { |
2058 xmlXPtrLocationSetAdd(newset, | 2077 xmlXPtrLocationSetAdd(newset, |
2059 xmlXPtrCoveringRange(ctxt, oldset->locTab[i])); | 2078 xmlXPtrCoveringRange(ctxt, oldset->locTab[i])); |
2060 } | 2079 } |
2061 | 2080 |
2062 /* | 2081 /* |
2063 * Save the new value and cleanup | 2082 * Save the new value and cleanup |
2064 */ | 2083 */ |
2065 valuePush(ctxt, xmlXPtrWrapLocationSet(newset)); | 2084 valuePush(ctxt, xmlXPtrWrapLocationSet(newset)); |
2066 xmlXPathFreeObject(set); | 2085 xmlXPathFreeObject(set); |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2185 | 2204 |
2186 set = valuePop(ctxt); | 2205 set = valuePop(ctxt); |
2187 if (set->type == XPATH_NODESET) { | 2206 if (set->type == XPATH_NODESET) { |
2188 xmlXPathObjectPtr tmp; | 2207 xmlXPathObjectPtr tmp; |
2189 | 2208 |
2190 /* | 2209 /* |
2191 * First convert to a location set | 2210 * First convert to a location set |
2192 */ | 2211 */ |
2193 tmp = xmlXPtrNewLocationSetNodeSet(set->nodesetval); | 2212 tmp = xmlXPtrNewLocationSetNodeSet(set->nodesetval); |
2194 xmlXPathFreeObject(set); | 2213 xmlXPathFreeObject(set); |
| 2214 if (tmp == NULL) |
| 2215 XP_ERROR(XPATH_MEMORY_ERROR) |
2195 set = tmp; | 2216 set = tmp; |
2196 } | 2217 } |
2197 oldset = (xmlLocationSetPtr) set->user; | 2218 oldset = (xmlLocationSetPtr) set->user; |
2198 | 2219 |
2199 /* | 2220 /* |
2200 * The loop is to compute the covering range for each item and add it | 2221 * The loop is to compute the covering range for each item and add it |
2201 */ | 2222 */ |
2202 newset = xmlXPtrLocationSetCreate(NULL); | 2223 newset = xmlXPtrLocationSetCreate(NULL); |
| 2224 if (newset == NULL) { |
| 2225 xmlXPathFreeObject(set); |
| 2226 XP_ERROR(XPATH_MEMORY_ERROR); |
| 2227 } |
2203 for (i = 0;i < oldset->locNr;i++) { | 2228 for (i = 0;i < oldset->locNr;i++) { |
2204 xmlXPtrLocationSetAdd(newset, | 2229 xmlXPtrLocationSetAdd(newset, |
2205 xmlXPtrInsideRange(ctxt, oldset->locTab[i])); | 2230 xmlXPtrInsideRange(ctxt, oldset->locTab[i])); |
2206 } | 2231 } |
2207 | 2232 |
2208 /* | 2233 /* |
2209 * Save the new value and cleanup | 2234 * Save the new value and cleanup |
2210 */ | 2235 */ |
2211 valuePush(ctxt, xmlXPtrWrapLocationSet(newset)); | 2236 valuePush(ctxt, xmlXPtrWrapLocationSet(newset)); |
2212 xmlXPathFreeObject(set); | 2237 xmlXPathFreeObject(set); |
(...skipping 22 matching lines...) Expand all Loading... |
2235 * Save the expression pointer since we will have to evaluate | 2260 * Save the expression pointer since we will have to evaluate |
2236 * it multiple times. Initialize the new set. | 2261 * it multiple times. Initialize the new set. |
2237 */ | 2262 */ |
2238 CHECK_TYPE(XPATH_NODESET); | 2263 CHECK_TYPE(XPATH_NODESET); |
2239 obj = valuePop(ctxt); | 2264 obj = valuePop(ctxt); |
2240 oldset = obj->nodesetval; | 2265 oldset = obj->nodesetval; |
2241 ctxt->context->node = NULL; | 2266 ctxt->context->node = NULL; |
2242 | 2267 |
2243 cur = ctxt->cur; | 2268 cur = ctxt->cur; |
2244 newset = xmlXPtrLocationSetCreate(NULL); | 2269 newset = xmlXPtrLocationSetCreate(NULL); |
2245 | 2270 |
2246 for (i = 0; i < oldset->nodeNr; i++) { | 2271 for (i = 0; i < oldset->nodeNr; i++) { |
2247 ctxt->cur = cur; | 2272 ctxt->cur = cur; |
2248 | 2273 |
2249 /* | 2274 /* |
2250 * Run the evaluation with a node list made of a single item | 2275 * Run the evaluation with a node list made of a single item |
2251 * in the nodeset. | 2276 * in the nodeset. |
2252 */ | 2277 */ |
2253 ctxt->context->node = oldset->nodeTab[i]; | 2278 ctxt->context->node = oldset->nodeTab[i]; |
2254 tmp = xmlXPathNewNodeSet(ctxt->context->node); | 2279 tmp = xmlXPathNewNodeSet(ctxt->context->node); |
2255 valuePush(ctxt, tmp); | 2280 valuePush(ctxt, tmp); |
(...skipping 13 matching lines...) Expand all Loading... |
2269 | 2294 |
2270 /* | 2295 /* |
2271 * Cleanup | 2296 * Cleanup |
2272 */ | 2297 */ |
2273 if (res != NULL) | 2298 if (res != NULL) |
2274 xmlXPathFreeObject(res); | 2299 xmlXPathFreeObject(res); |
2275 if (ctxt->value == tmp) { | 2300 if (ctxt->value == tmp) { |
2276 res = valuePop(ctxt); | 2301 res = valuePop(ctxt); |
2277 xmlXPathFreeObject(res); | 2302 xmlXPathFreeObject(res); |
2278 } | 2303 } |
2279 » | 2304 |
2280 ctxt->context->node = NULL; | 2305 ctxt->context->node = NULL; |
2281 } | 2306 } |
2282 | 2307 |
2283 /* | 2308 /* |
2284 * The result is used as the new evaluation set. | 2309 * The result is used as the new evaluation set. |
2285 */ | 2310 */ |
2286 xmlXPathFreeObject(obj); | 2311 xmlXPathFreeObject(obj); |
2287 ctxt->context->node = NULL; | 2312 ctxt->context->node = NULL; |
2288 ctxt->context->contextSize = -1; | 2313 ctxt->context->contextSize = -1; |
2289 ctxt->context->proximityPosition = -1; | 2314 ctxt->context->proximityPosition = -1; |
2290 valuePush(ctxt, xmlXPtrWrapLocationSet(newset)); | 2315 valuePush(ctxt, xmlXPtrWrapLocationSet(newset)); |
2291 } | 2316 } |
2292 | 2317 |
2293 /** | 2318 /** |
2294 * xmlXPtrAdvanceNode: | 2319 * xmlXPtrAdvanceNode: |
2295 * @cur: the node | 2320 * @cur: the node |
2296 * @level: incremented/decremented to show level in tree | 2321 * @level: incremented/decremented to show level in tree |
2297 * | 2322 * |
2298 * Advance to the next element or text node in document order | 2323 * Advance to the next element or text node in document order |
2299 * TODO: add a stack for entering/exiting entities | 2324 * TODO: add a stack for entering/exiting entities |
2300 * | 2325 * |
2301 * Returns -1 in case of failure, 0 otherwise | 2326 * Returns -1 in case of failure, 0 otherwise |
2302 */ | 2327 */ |
2303 xmlNodePtr | 2328 xmlNodePtr |
2304 xmlXPtrAdvanceNode(xmlNodePtr cur, int *level) { | 2329 xmlXPtrAdvanceNode(xmlNodePtr cur, int *level) { |
2305 next: | 2330 next: |
2306 if (cur == NULL) | 2331 if ((cur == NULL) || (cur->type == XML_NAMESPACE_DECL)) |
2307 return(NULL); | 2332 return(NULL); |
2308 if (cur->children != NULL) { | 2333 if (cur->children != NULL) { |
2309 cur = cur->children ; | 2334 cur = cur->children ; |
2310 if (level != NULL) | 2335 if (level != NULL) |
2311 (*level)++; | 2336 (*level)++; |
2312 goto found; | 2337 goto found; |
2313 } | 2338 } |
2314 skip: /* This label should only be needed if something is wrong! */ | 2339 skip: /* This label should only be needed if something is wrong! */ |
2315 if (cur->next != NULL) { | 2340 if (cur->next != NULL) { |
2316 cur = cur->next; | 2341 cur = cur->next; |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2354 */ | 2379 */ |
2355 static int | 2380 static int |
2356 xmlXPtrAdvanceChar(xmlNodePtr *node, int *indx, int bytes) { | 2381 xmlXPtrAdvanceChar(xmlNodePtr *node, int *indx, int bytes) { |
2357 xmlNodePtr cur; | 2382 xmlNodePtr cur; |
2358 int pos; | 2383 int pos; |
2359 int len; | 2384 int len; |
2360 | 2385 |
2361 if ((node == NULL) || (indx == NULL)) | 2386 if ((node == NULL) || (indx == NULL)) |
2362 return(-1); | 2387 return(-1); |
2363 cur = *node; | 2388 cur = *node; |
2364 if (cur == NULL) | 2389 if ((cur == NULL) || (cur->type == XML_NAMESPACE_DECL)) |
2365 return(-1); | 2390 return(-1); |
2366 pos = *indx; | 2391 pos = *indx; |
2367 | 2392 |
2368 while (bytes >= 0) { | 2393 while (bytes >= 0) { |
2369 /* | 2394 /* |
2370 * First position to the beginning of the first text node | 2395 * First position to the beginning of the first text node |
2371 * corresponding to this point | 2396 * corresponding to this point |
2372 */ | 2397 */ |
2373 while ((cur != NULL) && | 2398 while ((cur != NULL) && |
2374 ((cur->type == XML_ELEMENT_NODE) || | 2399 ((cur->type == XML_ELEMENT_NODE) || |
(...skipping 17 matching lines...) Expand all Loading... |
2392 /* | 2417 /* |
2393 * if there is no move needed return the current value. | 2418 * if there is no move needed return the current value. |
2394 */ | 2419 */ |
2395 if (pos == 0) pos = 1; | 2420 if (pos == 0) pos = 1; |
2396 if (bytes == 0) { | 2421 if (bytes == 0) { |
2397 *node = cur; | 2422 *node = cur; |
2398 *indx = pos; | 2423 *indx = pos; |
2399 return(0); | 2424 return(0); |
2400 } | 2425 } |
2401 /* | 2426 /* |
2402 » * We should have a text (or cdata) node ... | 2427 » * We should have a text (or cdata) node ... |
2403 */ | 2428 */ |
2404 len = 0; | 2429 len = 0; |
2405 if ((cur->type != XML_ELEMENT_NODE) && | 2430 if ((cur->type != XML_ELEMENT_NODE) && |
2406 (cur->content != NULL)) { | 2431 (cur->content != NULL)) { |
2407 len = xmlStrlen(cur->content); | 2432 len = xmlStrlen(cur->content); |
2408 } | 2433 } |
2409 if (pos > len) { | 2434 if (pos > len) { |
2410 /* Strange, the indx in the text node is greater than it's len */ | 2435 /* Strange, the indx in the text node is greater than it's len */ |
2411 STRANGE | 2436 STRANGE |
2412 pos = len; | 2437 pos = len; |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2445 xmlXPtrMatchString(const xmlChar *string, xmlNodePtr start, int startindex, | 2470 xmlXPtrMatchString(const xmlChar *string, xmlNodePtr start, int startindex, |
2446 xmlNodePtr *end, int *endindex) { | 2471 xmlNodePtr *end, int *endindex) { |
2447 xmlNodePtr cur; | 2472 xmlNodePtr cur; |
2448 int pos; /* 0 based */ | 2473 int pos; /* 0 based */ |
2449 int len; /* in bytes */ | 2474 int len; /* in bytes */ |
2450 int stringlen; /* in bytes */ | 2475 int stringlen; /* in bytes */ |
2451 int match; | 2476 int match; |
2452 | 2477 |
2453 if (string == NULL) | 2478 if (string == NULL) |
2454 return(-1); | 2479 return(-1); |
2455 if (start == NULL) | 2480 if ((start == NULL) || (start->type == XML_NAMESPACE_DECL)) |
2456 return(-1); | 2481 return(-1); |
2457 if ((end == NULL) || (endindex == NULL)) | 2482 if ((end == NULL) || (*end == NULL) || |
| 2483 ((*end)->type == XML_NAMESPACE_DECL) || (endindex == NULL)) |
2458 return(-1); | 2484 return(-1); |
2459 cur = start; | 2485 cur = start; |
2460 if (cur == NULL) | |
2461 return(-1); | |
2462 pos = startindex - 1; | 2486 pos = startindex - 1; |
2463 stringlen = xmlStrlen(string); | 2487 stringlen = xmlStrlen(string); |
2464 | 2488 |
2465 while (stringlen > 0) { | 2489 while (stringlen > 0) { |
2466 if ((cur == *end) && (pos + stringlen > *endindex)) | 2490 if ((cur == *end) && (pos + stringlen > *endindex)) |
2467 return(0); | 2491 return(0); |
2468 | 2492 |
2469 if ((cur->type != XML_ELEMENT_NODE) && (cur->content != NULL)) { | 2493 if ((cur->type != XML_ELEMENT_NODE) && (cur->content != NULL)) { |
2470 len = xmlStrlen(cur->content); | 2494 len = xmlStrlen(cur->content); |
2471 if (len >= pos + stringlen) { | 2495 if (len >= pos + stringlen) { |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2530 xmlXPtrSearchString(const xmlChar *string, xmlNodePtr *start, int *startindex, | 2554 xmlXPtrSearchString(const xmlChar *string, xmlNodePtr *start, int *startindex, |
2531 xmlNodePtr *end, int *endindex) { | 2555 xmlNodePtr *end, int *endindex) { |
2532 xmlNodePtr cur; | 2556 xmlNodePtr cur; |
2533 const xmlChar *str; | 2557 const xmlChar *str; |
2534 int pos; /* 0 based */ | 2558 int pos; /* 0 based */ |
2535 int len; /* in bytes */ | 2559 int len; /* in bytes */ |
2536 xmlChar first; | 2560 xmlChar first; |
2537 | 2561 |
2538 if (string == NULL) | 2562 if (string == NULL) |
2539 return(-1); | 2563 return(-1); |
2540 if ((start == NULL) || (startindex == NULL)) | 2564 if ((start == NULL) || (*start == NULL) || |
| 2565 ((*start)->type == XML_NAMESPACE_DECL) || (startindex == NULL)) |
2541 return(-1); | 2566 return(-1); |
2542 if ((end == NULL) || (endindex == NULL)) | 2567 if ((end == NULL) || (endindex == NULL)) |
2543 return(-1); | 2568 return(-1); |
2544 cur = *start; | 2569 cur = *start; |
2545 if (cur == NULL) | |
2546 return(-1); | |
2547 pos = *startindex - 1; | 2570 pos = *startindex - 1; |
2548 first = string[0]; | 2571 first = string[0]; |
2549 | 2572 |
2550 while (cur != NULL) { | 2573 while (cur != NULL) { |
2551 if ((cur->type != XML_ELEMENT_NODE) && (cur->content != NULL)) { | 2574 if ((cur->type != XML_ELEMENT_NODE) && (cur->content != NULL)) { |
2552 len = xmlStrlen(cur->content); | 2575 len = xmlStrlen(cur->content); |
2553 while (pos <= len) { | 2576 while (pos <= len) { |
2554 if (first != 0) { | 2577 if (first != 0) { |
2555 str = xmlStrchr(&cur->content[pos], first); | 2578 str = xmlStrchr(&cur->content[pos], first); |
2556 if (str != NULL) { | 2579 if (str != NULL) { |
(...skipping 12 matching lines...) Expand all Loading... |
2569 return(1); | 2592 return(1); |
2570 } | 2593 } |
2571 pos++; | 2594 pos++; |
2572 } else { | 2595 } else { |
2573 pos = len + 1; | 2596 pos = len + 1; |
2574 } | 2597 } |
2575 } else { | 2598 } else { |
2576 /* | 2599 /* |
2577 * An empty string is considered to match before each | 2600 * An empty string is considered to match before each |
2578 * character of the string-value and after the final | 2601 * character of the string-value and after the final |
2579 » » * character. | 2602 » » * character. |
2580 */ | 2603 */ |
2581 #ifdef DEBUG_RANGES | 2604 #ifdef DEBUG_RANGES |
2582 xmlGenericError(xmlGenericErrorContext, | 2605 xmlGenericError(xmlGenericErrorContext, |
2583 "found '' at index %d of ->", | 2606 "found '' at index %d of ->", |
2584 pos + 1); | 2607 pos + 1); |
2585 xmlDebugDumpString(stdout, cur->content); | 2608 xmlDebugDumpString(stdout, cur->content); |
2586 xmlGenericError(xmlGenericErrorContext, "\n"); | 2609 xmlGenericError(xmlGenericErrorContext, "\n"); |
2587 #endif | 2610 #endif |
2588 *start = cur; | 2611 *start = cur; |
2589 *startindex = pos + 1; | 2612 *startindex = pos + 1; |
(...skipping 20 matching lines...) Expand all Loading... |
2610 * | 2633 * |
2611 * Computes the point coordinates of the last char of this point | 2634 * Computes the point coordinates of the last char of this point |
2612 * | 2635 * |
2613 * Returns -1 in case of failure, 0 otherwise | 2636 * Returns -1 in case of failure, 0 otherwise |
2614 */ | 2637 */ |
2615 static int | 2638 static int |
2616 xmlXPtrGetLastChar(xmlNodePtr *node, int *indx) { | 2639 xmlXPtrGetLastChar(xmlNodePtr *node, int *indx) { |
2617 xmlNodePtr cur; | 2640 xmlNodePtr cur; |
2618 int pos, len = 0; | 2641 int pos, len = 0; |
2619 | 2642 |
2620 if ((node == NULL) || (indx == NULL)) | 2643 if ((node == NULL) || (*node == NULL) || |
| 2644 ((*node)->type == XML_NAMESPACE_DECL) || (indx == NULL)) |
2621 return(-1); | 2645 return(-1); |
2622 cur = *node; | 2646 cur = *node; |
2623 pos = *indx; | 2647 pos = *indx; |
2624 | 2648 |
2625 if (cur == NULL) | |
2626 return(-1); | |
2627 | |
2628 if ((cur->type == XML_ELEMENT_NODE) || | 2649 if ((cur->type == XML_ELEMENT_NODE) || |
2629 (cur->type == XML_DOCUMENT_NODE) || | 2650 (cur->type == XML_DOCUMENT_NODE) || |
2630 (cur->type == XML_HTML_DOCUMENT_NODE)) { | 2651 (cur->type == XML_HTML_DOCUMENT_NODE)) { |
2631 if (pos > 0) { | 2652 if (pos > 0) { |
2632 cur = xmlXPtrGetNthChild(cur, pos); | 2653 cur = xmlXPtrGetNthChild(cur, pos); |
2633 } | 2654 } |
2634 } | 2655 } |
2635 while (cur != NULL) { | 2656 while (cur != NULL) { |
2636 if (cur->last != NULL) | 2657 if (cur->last != NULL) |
2637 cur = cur->last; | 2658 cur = cur->last; |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2721 } | 2742 } |
2722 return(-1); | 2743 return(-1); |
2723 } | 2744 } |
2724 | 2745 |
2725 /** | 2746 /** |
2726 * xmlXPtrStringRangeFunction: | 2747 * xmlXPtrStringRangeFunction: |
2727 * @ctxt: the XPointer Parser context | 2748 * @ctxt: the XPointer Parser context |
2728 * @nargs: the number of args | 2749 * @nargs: the number of args |
2729 * | 2750 * |
2730 * Function implementing the string-range() function | 2751 * Function implementing the string-range() function |
2731 * range as described in 5.4.2 | 2752 * range as described in 5.4.2 |
2732 * | 2753 * |
2733 * ------------------------------ | 2754 * ------------------------------ |
2734 * [Definition: For each location in the location-set argument, | 2755 * [Definition: For each location in the location-set argument, |
2735 * string-range returns a set of string ranges, a set of substrings in a | 2756 * string-range returns a set of string ranges, a set of substrings in a |
2736 * string. Specifically, the string-value of the location is searched for | 2757 * string. Specifically, the string-value of the location is searched for |
2737 * substrings that match the string argument, and the resulting location-set | 2758 * substrings that match the string argument, and the resulting location-set |
2738 * will contain a range location for each non-overlapping match.] | 2759 * will contain a range location for each non-overlapping match.] |
2739 * An empty string is considered to match before each character of the | 2760 * An empty string is considered to match before each character of the |
2740 * string-value and after the final character. Whitespace in a string | 2761 * string-value and after the final character. Whitespace in a string |
2741 * is matched literally, with no normalization except that provided by | 2762 * is matched literally, with no normalization except that provided by |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2790 } | 2811 } |
2791 CHECK_TYPE(XPATH_STRING); | 2812 CHECK_TYPE(XPATH_STRING); |
2792 string = valuePop(ctxt); | 2813 string = valuePop(ctxt); |
2793 if ((ctxt->value == NULL) || | 2814 if ((ctxt->value == NULL) || |
2794 ((ctxt->value->type != XPATH_LOCATIONSET) && | 2815 ((ctxt->value->type != XPATH_LOCATIONSET) && |
2795 (ctxt->value->type != XPATH_NODESET))) | 2816 (ctxt->value->type != XPATH_NODESET))) |
2796 XP_ERROR(XPATH_INVALID_TYPE) | 2817 XP_ERROR(XPATH_INVALID_TYPE) |
2797 | 2818 |
2798 set = valuePop(ctxt); | 2819 set = valuePop(ctxt); |
2799 newset = xmlXPtrLocationSetCreate(NULL); | 2820 newset = xmlXPtrLocationSetCreate(NULL); |
| 2821 if (newset == NULL) { |
| 2822 xmlXPathFreeObject(set); |
| 2823 XP_ERROR(XPATH_MEMORY_ERROR); |
| 2824 } |
2800 if (set->nodesetval == NULL) { | 2825 if (set->nodesetval == NULL) { |
2801 goto error; | 2826 goto error; |
2802 } | 2827 } |
2803 if (set->type == XPATH_NODESET) { | 2828 if (set->type == XPATH_NODESET) { |
2804 xmlXPathObjectPtr tmp; | 2829 xmlXPathObjectPtr tmp; |
2805 | 2830 |
2806 /* | 2831 /* |
2807 * First convert to a location set | 2832 * First convert to a location set |
2808 */ | 2833 */ |
2809 tmp = xmlXPtrNewLocationSetNodeSet(set->nodesetval); | 2834 tmp = xmlXPtrNewLocationSetNodeSet(set->nodesetval); |
2810 xmlXPathFreeObject(set); | 2835 xmlXPathFreeObject(set); |
| 2836 if (tmp == NULL) |
| 2837 XP_ERROR(XPATH_MEMORY_ERROR) |
2811 set = tmp; | 2838 set = tmp; |
2812 } | 2839 } |
2813 oldset = (xmlLocationSetPtr) set->user; | 2840 oldset = (xmlLocationSetPtr) set->user; |
2814 | 2841 |
2815 /* | 2842 /* |
2816 * The loop is to search for each element in the location set | 2843 * The loop is to search for each element in the location set |
2817 * the list of location set corresponding to that search | 2844 * the list of location set corresponding to that search |
2818 */ | 2845 */ |
2819 for (i = 0;i < oldset->locNr;i++) { | 2846 for (i = 0;i < oldset->locNr;i++) { |
2820 #ifdef DEBUG_RANGES | 2847 #ifdef DEBUG_RANGES |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2885 xmlXPathFreeObject(string); | 2912 xmlXPathFreeObject(string); |
2886 if (position) xmlXPathFreeObject(position); | 2913 if (position) xmlXPathFreeObject(position); |
2887 if (number) xmlXPathFreeObject(number); | 2914 if (number) xmlXPathFreeObject(number); |
2888 } | 2915 } |
2889 | 2916 |
2890 /** | 2917 /** |
2891 * xmlXPtrEvalRangePredicate: | 2918 * xmlXPtrEvalRangePredicate: |
2892 * @ctxt: the XPointer Parser context | 2919 * @ctxt: the XPointer Parser context |
2893 * | 2920 * |
2894 * [8] Predicate ::= '[' PredicateExpr ']' | 2921 * [8] Predicate ::= '[' PredicateExpr ']' |
2895 * [9] PredicateExpr ::= Expr | 2922 * [9] PredicateExpr ::= Expr |
2896 * | 2923 * |
2897 * Evaluate a predicate as in xmlXPathEvalPredicate() but for | 2924 * Evaluate a predicate as in xmlXPathEvalPredicate() but for |
2898 * a Location Set instead of a node set | 2925 * a Location Set instead of a node set |
2899 */ | 2926 */ |
2900 void | 2927 void |
2901 xmlXPtrEvalRangePredicate(xmlXPathParserContextPtr ctxt) { | 2928 xmlXPtrEvalRangePredicate(xmlXPathParserContextPtr ctxt) { |
2902 const xmlChar *cur; | 2929 const xmlChar *cur; |
2903 xmlXPathObjectPtr res; | 2930 xmlXPathObjectPtr res; |
2904 xmlXPathObjectPtr obj, tmp; | 2931 xmlXPathObjectPtr obj, tmp; |
2905 xmlLocationSetPtr newset = NULL; | 2932 xmlLocationSetPtr newset = NULL; |
(...skipping 28 matching lines...) Expand all Loading... |
2934 xmlXPathFreeObject(res); | 2961 xmlXPathFreeObject(res); |
2935 valuePush(ctxt, obj); | 2962 valuePush(ctxt, obj); |
2936 CHECK_ERROR; | 2963 CHECK_ERROR; |
2937 } else { | 2964 } else { |
2938 /* | 2965 /* |
2939 * Save the expression pointer since we will have to evaluate | 2966 * Save the expression pointer since we will have to evaluate |
2940 * it multiple times. Initialize the new set. | 2967 * it multiple times. Initialize the new set. |
2941 */ | 2968 */ |
2942 cur = ctxt->cur; | 2969 cur = ctxt->cur; |
2943 newset = xmlXPtrLocationSetCreate(NULL); | 2970 newset = xmlXPtrLocationSetCreate(NULL); |
2944 » | 2971 |
2945 for (i = 0; i < oldset->locNr; i++) { | 2972 for (i = 0; i < oldset->locNr; i++) { |
2946 ctxt->cur = cur; | 2973 ctxt->cur = cur; |
2947 | 2974 |
2948 /* | 2975 /* |
2949 * Run the evaluation with a node list made of a single item | 2976 * Run the evaluation with a node list made of a single item |
2950 * in the nodeset. | 2977 * in the nodeset. |
2951 */ | 2978 */ |
2952 ctxt->context->node = oldset->locTab[i]->user; | 2979 ctxt->context->node = oldset->locTab[i]->user; |
2953 tmp = xmlXPathNewNodeSet(ctxt->context->node); | 2980 tmp = xmlXPathNewNodeSet(ctxt->context->node); |
2954 valuePush(ctxt, tmp); | 2981 valuePush(ctxt, tmp); |
(...skipping 15 matching lines...) Expand all Loading... |
2970 | 2997 |
2971 /* | 2998 /* |
2972 * Cleanup | 2999 * Cleanup |
2973 */ | 3000 */ |
2974 if (res != NULL) | 3001 if (res != NULL) |
2975 xmlXPathFreeObject(res); | 3002 xmlXPathFreeObject(res); |
2976 if (ctxt->value == tmp) { | 3003 if (ctxt->value == tmp) { |
2977 res = valuePop(ctxt); | 3004 res = valuePop(ctxt); |
2978 xmlXPathFreeObject(res); | 3005 xmlXPathFreeObject(res); |
2979 } | 3006 } |
2980 » | 3007 |
2981 ctxt->context->node = NULL; | 3008 ctxt->context->node = NULL; |
2982 } | 3009 } |
2983 | 3010 |
2984 /* | 3011 /* |
2985 * The result is used as the new evaluation set. | 3012 * The result is used as the new evaluation set. |
2986 */ | 3013 */ |
2987 xmlXPathFreeObject(obj); | 3014 xmlXPathFreeObject(obj); |
2988 ctxt->context->node = NULL; | 3015 ctxt->context->node = NULL; |
2989 ctxt->context->contextSize = -1; | 3016 ctxt->context->contextSize = -1; |
2990 ctxt->context->proximityPosition = -1; | 3017 ctxt->context->proximityPosition = -1; |
2991 valuePush(ctxt, xmlXPtrWrapLocationSet(newset)); | 3018 valuePush(ctxt, xmlXPtrWrapLocationSet(newset)); |
2992 } | 3019 } |
2993 if (CUR != ']') { | 3020 if (CUR != ']') { |
2994 XP_ERROR(XPATH_INVALID_PREDICATE_ERROR); | 3021 XP_ERROR(XPATH_INVALID_PREDICATE_ERROR); |
2995 } | 3022 } |
2996 | 3023 |
2997 NEXT; | 3024 NEXT; |
2998 SKIP_BLANKS; | 3025 SKIP_BLANKS; |
2999 } | 3026 } |
3000 | 3027 |
3001 #define bottom_xpointer | 3028 #define bottom_xpointer |
3002 #include "elfgcchack.h" | 3029 #include "elfgcchack.h" |
3003 #endif | 3030 #endif |
3004 | 3031 |
OLD | NEW |