diff options
author | William M. Brack <wbrack@src.gnome.org> | 2003-12-29 02:52:11 +0000 |
---|---|---|
committer | William M. Brack <wbrack@src.gnome.org> | 2003-12-29 02:52:11 +0000 |
commit | 081719182de3d15e6a438f32fdc3d1ca240a08e8 (patch) | |
tree | e92318bcd8d4b98d7782b1c89a5f31f4e100c907 /xpath.c | |
parent | b15351e54d29b139f40a32760d635258f586f7a3 (diff) | |
download | libxml2-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.c | 240 |
1 files changed, 161 insertions, 79 deletions
@@ -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 } |