| 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 |