summaryrefslogtreecommitdiff
path: root/xpath.c
diff options
context:
space:
mode:
authorWilliam M. Brack <wbrack@src.gnome.org>2003-12-29 02:52:11 +0000
committerWilliam M. Brack <wbrack@src.gnome.org>2003-12-29 02:52:11 +0000
commit081719182de3d15e6a438f32fdc3d1ca240a08e8 (patch)
treee92318bcd8d4b98d7782b1c89a5f31f4e100c907 /xpath.c
parentb15351e54d29b139f40a32760d635258f586f7a3 (diff)
downloadlibxml2-081719182de3d15e6a438f32fdc3d1ca240a08e8.tar.gz
edited a couple of comments in accordance with posting on the mailing list
* xmlschemas.c: edited a couple of comments in accordance with posting on the mailing list (no logic change) * xpointer.c: working on Bug 129967, added check for NULL nodeset to prevent crash. Further work required. * xpath.c: working on Bug 129967, added code to handle XPATH_LOCATIONSET in RANGETO code, also added code to handle it in xmlXPathEvaluatePredicateResult. Further work required.
Diffstat (limited to 'xpath.c')
-rw-r--r--xpath.c240
1 files changed, 161 insertions, 79 deletions
diff --git a/xpath.c b/xpath.c
index d6205438..0fa53b80 100644
--- a/xpath.c
+++ b/xpath.c
@@ -175,7 +175,9 @@ static int xmlXPathDisableOptimizer = 0;
* *
************************************************************************/
-
+/*
+ * The array xmlXPathErrorMessages corresponds to the enum xmlXPathError
+ */
static const char *xmlXPathErrorMessages[] = {
"Ok\n",
"Number encoding\n",
@@ -400,9 +402,9 @@ typedef enum {
typedef struct _xmlXPathStepOp xmlXPathStepOp;
typedef xmlXPathStepOp *xmlXPathStepOpPtr;
struct _xmlXPathStepOp {
- xmlXPathOp op;
- int ch1;
- int ch2;
+ xmlXPathOp op; /* The identifier of the operation */
+ int ch1; /* First child */
+ int ch2; /* Second child */
int value;
int value2;
int value3;
@@ -413,11 +415,11 @@ struct _xmlXPathStepOp {
};
struct _xmlXPathCompExpr {
- int nbStep;
- int maxStep;
- xmlXPathStepOp *steps; /* ops for computation */
- int last;
- xmlChar *expr;
+ int nbStep; /* Number of steps in this expression */
+ int maxStep; /* Maximum number of steps allocated */
+ xmlXPathStepOp *steps; /* ops for computation of this expression */
+ int last; /* index of last step in expression */
+ xmlChar *expr; /* the expression being computed */
#ifdef DEBUG_EVAL_COUNTS
int nb;
xmlChar *string;
@@ -516,7 +518,7 @@ xmlXPathFreeCompExpr(xmlXPathCompExprPtr comp)
* @value4: the first string value
* @value5: the second string value
*
- * Add an step to an XPath Compiled Expression
+ * Add a step to an XPath Compiled Expression
*
* Returns -1 in case of failure, the index otherwise
*/
@@ -564,7 +566,7 @@ xmlXPathCompSwap(xmlXPathStepOpPtr op) {
#ifndef LIBXML_THREAD_ENABLED
/*
* Since this manipulates possibly shared variables, this is
- * disable if one detects that the library is used in a multithreaded
+ * disabled if one detects that the library is used in a multithreaded
* application
*/
if (xmlXPathDisableOptimizer)
@@ -590,7 +592,8 @@ xmlXPathCompExprAdd(ctxt->comp, -1, -1, (op), (val), (val2), 0 ,NULL ,NULL)
xmlXPathCompExprAdd(ctxt->comp, (ch), -1, (op), (val), (val2), 0 ,NULL ,NULL)
#define PUSH_BINARY_EXPR(op, ch1, ch2, val, val2) \
-xmlXPathCompExprAdd(ctxt->comp, (ch1), (ch2), (op), (val), (val2), 0 ,NULL ,NULL)
+xmlXPathCompExprAdd(ctxt->comp, (ch1), (ch2), (op), \
+ (val), (val2), 0 ,NULL ,NULL)
/************************************************************************
* *
@@ -1117,7 +1120,10 @@ xmlXPathPopBoolean (xmlXPathParserContextPtr ctxt) {
xmlXPathSetError(ctxt, XPATH_INVALID_OPERAND);
return(0);
}
- ret = xmlXPathCastToBoolean(obj);
+ if (obj->type != XPATH_BOOLEAN)
+ ret = xmlXPathCastToBoolean(obj);
+ else
+ ret = obj->boolval;
xmlXPathFreeObject(obj);
return(ret);
}
@@ -1141,7 +1147,10 @@ xmlXPathPopNumber (xmlXPathParserContextPtr ctxt) {
xmlXPathSetError(ctxt, XPATH_INVALID_OPERAND);
return(0);
}
- ret = xmlXPathCastToNumber(obj);
+ if (obj->type != XPATH_NUMBER)
+ ret = xmlXPathCastToNumber(obj);
+ else
+ ret = obj->floatval;
xmlXPathFreeObject(obj);
return(ret);
}
@@ -1165,7 +1174,7 @@ xmlXPathPopString (xmlXPathParserContextPtr ctxt) {
xmlXPathSetError(ctxt, XPATH_INVALID_OPERAND);
return(NULL);
}
- ret = xmlXPathCastToString(obj);
+ ret = xmlXPathCastToString(obj); /* this does required strdup */
/* TODO: needs refactoring somewhere else */
if (obj->stringval == ret)
obj->stringval = NULL;
@@ -1418,10 +1427,10 @@ xmlXPathFormatNumber(double number, char buffer[], int buffersize)
* Call this routine to speed up XPath computation on static documents.
* This stamps all the element nodes with the document order
* Like for line information, the order is kept in the element->content
- * field, the value stored is actually - the node number (startting at -1)
- * to be able to differenciate from line numbers.
+ * field, the value stored is actually - the node number (starting at -1)
+ * to be able to differentiate from line numbers.
*
- * Returns the number of element found in the document or -1 in case
+ * Returns the number of elements found in the document or -1 in case
* of error.
*/
long
@@ -1469,7 +1478,7 @@ xmlXPathOrderDocElems(xmlDocPtr doc) {
* Compare two nodes w.r.t document order
*
* Returns -2 in case of error 1 if first point < second point, 0 if
- * that's the same node, -1 otherwise
+ * it's the same node, -1 otherwise
*/
int
xmlXPathCmpNodes(xmlNodePtr node1, xmlNodePtr node2) {
@@ -1662,9 +1671,9 @@ xmlXPathNodeSetDupNs(xmlNodePtr node, xmlNsPtr ns) {
* xmlXPathNodeSetFreeNs:
* @ns: the XPath namespace node found in a nodeset.
*
- * Namespace node in libxml don't match the XPath semantic. In a node set
+ * Namespace nodes in libxml don't match the XPath semantic. In a node set
* the namespace nodes are duplicated and the next pointer is set to the
- * parent node in the XPath semantic. Check if such a node need to be freed
+ * parent node in the XPath semantic. Check if such a node needs to be freed
*/
void
xmlXPathNodeSetFreeNs(xmlNsPtr ns) {
@@ -1772,9 +1781,9 @@ xmlXPathNodeSetAddNs(xmlNodeSetPtr cur, xmlNodePtr node, xmlNsPtr ns) {
(node->type != XML_ELEMENT_NODE))
return;
- /* @@ with_ns to check wether namespace nodes should be looked at @@ */
+ /* @@ with_ns to check whether namespace nodes should be looked at @@ */
/*
- * check against doublons
+ * prevent duplicates
*/
for (i = 0;i < cur->nodeNr;i++) {
if ((cur->nodeTab[i] != NULL) &&
@@ -1830,9 +1839,9 @@ xmlXPathNodeSetAdd(xmlNodeSetPtr cur, xmlNodePtr val) {
return; /* an XSLT fake node */
#endif
- /* @@ with_ns to check wether namespace nodes should be looked at @@ */
+ /* @@ with_ns to check whether namespace nodes should be looked at @@ */
/*
- * check against doublons
+ * prevent duplcates
*/
for (i = 0;i < cur->nodeNr;i++)
if (cur->nodeTab[i] == val) return;
@@ -1888,7 +1897,7 @@ xmlXPathNodeSetAddUnique(xmlNodeSetPtr cur, xmlNodePtr val) {
return; /* an XSLT fake node */
#endif
- /* @@ with_ns to check wether namespace nodes should be looked at @@ */
+ /* @@ with_ns to check whether namespace nodes should be looked at @@ */
/*
* grow the nodeTab if needed
*/
@@ -1942,12 +1951,12 @@ xmlXPathNodeSetMerge(xmlNodeSetPtr val1, xmlNodeSetPtr val2) {
val1 = xmlXPathNodeSetCreate(NULL);
}
- /* @@ with_ns to check wether namespace nodes should be looked at @@ */
+ /* @@ with_ns to check whether namespace nodes should be looked at @@ */
initNr = val1->nodeNr;
for (i = 0;i < val2->nodeNr;i++) {
/*
- * check against doublons
+ * check against duplicates
*/
skip = 0;
for (j = 0; j < initNr; j++) {
@@ -2025,7 +2034,7 @@ xmlXPathNodeSetMergeUnique(xmlNodeSetPtr val1, xmlNodeSetPtr val2) {
val1 = xmlXPathNodeSetCreate(NULL);
}
- /* @@ with_ns to check wether namespace nodes should be looked at @@ */
+ /* @@ with_ns to check whether namespace nodes should be looked at @@ */
for (i = 0;i < val2->nodeNr;i++) {
/*
@@ -2080,12 +2089,12 @@ xmlXPathNodeSetDel(xmlNodeSetPtr cur, xmlNodePtr val) {
if (val == NULL) return;
/*
- * check against doublons
+ * find node in nodeTab
*/
for (i = 0;i < cur->nodeNr;i++)
if (cur->nodeTab[i] == val) break;
- if (i >= cur->nodeNr) {
+ if (i >= cur->nodeNr) { /* not found */
#ifdef DEBUG
xmlGenericError(xmlGenericErrorContext,
"xmlXPathNodeSetDel: Node %s wasn't found in NodeList\n",
@@ -2134,7 +2143,7 @@ xmlXPathFreeNodeSet(xmlNodeSetPtr obj) {
if (obj->nodeTab != NULL) {
int i;
- /* @@ with_ns to check wether namespace nodes should be looked at @@ */
+ /* @@ with_ns to check whether namespace nodes should be looked at @@ */
for (i = 0;i < obj->nodeNr;i++)
if ((obj->nodeTab[i] != NULL) &&
(obj->nodeTab[i]->type == XML_NAMESPACE_DECL))
@@ -2176,7 +2185,7 @@ xmlXPathFreeValueTree(xmlNodeSetPtr obj) {
/**
* xmlGenericErrorContextNodeSet:
* @output: a FILE * for the output
- * @obj: the xmlNodeSetPtr to free
+ * @obj: the xmlNodeSetPtr to display
*
* Quick display of a NodeSet
*/
@@ -2235,7 +2244,7 @@ xmlXPathNewNodeSet(xmlNodePtr val) {
ret->type = XPATH_NODESET;
ret->boolval = 0;
ret->nodesetval = xmlXPathNodeSetCreate(val);
- /* @@ with_ns to check wether namespace nodes should be looked at @@ */
+ /* @@ with_ns to check whether namespace nodes should be looked at @@ */
return(ret);
}
@@ -2834,7 +2843,7 @@ xmlXPathRegisteredFuncsCleanup(xmlXPathContextPtr ctxt) {
/************************************************************************
* *
- * Routines to handle Variable *
+ * Routines to handle Variables *
* *
************************************************************************/
@@ -3065,7 +3074,7 @@ xmlXPathRegisteredNsCleanup(xmlXPathContextPtr ctxt) {
* *
************************************************************************/
-/* Allocations are terrible, one need to optimize all this !!! */
+/* Allocations are terrible, one needs to optimize all this !!! */
/**
* xmlXPathNewFloat:
@@ -4031,8 +4040,6 @@ xmlXPathNodeValHash(xmlNodePtr node) {
break;
}
if ((string != NULL) && (string[0] != 0)) {
- if (string[0] == 0)
- return(0);
if (len == 1) {
return(ret + (((unsigned int) string[0]) << 8));
}
@@ -4659,7 +4666,8 @@ xmlXPathEqualValuesCommon(xmlXPathParserContextPtr ctxt,
/* no break on purpose */
case XPATH_NUMBER:
/* Hand check NaN and Infinity equalities */
- if (xmlXPathIsNaN(arg1->floatval) || xmlXPathIsNaN(arg2->floatval)) {
+ if (xmlXPathIsNaN(arg1->floatval) ||
+ xmlXPathIsNaN(arg2->floatval)) {
ret = 0;
} else if (xmlXPathIsInf(arg1->floatval) == 1) {
if (xmlXPathIsInf(arg2->floatval) == 1)
@@ -4719,7 +4727,8 @@ xmlXPathEqualValuesCommon(xmlXPathParserContextPtr ctxt,
xmlXPathNumberFunction(ctxt, 1);
arg1 = valuePop(ctxt);
/* Hand check NaN and Infinity equalities */
- if (xmlXPathIsNaN(arg1->floatval) || xmlXPathIsNaN(arg2->floatval)) {
+ if (xmlXPathIsNaN(arg1->floatval) ||
+ xmlXPathIsNaN(arg2->floatval)) {
ret = 0;
} else if (xmlXPathIsInf(arg1->floatval) == 1) {
if (xmlXPathIsInf(arg2->floatval) == 1)
@@ -5539,7 +5548,7 @@ xmlXPathNextAncestor(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
if ((ns->next != NULL) &&
(ns->next->type != XML_NAMESPACE_DECL))
return((xmlNodePtr) ns->next);
- /* Bad, how did that namespace ended-up there ? */
+ /* Bad, how did that namespace end up here ? */
return(NULL);
}
}
@@ -5583,7 +5592,7 @@ xmlXPathNextAncestor(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
if ((ns->next != NULL) &&
(ns->next->type != XML_NAMESPACE_DECL))
return((xmlNodePtr) ns->next);
- /* Bad, how did that namespace ended-up there ? */
+ /* Bad, how did that namespace end up here ? */
return(NULL);
}
case XML_DOCUMENT_NODE:
@@ -6295,7 +6304,7 @@ xmlXPathNameFunction(xmlXPathParserContextPtr ctxt, int nargs)
*
* Implement the string() XPath function
* string string(object?)
- * he string function converts an object to a string as follows:
+ * The string function converts an object to a string as follows:
* - A node-set is converted to a string by returning the value of
* the node in the node-set that is first in document order.
* If the node-set is empty, an empty string is returned.
@@ -6855,7 +6864,7 @@ xmlXPathTranslateFunction(xmlXPathParserContextPtr ctxt, int nargs) {
*
* Implement the boolean() XPath function
* boolean boolean(object)
- * he boolean function converts its argument to a boolean as follows:
+ * The boolean function converts its argument to a boolean as follows:
* - a number is true if and only if it is neither positive or
* negative zero nor NaN
* - a node-set is true if and only if it is non-empty
@@ -7019,14 +7028,12 @@ xmlXPathSumFunction(xmlXPathParserContextPtr ctxt, int nargs) {
XP_ERROR(XPATH_INVALID_TYPE);
cur = valuePop(ctxt);
- if ((cur->nodesetval == NULL) || (cur->nodesetval->nodeNr == 0)) {
- valuePush(ctxt, xmlXPathNewFloat(0.0));
- } else {
+ if ((cur->nodesetval != NULL) && (cur->nodesetval->nodeNr != 0)) {
for (i = 0; i < cur->nodesetval->nodeNr; i++) {
res += xmlXPathCastNodeToNumber(cur->nodesetval->nodeTab[i]);
}
- valuePush(ctxt, xmlXPathNewFloat(res));
}
+ valuePush(ctxt, xmlXPathNewFloat(res));
xmlXPathFreeObject(cur);
}
@@ -7141,7 +7148,7 @@ xmlXPathRoundFunction(xmlXPathParserContextPtr ctxt, int nargs) {
************************************************************************/
/*
- * a couple of forward declarations since we use a recursive call based
+ * a few forward declarations since we use a recursive call based
* implementation.
*/
static void xmlXPathCompileExpr(xmlXPathParserContextPtr ctxt);
@@ -7226,8 +7233,8 @@ xmlXPathCurrentChar(xmlXPathParserContextPtr ctxt, int *len) {
}
encoding_error:
/*
- * If we detect an UTF8 error that probably mean that the
- * input encoding didn't get properly advertized in the
+ * If we detect an UTF8 error that probably means that the
+ * input encoding didn't get properly advertised in the
* declaration header. Report the error and switch the encoding
* to ISO-Latin-1 (if you don't like this policy, just declare the
* encoding !)
@@ -7713,7 +7720,7 @@ xmlXPathCompLiteral(xmlXPathParserContextPtr ctxt) {
* Parse a VariableReference, evaluate it and push it on the stack.
*
* The variable bindings consist of a mapping from variable names
- * to variable values. The value of a variable is an object, which
+ * to variable values. The value of a variable is an object, which can be
* of any of the types that are possible for the value of an expression,
* and may also be of additional types not specified here.
*
@@ -7994,7 +8001,7 @@ xmlXPathCompPathExpr(xmlXPathParserContextPtr ctxt) {
* - a element name
* We do an a priori analysis here rather than having to
* maintain parsed token content through the recursive function
- * calls. This looks uglier but makes the code quite easier to
+ * calls. This looks uglier but makes the code easier to
* read/write/debug.
*/
SKIP_BLANKS;
@@ -8073,7 +8080,7 @@ xmlXPathCompPathExpr(xmlXPathParserContextPtr ctxt) {
}
xmlFree(name);
} else {
- /* make sure all cases are covered explicitely */
+ /* make sure all cases are covered explicitly */
XP_ERROR(XPATH_EXPR_ERROR);
}
}
@@ -8435,7 +8442,7 @@ xmlXPathCompPredicate(xmlXPathParserContextPtr ctxt, int filter) {
* | 'processing-instruction'
* | 'node'
*
- * Returns the name found and update @test, @type and @prefix appropriately
+ * Returns the name found and updates @test, @type and @prefix appropriately
*/
static xmlChar *
xmlXPathCompNodeTest(xmlXPathParserContextPtr ctxt, xmlXPathTestVal *test,
@@ -8891,11 +8898,11 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op);
*
* This is the function implementing a step: based on the current list
* of nodes, it builds up a new list, looking at all nodes under that
- * axis and selecting them it also do the predicate filtering
+ * axis and selecting them. It also does the predicate filtering
*
* Pushes the new NodeSet resulting from the search.
*
- * Returns the number of node traversed
+ * Returns the number of nodes traversed
*/
static int
xmlXPathNodeCollectAndTest(xmlXPathParserContextPtr ctxt,
@@ -9313,7 +9320,7 @@ xmlXPathNodeCollectAndTest(xmlXPathParserContextPtr ctxt,
*
* This is the function implementing a step: based on the current list
* of nodes, it builds up a new list, looking at all nodes under that
- * axis and selecting them it also do the predicate filtering
+ * axis and selecting them. It also does the predicate filtering
*
* Pushes the new NodeSet resulting from the search.
* Returns the number of node traversed
@@ -9830,7 +9837,7 @@ xmlXPathCompOpEvalFirst(xmlXPathParserContextPtr ctxt,
* Evaluate the Precompiled XPath operation searching only the last
* element in document order
*
- * Returns the number of node traversed
+ * Returns the number of nodes traversed
*/
static int
xmlXPathCompOpEvalLast(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op,
@@ -9965,7 +9972,7 @@ xmlXPathCompOpEvalLast(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op,
* @op: an XPath compiled operation
*
* Evaluate the Precompiled XPath operation
- * Returns the number of node traversed
+ * Returns the number of nodes traversed
*/
static int
xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op)
@@ -10537,8 +10544,8 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op)
CHECK_ERROR0;
/*
- * The result of the evaluation need to be tested to
- * decided whether the filter succeeded or not
+ * The result of the evaluation needs to be tested to
+ * decide whether the filter succeeded or not
*/
res = valuePop(ctxt);
if (xmlXPathEvaluatePredicateResult(ctxt, res)) {
@@ -10584,7 +10591,8 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op)
xmlXPathObjectPtr range;
xmlXPathObjectPtr res, obj;
xmlXPathObjectPtr tmp;
- xmlLocationSetPtr newset = NULL;
+ xmlLocationSetPtr newlocset = NULL;
+ xmlLocationSetPtr oldlocset;
xmlNodeSetPtr oldset;
int i;
@@ -10594,22 +10602,40 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op)
if (op->ch2 == -1)
return (total);
- CHECK_TYPE0(XPATH_NODESET);
- obj = valuePop(ctxt);
- oldset = obj->nodesetval;
- ctxt->context->node = NULL;
+ if (ctxt->value->type == XPATH_LOCATIONSET) {
+ /*
+ * Extract the old locset, and then evaluate the result of the
+ * expression for all the element in the locset. use it to grow
+ * up a new locset.
+ */
+ CHECK_TYPE0(XPATH_LOCATIONSET);
+ obj = valuePop(ctxt);
+ oldlocset = obj->user;
+ ctxt->context->node = NULL;
- newset = xmlXPtrLocationSetCreate(NULL);
+ if ((oldlocset == NULL) || (oldlocset->locNr == 0)) {
+ ctxt->context->contextSize = 0;
+ ctxt->context->proximityPosition = 0;
+ total += xmlXPathCompOpEval(ctxt,&comp->steps[op->ch2]);
+ res = valuePop(ctxt);
+ if (res != NULL)
+ xmlXPathFreeObject(res);
+ valuePush(ctxt, obj);
+ CHECK_ERROR0;
+ return (total);
+ }
+ newlocset = xmlXPtrLocationSetCreate(NULL);
- if (oldset != NULL) {
- for (i = 0; i < oldset->nodeNr; i++) {
+ for (i = 0; i < oldlocset->locNr; i++) {
/*
- * Run the evaluation with a node list made of a single item
- * in the nodeset.
+ * Run the evaluation with a node list made of a
+ * single item in the nodelocset.
*/
- ctxt->context->node = oldset->nodeTab[i];
+ ctxt->context->node = oldlocset->locTab[i]->user;
tmp = xmlXPathNewNodeSet(ctxt->context->node);
valuePush(ctxt, tmp);
+ ctxt->context->contextSize = oldlocset->locNr;
+ ctxt->context->proximityPosition = i + 1;
if (op->ch2 != -1)
total +=
@@ -10622,11 +10648,10 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op)
* decided whether the filter succeeded or not
*/
res = valuePop(ctxt);
- range =
- xmlXPtrNewRangeNodeObject(oldset->nodeTab[i],
- res);
- if (range != NULL) {
- xmlXPtrLocationSetAdd(newset, range);
+ if (xmlXPathEvaluatePredicateResult(ctxt, res)) {
+ xmlXPtrLocationSetAdd(newlocset,
+ xmlXPathObjectCopy
+ (oldlocset->locTab[i]));
}
/*
@@ -10641,6 +10666,55 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op)
ctxt->context->node = NULL;
}
+ } else { /* Not a location set */
+ CHECK_TYPE0(XPATH_NODESET);
+ obj = valuePop(ctxt);
+ oldset = obj->nodesetval;
+ ctxt->context->node = NULL;
+
+ newlocset = xmlXPtrLocationSetCreate(NULL);
+
+ if (oldset != NULL) {
+ for (i = 0; i < oldset->nodeNr; i++) {
+ /*
+ * Run the evaluation with a node list made of a single item
+ * in the nodeset.
+ */
+ ctxt->context->node = oldset->nodeTab[i];
+ tmp = xmlXPathNewNodeSet(ctxt->context->node);
+ valuePush(ctxt, tmp);
+
+ if (op->ch2 != -1)
+ total +=
+ xmlXPathCompOpEval(ctxt,
+ &comp->steps[op->ch2]);
+ CHECK_ERROR0;
+
+ /*
+ * The result of the evaluation need to be tested to
+ * decided whether the filter succeeded or not
+ */
+ res = valuePop(ctxt);
+ range =
+ xmlXPtrNewRangeNodeObject(oldset->nodeTab[i],
+ res);
+ if (range != NULL) {
+ xmlXPtrLocationSetAdd(newlocset, range);
+ }
+
+ /*
+ * Cleanup
+ */
+ if (res != NULL)
+ xmlXPathFreeObject(res);
+ if (ctxt->value == tmp) {
+ res = valuePop(ctxt);
+ xmlXPathFreeObject(res);
+ }
+
+ ctxt->context->node = NULL;
+ }
+ }
}
/*
@@ -10650,7 +10724,7 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op)
ctxt->context->node = NULL;
ctxt->context->contextSize = -1;
ctxt->context->proximityPosition = -1;
- valuePush(ctxt, xmlXPtrWrapLocationSet(newset));
+ valuePush(ctxt, xmlXPtrWrapLocationSet(newlocset));
return (total);
}
#endif /* LIBXML_XPTR_ENABLED */
@@ -10771,6 +10845,14 @@ xmlXPathEvaluatePredicateResult(xmlXPathParserContextPtr ctxt,
case XPATH_STRING:
return((res->stringval != NULL) &&
(xmlStrlen(res->stringval) != 0));
+#ifdef LIBXML_XPTR_ENABLED
+ case XPATH_LOCATIONSET:{
+ xmlLocationSetPtr ptr = res->user;
+ if (ptr == NULL)
+ return(0);
+ return (ptr->locNr != 0);
+ }
+#endif
default:
STRANGE
}