* xmlXPathCompareValues: * @ctxt: the XPath Parser context * @inf: less than (1) or greater than (0) * @strict: is the comparison strict * * Implement the compare operation on XPath objects: * @arg1 < @arg2 (1, 1, ... * @arg1 <= @arg2 (1, 0, ... * @arg1 > @arg2 (0, 1, ... * @arg1 >= @arg2 (0, 0, ... * * When neither object to be compared is a node-set and th
| 6296 | * Returns 1 if the comparison succeeded, 0 if it failed |
| 6297 | */ |
| 6298 | int |
| 6299 | xmlXPathCompareValues(xmlXPathParserContextPtr ctxt, int inf, int strict) { |
| 6300 | int ret = 0, arg1i = 0, arg2i = 0; |
| 6301 | xmlXPathObjectPtr arg1, arg2; |
| 6302 | |
| 6303 | if ((ctxt == NULL) || (ctxt->context == NULL)) return(0); |
| 6304 | arg2 = valuePop(ctxt); |
| 6305 | arg1 = valuePop(ctxt); |
| 6306 | if ((arg1 == NULL) || (arg2 == NULL)) { |
| 6307 | if (arg1 != NULL) |
| 6308 | xmlXPathReleaseObject(ctxt->context, arg1); |
| 6309 | else |
| 6310 | xmlXPathReleaseObject(ctxt->context, arg2); |
| 6311 | XP_ERROR0(XPATH_INVALID_OPERAND); |
| 6312 | } |
| 6313 | |
| 6314 | if ((arg2->type == XPATH_NODESET) || (arg2->type == XPATH_XSLT_TREE) || |
| 6315 | (arg1->type == XPATH_NODESET) || (arg1->type == XPATH_XSLT_TREE)) { |
| 6316 | /* |
| 6317 | * If either argument is a XPATH_NODESET or XPATH_XSLT_TREE the two arguments |
| 6318 | * are not freed from within this routine; they will be freed from the |
| 6319 | * called routine, e.g. xmlXPathCompareNodeSets or xmlXPathCompareNodeSetValue |
| 6320 | */ |
| 6321 | if (((arg2->type == XPATH_NODESET) || (arg2->type == XPATH_XSLT_TREE)) && |
| 6322 | ((arg1->type == XPATH_NODESET) || (arg1->type == XPATH_XSLT_TREE))){ |
| 6323 | ret = xmlXPathCompareNodeSets(ctxt, inf, strict, arg1, arg2); |
| 6324 | } else { |
| 6325 | if ((arg1->type == XPATH_NODESET) || (arg1->type == XPATH_XSLT_TREE)) { |
| 6326 | ret = xmlXPathCompareNodeSetValue(ctxt, inf, strict, |
| 6327 | arg1, arg2); |
| 6328 | } else { |
| 6329 | ret = xmlXPathCompareNodeSetValue(ctxt, !inf, strict, |
| 6330 | arg2, arg1); |
| 6331 | } |
| 6332 | } |
| 6333 | return(ret); |
| 6334 | } |
| 6335 | |
| 6336 | if (arg1->type != XPATH_NUMBER) { |
| 6337 | valuePush(ctxt, arg1); |
| 6338 | xmlXPathNumberFunction(ctxt, 1); |
| 6339 | arg1 = valuePop(ctxt); |
| 6340 | } |
| 6341 | if (arg2->type != XPATH_NUMBER) { |
| 6342 | valuePush(ctxt, arg2); |
| 6343 | xmlXPathNumberFunction(ctxt, 1); |
| 6344 | arg2 = valuePop(ctxt); |
| 6345 | } |
| 6346 | if (ctxt->error) |
| 6347 | goto error; |
| 6348 | /* |
| 6349 | * Add tests for infinity and nan |
| 6350 | * => feedback on 3.4 for Inf and NaN |
| 6351 | */ |
| 6352 | /* Hand check NaN and Infinity comparisons */ |
| 6353 | if (xmlXPathIsNaN(arg1->floatval) || xmlXPathIsNaN(arg2->floatval)) { |
| 6354 | ret=0; |
| 6355 | } else { |
no test coverage detected