xpath.c revision ea152c05b3f3d9e47b282b88ffdb16fcb8c779c1
13473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/* 23473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xpath.c: XML Path Language implementation 33473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * XPath is a language for addressing parts of an XML document, 43473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * designed to be used by both XSLT and XPointer 53473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 63473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Reference: W3C Recommendation 16 November 1999 73473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * http://www.w3.org/TR/1999/REC-xpath-19991116 83473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Public reference: 93473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * http://www.w3.org/TR/xpath 103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 11cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * See Copyright for the status of this software 123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 13c5d64345cf19bfd72418eb0a837869b0462e9130Daniel Veillard * Author: daniel@veillard.com 143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1734ce8bece2f22cc99d25221b77315cd008f4866bDaniel Veillard#define IN_LIBXML 1870a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese#include "libxml.h" 193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include <string.h> 213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef HAVE_SYS_TYPES_H 233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include <sys/types.h> 243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef HAVE_MATH_H 263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include <math.h> 273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef HAVE_FLOAT_H 293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include <float.h> 303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef HAVE_CTYPE_H 323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include <ctype.h> 333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 345792e16f0562d206e1ef4e611f7b43ec53c92149Daniel Veillard#ifdef HAVE_SIGNAL_H 35b45c43be206b8c824558269731128c6a64599a54Daniel Veillard#include <signal.h> 36b45c43be206b8c824558269731128c6a64599a54Daniel Veillard#endif 373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include <libxml/xmlmemory.h> 393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include <libxml/tree.h> 403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include <libxml/valid.h> 413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include <libxml/xpath.h> 423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include <libxml/xpathInternals.h> 433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include <libxml/parserInternals.h> 443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include <libxml/hash.h> 453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef LIBXML_XPTR_ENABLED 463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include <libxml/xpointer.h> 473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef LIBXML_DEBUG_ENABLED 493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include <libxml/debugXML.h> 503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include <libxml/xmlerror.h> 528146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard#include <libxml/threads.h> 533c01b1d81b696fe8624b6d7e26ec0ebffcc7c06bDaniel Veillard#include <libxml/globals.h> 5456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard#ifdef LIBXML_PATTERN_ENABLED 5556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard#include <libxml/pattern.h> 5656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard#endif 5756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard 5856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard#ifdef LIBXML_PATTERN_ENABLED 59fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard#define XPATH_STREAMING 6056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard#endif 613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 62d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard#define TODO \ 63d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard xmlGenericError(xmlGenericErrorContext, \ 64d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard "Unimplemented block at %s:%d\n", \ 65d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard __FILE__, __LINE__); 66d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard 67d1757abcb891e01a9017f4aad041cc306d0d467bWilliam M. Brack/* 68d1757abcb891e01a9017f4aad041cc306d0d467bWilliam M. Brack * TODO: 69d1757abcb891e01a9017f4aad041cc306d0d467bWilliam M. Brack * There are a few spots where some tests are done which depend upon ascii 70d1757abcb891e01a9017f4aad041cc306d0d467bWilliam M. Brack * data. These should be enhanced for full UTF8 support (see particularly 71d1757abcb891e01a9017f4aad041cc306d0d467bWilliam M. Brack * any use of the macros IS_ASCII_CHARACTER and IS_ASCII_DIGIT) 72d1757abcb891e01a9017f4aad041cc306d0d467bWilliam M. Brack */ 73d1757abcb891e01a9017f4aad041cc306d0d467bWilliam M. Brack 7421e4ef20f64ebd740ebac0ead5d85a5631d2db5eWilliam M. Brack#if defined(LIBXML_XPATH_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED) 759e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard/************************************************************************ 769e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * * 779e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * Floating point stuff * 789e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * * 799e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard ************************************************************************/ 809e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 81c0631a608f62902eca453096f0b2fc5b449b0b0aDaniel Veillard#ifndef TRIO_REPLACE_STDIO 82cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard#define TRIO_PUBLIC static 83c0631a608f62902eca453096f0b2fc5b449b0b0aDaniel Veillard#endif 84cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard#include "trionan.c" 85cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard 863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/* 873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The lack of portability of this section of the libc is annoying ! 883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylordouble xmlXPathNAN = 0; 903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylordouble xmlXPathPINF = 1; 913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylordouble xmlXPathNINF = -1; 925fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillarddouble xmlXPathNZERO = 0; 9320ee8c03107e5d5724765da513d595fdaf290dceDaniel Veillardstatic int xmlXPathInitialized = 0; 943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathInit: 973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Initialize the XPath environment 993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 1003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 1013473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathInit(void) { 10220ee8c03107e5d5724765da513d595fdaf290dceDaniel Veillard if (xmlXPathInitialized) return; 1033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 104450296070e14629141738fbb34b9a0ad13af1f02Bjorn Reese xmlXPathPINF = trio_pinf(); 105450296070e14629141738fbb34b9a0ad13af1f02Bjorn Reese xmlXPathNINF = trio_ninf(); 106450296070e14629141738fbb34b9a0ad13af1f02Bjorn Reese xmlXPathNAN = trio_nan(); 1075fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard xmlXPathNZERO = trio_nzero(); 1083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 10920ee8c03107e5d5724765da513d595fdaf290dceDaniel Veillard xmlXPathInitialized = 1; 1103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 1113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 112cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard/** 113cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * xmlXPathIsNaN: 114cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * @val: a double value 115cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * 116cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * Provides a portable isnan() function to detect whether a double 117cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * is a NotaNumber. Based on trio code 118cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * http://sourceforge.net/projects/ctrio/ 119cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * 120cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * Returns 1 if the value is a NaN, 0 otherwise 121cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard */ 122cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillardint 123cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel VeillardxmlXPathIsNaN(double val) { 124cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard return(trio_isnan(val)); 125cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard} 126cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard 127cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard/** 128cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * xmlXPathIsInf: 129cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * @val: a double value 130cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * 131cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * Provides a portable isinf() function to detect whether a double 132cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * is a +Infinite or -Infinite. Based on trio code 133cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * http://sourceforge.net/projects/ctrio/ 134cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * 135cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * Returns 1 vi the value is +Infinite, -1 if -Infinite, 0 otherwise 136cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard */ 137cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillardint 138cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel VeillardxmlXPathIsInf(double val) { 139cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard return(trio_isinf(val)); 140cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard} 141cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard 1424432df239b7aba6bff86c838e0be11d08f283b76Daniel Veillard#endif /* SCHEMAS or XPATH */ 1434432df239b7aba6bff86c838e0be11d08f283b76Daniel Veillard#ifdef LIBXML_XPATH_ENABLED 1445fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard/** 1455fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard * xmlXPathGetSign: 1465fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard * @val: a double value 1475fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard * 1485fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard * Provides a portable function to detect the sign of a double 1495fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard * Modified from trio code 1505fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard * http://sourceforge.net/projects/ctrio/ 1515fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard * 1525fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard * Returns 1 if the value is Negative, 0 if positive 1535fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard */ 15421458c85e209cd2621ac3eadfee075ae2dc0121dDaniel Veillardstatic int 1555fc1f0893af6ffe76453ac16817204a866bdeab2Daniel VeillardxmlXPathGetSign(double val) { 15621458c85e209cd2621ac3eadfee075ae2dc0121dDaniel Veillard return(trio_signbit(val)); 1575fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard} 1585fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard 1595fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard 160d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillard/* 161d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillard * TODO: when compatibility allows remove all "fake node libxslt" strings 162d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillard * the test should just be name[0] = ' ' 163d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillard */ 164d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillard/* #define DEBUG */ 165d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillard/* #define DEBUG_STEP */ 166d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillard/* #define DEBUG_STEP_NTH */ 167d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillard/* #define DEBUG_EXPR */ 168d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillard/* #define DEBUG_EVAL_COUNTS */ 169d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillard 170d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillardstatic xmlNs xmlXPathXMLNamespaceStruct = { 171d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillard NULL, 172d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillard XML_NAMESPACE_DECL, 173d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillard XML_XML_NAMESPACE, 174d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillard BAD_CAST "xml", 175d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillard NULL 176d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillard}; 177d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillardstatic xmlNsPtr xmlXPathXMLNamespace = &xmlXPathXMLNamespaceStruct; 178d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillard#ifndef LIBXML_THREAD_ENABLED 179d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillard/* 180d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillard * Optimizer is disabled only when threaded apps are detected while 181d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillard * the library ain't compiled for thread safety. 182d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillard */ 183d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillardstatic int xmlXPathDisableOptimizer = 0; 184d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillard#endif 185d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillard 1863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/************************************************************************ 187d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard * * 188d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard * Error handling routines * 189d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard * * 190d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard ************************************************************************/ 191d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard 192081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack/* 193081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack * The array xmlXPathErrorMessages corresponds to the enum xmlXPathError 194081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack */ 195d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillardstatic const char *xmlXPathErrorMessages[] = { 196d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard "Ok\n", 197d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard "Number encoding\n", 198d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard "Unfinished literal\n", 199d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard "Start of literal\n", 200d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard "Expected $ for variable reference\n", 201d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard "Undefined variable\n", 202d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard "Invalid predicate\n", 203d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard "Invalid expression\n", 204d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard "Missing closing curly brace\n", 205d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard "Unregistered function\n", 206d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard "Invalid operand\n", 207d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard "Invalid type\n", 208d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard "Invalid number of arguments\n", 209d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard "Invalid context size\n", 210d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard "Invalid context position\n", 211d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard "Memory allocation error\n", 212d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard "Syntax error\n", 213d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard "Resource error\n", 214d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard "Sub resource error\n", 215d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard "Undefined namespace prefix\n", 216d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard "Encoding error\n", 21757b2516af5e2e06c54750b6549723cf5b8edf8a4Daniel Veillard "Char out of XML range\n", 218cd65bc9a49b406899c78e9e8f6757acca54fc04eWilliam M. Brack "Invalid or incomplete context\n", 219cd65bc9a49b406899c78e9e8f6757acca54fc04eWilliam M. Brack "?? Unknown error ??\n" /* Must be last in the list! */ 220d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard}; 221cd65bc9a49b406899c78e9e8f6757acca54fc04eWilliam M. Brack#define MAXERRNO ((int)(sizeof(xmlXPathErrorMessages) / \ 222cd65bc9a49b406899c78e9e8f6757acca54fc04eWilliam M. Brack sizeof(xmlXPathErrorMessages[0])) - 1) 223d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard/** 224d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard * xmlXPathErrMemory: 225d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard * @ctxt: an XPath context 226d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard * @extra: extra informations 227d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard * 228d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard * Handle a redefinition of attribute error 229d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard */ 230d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillardstatic void 231d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel VeillardxmlXPathErrMemory(xmlXPathContextPtr ctxt, const char *extra) 232d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard{ 233d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard if (ctxt != NULL) { 234d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard if (extra) { 235d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard xmlChar buf[200]; 236d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard 237d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard xmlStrPrintf(buf, 200, 238d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard BAD_CAST "Memory allocation failed : %s\n", 239d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard extra); 240d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard ctxt->lastError.message = (char *) xmlStrdup(buf); 241d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard } else { 242d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard ctxt->lastError.message = (char *) 243d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard xmlStrdup(BAD_CAST "Memory allocation failed\n"); 244d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard } 245d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard ctxt->lastError.domain = XML_FROM_XPATH; 246d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard ctxt->lastError.code = XML_ERR_NO_MEMORY; 247d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard if (ctxt->error != NULL) 248d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard ctxt->error(ctxt->userData, &ctxt->lastError); 249d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard } else { 250d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard if (extra) 251659e71ec2476d24bfca0d6432a69ef9a49a62be4Daniel Veillard __xmlRaiseError(NULL, NULL, NULL, 252d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard NULL, NULL, XML_FROM_XPATH, 253d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard XML_ERR_NO_MEMORY, XML_ERR_FATAL, NULL, 0, 254d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard extra, NULL, NULL, 0, 0, 255d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard "Memory allocation failed : %s\n", extra); 256d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard else 257659e71ec2476d24bfca0d6432a69ef9a49a62be4Daniel Veillard __xmlRaiseError(NULL, NULL, NULL, 258d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard NULL, NULL, XML_FROM_XPATH, 259d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard XML_ERR_NO_MEMORY, XML_ERR_FATAL, NULL, 0, 260d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard NULL, NULL, NULL, 0, 0, 261d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard "Memory allocation failed\n"); 262d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard } 263d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard} 264d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard 265d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard/** 2668de5c0bd79cceeca3d55d6dbf8f0248b7239e050Daniel Veillard * xmlXPathPErrMemory: 267d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard * @ctxt: an XPath parser context 268d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard * @extra: extra informations 269d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard * 270d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard * Handle a redefinition of attribute error 271d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard */ 272d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillardstatic void 273d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel VeillardxmlXPathPErrMemory(xmlXPathParserContextPtr ctxt, const char *extra) 274d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard{ 275d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard ctxt->error = XPATH_MEMORY_ERROR; 276d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard if (ctxt == NULL) 277d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard xmlXPathErrMemory(NULL, extra); 278d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard else 279d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard xmlXPathErrMemory(ctxt->context, extra); 280d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard} 281d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard 282d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard/** 283d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard * xmlXPathErr: 284d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard * @ctxt: a XPath parser context 285d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard * @error: the error code 286d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard * 287cd65bc9a49b406899c78e9e8f6757acca54fc04eWilliam M. Brack * Handle an XPath error 288d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard */ 289d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillardvoid 290d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel VeillardxmlXPathErr(xmlXPathParserContextPtr ctxt, int error) 291d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard{ 292cd65bc9a49b406899c78e9e8f6757acca54fc04eWilliam M. Brack if ((error < 0) || (error > MAXERRNO)) 293cd65bc9a49b406899c78e9e8f6757acca54fc04eWilliam M. Brack error = MAXERRNO; 294f88d8cf9f1c9538dba187290ad5add003dc22bc7Daniel Veillard if (ctxt == NULL) { 295659e71ec2476d24bfca0d6432a69ef9a49a62be4Daniel Veillard __xmlRaiseError(NULL, NULL, NULL, 296d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard NULL, NULL, XML_FROM_XPATH, 297d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard error + XML_XPATH_EXPRESSION_OK - XPATH_EXPRESSION_OK, 298d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard XML_ERR_ERROR, NULL, 0, 299d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard NULL, NULL, NULL, 0, 0, 300d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard xmlXPathErrorMessages[error]); 301d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard return; 302d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard } 303f88d8cf9f1c9538dba187290ad5add003dc22bc7Daniel Veillard ctxt->error = error; 304f88d8cf9f1c9538dba187290ad5add003dc22bc7Daniel Veillard if (ctxt->context == NULL) { 305f88d8cf9f1c9538dba187290ad5add003dc22bc7Daniel Veillard __xmlRaiseError(NULL, NULL, NULL, 306f88d8cf9f1c9538dba187290ad5add003dc22bc7Daniel Veillard NULL, NULL, XML_FROM_XPATH, 307f88d8cf9f1c9538dba187290ad5add003dc22bc7Daniel Veillard error + XML_XPATH_EXPRESSION_OK - XPATH_EXPRESSION_OK, 308f88d8cf9f1c9538dba187290ad5add003dc22bc7Daniel Veillard XML_ERR_ERROR, NULL, 0, 309f88d8cf9f1c9538dba187290ad5add003dc22bc7Daniel Veillard (const char *) ctxt->base, NULL, NULL, 310f88d8cf9f1c9538dba187290ad5add003dc22bc7Daniel Veillard ctxt->cur - ctxt->base, 0, 311f88d8cf9f1c9538dba187290ad5add003dc22bc7Daniel Veillard xmlXPathErrorMessages[error]); 312f88d8cf9f1c9538dba187290ad5add003dc22bc7Daniel Veillard return; 313f88d8cf9f1c9538dba187290ad5add003dc22bc7Daniel Veillard } 314d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard ctxt->context->lastError.domain = XML_FROM_XPATH; 315d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard ctxt->context->lastError.code = error + XML_XPATH_EXPRESSION_OK - 316d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard XPATH_EXPRESSION_OK; 317fcf719ce0a94f0d438f69b73cd1ca31a7000da81Daniel Veillard ctxt->context->lastError.level = XML_ERR_ERROR; 318d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard ctxt->context->lastError.str1 = (char *) xmlStrdup(ctxt->base); 319d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard ctxt->context->lastError.int1 = ctxt->cur - ctxt->base; 320d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard ctxt->context->lastError.node = ctxt->context->debugNode; 321d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard if (ctxt->context->error != NULL) { 322d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard ctxt->context->error(ctxt->context->userData, 323d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard &ctxt->context->lastError); 324d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard } else { 325659e71ec2476d24bfca0d6432a69ef9a49a62be4Daniel Veillard __xmlRaiseError(NULL, NULL, NULL, 326d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard NULL, ctxt->context->debugNode, XML_FROM_XPATH, 327d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard error + XML_XPATH_EXPRESSION_OK - XPATH_EXPRESSION_OK, 328d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard XML_ERR_ERROR, NULL, 0, 329d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard (const char *) ctxt->base, NULL, NULL, 330d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard ctxt->cur - ctxt->base, 0, 331d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard xmlXPathErrorMessages[error]); 332d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard } 333d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard 334d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard} 335d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard 336d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard/** 337d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard * xmlXPatherror: 338d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard * @ctxt: the XPath Parser context 339d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard * @file: the file name 340d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard * @line: the line number 341d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard * @no: the error number 342d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard * 343d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard * Formats an error message. 344d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard */ 345d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillardvoid 346d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel VeillardxmlXPatherror(xmlXPathParserContextPtr ctxt, const char *file ATTRIBUTE_UNUSED, 347d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard int line ATTRIBUTE_UNUSED, int no) { 348d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard xmlXPathErr(ctxt, no); 349d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard} 350d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard 351d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard 352d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard/************************************************************************ 3539e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * * 3549e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * Parser Types * 3559e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * * 3569e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard ************************************************************************/ 3579e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 3589e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard/* 3599e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * Types are private: 3609e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard */ 3619e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 3629e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillardtypedef enum { 3639e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard XPATH_OP_END=0, 3649e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard XPATH_OP_AND, 3659e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard XPATH_OP_OR, 3669e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard XPATH_OP_EQUAL, 3679e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard XPATH_OP_CMP, 3689e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard XPATH_OP_PLUS, 3699e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard XPATH_OP_MULT, 3709e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard XPATH_OP_UNION, 3719e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard XPATH_OP_ROOT, 3729e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard XPATH_OP_NODE, 3739e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard XPATH_OP_RESET, 3749e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard XPATH_OP_COLLECT, 3759e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard XPATH_OP_VALUE, 3769e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard XPATH_OP_VARIABLE, 3779e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard XPATH_OP_FUNCTION, 3789e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard XPATH_OP_ARG, 3799e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard XPATH_OP_PREDICATE, 380d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard XPATH_OP_FILTER, 3819e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard XPATH_OP_SORT 3829e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard#ifdef LIBXML_XPTR_ENABLED 3839e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard ,XPATH_OP_RANGETO 3849e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard#endif 3859e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard} xmlXPathOp; 3869e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 3879e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillardtypedef enum { 3889e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard AXIS_ANCESTOR = 1, 3899e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard AXIS_ANCESTOR_OR_SELF, 3909e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard AXIS_ATTRIBUTE, 3919e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard AXIS_CHILD, 3929e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard AXIS_DESCENDANT, 3939e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard AXIS_DESCENDANT_OR_SELF, 3949e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard AXIS_FOLLOWING, 3959e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard AXIS_FOLLOWING_SIBLING, 3969e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard AXIS_NAMESPACE, 3979e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard AXIS_PARENT, 3989e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard AXIS_PRECEDING, 3999e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard AXIS_PRECEDING_SIBLING, 4009e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard AXIS_SELF 4019e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard} xmlXPathAxisVal; 4029e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 4039e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillardtypedef enum { 4049e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard NODE_TEST_NONE = 0, 4059e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard NODE_TEST_TYPE = 1, 4069e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard NODE_TEST_PI = 2, 4079e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard NODE_TEST_ALL = 3, 4089e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard NODE_TEST_NS = 4, 4099e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard NODE_TEST_NAME = 5 4109e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard} xmlXPathTestVal; 4119e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 4129e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillardtypedef enum { 4139e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard NODE_TYPE_NODE = 0, 4149e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard NODE_TYPE_COMMENT = XML_COMMENT_NODE, 4159e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard NODE_TYPE_TEXT = XML_TEXT_NODE, 4169e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard NODE_TYPE_PI = XML_PI_NODE 4179e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard} xmlXPathTypeVal; 4189e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 4199e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 4209e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillardtypedef struct _xmlXPathStepOp xmlXPathStepOp; 4219e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillardtypedef xmlXPathStepOp *xmlXPathStepOpPtr; 4229e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillardstruct _xmlXPathStepOp { 423081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack xmlXPathOp op; /* The identifier of the operation */ 424081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack int ch1; /* First child */ 425081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack int ch2; /* Second child */ 4269e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard int value; 4279e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard int value2; 4289e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard int value3; 4299e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard void *value4; 4309e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard void *value5; 431e39a93d0d3df9907cf3538cd3f1fbbe4106e893dDaniel Veillard void *cache; 43242596ad20cdf1925dd79ea801cbe598b6e7b7aecDaniel Veillard void *cacheURI; 4339e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard}; 4349e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 4359e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillardstruct _xmlXPathCompExpr { 436081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack int nbStep; /* Number of steps in this expression */ 437081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack int maxStep; /* Maximum number of steps allocated */ 438081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack xmlXPathStepOp *steps; /* ops for computation of this expression */ 439081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack int last; /* index of last step in expression */ 440081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack xmlChar *expr; /* the expression being computed */ 4414773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard xmlDictPtr dict; /* the dictionnary to use if any */ 442f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#ifdef DEBUG_EVAL_COUNTS 443f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard int nb; 444f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlChar *string; 445f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#endif 44656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard#ifdef XPATH_STREAMING 44756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard xmlPatternPtr stream; 44856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard#endif 4499e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard}; 4509e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 4519e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard/************************************************************************ 4529e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * * 4539e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * Parser Type functions * 4549e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * * 4559e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard ************************************************************************/ 4569e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 4579e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard/** 4589e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * xmlXPathNewCompExpr: 4599e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * 4609e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * Create a new Xpath component 4619e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * 4629e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * Returns the newly allocated xmlXPathCompExprPtr or NULL in case of error 4639e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard */ 46456a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic xmlXPathCompExprPtr 4659e7160d45a18bfa26d708e22ba991f7670d0128bDaniel VeillardxmlXPathNewCompExpr(void) { 4669e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlXPathCompExprPtr cur; 4679e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 4689e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard cur = (xmlXPathCompExprPtr) xmlMalloc(sizeof(xmlXPathCompExpr)); 4699e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (cur == NULL) { 470d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard xmlXPathErrMemory(NULL, "allocating component\n"); 4719e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard return(NULL); 4729e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } 4739e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard memset(cur, 0, sizeof(xmlXPathCompExpr)); 4749e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard cur->maxStep = 10; 4759e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard cur->nbStep = 0; 4769e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard cur->steps = (xmlXPathStepOp *) xmlMalloc(cur->maxStep * 4779e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard sizeof(xmlXPathStepOp)); 4789e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (cur->steps == NULL) { 479d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard xmlXPathErrMemory(NULL, "allocating steps\n"); 4809e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlFree(cur); 4819e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard return(NULL); 4829e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } 4839e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard memset(cur->steps, 0, cur->maxStep * sizeof(xmlXPathStepOp)); 4849e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard cur->last = -1; 485f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#ifdef DEBUG_EVAL_COUNTS 486f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard cur->nb = 0; 487f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#endif 4889e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard return(cur); 4899e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard} 4909e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 4919e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard/** 4929e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * xmlXPathFreeCompExpr: 4939e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * @comp: an XPATH comp 4949e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * 4959e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * Free up the memory allocated by @comp 4969e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard */ 4979e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillardvoid 498f06307e2c172284bb41376c396f757bdac9bdd19Daniel VeillardxmlXPathFreeCompExpr(xmlXPathCompExprPtr comp) 499f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard{ 5009e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlXPathStepOpPtr op; 5019e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard int i; 5029e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 5039e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (comp == NULL) 504f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return; 5054773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard if (comp->dict == NULL) { 5064773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard for (i = 0; i < comp->nbStep; i++) { 5074773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard op = &comp->steps[i]; 5084773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard if (op->value4 != NULL) { 5094773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard if (op->op == XPATH_OP_VALUE) 5104773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard xmlXPathFreeObject(op->value4); 5114773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard else 5124773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard xmlFree(op->value4); 5134773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard } 5144773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard if (op->value5 != NULL) 5154773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard xmlFree(op->value5); 5164773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard } 5174773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard } else { 5184773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard for (i = 0; i < comp->nbStep; i++) { 5194773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard op = &comp->steps[i]; 5204773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard if (op->value4 != NULL) { 5214773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard if (op->op == XPATH_OP_VALUE) 5224773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard xmlXPathFreeObject(op->value4); 5234773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard } 5244773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard } 5254773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard xmlDictFree(comp->dict); 5269e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } 5279e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (comp->steps != NULL) { 528f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlFree(comp->steps); 5299e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } 530f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#ifdef DEBUG_EVAL_COUNTS 531f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (comp->string != NULL) { 532f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlFree(comp->string); 533f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 534f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#endif 53556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard#ifdef XPATH_STREAMING 53656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard if (comp->stream != NULL) { 53756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard xmlFreePatternList(comp->stream); 53856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard } 53956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard#endif 540118aed78f360f51d182770e62b251ef324707aa2Daniel Veillard if (comp->expr != NULL) { 541118aed78f360f51d182770e62b251ef324707aa2Daniel Veillard xmlFree(comp->expr); 542118aed78f360f51d182770e62b251ef324707aa2Daniel Veillard } 543f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 5449e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlFree(comp); 5459e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard} 5469e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 5479e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard/** 5489e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * xmlXPathCompExprAdd: 5499e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * @comp: the compiled expression 5509e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * @ch1: first child index 5519e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * @ch2: second child index 5529e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * @op: an op 5539e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * @value: the first int value 5549e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * @value2: the second int value 5559e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * @value3: the third int value 5569e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * @value4: the first string value 5579e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * @value5: the second string value 5589e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * 559081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack * Add a step to an XPath Compiled Expression 5609e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * 5619e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * Returns -1 in case of failure, the index otherwise 5629e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard */ 56356a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic int 5649e7160d45a18bfa26d708e22ba991f7670d0128bDaniel VeillardxmlXPathCompExprAdd(xmlXPathCompExprPtr comp, int ch1, int ch2, 5659e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlXPathOp op, int value, 5669e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard int value2, int value3, void *value4, void *value5) { 5679e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (comp->nbStep >= comp->maxStep) { 5689e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlXPathStepOp *real; 5699e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 5709e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard comp->maxStep *= 2; 5719e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard real = (xmlXPathStepOp *) xmlRealloc(comp->steps, 5729e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard comp->maxStep * sizeof(xmlXPathStepOp)); 5739e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (real == NULL) { 5749e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard comp->maxStep /= 2; 575d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard xmlXPathErrMemory(NULL, "adding step\n"); 5769e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard return(-1); 5779e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } 5789e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard comp->steps = real; 5799e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } 5809e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard comp->last = comp->nbStep; 5819e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard comp->steps[comp->nbStep].ch1 = ch1; 5829e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard comp->steps[comp->nbStep].ch2 = ch2; 5839e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard comp->steps[comp->nbStep].op = op; 5849e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard comp->steps[comp->nbStep].value = value; 5859e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard comp->steps[comp->nbStep].value2 = value2; 5869e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard comp->steps[comp->nbStep].value3 = value3; 5874773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard if ((comp->dict != NULL) && 5884773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard ((op == XPATH_OP_FUNCTION) || (op == XPATH_OP_VARIABLE) || 5894773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard (op == XPATH_OP_COLLECT))) { 5904773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard if (value4 != NULL) { 591b337795500cbe3fc47ac2b81f3d955126c6fbfdeDaniel Veillard comp->steps[comp->nbStep].value4 = (xmlChar *) 592c07ed5e6a14fb801cfd6bbb2a582caf726e5324eWilliam M. Brack (void *)xmlDictLookup(comp->dict, value4, -1); 5934773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard xmlFree(value4); 5944773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard } else 5954773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard comp->steps[comp->nbStep].value4 = NULL; 5964773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard if (value5 != NULL) { 597b337795500cbe3fc47ac2b81f3d955126c6fbfdeDaniel Veillard comp->steps[comp->nbStep].value5 = (xmlChar *) 598c07ed5e6a14fb801cfd6bbb2a582caf726e5324eWilliam M. Brack (void *)xmlDictLookup(comp->dict, value5, -1); 5994773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard xmlFree(value5); 6004773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard } else 6014773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard comp->steps[comp->nbStep].value5 = NULL; 6024773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard } else { 6034773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard comp->steps[comp->nbStep].value4 = value4; 6044773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard comp->steps[comp->nbStep].value5 = value5; 6054773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard } 606e39a93d0d3df9907cf3538cd3f1fbbe4106e893dDaniel Veillard comp->steps[comp->nbStep].cache = NULL; 6079e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard return(comp->nbStep++); 6089e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard} 6099e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 610f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard/** 611f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * xmlXPathCompSwap: 612f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * @comp: the compiled expression 613f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * @op: operation index 614f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * 615f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Swaps 2 operations in the compiled expression 616f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 617f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillardstatic void 618f06307e2c172284bb41376c396f757bdac9bdd19Daniel VeillardxmlXPathCompSwap(xmlXPathStepOpPtr op) { 619f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard int tmp; 620f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 621bc6f759ac9b41773e3643ad288b5214732051c98Daniel Veillard#ifndef LIBXML_THREAD_ENABLED 6228146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard /* 6238146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard * Since this manipulates possibly shared variables, this is 624081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack * disabled if one detects that the library is used in a multithreaded 6258146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard * application 6268146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard */ 6278146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard if (xmlXPathDisableOptimizer) 6288146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard return; 6298146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard#endif 6308146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard 631f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard tmp = op->ch1; 632f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard op->ch1 = op->ch2; 633f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard op->ch2 = tmp; 634f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard} 635f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 636d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#define PUSH_FULL_EXPR(op, op1, op2, val, val2, val3, val4, val5) \ 637d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard xmlXPathCompExprAdd(ctxt->comp, (op1), (op2), \ 638d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard (op), (val), (val2), (val3), (val4), (val5)) 6399e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard#define PUSH_LONG_EXPR(op, val, val2, val3, val4, val5) \ 6409e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlXPathCompExprAdd(ctxt->comp, ctxt->comp->last, -1, \ 6419e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard (op), (val), (val2), (val3), (val4), (val5)) 6429e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 6439e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard#define PUSH_LEAVE_EXPR(op, val, val2) \ 6449e7160d45a18bfa26d708e22ba991f7670d0128bDaniel VeillardxmlXPathCompExprAdd(ctxt->comp, -1, -1, (op), (val), (val2), 0 ,NULL ,NULL) 6459e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 6469e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard#define PUSH_UNARY_EXPR(op, ch, val, val2) \ 6479e7160d45a18bfa26d708e22ba991f7670d0128bDaniel VeillardxmlXPathCompExprAdd(ctxt->comp, (ch), -1, (op), (val), (val2), 0 ,NULL ,NULL) 6489e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 6499e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard#define PUSH_BINARY_EXPR(op, ch1, ch2, val, val2) \ 650081719182de3d15e6a438f32fdc3d1ca240a08e8William M. BrackxmlXPathCompExprAdd(ctxt->comp, (ch1), (ch2), (op), \ 651081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack (val), (val2), 0 ,NULL ,NULL) 6529e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 6539e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard/************************************************************************ 6543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * * 6553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Debugging related functions * 6563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * * 6573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ************************************************************************/ 6583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 6593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define STRANGE \ 6603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, \ 6613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "Internal error at %s:%d\n", \ 6623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor __FILE__, __LINE__); 6633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 6643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef LIBXML_DEBUG_ENABLED 66556a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic void 66656a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel VeillardxmlXPathDebugDumpNode(FILE *output, xmlNodePtr cur, int depth) { 6673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int i; 6683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor char shift[100]; 6693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 6703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor for (i = 0;((i < depth) && (i < 25));i++) 6713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor shift[2 * i] = shift[2 * i + 1] = ' '; 6723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor shift[2 * i] = shift[2 * i + 1] = 0; 6733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == NULL) { 6743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, shift); 6753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, "Node is NULL !\n"); 6763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return; 6773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 6783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 6793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 6803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((cur->type == XML_DOCUMENT_NODE) || 6813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor (cur->type == XML_HTML_DOCUMENT_NODE)) { 6823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, shift); 6833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, " /\n"); 6843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else if (cur->type == XML_ATTRIBUTE_NODE) 6853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlDebugDumpAttr(output, (xmlAttrPtr)cur, depth); 6863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else 6873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlDebugDumpOneNode(output, cur, depth); 6883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 68956a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic void 69056a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel VeillardxmlXPathDebugDumpNodeList(FILE *output, xmlNodePtr cur, int depth) { 691f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard xmlNodePtr tmp; 692f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard int i; 693f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard char shift[100]; 694f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard 695f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard for (i = 0;((i < depth) && (i < 25));i++) 696f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard shift[2 * i] = shift[2 * i + 1] = ' '; 697f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard shift[2 * i] = shift[2 * i + 1] = 0; 698f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard if (cur == NULL) { 699f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard fprintf(output, shift); 700f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard fprintf(output, "Node is NULL !\n"); 701f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard return; 702f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard 703f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard } 704f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard 705f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard while (cur != NULL) { 706f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard tmp = cur; 707f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard cur = cur->next; 708f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard xmlDebugDumpOneNode(output, tmp, depth); 709f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard } 710f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard} 7113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 71256a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic void 71356a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel VeillardxmlXPathDebugDumpNodeSet(FILE *output, xmlNodeSetPtr cur, int depth) { 7143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int i; 7153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor char shift[100]; 7163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 7173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor for (i = 0;((i < depth) && (i < 25));i++) 7183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor shift[2 * i] = shift[2 * i + 1] = ' '; 7193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor shift[2 * i] = shift[2 * i + 1] = 0; 7203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 7213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == NULL) { 7223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, shift); 7233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, "NodeSet is NULL !\n"); 7243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return; 7253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 7263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 7273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 728911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard if (cur != NULL) { 729911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard fprintf(output, "Set contains %d nodes:\n", cur->nodeNr); 730911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard for (i = 0;i < cur->nodeNr;i++) { 731911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard fprintf(output, shift); 732911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard fprintf(output, "%d", i + 1); 733911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard xmlXPathDebugDumpNode(output, cur->nodeTab[i], depth + 1); 734911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard } 7353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 7363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 7373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 73856a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic void 73956a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel VeillardxmlXPathDebugDumpValueTree(FILE *output, xmlNodeSetPtr cur, int depth) { 740f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard int i; 741f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard char shift[100]; 742f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard 743f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard for (i = 0;((i < depth) && (i < 25));i++) 744f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard shift[2 * i] = shift[2 * i + 1] = ' '; 745f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard shift[2 * i] = shift[2 * i + 1] = 0; 746f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard 747f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard if ((cur == NULL) || (cur->nodeNr == 0) || (cur->nodeTab[0] == NULL)) { 748f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard fprintf(output, shift); 749f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard fprintf(output, "Value Tree is NULL !\n"); 750f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard return; 751f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard 752f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard } 753f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard 754f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard fprintf(output, shift); 755f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard fprintf(output, "%d", i + 1); 756f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard xmlXPathDebugDumpNodeList(output, cur->nodeTab[0]->children, depth + 1); 757f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard} 7583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#if defined(LIBXML_XPTR_ENABLED) 75956a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic void 76056a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel VeillardxmlXPathDebugDumpLocationSet(FILE *output, xmlLocationSetPtr cur, int depth) { 7613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int i; 7623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor char shift[100]; 7633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 7643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor for (i = 0;((i < depth) && (i < 25));i++) 7653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor shift[2 * i] = shift[2 * i + 1] = ' '; 7663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor shift[2 * i] = shift[2 * i + 1] = 0; 7673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 7683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == NULL) { 7693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, shift); 7703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, "LocationSet is NULL !\n"); 7713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return; 7723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 7733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 7743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 7753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor for (i = 0;i < cur->locNr;i++) { 7763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, shift); 7773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, "%d : ", i + 1); 7783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathDebugDumpObject(output, cur->locTab[i], depth + 1); 7793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 7803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 781017b108fcf16dbce05ca7ebd75763f3d888abb5fDaniel Veillard#endif /* LIBXML_XPTR_ENABLED */ 7823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 783afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard/** 784afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathDebugDumpObject: 785afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * @output: the FILE * to dump the output 786afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * @cur: the object to inspect 787afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * @depth: indentation level 788afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * 789afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Dump the content of the object for debugging purposes 790afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard */ 791afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardvoid 792afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathDebugDumpObject(FILE *output, xmlXPathObjectPtr cur, int depth) { 7933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int i; 7943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor char shift[100]; 7953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 796a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard if (output == NULL) return; 797a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard 7983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor for (i = 0;((i < depth) && (i < 25));i++) 7993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor shift[2 * i] = shift[2 * i + 1] = ' '; 8003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor shift[2 * i] = shift[2 * i + 1] = 0; 8013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 8023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, shift); 8033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 8043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == NULL) { 8053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, "Object is empty (NULL)\n"); 8063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return; 8073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 8083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor switch(cur->type) { 8093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_UNDEFINED: 8103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, "Object is uninitialized\n"); 8113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 8123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_NODESET: 8133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, "Object is a Node Set :\n"); 8143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathDebugDumpNodeSet(output, cur->nodesetval, depth); 8153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 8163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_XSLT_TREE: 8173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, "Object is an XSLT value tree :\n"); 818f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard xmlXPathDebugDumpValueTree(output, cur->nodesetval, depth); 8193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 8203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_BOOLEAN: 8213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, "Object is a Boolean : "); 8223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur->boolval) fprintf(output, "true\n"); 8233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else fprintf(output, "false\n"); 8243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 8253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_NUMBER: 826cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard switch (xmlXPathIsInf(cur->floatval)) { 827357c960e4035ee2fb40d0072bb7bde4533be76f8Daniel Veillard case 1: 8285fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard fprintf(output, "Object is a number : Infinity\n"); 829357c960e4035ee2fb40d0072bb7bde4533be76f8Daniel Veillard break; 830357c960e4035ee2fb40d0072bb7bde4533be76f8Daniel Veillard case -1: 831357c960e4035ee2fb40d0072bb7bde4533be76f8Daniel Veillard fprintf(output, "Object is a number : -Infinity\n"); 832357c960e4035ee2fb40d0072bb7bde4533be76f8Daniel Veillard break; 833357c960e4035ee2fb40d0072bb7bde4533be76f8Daniel Veillard default: 834cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard if (xmlXPathIsNaN(cur->floatval)) { 835357c960e4035ee2fb40d0072bb7bde4533be76f8Daniel Veillard fprintf(output, "Object is a number : NaN\n"); 836d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard } else if (cur->floatval == 0 && xmlXPathGetSign(cur->floatval) != 0) { 837d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard fprintf(output, "Object is a number : 0\n"); 838357c960e4035ee2fb40d0072bb7bde4533be76f8Daniel Veillard } else { 839357c960e4035ee2fb40d0072bb7bde4533be76f8Daniel Veillard fprintf(output, "Object is a number : %0g\n", cur->floatval); 840357c960e4035ee2fb40d0072bb7bde4533be76f8Daniel Veillard } 841357c960e4035ee2fb40d0072bb7bde4533be76f8Daniel Veillard } 8423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 8433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_STRING: 8443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, "Object is a string : "); 8453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlDebugDumpString(output, cur->stringval); 8463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, "\n"); 8473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 8483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_POINT: 8493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, "Object is a point : index %d in node", cur->index); 8503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathDebugDumpNode(output, (xmlNodePtr) cur->user, depth + 1); 8513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, "\n"); 8523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 8533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_RANGE: 8543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((cur->user2 == NULL) || 8553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ((cur->user2 == cur->user) && (cur->index == cur->index2))) { 8563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, "Object is a collapsed range :\n"); 8573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, shift); 8583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur->index >= 0) 8593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, "index %d in ", cur->index); 8603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, "node\n"); 8613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathDebugDumpNode(output, (xmlNodePtr) cur->user, 8623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor depth + 1); 8633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else { 8643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, "Object is a range :\n"); 8653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, shift); 8663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, "From "); 8673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur->index >= 0) 8683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, "index %d in ", cur->index); 8693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, "node\n"); 8703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathDebugDumpNode(output, (xmlNodePtr) cur->user, 8713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor depth + 1); 8723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, shift); 8733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, "To "); 8743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur->index2 >= 0) 8753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, "index %d in ", cur->index2); 8763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, "node\n"); 8773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathDebugDumpNode(output, (xmlNodePtr) cur->user2, 8783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor depth + 1); 8793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, "\n"); 8803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 8813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 8823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_LOCATIONSET: 8833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#if defined(LIBXML_XPTR_ENABLED) 8843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, "Object is a Location Set:\n"); 8853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathDebugDumpLocationSet(output, 8863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor (xmlLocationSetPtr) cur->user, depth); 8873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 8883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 8893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_USERS: 8903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, "Object is user defined\n"); 8913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 8923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 8933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 8949e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 89556a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic void 89656a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel VeillardxmlXPathDebugDumpStepOp(FILE *output, xmlXPathCompExprPtr comp, 8979e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlXPathStepOpPtr op, int depth) { 8989e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard int i; 8999e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard char shift[100]; 9009e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 9019e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard for (i = 0;((i < depth) && (i < 25));i++) 9029e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard shift[2 * i] = shift[2 * i + 1] = ' '; 9039e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard shift[2 * i] = shift[2 * i + 1] = 0; 9049e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 9059e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, shift); 9069e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (op == NULL) { 9079e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "Step is NULL\n"); 9089e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard return; 9099e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } 9109e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard switch (op->op) { 9119e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case XPATH_OP_END: 9129e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "END"); break; 9139e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case XPATH_OP_AND: 9149e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "AND"); break; 9159e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case XPATH_OP_OR: 9169e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "OR"); break; 9179e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case XPATH_OP_EQUAL: 9189e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (op->value) 9199e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "EQUAL ="); 9209e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard else 9219e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "EQUAL !="); 9229e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard break; 9239e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case XPATH_OP_CMP: 9249e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (op->value) 9259e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "CMP <"); 9269e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard else 9279e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "CMP >"); 9289e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (!op->value2) 9299e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "="); 9309e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard break; 9319e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case XPATH_OP_PLUS: 9329e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (op->value == 0) 9339e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "PLUS -"); 9349e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard else if (op->value == 1) 9359e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "PLUS +"); 9369e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard else if (op->value == 2) 9379e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "PLUS unary -"); 9389e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard else if (op->value == 3) 9399e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "PLUS unary - -"); 9409e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard break; 9419e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case XPATH_OP_MULT: 9429e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (op->value == 0) 9439e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "MULT *"); 9449e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard else if (op->value == 1) 9459e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "MULT div"); 9469e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard else 9479e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "MULT mod"); 9489e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard break; 9499e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case XPATH_OP_UNION: 9509e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "UNION"); break; 9519e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case XPATH_OP_ROOT: 9529e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "ROOT"); break; 9539e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case XPATH_OP_NODE: 9549e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "NODE"); break; 9559e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case XPATH_OP_RESET: 9569e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "RESET"); break; 9579e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case XPATH_OP_SORT: 9589e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "SORT"); break; 9599e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case XPATH_OP_COLLECT: { 96078637da0ea1c833dfdfad87a9aa5bea14510d08aWilliam M. Brack xmlXPathAxisVal axis = (xmlXPathAxisVal)op->value; 96178637da0ea1c833dfdfad87a9aa5bea14510d08aWilliam M. Brack xmlXPathTestVal test = (xmlXPathTestVal)op->value2; 96278637da0ea1c833dfdfad87a9aa5bea14510d08aWilliam M. Brack xmlXPathTypeVal type = (xmlXPathTypeVal)op->value3; 9639e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard const xmlChar *prefix = op->value4; 9649e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard const xmlChar *name = op->value5; 9659e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 9669e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "COLLECT "); 9679e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard switch (axis) { 9689e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case AXIS_ANCESTOR: 9699e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, " 'ancestors' "); break; 9709e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case AXIS_ANCESTOR_OR_SELF: 9719e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, " 'ancestors-or-self' "); break; 9729e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case AXIS_ATTRIBUTE: 9739e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, " 'attributes' "); break; 9749e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case AXIS_CHILD: 9759e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, " 'child' "); break; 9769e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case AXIS_DESCENDANT: 9779e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, " 'descendant' "); break; 9789e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case AXIS_DESCENDANT_OR_SELF: 9799e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, " 'descendant-or-self' "); break; 9809e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case AXIS_FOLLOWING: 9819e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, " 'following' "); break; 9829e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case AXIS_FOLLOWING_SIBLING: 9839e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, " 'following-siblings' "); break; 9849e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case AXIS_NAMESPACE: 9859e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, " 'namespace' "); break; 9869e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case AXIS_PARENT: 9879e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, " 'parent' "); break; 9889e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case AXIS_PRECEDING: 9899e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, " 'preceding' "); break; 9909e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case AXIS_PRECEDING_SIBLING: 9919e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, " 'preceding-sibling' "); break; 9929e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case AXIS_SELF: 9939e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, " 'self' "); break; 9949e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } 9959e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard switch (test) { 9969e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case NODE_TEST_NONE: 9979e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "'none' "); break; 9989e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case NODE_TEST_TYPE: 9999e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "'type' "); break; 10009e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case NODE_TEST_PI: 10019e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "'PI' "); break; 10029e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case NODE_TEST_ALL: 10039e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "'all' "); break; 10049e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case NODE_TEST_NS: 10059e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "'namespace' "); break; 10069e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case NODE_TEST_NAME: 10079e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "'name' "); break; 10089e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } 10099e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard switch (type) { 10109e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case NODE_TYPE_NODE: 10119e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "'node' "); break; 10129e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case NODE_TYPE_COMMENT: 10139e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "'comment' "); break; 10149e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case NODE_TYPE_TEXT: 10159e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "'text' "); break; 10169e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case NODE_TYPE_PI: 10179e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "'PI' "); break; 10189e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } 10199e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (prefix != NULL) 10209e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "%s:", prefix); 10219e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (name != NULL) 1022580ced8ee28ecd99374da9383897678e4ba6c358Daniel Veillard fprintf(output, "%s", (const char *) name); 10239e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard break; 10249e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 10259e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } 10269e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case XPATH_OP_VALUE: { 10279e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlXPathObjectPtr object = (xmlXPathObjectPtr) op->value4; 10289e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 10299e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "ELEM "); 10309e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlXPathDebugDumpObject(output, object, 0); 10319e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard goto finish; 10329e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } 10339e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case XPATH_OP_VARIABLE: { 10349e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard const xmlChar *prefix = op->value5; 10359e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard const xmlChar *name = op->value4; 10369e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 10379e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (prefix != NULL) 10389e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "VARIABLE %s:%s", prefix, name); 10399e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard else 10409e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "VARIABLE %s", name); 10419e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard break; 10429e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } 10439e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case XPATH_OP_FUNCTION: { 10449e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard int nbargs = op->value; 10459e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard const xmlChar *prefix = op->value5; 10469e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard const xmlChar *name = op->value4; 10479e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 10489e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (prefix != NULL) 10499e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "FUNCTION %s:%s(%d args)", 10509e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard prefix, name, nbargs); 10519e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard else 10529e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "FUNCTION %s(%d args)", name, nbargs); 10539e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard break; 10549e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } 10559e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case XPATH_OP_ARG: fprintf(output, "ARG"); break; 10569e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case XPATH_OP_PREDICATE: fprintf(output, "PREDICATE"); break; 1057d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard case XPATH_OP_FILTER: fprintf(output, "FILTER"); break; 1058fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard#ifdef LIBXML_XPTR_ENABLED 1059fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard case XPATH_OP_RANGETO: fprintf(output, "RANGETO"); break; 1060fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard#endif 10619e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard default: 10629e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "UNKNOWN %d\n", op->op); return; 10639e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } 10649e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "\n"); 10659e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillardfinish: 10669e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (op->ch1 >= 0) 10679e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlXPathDebugDumpStepOp(output, comp, &comp->steps[op->ch1], depth + 1); 10689e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (op->ch2 >= 0) 10699e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlXPathDebugDumpStepOp(output, comp, &comp->steps[op->ch2], depth + 1); 10709e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard} 107156a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillard 10725e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard/** 10735e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard * xmlXPathDebugDumpCompExpr: 10745e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard * @output: the FILE * for the output 10755e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard * @comp: the precompiled XPath expression 10765e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard * @depth: the indentation level. 10775e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard * 10785e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard * Dumps the tree of the compiled XPath expression. 10795e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard */ 108056a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardvoid 108156a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel VeillardxmlXPathDebugDumpCompExpr(FILE *output, xmlXPathCompExprPtr comp, 108256a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillard int depth) { 10839e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard int i; 10849e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard char shift[100]; 10859e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 1086a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard if ((output == NULL) || (comp == NULL)) return; 1087a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard 10889e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard for (i = 0;((i < depth) && (i < 25));i++) 10899e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard shift[2 * i] = shift[2 * i + 1] = ' '; 10909e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard shift[2 * i] = shift[2 * i + 1] = 0; 10919e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 10929e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, shift); 10939e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 10949e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (comp == NULL) { 10959e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "Compiled Expression is NULL\n"); 10969e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard return; 10979e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } 10989e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "Compiled Expression : %d elements\n", 10999e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard comp->nbStep); 11009e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard i = comp->last; 11019e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlXPathDebugDumpStepOp(output, comp, &comp->steps[i], depth + 1); 11029e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard} 1103017b108fcf16dbce05ca7ebd75763f3d888abb5fDaniel Veillard#endif /* LIBXML_DEBUG_ENABLED */ 11043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 11053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/************************************************************************ 11063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * * 11073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Parser stacks related functions and macros * 11083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * * 11093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ************************************************************************/ 11103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 11115e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard/** 11125e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard * valuePop: 11135e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard * @ctxt: an XPath evaluation context 11145e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard * 11155e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard * Pops the top XPath object from the value stack 11165e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard * 11175e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard * Returns the XPath object just removed 11185e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard */ 11191c732d2e10935529b717864b6fa4296f80edace1Daniel Veillardextern xmlXPathObjectPtr 11201c732d2e10935529b717864b6fa4296f80edace1Daniel VeillardvaluePop(xmlXPathParserContextPtr ctxt) 11211c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard{ 11221c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard xmlXPathObjectPtr ret; 11231c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard 1124a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard if ((ctxt == NULL) || (ctxt->valueNr <= 0)) 11251c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard return (0); 11261c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard ctxt->valueNr--; 11271c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard if (ctxt->valueNr > 0) 11281c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard ctxt->value = ctxt->valueTab[ctxt->valueNr - 1]; 11291c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard else 11301c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard ctxt->value = NULL; 11311c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard ret = ctxt->valueTab[ctxt->valueNr]; 11321c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard ctxt->valueTab[ctxt->valueNr] = 0; 11331c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard return (ret); 11341c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard} 11355e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard/** 11365e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard * valuePush: 11375e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard * @ctxt: an XPath evaluation context 11385e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard * @value: the XPath object 11395e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard * 11405e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard * Pushes a new XPath object on top of the value stack 1141cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * 1142cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * returns the number of items on the value stack 11435e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard */ 11441c732d2e10935529b717864b6fa4296f80edace1Daniel Veillardextern int 11451c732d2e10935529b717864b6fa4296f80edace1Daniel VeillardvaluePush(xmlXPathParserContextPtr ctxt, xmlXPathObjectPtr value) 11461c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard{ 1147a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard if ((ctxt == NULL) || (value == NULL)) return(-1); 11481c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard if (ctxt->valueNr >= ctxt->valueMax) { 1149a918b5b08ac20d4e7c765bdce653969ebad6c315Daniel Veillard xmlXPathObjectPtr *tmp; 1150a918b5b08ac20d4e7c765bdce653969ebad6c315Daniel Veillard 1151a918b5b08ac20d4e7c765bdce653969ebad6c315Daniel Veillard tmp = (xmlXPathObjectPtr *) xmlRealloc(ctxt->valueTab, 1152a918b5b08ac20d4e7c765bdce653969ebad6c315Daniel Veillard 2 * ctxt->valueMax * 11531c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard sizeof(ctxt->valueTab[0])); 1154a918b5b08ac20d4e7c765bdce653969ebad6c315Daniel Veillard if (tmp == NULL) { 11551c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard xmlGenericError(xmlGenericErrorContext, "realloc failed !\n"); 11561c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard return (0); 11571c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard } 1158a918b5b08ac20d4e7c765bdce653969ebad6c315Daniel Veillard ctxt->valueMax *= 2; 1159a918b5b08ac20d4e7c765bdce653969ebad6c315Daniel Veillard ctxt->valueTab = tmp; 11601c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard } 11611c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard ctxt->valueTab[ctxt->valueNr] = value; 11621c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard ctxt->value = value; 11631c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard return (ctxt->valueNr++); 11641c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard} 11653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1166f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/** 1167f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathPopBoolean: 1168f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @ctxt: an XPath parser context 1169f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 1170f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Pops a boolean from the stack, handling conversion if needed. 1171f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Check error with #xmlXPathCheckError. 1172f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 1173f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns the boolean 1174f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */ 1175f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyerint 1176f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathPopBoolean (xmlXPathParserContextPtr ctxt) { 1177f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathObjectPtr obj; 1178f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer int ret; 1179f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 1180f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer obj = valuePop(ctxt); 1181f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (obj == NULL) { 1182f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathSetError(ctxt, XPATH_INVALID_OPERAND); 1183f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(0); 1184f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer } 1185081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack if (obj->type != XPATH_BOOLEAN) 1186081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack ret = xmlXPathCastToBoolean(obj); 1187081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack else 1188081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack ret = obj->boolval; 1189f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathFreeObject(obj); 1190f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(ret); 1191f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer} 1192f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 1193f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/** 1194f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathPopNumber: 1195f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @ctxt: an XPath parser context 1196f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 1197f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Pops a number from the stack, handling conversion if needed. 1198f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Check error with #xmlXPathCheckError. 1199f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 1200f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns the number 1201f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */ 1202f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyerdouble 1203f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathPopNumber (xmlXPathParserContextPtr ctxt) { 1204f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathObjectPtr obj; 1205f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer double ret; 1206f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 1207f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer obj = valuePop(ctxt); 1208f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (obj == NULL) { 1209f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathSetError(ctxt, XPATH_INVALID_OPERAND); 1210f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(0); 1211f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer } 1212081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack if (obj->type != XPATH_NUMBER) 1213081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack ret = xmlXPathCastToNumber(obj); 1214081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack else 1215081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack ret = obj->floatval; 1216f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathFreeObject(obj); 1217f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(ret); 1218f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer} 1219f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 1220f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/** 1221f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathPopString: 1222f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @ctxt: an XPath parser context 1223f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 1224f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Pops a string from the stack, handling conversion if needed. 1225f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Check error with #xmlXPathCheckError. 1226f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 1227f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns the string 1228f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */ 1229f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlChar * 1230f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathPopString (xmlXPathParserContextPtr ctxt) { 1231f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathObjectPtr obj; 1232f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlChar * ret; 1233f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 1234f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer obj = valuePop(ctxt); 1235f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (obj == NULL) { 1236f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathSetError(ctxt, XPATH_INVALID_OPERAND); 1237f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(NULL); 1238f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer } 1239081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack ret = xmlXPathCastToString(obj); /* this does required strdup */ 1240f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer /* TODO: needs refactoring somewhere else */ 1241f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (obj->stringval == ret) 1242f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer obj->stringval = NULL; 1243f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathFreeObject(obj); 1244f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(ret); 1245f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer} 1246f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 1247f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/** 1248f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathPopNodeSet: 1249f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @ctxt: an XPath parser context 1250f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 1251f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Pops a node-set from the stack, handling conversion if needed. 1252f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Check error with #xmlXPathCheckError. 1253f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 1254f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns the node-set 1255f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */ 1256f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlNodeSetPtr 1257f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathPopNodeSet (xmlXPathParserContextPtr ctxt) { 1258f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathObjectPtr obj; 1259f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlNodeSetPtr ret; 1260f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 1261f2a36f98e16efa8a89d9bed359d59be10e5d33cdDaniel Veillard if (ctxt == NULL) return(NULL); 1262f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (ctxt->value == NULL) { 1263f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathSetError(ctxt, XPATH_INVALID_OPERAND); 1264f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(NULL); 1265f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer } 1266f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (!xmlXPathStackIsNodeSet(ctxt)) { 1267f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathSetTypeError(ctxt); 1268f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(NULL); 1269f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer } 1270f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer obj = valuePop(ctxt); 1271f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer ret = obj->nodesetval; 1272e9449c5d29d87b1dc51de7784ed947ae1e3da831William M. Brack#if 0 12739deb242b558cbcff45165866e0634a1962404885Daniel Veillard /* to fix memory leak of not clearing obj->user */ 12749deb242b558cbcff45165866e0634a1962404885Daniel Veillard if (obj->boolval && obj->user != NULL) 12759deb242b558cbcff45165866e0634a1962404885Daniel Veillard xmlFreeNodeList((xmlNodePtr) obj->user); 1276e9449c5d29d87b1dc51de7784ed947ae1e3da831William M. Brack#endif 1277f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathFreeNodeSetList(obj); 1278f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(ret); 1279f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer} 1280f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 1281f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/** 1282f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathPopExternal: 1283f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @ctxt: an XPath parser context 1284f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 1285cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * Pops an external object from the stack, handling conversion if needed. 1286f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Check error with #xmlXPathCheckError. 1287f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 1288f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns the object 1289f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */ 1290f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyervoid * 1291f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathPopExternal (xmlXPathParserContextPtr ctxt) { 1292f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathObjectPtr obj; 1293f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer void * ret; 1294f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 1295a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard if ((ctxt == NULL) || (ctxt->value == NULL)) { 1296f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathSetError(ctxt, XPATH_INVALID_OPERAND); 1297f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(NULL); 1298f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer } 1299f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (ctxt->value->type != XPATH_USERS) { 1300f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathSetTypeError(ctxt); 1301f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(NULL); 1302f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer } 1303f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer obj = valuePop(ctxt); 1304f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer ret = obj->user; 1305f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathFreeObject(obj); 1306f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(ret); 1307f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer} 1308f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 13093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/* 13103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Macros for accessing the content. Those should be used only by the parser, 13113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * and not exported. 13123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 13133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Dirty macros, i.e. one need to make assumption on the context to use them 13143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 13153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * CUR_PTR return the current pointer to the xmlChar to be parsed. 13163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * CUR returns the current xmlChar value, i.e. a 8 bit value 13173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * in ISO-Latin or UTF-8. 13183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * This should be used internally by the parser 13193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * only to compare to ASCII values otherwise it would break when 13203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * running with UTF-8 encoding. 13213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * NXT(n) returns the n'th next xmlChar. Same as CUR is should be used only 13223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * to compare on ASCII based substring. 13233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * SKIP(n) Skip n xmlChar, and must also be used only to skip ASCII defined 13243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * strings within the parser. 13253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * CURRENT Returns the current char value, with the full decoding of 13263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * UTF-8 if we are using this mode. It returns an int. 13273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * NEXT Skip to the next character, this does the proper decoding 13283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * in UTF-8 mode. It also pop-up unfinished entities on the fly. 13293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * It returns the pointer to the current xmlChar. 13303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 13313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 13323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define CUR (*ctxt->cur) 13333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define SKIP(val) ctxt->cur += (val) 13343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define NXT(val) ctxt->cur[(val)] 13353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define CUR_PTR ctxt->cur 133661d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard#define CUR_CHAR(l) xmlXPathCurrentChar(ctxt, &l) 133761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard 133861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard#define COPY_BUF(l,b,i,v) \ 133961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard if (l == 1) b[i++] = (xmlChar) v; \ 134061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard else i += xmlCopyChar(l,&b[i],v) 134161d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard 134261d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard#define NEXTL(l) ctxt->cur += l 13433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 13443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define SKIP_BLANKS \ 134576e95df05556c9610b564b14cf578c8f9e34c9c1William M. Brack while (IS_BLANK_CH(*(ctxt->cur))) NEXT 13463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 13473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define CURRENT (*ctxt->cur) 13483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define NEXT ((*ctxt->cur) ? ctxt->cur++: ctxt->cur) 13493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1350e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese 1351e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese#ifndef DBL_DIG 1352e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese#define DBL_DIG 16 1353e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese#endif 1354e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese#ifndef DBL_EPSILON 1355e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese#define DBL_EPSILON 1E-9 1356e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese#endif 1357e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese 1358e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese#define UPPER_DOUBLE 1E9 1359e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese#define LOWER_DOUBLE 1E-5 1360e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese 1361e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese#define INTEGER_DIGITS DBL_DIG 1362e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese#define FRACTION_DIGITS (DBL_DIG + 1) 1363e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese#define EXPONENT_DIGITS (3 + 2) 1364e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese 1365e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese/** 1366e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese * xmlXPathFormatNumber: 1367e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese * @number: number to format 1368e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese * @buffer: output buffer 1369e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese * @buffersize: size of output buffer 1370e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese * 1371e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese * Convert the number into a string representation. 1372e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese */ 1373e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reesestatic void 1374e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn ReesexmlXPathFormatNumber(double number, char buffer[], int buffersize) 1375e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese{ 1376cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard switch (xmlXPathIsInf(number)) { 1377e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese case 1: 13785fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard if (buffersize > (int)sizeof("Infinity")) 137949cc97565fbe2928388a1e437c44429097a504aeAleksey Sanin snprintf(buffer, buffersize, "Infinity"); 1380e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese break; 1381e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese case -1: 1382e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese if (buffersize > (int)sizeof("-Infinity")) 138349cc97565fbe2928388a1e437c44429097a504aeAleksey Sanin snprintf(buffer, buffersize, "-Infinity"); 1384e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese break; 1385e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese default: 1386cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard if (xmlXPathIsNaN(number)) { 1387e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese if (buffersize > (int)sizeof("NaN")) 138849cc97565fbe2928388a1e437c44429097a504aeAleksey Sanin snprintf(buffer, buffersize, "NaN"); 1389d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard } else if (number == 0 && xmlXPathGetSign(number) != 0) { 139049cc97565fbe2928388a1e437c44429097a504aeAleksey Sanin snprintf(buffer, buffersize, "0"); 139128cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard } else if (number == ((int) number)) { 139228cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard char work[30]; 139328cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard char *ptr, *cur; 139428cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard int res, value = (int) number; 139528cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard 139628cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard ptr = &buffer[0]; 139728cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard if (value < 0) { 139828cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard *ptr++ = '-'; 139928cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard value = -value; 140028cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard } 140128cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard if (value == 0) { 140228cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard *ptr++ = '0'; 140328cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard } else { 140428cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard cur = &work[0]; 140528cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard while (value != 0) { 140628cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard res = value % 10; 140728cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard value = value / 10; 140828cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard *cur++ = '0' + res; 140928cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard } 141028cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard cur--; 141128cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard while ((cur >= &work[0]) && (ptr - buffer < buffersize)) { 141228cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard *ptr++ = *cur--; 141328cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard } 141428cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard } 141528cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard if (ptr - buffer < buffersize) { 141628cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard *ptr = 0; 141728cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard } else if (buffersize > 0) { 141828cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard ptr--; 141928cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard *ptr = 0; 142028cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard } 1421e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese } else { 142270a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese /* 3 is sign, decimal point, and terminating zero */ 142370a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese char work[DBL_DIG + EXPONENT_DIGITS + 3]; 142470a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese int integer_place, fraction_place; 142570a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese char *ptr; 142670a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese char *after_fraction; 142770a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese double absolute_value; 142870a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese int size; 142970a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese 143070a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese absolute_value = fabs(number); 143170a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese 143270a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese /* 143370a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese * First choose format - scientific or regular floating point. 143470a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese * In either case, result is in work, and after_fraction points 143570a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese * just past the fractional part. 143670a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese */ 143770a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese if ( ((absolute_value > UPPER_DOUBLE) || 143870a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese (absolute_value < LOWER_DOUBLE)) && 143970a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese (absolute_value != 0.0) ) { 144070a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese /* Use scientific notation */ 144170a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese integer_place = DBL_DIG + EXPONENT_DIGITS + 1; 144270a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese fraction_place = DBL_DIG - 1; 144370a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese snprintf(work, sizeof(work),"%*.*e", 144470a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese integer_place, fraction_place, number); 144570a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese after_fraction = strchr(work + DBL_DIG, 'e'); 1446e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese } 144770a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese else { 144870a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese /* Use regular notation */ 144956f0646e734ffbdd6945d86cc28b69b6569a82fcDaniel Veillard if (absolute_value > 0.0) 145056f0646e734ffbdd6945d86cc28b69b6569a82fcDaniel Veillard integer_place = 1 + (int)log10(absolute_value); 145156f0646e734ffbdd6945d86cc28b69b6569a82fcDaniel Veillard else 1452a3067d19ec3a96fd6e7997753e27a5422a2856f7Daniel Veillard integer_place = 0; 145370a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese fraction_place = (integer_place > 0) 145470a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese ? DBL_DIG - integer_place 145570a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese : DBL_DIG; 145670a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese size = snprintf(work, sizeof(work), "%0.*f", 145770a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese fraction_place, number); 145870a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese after_fraction = work + size; 1459e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese } 1460e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese 146170a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese /* Remove fractional trailing zeroes */ 146270a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese ptr = after_fraction; 146370a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese while (*(--ptr) == '0') 146470a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese ; 146570a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese if (*ptr != '.') 146670a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese ptr++; 14675dd3c9622ab6a8e75870bc5351499155e7963abcDaniel Veillard while ((*ptr++ = *after_fraction++) != 0); 146870a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese 146970a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese /* Finally copy result back to caller */ 147070a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese size = strlen(work) + 1; 147170a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese if (size > buffersize) { 147270a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese work[buffersize - 1] = 0; 147370a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese size = buffersize; 147470a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese } 14755dd3c9622ab6a8e75870bc5351499155e7963abcDaniel Veillard memmove(buffer, work, size); 1476e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese } 1477e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese break; 1478e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese } 1479e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese} 1480e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese 14813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 14823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/************************************************************************ 14833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * * 14843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Routines to handle NodeSets * 14853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * * 14863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ************************************************************************/ 14873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 14883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 1489e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard * xmlXPathOrderDocElems: 1490e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard * @doc: an input document 1491e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard * 1492e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard * Call this routine to speed up XPath computation on static documents. 1493e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard * This stamps all the element nodes with the document order 1494e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard * Like for line information, the order is kept in the element->content 1495081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack * field, the value stored is actually - the node number (starting at -1) 1496081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack * to be able to differentiate from line numbers. 1497e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard * 1498081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack * Returns the number of elements found in the document or -1 in case 1499e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard * of error. 1500e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard */ 1501e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillardlong 1502e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel VeillardxmlXPathOrderDocElems(xmlDocPtr doc) { 1503e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard long count = 0; 1504e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard xmlNodePtr cur; 1505e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard 1506e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard if (doc == NULL) 1507e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard return(-1); 1508e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard cur = doc->children; 1509e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard while (cur != NULL) { 1510e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard if (cur->type == XML_ELEMENT_NODE) { 1511e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard cur->content = (void *) (-(++count)); 1512e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard if (cur->children != NULL) { 1513e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard cur = cur->children; 1514e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard continue; 1515e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard } 1516e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard } 1517e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard if (cur->next != NULL) { 1518e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard cur = cur->next; 1519e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard continue; 1520e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard } 1521e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard do { 1522e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard cur = cur->parent; 1523e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard if (cur == NULL) 1524e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard break; 1525e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard if (cur == (xmlNodePtr) doc) { 1526e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard cur = NULL; 1527e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard break; 1528e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard } 1529e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard if (cur->next != NULL) { 1530e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard cur = cur->next; 1531e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard break; 1532e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard } 1533e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard } while (cur != NULL); 1534e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard } 1535e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard return(count); 1536e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard} 1537e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard 1538e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard/** 15393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathCmpNodes: 15403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @node1: the first node 15413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @node2: the second node 15423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 15433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Compare two nodes w.r.t document order 15443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 15453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns -2 in case of error 1 if first point < second point, 0 if 1546081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack * it's the same node, -1 otherwise 15473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 15483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorint 15493473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathCmpNodes(xmlNodePtr node1, xmlNodePtr node2) { 15503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int depth1, depth2; 1551edfd588e95d7c4690b5e85880521a32c20ed4fdeDaniel Veillard int attr1 = 0, attr2 = 0; 1552e8d1bd9daa881b01259e83eab60df8cbb56785c6William M. Brack xmlNodePtr attrNode1 = NULL, attrNode2 = NULL; 15533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlNodePtr cur, root; 15543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 15553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((node1 == NULL) || (node2 == NULL)) 15563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(-2); 15573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 15583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * a couple of optimizations which will avoid computations in most cases 15593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 1560edfd588e95d7c4690b5e85880521a32c20ed4fdeDaniel Veillard if (node1->type == XML_ATTRIBUTE_NODE) { 1561edfd588e95d7c4690b5e85880521a32c20ed4fdeDaniel Veillard attr1 = 1; 1562e8d1bd9daa881b01259e83eab60df8cbb56785c6William M. Brack attrNode1 = node1; 1563edfd588e95d7c4690b5e85880521a32c20ed4fdeDaniel Veillard node1 = node1->parent; 1564edfd588e95d7c4690b5e85880521a32c20ed4fdeDaniel Veillard } 1565edfd588e95d7c4690b5e85880521a32c20ed4fdeDaniel Veillard if (node2->type == XML_ATTRIBUTE_NODE) { 1566edfd588e95d7c4690b5e85880521a32c20ed4fdeDaniel Veillard attr2 = 1; 1567e8d1bd9daa881b01259e83eab60df8cbb56785c6William M. Brack attrNode2 = node2; 1568edfd588e95d7c4690b5e85880521a32c20ed4fdeDaniel Veillard node2 = node2->parent; 1569edfd588e95d7c4690b5e85880521a32c20ed4fdeDaniel Veillard } 1570edfd588e95d7c4690b5e85880521a32c20ed4fdeDaniel Veillard if (node1 == node2) { 1571e8d1bd9daa881b01259e83eab60df8cbb56785c6William M. Brack if (attr1 == attr2) { 1572e8d1bd9daa881b01259e83eab60df8cbb56785c6William M. Brack /* not required, but we keep attributes in order */ 1573e8d1bd9daa881b01259e83eab60df8cbb56785c6William M. Brack if (attr1 != 0) { 1574e8d1bd9daa881b01259e83eab60df8cbb56785c6William M. Brack cur = attrNode2->prev; 1575e8d1bd9daa881b01259e83eab60df8cbb56785c6William M. Brack while (cur != NULL) { 1576e8d1bd9daa881b01259e83eab60df8cbb56785c6William M. Brack if (cur == attrNode1) 1577e8d1bd9daa881b01259e83eab60df8cbb56785c6William M. Brack return (1); 1578e8d1bd9daa881b01259e83eab60df8cbb56785c6William M. Brack cur = cur->prev; 1579e8d1bd9daa881b01259e83eab60df8cbb56785c6William M. Brack } 1580e8d1bd9daa881b01259e83eab60df8cbb56785c6William M. Brack return (-1); 1581e8d1bd9daa881b01259e83eab60df8cbb56785c6William M. Brack } 1582edfd588e95d7c4690b5e85880521a32c20ed4fdeDaniel Veillard return(0); 1583e8d1bd9daa881b01259e83eab60df8cbb56785c6William M. Brack } 1584edfd588e95d7c4690b5e85880521a32c20ed4fdeDaniel Veillard if (attr2 == 1) 1585edfd588e95d7c4690b5e85880521a32c20ed4fdeDaniel Veillard return(1); 1586edfd588e95d7c4690b5e85880521a32c20ed4fdeDaniel Veillard return(-1); 1587edfd588e95d7c4690b5e85880521a32c20ed4fdeDaniel Veillard } 1588b33c201978ed1c434877cdc6e2000b7012cc26f9Daniel Veillard if ((node1->type == XML_NAMESPACE_DECL) || 1589b33c201978ed1c434877cdc6e2000b7012cc26f9Daniel Veillard (node2->type == XML_NAMESPACE_DECL)) 1590b33c201978ed1c434877cdc6e2000b7012cc26f9Daniel Veillard return(1); 15913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (node1 == node2->prev) 15923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(1); 15933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (node1 == node2->next) 15943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(-1); 15953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 15963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 1597e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard * Speedup using document order if availble. 15987216cfd6622d947695c67b7b430edef8cc0af967Daniel Veillard */ 15997216cfd6622d947695c67b7b430edef8cc0af967Daniel Veillard if ((node1->type == XML_ELEMENT_NODE) && 16007216cfd6622d947695c67b7b430edef8cc0af967Daniel Veillard (node2->type == XML_ELEMENT_NODE) && 1601e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard (0 > (long) node1->content) && 1602e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard (0 > (long) node2->content) && 1603e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard (node1->doc == node2->doc)) { 1604e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard long l1, l2; 1605e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard 1606e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard l1 = -((long) node1->content); 1607e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard l2 = -((long) node2->content); 16087216cfd6622d947695c67b7b430edef8cc0af967Daniel Veillard if (l1 < l2) 16097216cfd6622d947695c67b7b430edef8cc0af967Daniel Veillard return(1); 16107216cfd6622d947695c67b7b430edef8cc0af967Daniel Veillard if (l1 > l2) 16117216cfd6622d947695c67b7b430edef8cc0af967Daniel Veillard return(-1); 16127216cfd6622d947695c67b7b430edef8cc0af967Daniel Veillard } 1613e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard 16147216cfd6622d947695c67b7b430edef8cc0af967Daniel Veillard /* 16153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * compute depth to root 16163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 16173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor for (depth2 = 0, cur = node2;cur->parent != NULL;cur = cur->parent) { 16183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == node1) 16193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(1); 16203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor depth2++; 16213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 16223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor root = cur; 16233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor for (depth1 = 0, cur = node1;cur->parent != NULL;cur = cur->parent) { 16243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == node2) 16253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(-1); 16263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor depth1++; 16273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 16283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 16293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Distinct document (or distinct entities :-( ) case. 16303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 16313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (root != cur) { 16323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(-2); 16333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 16343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 16353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * get the nearest common ancestor. 16363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 16373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while (depth1 > depth2) { 16383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor depth1--; 16393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor node1 = node1->parent; 16403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 16413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while (depth2 > depth1) { 16423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor depth2--; 16433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor node2 = node2->parent; 16443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 16453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while (node1->parent != node2->parent) { 16463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor node1 = node1->parent; 16473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor node2 = node2->parent; 16483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* should not happen but just in case ... */ 16493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((node1 == NULL) || (node2 == NULL)) 16503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(-2); 16513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 16523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 16533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Find who's first. 16543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 1655f49be4778db34e8bbcfabc5d5f1ad33c594b7387Daniel Veillard if (node1 == node2->prev) 1656f49be4778db34e8bbcfabc5d5f1ad33c594b7387Daniel Veillard return(1); 16573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (node1 == node2->next) 16583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(-1); 1659f49be4778db34e8bbcfabc5d5f1ad33c594b7387Daniel Veillard /* 1660f49be4778db34e8bbcfabc5d5f1ad33c594b7387Daniel Veillard * Speedup using document order if availble. 1661f49be4778db34e8bbcfabc5d5f1ad33c594b7387Daniel Veillard */ 1662f49be4778db34e8bbcfabc5d5f1ad33c594b7387Daniel Veillard if ((node1->type == XML_ELEMENT_NODE) && 1663f49be4778db34e8bbcfabc5d5f1ad33c594b7387Daniel Veillard (node2->type == XML_ELEMENT_NODE) && 1664f49be4778db34e8bbcfabc5d5f1ad33c594b7387Daniel Veillard (0 > (long) node1->content) && 1665f49be4778db34e8bbcfabc5d5f1ad33c594b7387Daniel Veillard (0 > (long) node2->content) && 1666f49be4778db34e8bbcfabc5d5f1ad33c594b7387Daniel Veillard (node1->doc == node2->doc)) { 1667f49be4778db34e8bbcfabc5d5f1ad33c594b7387Daniel Veillard long l1, l2; 1668f49be4778db34e8bbcfabc5d5f1ad33c594b7387Daniel Veillard 1669f49be4778db34e8bbcfabc5d5f1ad33c594b7387Daniel Veillard l1 = -((long) node1->content); 1670f49be4778db34e8bbcfabc5d5f1ad33c594b7387Daniel Veillard l2 = -((long) node2->content); 1671f49be4778db34e8bbcfabc5d5f1ad33c594b7387Daniel Veillard if (l1 < l2) 1672f49be4778db34e8bbcfabc5d5f1ad33c594b7387Daniel Veillard return(1); 1673f49be4778db34e8bbcfabc5d5f1ad33c594b7387Daniel Veillard if (l1 > l2) 1674f49be4778db34e8bbcfabc5d5f1ad33c594b7387Daniel Veillard return(-1); 1675f49be4778db34e8bbcfabc5d5f1ad33c594b7387Daniel Veillard } 1676f49be4778db34e8bbcfabc5d5f1ad33c594b7387Daniel Veillard 16773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor for (cur = node1->next;cur != NULL;cur = cur->next) 16783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == node2) 16793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(1); 16803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(-1); /* assume there is no sibling list corruption */ 16813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 16823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 16833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 16843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNodeSetSort: 16853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @set: the node set 16863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 16873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Sort the node set in document order 16883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 16893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 16903473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNodeSetSort(xmlNodeSetPtr set) { 1691e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese int i, j, incr, len; 16923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlNodePtr tmp; 16933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 16943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (set == NULL) 16953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return; 16963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 16973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* Use Shell's sort to sort the node-set */ 16983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor len = set->nodeNr; 16993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor for (incr = len / 2; incr > 0; incr /= 2) { 17003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor for (i = incr; i < len; i++) { 17013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor j = i - incr; 17023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while (j >= 0) { 1703e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese if (xmlXPathCmpNodes(set->nodeTab[j], 1704e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese set->nodeTab[j + incr]) == -1) { 17053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor tmp = set->nodeTab[j]; 17063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor set->nodeTab[j] = set->nodeTab[j + incr]; 17073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor set->nodeTab[j + incr] = tmp; 17083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor j -= incr; 17093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else 17103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 17113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 17123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 17133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 17143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 17153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 17163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define XML_NODESET_DEFAULT 10 17173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 1718044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * xmlXPathNodeSetDupNs: 1719044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * @node: the parent node of the namespace XPath node 1720044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * @ns: the libxml namespace declaration node. 1721044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * 1722044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * Namespace node in libxml don't match the XPath semantic. In a node set 1723044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * the namespace nodes are duplicated and the next pointer is set to the 1724044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * parent node in the XPath semantic. 1725044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * 1726044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * Returns the newly created object. 1727044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard */ 1728044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillardstatic xmlNodePtr 1729044fc6b7476798cbb95277b4905e5111d7c2775dDaniel VeillardxmlXPathNodeSetDupNs(xmlNodePtr node, xmlNsPtr ns) { 1730044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlNsPtr cur; 1731044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard 1732044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if ((ns == NULL) || (ns->type != XML_NAMESPACE_DECL)) 1733044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard return(NULL); 1734044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if ((node == NULL) || (node->type == XML_NAMESPACE_DECL)) 1735044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard return((xmlNodePtr) ns); 1736044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard 1737044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard /* 1738044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * Allocate a new Namespace and fill the fields. 1739044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard */ 1740044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard cur = (xmlNsPtr) xmlMalloc(sizeof(xmlNs)); 1741044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if (cur == NULL) { 1742d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard xmlXPathErrMemory(NULL, "duplicating namespace\n"); 1743044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard return(NULL); 1744044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } 1745044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard memset(cur, 0, sizeof(xmlNs)); 1746044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard cur->type = XML_NAMESPACE_DECL; 1747044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if (ns->href != NULL) 1748044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard cur->href = xmlStrdup(ns->href); 1749044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if (ns->prefix != NULL) 1750044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard cur->prefix = xmlStrdup(ns->prefix); 1751044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard cur->next = (xmlNsPtr) node; 1752044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard return((xmlNodePtr) cur); 1753044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard} 1754044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard 1755044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard/** 1756044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * xmlXPathNodeSetFreeNs: 1757044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * @ns: the XPath namespace node found in a nodeset. 1758044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * 1759081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack * Namespace nodes in libxml don't match the XPath semantic. In a node set 1760044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * the namespace nodes are duplicated and the next pointer is set to the 1761081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack * parent node in the XPath semantic. Check if such a node needs to be freed 1762044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard */ 1763f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Saninvoid 1764044fc6b7476798cbb95277b4905e5111d7c2775dDaniel VeillardxmlXPathNodeSetFreeNs(xmlNsPtr ns) { 1765044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if ((ns == NULL) || (ns->type != XML_NAMESPACE_DECL)) 1766044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard return; 1767044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard 1768044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if ((ns->next != NULL) && (ns->next->type != XML_NAMESPACE_DECL)) { 1769044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if (ns->href != NULL) 1770044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlFree((xmlChar *)ns->href); 1771044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if (ns->prefix != NULL) 1772044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlFree((xmlChar *)ns->prefix); 1773044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlFree(ns); 1774044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } 1775044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard} 1776044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard 1777044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard/** 17783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNodeSetCreate: 17793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val: an initial xmlNodePtr, or NULL 17803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 17813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Create a new xmlNodeSetPtr of type double and of value @val 17823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 17833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the newly created object. 17843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 17853473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNodeSetPtr 17863473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNodeSetCreate(xmlNodePtr val) { 17873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlNodeSetPtr ret; 17883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 17893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = (xmlNodeSetPtr) xmlMalloc(sizeof(xmlNodeSet)); 17903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ret == NULL) { 1791d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard xmlXPathErrMemory(NULL, "creating nodeset\n"); 17923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 17933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 17943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor memset(ret, 0 , (size_t) sizeof(xmlNodeSet)); 17953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (val != NULL) { 17963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->nodeTab = (xmlNodePtr *) xmlMalloc(XML_NODESET_DEFAULT * 17973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor sizeof(xmlNodePtr)); 17983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ret->nodeTab == NULL) { 1799d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard xmlXPathErrMemory(NULL, "creating nodeset\n"); 1800d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard xmlFree(ret); 18013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 18023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 18033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor memset(ret->nodeTab, 0 , 18043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XML_NODESET_DEFAULT * (size_t) sizeof(xmlNodePtr)); 18053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->nodeMax = XML_NODESET_DEFAULT; 1806044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if (val->type == XML_NAMESPACE_DECL) { 1807044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlNsPtr ns = (xmlNsPtr) val; 1808044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard 1809044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard ret->nodeTab[ret->nodeNr++] = 1810044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlXPathNodeSetDupNs((xmlNodePtr) ns->next, ns); 1811044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } else 1812044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard ret->nodeTab[ret->nodeNr++] = val; 18133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 18143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ret); 18153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 18163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 18173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 1818f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathNodeSetContains: 1819f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @cur: the node-set 1820f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @val: the node 1821f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 1822f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * checks whether @cur contains @val 1823f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 1824f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns true (1) if @cur contains @val, false (0) otherwise 1825f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */ 1826f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyerint 1827f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathNodeSetContains (xmlNodeSetPtr cur, xmlNodePtr val) { 1828f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer int i; 1829f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 1830a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard if ((cur == NULL) || (val == NULL)) return(0); 1831044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if (val->type == XML_NAMESPACE_DECL) { 1832044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard for (i = 0; i < cur->nodeNr; i++) { 1833044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if (cur->nodeTab[i]->type == XML_NAMESPACE_DECL) { 1834044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlNsPtr ns1, ns2; 1835044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard 1836044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard ns1 = (xmlNsPtr) val; 1837044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard ns2 = (xmlNsPtr) cur->nodeTab[i]; 1838044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if (ns1 == ns2) 1839044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard return(1); 1840044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if ((ns1->next != NULL) && (ns2->next == ns1->next) && 1841044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard (xmlStrEqual(ns1->prefix, ns2->prefix))) 1842044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard return(1); 1843044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } 1844044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } 1845044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } else { 1846044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard for (i = 0; i < cur->nodeNr; i++) { 1847044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if (cur->nodeTab[i] == val) 1848044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard return(1); 1849044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } 1850f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer } 1851f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(0); 1852f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer} 1853f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 1854f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/** 1855044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * xmlXPathNodeSetAddNs: 1856044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * @cur: the initial node set 1857044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * @node: the hosting node 1858044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * @ns: a the namespace node 1859044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * 1860044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * add a new namespace node to an existing NodeSet 1861044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard */ 186279376ba94845db7096c3917f4f40baeb450eb0e9Aleksey Saninvoid 1863044fc6b7476798cbb95277b4905e5111d7c2775dDaniel VeillardxmlXPathNodeSetAddNs(xmlNodeSetPtr cur, xmlNodePtr node, xmlNsPtr ns) { 1864044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard int i; 1865044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard 1866a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard 1867a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard if ((cur == NULL) || (ns == NULL) || (node == NULL) || 1868a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard (ns->type != XML_NAMESPACE_DECL) || 1869044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard (node->type != XML_ELEMENT_NODE)) 1870044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard return; 1871044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard 1872081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack /* @@ with_ns to check whether namespace nodes should be looked at @@ */ 1873044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard /* 1874081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack * prevent duplicates 1875044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard */ 1876044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard for (i = 0;i < cur->nodeNr;i++) { 1877044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if ((cur->nodeTab[i] != NULL) && 1878044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard (cur->nodeTab[i]->type == XML_NAMESPACE_DECL) && 1879c62a147963b5839fc815267706eaec381f90ca16Daniel Veillard (((xmlNsPtr)cur->nodeTab[i])->next == (xmlNsPtr) node) && 1880044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard (xmlStrEqual(ns->prefix, ((xmlNsPtr)cur->nodeTab[i])->prefix))) 1881044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard return; 1882044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } 1883044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard 1884044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard /* 1885044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * grow the nodeTab if needed 1886044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard */ 1887044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if (cur->nodeMax == 0) { 1888044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard cur->nodeTab = (xmlNodePtr *) xmlMalloc(XML_NODESET_DEFAULT * 1889044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard sizeof(xmlNodePtr)); 1890044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if (cur->nodeTab == NULL) { 1891d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard xmlXPathErrMemory(NULL, "growing nodeset\n"); 1892044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard return; 1893044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } 1894044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard memset(cur->nodeTab, 0 , 1895044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard XML_NODESET_DEFAULT * (size_t) sizeof(xmlNodePtr)); 1896044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard cur->nodeMax = XML_NODESET_DEFAULT; 1897044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } else if (cur->nodeNr == cur->nodeMax) { 1898044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlNodePtr *temp; 1899044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard 1900044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard cur->nodeMax *= 2; 1901044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard temp = (xmlNodePtr *) xmlRealloc(cur->nodeTab, cur->nodeMax * 1902044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard sizeof(xmlNodePtr)); 1903044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if (temp == NULL) { 1904d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard xmlXPathErrMemory(NULL, "growing nodeset\n"); 1905044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard return; 1906044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } 1907044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard cur->nodeTab = temp; 1908044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } 1909044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard cur->nodeTab[cur->nodeNr++] = xmlXPathNodeSetDupNs(node, ns); 1910044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard} 1911044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard 1912044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard/** 19133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNodeSetAdd: 19143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur: the initial node set 19153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val: a new xmlNodePtr 19163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 1917cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * add a new xmlNodePtr to an existing NodeSet 19183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 19193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 19203473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNodeSetAdd(xmlNodeSetPtr cur, xmlNodePtr val) { 19213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int i; 19223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1923a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard if ((cur == NULL) || (val == NULL)) return; 19243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1925ef0b45016373d65700ef6f7d494a200758b2e4c5Daniel Veillard#if 0 1926652d8a949447833405cc0805f4b7ff1179e59ed2Daniel Veillard if ((val->type == XML_ELEMENT_NODE) && (val->name[0] == ' ')) 1927652d8a949447833405cc0805f4b7ff1179e59ed2Daniel Veillard return; /* an XSLT fake node */ 1928ef0b45016373d65700ef6f7d494a200758b2e4c5Daniel Veillard#endif 1929652d8a949447833405cc0805f4b7ff1179e59ed2Daniel Veillard 1930081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack /* @@ with_ns to check whether namespace nodes should be looked at @@ */ 19313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 1932081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack * prevent duplcates 19333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 19343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor for (i = 0;i < cur->nodeNr;i++) 19353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur->nodeTab[i] == val) return; 19363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 19373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 19383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * grow the nodeTab if needed 19393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 19403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur->nodeMax == 0) { 19413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur->nodeTab = (xmlNodePtr *) xmlMalloc(XML_NODESET_DEFAULT * 19423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor sizeof(xmlNodePtr)); 19433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur->nodeTab == NULL) { 1944d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard xmlXPathErrMemory(NULL, "growing nodeset\n"); 19453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return; 19463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 19473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor memset(cur->nodeTab, 0 , 19483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XML_NODESET_DEFAULT * (size_t) sizeof(xmlNodePtr)); 19493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur->nodeMax = XML_NODESET_DEFAULT; 19503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else if (cur->nodeNr == cur->nodeMax) { 19513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlNodePtr *temp; 19523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 19533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur->nodeMax *= 2; 19543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor temp = (xmlNodePtr *) xmlRealloc(cur->nodeTab, cur->nodeMax * 19553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor sizeof(xmlNodePtr)); 19563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (temp == NULL) { 1957d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard xmlXPathErrMemory(NULL, "growing nodeset\n"); 19583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return; 19593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 19603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur->nodeTab = temp; 19613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 1962044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if (val->type == XML_NAMESPACE_DECL) { 1963044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlNsPtr ns = (xmlNsPtr) val; 1964044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard 1965044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard cur->nodeTab[cur->nodeNr++] = 1966044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlXPathNodeSetDupNs((xmlNodePtr) ns->next, ns); 1967044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } else 1968044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard cur->nodeTab[cur->nodeNr++] = val; 19693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 19703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 19713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 19723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNodeSetAddUnique: 19733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur: the initial node set 19743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val: a new xmlNodePtr 19753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 1976cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * add a new xmlNodePtr to an existing NodeSet, optimized version 19773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * when we are sure the node is not already in the set. 19783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 19793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 19803473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNodeSetAddUnique(xmlNodeSetPtr cur, xmlNodePtr val) { 1981a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard if ((cur == NULL) || (val == NULL)) return; 19823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1983ef0b45016373d65700ef6f7d494a200758b2e4c5Daniel Veillard#if 0 1984652d8a949447833405cc0805f4b7ff1179e59ed2Daniel Veillard if ((val->type == XML_ELEMENT_NODE) && (val->name[0] == ' ')) 1985652d8a949447833405cc0805f4b7ff1179e59ed2Daniel Veillard return; /* an XSLT fake node */ 1986ef0b45016373d65700ef6f7d494a200758b2e4c5Daniel Veillard#endif 1987652d8a949447833405cc0805f4b7ff1179e59ed2Daniel Veillard 1988081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack /* @@ with_ns to check whether namespace nodes should be looked at @@ */ 19893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 19903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * grow the nodeTab if needed 19913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 19923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur->nodeMax == 0) { 19933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur->nodeTab = (xmlNodePtr *) xmlMalloc(XML_NODESET_DEFAULT * 19943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor sizeof(xmlNodePtr)); 19953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur->nodeTab == NULL) { 1996d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard xmlXPathErrMemory(NULL, "growing nodeset\n"); 19973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return; 19983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 19993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor memset(cur->nodeTab, 0 , 20003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XML_NODESET_DEFAULT * (size_t) sizeof(xmlNodePtr)); 20013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur->nodeMax = XML_NODESET_DEFAULT; 20023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else if (cur->nodeNr == cur->nodeMax) { 20033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlNodePtr *temp; 20043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 20053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur->nodeMax *= 2; 20063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor temp = (xmlNodePtr *) xmlRealloc(cur->nodeTab, cur->nodeMax * 20073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor sizeof(xmlNodePtr)); 20083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (temp == NULL) { 2009d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard xmlXPathErrMemory(NULL, "growing nodeset\n"); 20103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return; 20113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 20123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur->nodeTab = temp; 20133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 2014044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if (val->type == XML_NAMESPACE_DECL) { 2015044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlNsPtr ns = (xmlNsPtr) val; 2016044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard 2017044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard cur->nodeTab[cur->nodeNr++] = 2018044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlXPathNodeSetDupNs((xmlNodePtr) ns->next, ns); 2019044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } else 2020044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard cur->nodeTab[cur->nodeNr++] = val; 20213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 20223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 20233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 20243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNodeSetMerge: 20253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val1: the first NodeSet or NULL 20263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val2: the second NodeSet 20273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 20283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Merges two nodesets, all nodes from @val2 are added to @val1 20293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * if @val1 is NULL, a new set is created and copied from @val2 20303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 2031cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * Returns @val1 once extended or NULL in case of error. 20323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 20333473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNodeSetPtr 20343473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNodeSetMerge(xmlNodeSetPtr val1, xmlNodeSetPtr val2) { 2035d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard int i, j, initNr, skip; 20363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 20373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (val2 == NULL) return(val1); 20383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (val1 == NULL) { 20393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor val1 = xmlXPathNodeSetCreate(NULL); 20403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 20413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 2042081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack /* @@ with_ns to check whether namespace nodes should be looked at @@ */ 20433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor initNr = val1->nodeNr; 20443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 20453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor for (i = 0;i < val2->nodeNr;i++) { 20463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 2047081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack * check against duplicates 20483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 2049d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard skip = 0; 2050d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard for (j = 0; j < initNr; j++) { 2051d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard if (val1->nodeTab[j] == val2->nodeTab[i]) { 2052d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard skip = 1; 2053d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard break; 2054044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } else if ((val1->nodeTab[j]->type == XML_NAMESPACE_DECL) && 2055044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard (val2->nodeTab[i]->type == XML_NAMESPACE_DECL)) { 2056044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlNsPtr ns1, ns2; 2057044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard ns1 = (xmlNsPtr) val1->nodeTab[j]; 2058044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard ns2 = (xmlNsPtr) val2->nodeTab[i]; 2059044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if ((ns1->next == ns2->next) && 2060044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard (xmlStrEqual(ns1->prefix, ns2->prefix))) { 2061044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard skip = 1; 2062044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard break; 2063044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } 2064d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard } 2065d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard } 2066d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard if (skip) 2067d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard continue; 20683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 20693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 20703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * grow the nodeTab if needed 20713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 20723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (val1->nodeMax == 0) { 20733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor val1->nodeTab = (xmlNodePtr *) xmlMalloc(XML_NODESET_DEFAULT * 20743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor sizeof(xmlNodePtr)); 20753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (val1->nodeTab == NULL) { 2076d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard xmlXPathErrMemory(NULL, "merging nodeset\n"); 20773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 20783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 20793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor memset(val1->nodeTab, 0 , 20803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XML_NODESET_DEFAULT * (size_t) sizeof(xmlNodePtr)); 20813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor val1->nodeMax = XML_NODESET_DEFAULT; 20823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else if (val1->nodeNr == val1->nodeMax) { 20833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlNodePtr *temp; 20843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 20853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor val1->nodeMax *= 2; 20863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor temp = (xmlNodePtr *) xmlRealloc(val1->nodeTab, val1->nodeMax * 20873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor sizeof(xmlNodePtr)); 20883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (temp == NULL) { 2089d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard xmlXPathErrMemory(NULL, "merging nodeset\n"); 20903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 20913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 20923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor val1->nodeTab = temp; 20933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 2094044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if (val2->nodeTab[i]->type == XML_NAMESPACE_DECL) { 2095044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlNsPtr ns = (xmlNsPtr) val2->nodeTab[i]; 2096044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard 2097044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard val1->nodeTab[val1->nodeNr++] = 2098044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlXPathNodeSetDupNs((xmlNodePtr) ns->next, ns); 2099044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } else 2100044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard val1->nodeTab[val1->nodeNr++] = val2->nodeTab[i]; 21013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 21023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 21033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(val1); 21043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 21053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 21063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 210775be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard * xmlXPathNodeSetMergeUnique: 210875be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard * @val1: the first NodeSet or NULL 210975be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard * @val2: the second NodeSet 211075be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard * 211175be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard * Merges two nodesets, all nodes from @val2 are added to @val1 211275be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard * if @val1 is NULL, a new set is created and copied from @val2 211375be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard * 211475be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard * Returns @val1 once extended or NULL in case of error. 211575be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard */ 211675be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillardstatic xmlNodeSetPtr 211775be0130855fe02d238bbbf19a04d3c5eb45f494Daniel VeillardxmlXPathNodeSetMergeUnique(xmlNodeSetPtr val1, xmlNodeSetPtr val2) { 211878637da0ea1c833dfdfad87a9aa5bea14510d08aWilliam M. Brack int i; 211975be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard 212075be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard if (val2 == NULL) return(val1); 212175be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard if (val1 == NULL) { 212275be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard val1 = xmlXPathNodeSetCreate(NULL); 212375be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard } 212475be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard 2125081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack /* @@ with_ns to check whether namespace nodes should be looked at @@ */ 212675be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard 212775be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard for (i = 0;i < val2->nodeNr;i++) { 212875be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard /* 212975be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard * grow the nodeTab if needed 213075be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard */ 213175be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard if (val1->nodeMax == 0) { 213275be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard val1->nodeTab = (xmlNodePtr *) xmlMalloc(XML_NODESET_DEFAULT * 213375be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard sizeof(xmlNodePtr)); 213475be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard if (val1->nodeTab == NULL) { 2135d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard xmlXPathErrMemory(NULL, "merging nodeset\n"); 213675be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard return(NULL); 213775be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard } 213875be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard memset(val1->nodeTab, 0 , 213975be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard XML_NODESET_DEFAULT * (size_t) sizeof(xmlNodePtr)); 214075be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard val1->nodeMax = XML_NODESET_DEFAULT; 214175be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard } else if (val1->nodeNr == val1->nodeMax) { 214275be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard xmlNodePtr *temp; 214375be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard 214475be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard val1->nodeMax *= 2; 214575be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard temp = (xmlNodePtr *) xmlRealloc(val1->nodeTab, val1->nodeMax * 214675be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard sizeof(xmlNodePtr)); 214775be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard if (temp == NULL) { 2148d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard xmlXPathErrMemory(NULL, "merging nodeset\n"); 214975be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard return(NULL); 215075be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard } 215175be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard val1->nodeTab = temp; 215275be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard } 215375be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard if (val2->nodeTab[i]->type == XML_NAMESPACE_DECL) { 215475be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard xmlNsPtr ns = (xmlNsPtr) val2->nodeTab[i]; 215575be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard 215675be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard val1->nodeTab[val1->nodeNr++] = 215775be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard xmlXPathNodeSetDupNs((xmlNodePtr) ns->next, ns); 215875be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard } else 215975be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard val1->nodeTab[val1->nodeNr++] = val2->nodeTab[i]; 216075be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard } 216175be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard 216275be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard return(val1); 216375be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard} 216475be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard 216575be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard/** 21663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNodeSetDel: 21673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur: the initial node set 21683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val: an xmlNodePtr 21693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 21703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Removes an xmlNodePtr from an existing NodeSet 21713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 21723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 21733473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNodeSetDel(xmlNodeSetPtr cur, xmlNodePtr val) { 21743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int i; 21753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 21763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == NULL) return; 21773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (val == NULL) return; 21783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 21793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 2180081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack * find node in nodeTab 21813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 21823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor for (i = 0;i < cur->nodeNr;i++) 21833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur->nodeTab[i] == val) break; 21843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 2185081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack if (i >= cur->nodeNr) { /* not found */ 21863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG 21873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 21883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "xmlXPathNodeSetDel: Node %s wasn't found in NodeList\n", 21893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor val->name); 21903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 21913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return; 21923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 2193044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if ((cur->nodeTab[i] != NULL) && 2194044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard (cur->nodeTab[i]->type == XML_NAMESPACE_DECL)) 2195044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlXPathNodeSetFreeNs((xmlNsPtr) cur->nodeTab[i]); 21963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur->nodeNr--; 21973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor for (;i < cur->nodeNr;i++) 21983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur->nodeTab[i] = cur->nodeTab[i + 1]; 21993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur->nodeTab[cur->nodeNr] = NULL; 22003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 22013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 22023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 22033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNodeSetRemove: 22043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur: the initial node set 22053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val: the index to remove 22063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 22073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Removes an entry from an existing NodeSet list. 22083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 22093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 22103473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNodeSetRemove(xmlNodeSetPtr cur, int val) { 22113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == NULL) return; 22123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (val >= cur->nodeNr) return; 2213044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if ((cur->nodeTab[val] != NULL) && 2214044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard (cur->nodeTab[val]->type == XML_NAMESPACE_DECL)) 2215044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlXPathNodeSetFreeNs((xmlNsPtr) cur->nodeTab[val]); 22163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur->nodeNr--; 22173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor for (;val < cur->nodeNr;val++) 22183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur->nodeTab[val] = cur->nodeTab[val + 1]; 22193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur->nodeTab[cur->nodeNr] = NULL; 22203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 22213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 22223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 22233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathFreeNodeSet: 22243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @obj: the xmlNodeSetPtr to free 22253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 22263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Free the NodeSet compound (not the actual nodes !). 22273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 22283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 22293473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathFreeNodeSet(xmlNodeSetPtr obj) { 22303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (obj == NULL) return; 22313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (obj->nodeTab != NULL) { 2232044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard int i; 2233044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard 2234081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack /* @@ with_ns to check whether namespace nodes should be looked at @@ */ 2235044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard for (i = 0;i < obj->nodeNr;i++) 2236044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if ((obj->nodeTab[i] != NULL) && 2237044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard (obj->nodeTab[i]->type == XML_NAMESPACE_DECL)) 2238044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlXPathNodeSetFreeNs((xmlNsPtr) obj->nodeTab[i]); 22393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(obj->nodeTab); 22403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 22413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(obj); 22423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 22433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 22443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 22453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathFreeValueTree: 22463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @obj: the xmlNodeSetPtr to free 22473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 22483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Free the NodeSet compound and the actual tree, this is different 22493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * from xmlXPathFreeNodeSet() 22503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 225156a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic void 22523473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathFreeValueTree(xmlNodeSetPtr obj) { 22533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int i; 22543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 22553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (obj == NULL) return; 22563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 22573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (obj->nodeTab != NULL) { 2258044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard for (i = 0;i < obj->nodeNr;i++) { 2259044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if (obj->nodeTab[i] != NULL) { 2260044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if (obj->nodeTab[i]->type == XML_NAMESPACE_DECL) { 2261044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlXPathNodeSetFreeNs((xmlNsPtr) obj->nodeTab[i]); 2262044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } else { 2263044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlFreeNodeList(obj->nodeTab[i]); 2264044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } 2265044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } 2266044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } 22673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(obj->nodeTab); 22683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 22693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(obj); 22703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 22713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 22723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#if defined(DEBUG) || defined(DEBUG_STEP) 22733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 22743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlGenericErrorContextNodeSet: 22753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @output: a FILE * for the output 2276081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack * @obj: the xmlNodeSetPtr to display 22773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 22783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Quick display of a NodeSet 22793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 22803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 22813473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlGenericErrorContextNodeSet(FILE *output, xmlNodeSetPtr obj) { 22823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int i; 22833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 22843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (output == NULL) output = xmlGenericErrorContext; 22853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (obj == NULL) { 22863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, "NodeSet == NULL !\n"); 22873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return; 22883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 22893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (obj->nodeNr == 0) { 22903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, "NodeSet is empty\n"); 22913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return; 22923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 22933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (obj->nodeTab == NULL) { 22943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, " nodeTab == NULL !\n"); 22953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return; 22963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 22973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor for (i = 0; i < obj->nodeNr; i++) { 22983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (obj->nodeTab[i] == NULL) { 22993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, " NULL !\n"); 23003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return; 23013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 23023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((obj->nodeTab[i]->type == XML_DOCUMENT_NODE) || 23033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor (obj->nodeTab[i]->type == XML_HTML_DOCUMENT_NODE)) 23043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, " /"); 23053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else if (obj->nodeTab[i]->name == NULL) 23063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, " noname!"); 23073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else fprintf(output, " %s", obj->nodeTab[i]->name); 23083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 23093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, "\n"); 23103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 23113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 23123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 23133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 23143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNewNodeSet: 23153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val: the NodePtr value 23163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 23173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Create a new xmlXPathObjectPtr of type NodeSet and initialize 23183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * it with the single Node @val 23193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 23203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the newly created object. 23213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 23223473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathObjectPtr 23233473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNewNodeSet(xmlNodePtr val) { 23243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr ret; 23253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 23263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject)); 23273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ret == NULL) { 2328d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard xmlXPathErrMemory(NULL, "creating nodeset\n"); 23293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 23303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 23313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor memset(ret, 0 , (size_t) sizeof(xmlXPathObject)); 23323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->type = XPATH_NODESET; 233377851710aba3a0effdc6af67ea4caf212307420cDaniel Veillard ret->boolval = 0; 23343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->nodesetval = xmlXPathNodeSetCreate(val); 2335081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack /* @@ with_ns to check whether namespace nodes should be looked at @@ */ 23363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ret); 23373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 23383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 23393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 23403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNewValueTree: 23413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val: the NodePtr value 23423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 23433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Create a new xmlXPathObjectPtr of type Value Tree (XSLT) and initialize 23443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * it with the tree root @val 23453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 23463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the newly created object. 23473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 23483473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathObjectPtr 23493473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNewValueTree(xmlNodePtr val) { 23503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr ret; 23513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 23523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject)); 23533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ret == NULL) { 2354d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard xmlXPathErrMemory(NULL, "creating result value tree\n"); 23553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 23563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 23573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor memset(ret, 0 , (size_t) sizeof(xmlXPathObject)); 23583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->type = XPATH_XSLT_TREE; 23590ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard ret->boolval = 1; 23600ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard ret->user = (void *) val; 23613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->nodesetval = xmlXPathNodeSetCreate(val); 23623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ret); 23633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 23643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 23653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 23663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNewNodeSetList: 23673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val: an existing NodeSet 23683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 23693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Create a new xmlXPathObjectPtr of type NodeSet and initialize 23703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * it with the Nodeset @val 23713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 23723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the newly created object. 23733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 23743473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathObjectPtr 2375044fc6b7476798cbb95277b4905e5111d7c2775dDaniel VeillardxmlXPathNewNodeSetList(xmlNodeSetPtr val) 2376044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard{ 23773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr ret; 23783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int i; 23793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 23803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (val == NULL) 2381044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard ret = NULL; 23823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else if (val->nodeTab == NULL) 2383044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard ret = xmlXPathNewNodeSet(NULL); 2384044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard else { 2385044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard ret = xmlXPathNewNodeSet(val->nodeTab[0]); 2386044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard for (i = 1; i < val->nodeNr; ++i) 2387044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlXPathNodeSetAddUnique(ret->nodesetval, val->nodeTab[i]); 2388044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } 23893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 2390044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard return (ret); 23913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 23923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 23933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 23943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathWrapNodeSet: 23953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val: the NodePtr value 23963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 23973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Wrap the Nodeset @val in a new xmlXPathObjectPtr 23983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 23993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the newly created object. 24003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 24013473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathObjectPtr 24023473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathWrapNodeSet(xmlNodeSetPtr val) { 24033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr ret; 24043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 24053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject)); 24063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ret == NULL) { 2407d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard xmlXPathErrMemory(NULL, "creating node set object\n"); 24083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 24093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 24103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor memset(ret, 0 , (size_t) sizeof(xmlXPathObject)); 24113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->type = XPATH_NODESET; 24123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->nodesetval = val; 24133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ret); 24143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 24153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 24163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 24173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathFreeNodeSetList: 24183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @obj: an existing NodeSetList object 24193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 24203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Free up the xmlXPathObjectPtr @obj but don't deallocate the objects in 24213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the list contrary to xmlXPathFreeObject(). 24223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 24233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 24243473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathFreeNodeSetList(xmlXPathObjectPtr obj) { 24253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (obj == NULL) return; 24263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(obj); 24273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 24283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 2429f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/** 2430f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathDifference: 2431f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes1: a node-set 2432f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes2: a node-set 2433f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 2434f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Implements the EXSLT - Sets difference() function: 2435f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * node-set set:difference (node-set, node-set) 2436f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 2437f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns the difference between the two node sets, or nodes1 if 2438f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * nodes2 is empty 2439f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */ 2440f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlNodeSetPtr 2441f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathDifference (xmlNodeSetPtr nodes1, xmlNodeSetPtr nodes2) { 2442f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlNodeSetPtr ret; 2443f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer int i, l1; 2444f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlNodePtr cur; 2445f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 2446f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (xmlXPathNodeSetIsEmpty(nodes2)) 2447f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(nodes1); 2448f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 2449f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer ret = xmlXPathNodeSetCreate(NULL); 2450f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (xmlXPathNodeSetIsEmpty(nodes1)) 2451f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(ret); 2452f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 2453f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer l1 = xmlXPathNodeSetGetLength(nodes1); 2454f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 2455f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer for (i = 0; i < l1; i++) { 2456f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer cur = xmlXPathNodeSetItem(nodes1, i); 2457f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (!xmlXPathNodeSetContains(nodes2, cur)) 2458f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathNodeSetAddUnique(ret, cur); 2459f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer } 2460f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(ret); 2461f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer} 2462f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 2463f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/** 2464f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathIntersection: 2465f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes1: a node-set 2466f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes2: a node-set 2467f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 2468f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Implements the EXSLT - Sets intersection() function: 2469f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * node-set set:intersection (node-set, node-set) 2470f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 2471f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns a node set comprising the nodes that are within both the 2472f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * node sets passed as arguments 2473f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */ 2474f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlNodeSetPtr 2475f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathIntersection (xmlNodeSetPtr nodes1, xmlNodeSetPtr nodes2) { 2476f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlNodeSetPtr ret = xmlXPathNodeSetCreate(NULL); 2477f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer int i, l1; 2478f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlNodePtr cur; 2479f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 2480f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (xmlXPathNodeSetIsEmpty(nodes1)) 2481f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(ret); 2482f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (xmlXPathNodeSetIsEmpty(nodes2)) 2483f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(ret); 2484f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 2485f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer l1 = xmlXPathNodeSetGetLength(nodes1); 2486f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 2487f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer for (i = 0; i < l1; i++) { 2488f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer cur = xmlXPathNodeSetItem(nodes1, i); 2489f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (xmlXPathNodeSetContains(nodes2, cur)) 2490f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathNodeSetAddUnique(ret, cur); 2491f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer } 2492f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(ret); 2493f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer} 2494f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 2495f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/** 2496f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathDistinctSorted: 2497f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes: a node-set, sorted by document order 2498f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 2499f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Implements the EXSLT - Sets distinct() function: 2500f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * node-set set:distinct (node-set) 2501f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 2502f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns a subset of the nodes contained in @nodes, or @nodes if 2503f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * it is empty 2504f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */ 2505f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlNodeSetPtr 2506f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathDistinctSorted (xmlNodeSetPtr nodes) { 2507f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlNodeSetPtr ret; 2508f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlHashTablePtr hash; 2509f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer int i, l; 2510f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlChar * strval; 2511f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlNodePtr cur; 2512f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 2513f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (xmlXPathNodeSetIsEmpty(nodes)) 2514f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(nodes); 2515f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 2516f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer ret = xmlXPathNodeSetCreate(NULL); 2517f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer l = xmlXPathNodeSetGetLength(nodes); 2518f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer hash = xmlHashCreate (l); 2519f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer for (i = 0; i < l; i++) { 2520f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer cur = xmlXPathNodeSetItem(nodes, i); 2521f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer strval = xmlXPathCastNodeToString(cur); 2522f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (xmlHashLookup(hash, strval) == NULL) { 2523f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlHashAddEntry(hash, strval, strval); 2524f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathNodeSetAddUnique(ret, cur); 2525f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer } else { 2526f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlFree(strval); 2527f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer } 2528f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer } 2529f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlHashFree(hash, (xmlHashDeallocator) xmlFree); 2530f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(ret); 2531f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer} 2532f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 2533f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/** 2534f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathDistinct: 2535f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes: a node-set 2536f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 2537f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Implements the EXSLT - Sets distinct() function: 2538f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * node-set set:distinct (node-set) 2539f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes is sorted by document order, then #exslSetsDistinctSorted 2540f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * is called with the sorted node-set 2541f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 2542f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns a subset of the nodes contained in @nodes, or @nodes if 2543f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * it is empty 2544f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */ 2545f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlNodeSetPtr 2546f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathDistinct (xmlNodeSetPtr nodes) { 2547f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (xmlXPathNodeSetIsEmpty(nodes)) 2548f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(nodes); 2549f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 2550f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathNodeSetSort(nodes); 2551f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(xmlXPathDistinctSorted(nodes)); 2552f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer} 2553f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 2554f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/** 2555f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathHasSameNodes: 2556f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes1: a node-set 2557f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes2: a node-set 2558f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 2559f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Implements the EXSLT - Sets has-same-nodes function: 2560f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * boolean set:has-same-node(node-set, node-set) 2561f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 2562f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns true (1) if @nodes1 shares any node with @nodes2, false (0) 2563f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * otherwise 2564f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */ 2565f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyerint 2566f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathHasSameNodes (xmlNodeSetPtr nodes1, xmlNodeSetPtr nodes2) { 2567f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer int i, l; 2568f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlNodePtr cur; 2569f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 2570f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (xmlXPathNodeSetIsEmpty(nodes1) || 2571f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathNodeSetIsEmpty(nodes2)) 2572f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(0); 2573f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 2574f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer l = xmlXPathNodeSetGetLength(nodes1); 2575f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer for (i = 0; i < l; i++) { 2576f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer cur = xmlXPathNodeSetItem(nodes1, i); 2577f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (xmlXPathNodeSetContains(nodes2, cur)) 2578f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(1); 2579f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer } 2580f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(0); 2581f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer} 2582f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 2583f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/** 2584f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathNodeLeadingSorted: 2585f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes: a node-set, sorted by document order 2586f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @node: a node 2587f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 2588f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Implements the EXSLT - Sets leading() function: 2589f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * node-set set:leading (node-set, node-set) 2590f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 2591f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns the nodes in @nodes that precede @node in document order, 2592f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes if @node is NULL or an empty node-set if @nodes 2593f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * doesn't contain @node 2594f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */ 2595f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlNodeSetPtr 2596f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathNodeLeadingSorted (xmlNodeSetPtr nodes, xmlNodePtr node) { 2597f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer int i, l; 2598f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlNodePtr cur; 2599f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlNodeSetPtr ret; 2600f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 2601f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (node == NULL) 2602f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(nodes); 2603f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 2604f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer ret = xmlXPathNodeSetCreate(NULL); 2605f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (xmlXPathNodeSetIsEmpty(nodes) || 2606f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer (!xmlXPathNodeSetContains(nodes, node))) 2607f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(ret); 2608f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 2609f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer l = xmlXPathNodeSetGetLength(nodes); 2610f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer for (i = 0; i < l; i++) { 2611f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer cur = xmlXPathNodeSetItem(nodes, i); 2612f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (cur == node) 2613f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer break; 2614f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathNodeSetAddUnique(ret, cur); 2615f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer } 2616f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(ret); 2617f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer} 2618f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 2619f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/** 2620f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathNodeLeading: 2621f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes: a node-set 2622f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @node: a node 2623f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 2624f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Implements the EXSLT - Sets leading() function: 2625f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * node-set set:leading (node-set, node-set) 2626f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes is sorted by document order, then #exslSetsNodeLeadingSorted 2627f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * is called. 2628f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 2629f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns the nodes in @nodes that precede @node in document order, 2630f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes if @node is NULL or an empty node-set if @nodes 2631f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * doesn't contain @node 2632f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */ 2633f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlNodeSetPtr 2634f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathNodeLeading (xmlNodeSetPtr nodes, xmlNodePtr node) { 2635f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathNodeSetSort(nodes); 2636f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(xmlXPathNodeLeadingSorted(nodes, node)); 2637f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer} 2638f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 2639f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/** 2640f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathLeadingSorted: 2641f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes1: a node-set, sorted by document order 2642f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes2: a node-set, sorted by document order 2643f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 2644f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Implements the EXSLT - Sets leading() function: 2645f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * node-set set:leading (node-set, node-set) 2646f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 2647f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns the nodes in @nodes1 that precede the first node in @nodes2 2648f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * in document order, @nodes1 if @nodes2 is NULL or empty or 2649f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * an empty node-set if @nodes1 doesn't contain @nodes2 2650f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */ 2651f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlNodeSetPtr 2652f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathLeadingSorted (xmlNodeSetPtr nodes1, xmlNodeSetPtr nodes2) { 2653f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (xmlXPathNodeSetIsEmpty(nodes2)) 2654f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(nodes1); 2655f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(xmlXPathNodeLeadingSorted(nodes1, 2656f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathNodeSetItem(nodes2, 1))); 2657f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer} 2658f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 2659f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/** 2660f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathLeading: 2661f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes1: a node-set 2662f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes2: a node-set 2663f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 2664f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Implements the EXSLT - Sets leading() function: 2665f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * node-set set:leading (node-set, node-set) 2666f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes1 and @nodes2 are sorted by document order, then 2667f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * #exslSetsLeadingSorted is called. 2668f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 2669f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns the nodes in @nodes1 that precede the first node in @nodes2 2670f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * in document order, @nodes1 if @nodes2 is NULL or empty or 2671f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * an empty node-set if @nodes1 doesn't contain @nodes2 2672f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */ 2673f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlNodeSetPtr 2674f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathLeading (xmlNodeSetPtr nodes1, xmlNodeSetPtr nodes2) { 2675f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (xmlXPathNodeSetIsEmpty(nodes2)) 2676f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(nodes1); 2677f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (xmlXPathNodeSetIsEmpty(nodes1)) 2678f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(xmlXPathNodeSetCreate(NULL)); 2679f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathNodeSetSort(nodes1); 2680f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathNodeSetSort(nodes2); 2681f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(xmlXPathNodeLeadingSorted(nodes1, 2682f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathNodeSetItem(nodes2, 1))); 2683f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer} 2684f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 2685f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/** 2686f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathNodeTrailingSorted: 2687f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes: a node-set, sorted by document order 2688f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @node: a node 2689f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 2690f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Implements the EXSLT - Sets trailing() function: 2691f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * node-set set:trailing (node-set, node-set) 2692f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 2693f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns the nodes in @nodes that follow @node in document order, 2694f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes if @node is NULL or an empty node-set if @nodes 2695f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * doesn't contain @node 2696f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */ 2697f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlNodeSetPtr 2698f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathNodeTrailingSorted (xmlNodeSetPtr nodes, xmlNodePtr node) { 2699f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer int i, l; 2700f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlNodePtr cur; 2701f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlNodeSetPtr ret; 2702f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 2703f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (node == NULL) 2704f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(nodes); 2705f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 2706f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer ret = xmlXPathNodeSetCreate(NULL); 2707f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (xmlXPathNodeSetIsEmpty(nodes) || 2708f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer (!xmlXPathNodeSetContains(nodes, node))) 2709f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(ret); 2710f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 2711f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer l = xmlXPathNodeSetGetLength(nodes); 2712f186c8259ae985cd56b3e14c1def484ab127fd14Thomas Broyer for (i = l; i > 0; i--) { 2713f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer cur = xmlXPathNodeSetItem(nodes, i); 2714f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (cur == node) 2715f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer break; 2716f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathNodeSetAddUnique(ret, cur); 2717f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer } 2718f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(ret); 2719f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer} 2720f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 2721f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/** 2722f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathNodeTrailing: 2723f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes: a node-set 2724f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @node: a node 2725f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 2726f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Implements the EXSLT - Sets trailing() function: 2727f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * node-set set:trailing (node-set, node-set) 2728f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes is sorted by document order, then #xmlXPathNodeTrailingSorted 2729f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * is called. 2730f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 2731f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns the nodes in @nodes that follow @node in document order, 2732f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes if @node is NULL or an empty node-set if @nodes 2733f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * doesn't contain @node 2734f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */ 2735f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlNodeSetPtr 2736f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathNodeTrailing (xmlNodeSetPtr nodes, xmlNodePtr node) { 2737f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathNodeSetSort(nodes); 2738f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(xmlXPathNodeTrailingSorted(nodes, node)); 2739f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer} 2740f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 2741f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/** 2742f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathTrailingSorted: 2743f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes1: a node-set, sorted by document order 2744f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes2: a node-set, sorted by document order 2745f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 2746f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Implements the EXSLT - Sets trailing() function: 2747f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * node-set set:trailing (node-set, node-set) 2748f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 2749f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns the nodes in @nodes1 that follow the first node in @nodes2 2750f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * in document order, @nodes1 if @nodes2 is NULL or empty or 2751f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * an empty node-set if @nodes1 doesn't contain @nodes2 2752f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */ 2753f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlNodeSetPtr 2754f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathTrailingSorted (xmlNodeSetPtr nodes1, xmlNodeSetPtr nodes2) { 2755f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (xmlXPathNodeSetIsEmpty(nodes2)) 2756f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(nodes1); 2757f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(xmlXPathNodeTrailingSorted(nodes1, 2758f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathNodeSetItem(nodes2, 0))); 2759f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer} 2760f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 2761f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/** 2762f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathTrailing: 2763f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes1: a node-set 2764f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes2: a node-set 2765f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 2766f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Implements the EXSLT - Sets trailing() function: 2767f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * node-set set:trailing (node-set, node-set) 2768f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes1 and @nodes2 are sorted by document order, then 2769f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * #xmlXPathTrailingSorted is called. 2770f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 2771f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns the nodes in @nodes1 that follow the first node in @nodes2 2772f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * in document order, @nodes1 if @nodes2 is NULL or empty or 2773f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * an empty node-set if @nodes1 doesn't contain @nodes2 2774f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */ 2775f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlNodeSetPtr 2776f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathTrailing (xmlNodeSetPtr nodes1, xmlNodeSetPtr nodes2) { 2777f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (xmlXPathNodeSetIsEmpty(nodes2)) 2778f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(nodes1); 2779f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (xmlXPathNodeSetIsEmpty(nodes1)) 2780f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(xmlXPathNodeSetCreate(NULL)); 2781f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathNodeSetSort(nodes1); 2782f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathNodeSetSort(nodes2); 2783f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(xmlXPathNodeTrailingSorted(nodes1, 2784f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathNodeSetItem(nodes2, 0))); 2785f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer} 2786f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 27873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/************************************************************************ 27883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * * 27893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Routines to handle extra functions * 27903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * * 27913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ************************************************************************/ 27923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 27933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 27943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathRegisterFunc: 27953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath context 27963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @name: the function name 27973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @f: the function implementation or NULL 27983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 27993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Register a new function. If @f is NULL it unregisters the function 28003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 28013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns 0 in case of success, -1 in case of error 28023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 28033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorint 28043473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathRegisterFunc(xmlXPathContextPtr ctxt, const xmlChar *name, 28053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFunction f) { 28063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(xmlXPathRegisterFuncNS(ctxt, name, NULL, f)); 28073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 28083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 28093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 28103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathRegisterFuncNS: 28113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath context 28123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @name: the function name 28133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ns_uri: the function namespace URI 28143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @f: the function implementation or NULL 28153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 28163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Register a new function. If @f is NULL it unregisters the function 28173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 28183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns 0 in case of success, -1 in case of error 28193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 28203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorint 28213473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathRegisterFuncNS(xmlXPathContextPtr ctxt, const xmlChar *name, 28223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor const xmlChar *ns_uri, xmlXPathFunction f) { 28233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt == NULL) 28243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(-1); 28253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (name == NULL) 28263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(-1); 28273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 28283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->funcHash == NULL) 28293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ctxt->funcHash = xmlHashCreate(0); 28303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->funcHash == NULL) 28313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(-1); 283294394cd1e494f8d669b310748f54192268185c8dDaniel Veillard if (f == NULL) 283394394cd1e494f8d669b310748f54192268185c8dDaniel Veillard return(xmlHashRemoveEntry2(ctxt->funcHash, name, ns_uri, NULL)); 2834ad0e67c57f26f691fc120d5c5336cee9885cf324William M. Brack return(xmlHashAddEntry2(ctxt->funcHash, name, ns_uri, XML_CAST_FPTR(f))); 28353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 28363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 28373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 2838ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer * xmlXPathRegisterFuncLookup: 2839ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer * @ctxt: the XPath context 2840ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer * @f: the lookup function 2841cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * @funcCtxt: the lookup data 2842ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer * 2843cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * Registers an external mechanism to do function lookup. 2844ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer */ 2845ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyervoid 2846ba4ad3263bf7f5625329f115367e0c7018521a16Thomas BroyerxmlXPathRegisterFuncLookup (xmlXPathContextPtr ctxt, 2847ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer xmlXPathFuncLookupFunc f, 2848ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer void *funcCtxt) { 2849ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer if (ctxt == NULL) 2850ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer return; 28516ebf3c4c1a78406d15e8629b4a7b3d52549f0c8bDaniel Veillard ctxt->funcLookupFunc = f; 2852ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer ctxt->funcLookupData = funcCtxt; 2853ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer} 2854ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer 2855ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer/** 28563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathFunctionLookup: 28573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath context 28583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @name: the function name 28593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 28603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Search in the Function array of the context for the given 28613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * function. 28623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 28633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the xmlXPathFunction or NULL if not found 28643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 28653473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathFunction 28663473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathFunctionLookup(xmlXPathContextPtr ctxt, const xmlChar *name) { 2867ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer if (ctxt == NULL) 2868ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer return (NULL); 2869ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer 2870ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer if (ctxt->funcLookupFunc != NULL) { 2871ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer xmlXPathFunction ret; 287299e55ebe945f6f4de33e8454f2770e02295a3a00Daniel Veillard xmlXPathFuncLookupFunc f; 2873ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer 28746ebf3c4c1a78406d15e8629b4a7b3d52549f0c8bDaniel Veillard f = ctxt->funcLookupFunc; 2875963d2ae41574066f9b44bcae610dd280c1e57dd8Daniel Veillard ret = f(ctxt->funcLookupData, name, NULL); 2876ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer if (ret != NULL) 2877ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer return(ret); 2878ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer } 28793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(xmlXPathFunctionLookupNS(ctxt, name, NULL)); 28803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 28813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 28823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 28833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathFunctionLookupNS: 28843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath context 28853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @name: the function name 28863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ns_uri: the function namespace URI 28873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 28883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Search in the Function array of the context for the given 28893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * function. 28903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 28913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the xmlXPathFunction or NULL if not found 28923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 28933473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathFunction 28943473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathFunctionLookupNS(xmlXPathContextPtr ctxt, const xmlChar *name, 28953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor const xmlChar *ns_uri) { 2896ad0e67c57f26f691fc120d5c5336cee9885cf324William M. Brack xmlXPathFunction ret; 2897ad0e67c57f26f691fc120d5c5336cee9885cf324William M. Brack 28983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt == NULL) 28993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 29003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (name == NULL) 29013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 29023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 2903ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer if (ctxt->funcLookupFunc != NULL) { 290499e55ebe945f6f4de33e8454f2770e02295a3a00Daniel Veillard xmlXPathFuncLookupFunc f; 2905ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer 29066ebf3c4c1a78406d15e8629b4a7b3d52549f0c8bDaniel Veillard f = ctxt->funcLookupFunc; 2907963d2ae41574066f9b44bcae610dd280c1e57dd8Daniel Veillard ret = f(ctxt->funcLookupData, name, ns_uri); 2908ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer if (ret != NULL) 2909ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer return(ret); 2910ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer } 2911ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer 2912ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer if (ctxt->funcHash == NULL) 2913ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer return(NULL); 2914ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer 2915ad0e67c57f26f691fc120d5c5336cee9885cf324William M. Brack XML_CAST_FPTR(ret) = xmlHashLookup2(ctxt->funcHash, name, ns_uri); 2916ad0e67c57f26f691fc120d5c5336cee9885cf324William M. Brack return(ret); 29173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 29183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 29193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 29203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathRegisteredFuncsCleanup: 29213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath context 29223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 29233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Cleanup the XPath context data associated to registered functions 29243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 29253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 29263473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathRegisteredFuncsCleanup(xmlXPathContextPtr ctxt) { 29273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt == NULL) 29283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return; 29293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 29303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlHashFree(ctxt->funcHash, NULL); 29313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ctxt->funcHash = NULL; 29323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 29333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 29343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/************************************************************************ 29353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * * 2936081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack * Routines to handle Variables * 29373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * * 29383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ************************************************************************/ 29393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 29403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 29413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathRegisterVariable: 29423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath context 29433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @name: the variable name 29443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @value: the variable value or NULL 29453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 29463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Register a new variable value. If @value is NULL it unregisters 29473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the variable 29483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 29493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns 0 in case of success, -1 in case of error 29503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 29513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorint 29523473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathRegisterVariable(xmlXPathContextPtr ctxt, const xmlChar *name, 29533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr value) { 29543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(xmlXPathRegisterVariableNS(ctxt, name, NULL, value)); 29553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 29563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 29573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 29583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathRegisterVariableNS: 29593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath context 29603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @name: the variable name 29613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ns_uri: the variable namespace URI 29623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @value: the variable value or NULL 29633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 29643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Register a new variable value. If @value is NULL it unregisters 29653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the variable 29663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 29673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns 0 in case of success, -1 in case of error 29683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 29693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorint 29703473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathRegisterVariableNS(xmlXPathContextPtr ctxt, const xmlChar *name, 29713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor const xmlChar *ns_uri, 29723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr value) { 29733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt == NULL) 29743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(-1); 29753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (name == NULL) 29763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(-1); 29773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 29783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->varHash == NULL) 29793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ctxt->varHash = xmlHashCreate(0); 29803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->varHash == NULL) 29813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(-1); 298294394cd1e494f8d669b310748f54192268185c8dDaniel Veillard if (value == NULL) 298394394cd1e494f8d669b310748f54192268185c8dDaniel Veillard return(xmlHashRemoveEntry2(ctxt->varHash, name, ns_uri, 298494394cd1e494f8d669b310748f54192268185c8dDaniel Veillard (xmlHashDeallocator)xmlXPathFreeObject)); 29853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(xmlHashUpdateEntry2(ctxt->varHash, name, ns_uri, 29863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor (void *) value, 29873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor (xmlHashDeallocator)xmlXPathFreeObject)); 29883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 29893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 29903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 29913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathRegisterVariableLookup: 29923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath context 29933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @f: the lookup function 29943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @data: the lookup data 29953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 29963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * register an external mechanism to do variable lookup 29973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 29983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 29993473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathRegisterVariableLookup(xmlXPathContextPtr ctxt, 30003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathVariableLookupFunc f, void *data) { 30013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt == NULL) 30023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return; 30036ebf3c4c1a78406d15e8629b4a7b3d52549f0c8bDaniel Veillard ctxt->varLookupFunc = f; 30043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ctxt->varLookupData = data; 30053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 30063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 30073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 30083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathVariableLookup: 30093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath context 30103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @name: the variable name 30113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 30123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Search in the Variable array of the context for the given 30133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * variable value. 30143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 301573c9c049195bf897dbcb6308a1ab9d16b3fe6b2cDaniel Veillard * Returns a copy of the value or NULL if not found 30163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 30173473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathObjectPtr 30183473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathVariableLookup(xmlXPathContextPtr ctxt, const xmlChar *name) { 30193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt == NULL) 30203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 30213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 30223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->varLookupFunc != NULL) { 30233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr ret; 30243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 30253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = ((xmlXPathVariableLookupFunc)ctxt->varLookupFunc) 30263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor (ctxt->varLookupData, name, NULL); 3027556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard return(ret); 30283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 30293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(xmlXPathVariableLookupNS(ctxt, name, NULL)); 30303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 30313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 30323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 30333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathVariableLookupNS: 30343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath context 30353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @name: the variable name 30363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ns_uri: the variable namespace URI 30373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 30383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Search in the Variable array of the context for the given 303973c9c049195bf897dbcb6308a1ab9d16b3fe6b2cDaniel Veillard * variable value. 30403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 304173c9c049195bf897dbcb6308a1ab9d16b3fe6b2cDaniel Veillard * Returns the a copy of the value or NULL if not found 30423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 30433473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathObjectPtr 30443473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathVariableLookupNS(xmlXPathContextPtr ctxt, const xmlChar *name, 30453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor const xmlChar *ns_uri) { 30463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt == NULL) 30473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 30483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 30493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->varLookupFunc != NULL) { 30503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr ret; 30513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 30523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = ((xmlXPathVariableLookupFunc)ctxt->varLookupFunc) 30533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor (ctxt->varLookupData, name, ns_uri); 30543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ret != NULL) return(ret); 30553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 30563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 30573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->varHash == NULL) 30583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 30593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (name == NULL) 30603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 30613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 30628c357d58c2d1dde022b67393a47dcb52100ce129Daniel Veillard return(xmlXPathObjectCopy((xmlXPathObjectPtr) 30638c357d58c2d1dde022b67393a47dcb52100ce129Daniel Veillard xmlHashLookup2(ctxt->varHash, name, ns_uri))); 30643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 30653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 30663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 30673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathRegisteredVariablesCleanup: 30683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath context 30693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 30703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Cleanup the XPath context data associated to registered variables 30713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 30723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 30733473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathRegisteredVariablesCleanup(xmlXPathContextPtr ctxt) { 30743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt == NULL) 30753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return; 30763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 307776d66f416d2d0d5db4a09d212b4e43087e9cdae7Daniel Veillard xmlHashFree(ctxt->varHash, (xmlHashDeallocator)xmlXPathFreeObject); 30783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ctxt->varHash = NULL; 30793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 30803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 30813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 30823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathRegisterNs: 30833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath context 30843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @prefix: the namespace prefix 30853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ns_uri: the namespace name 30863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 30873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Register a new namespace. If @ns_uri is NULL it unregisters 30883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the namespace 30893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 30903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns 0 in case of success, -1 in case of error 30913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 30923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorint 30933473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathRegisterNs(xmlXPathContextPtr ctxt, const xmlChar *prefix, 30943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor const xmlChar *ns_uri) { 30953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt == NULL) 30963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(-1); 30973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (prefix == NULL) 30983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(-1); 30993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 31003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->nsHash == NULL) 31013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ctxt->nsHash = xmlHashCreate(10); 31023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->nsHash == NULL) 31033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(-1); 3104e991fe958f5269a459262bcff802a3d26167edb8Daniel Veillard if (ns_uri == NULL) 310594394cd1e494f8d669b310748f54192268185c8dDaniel Veillard return(xmlHashRemoveEntry(ctxt->nsHash, prefix, 3106e991fe958f5269a459262bcff802a3d26167edb8Daniel Veillard (xmlHashDeallocator)xmlFree)); 310742766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard return(xmlHashUpdateEntry(ctxt->nsHash, prefix, (void *) xmlStrdup(ns_uri), 31083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor (xmlHashDeallocator)xmlFree)); 31093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 31103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 31113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 31123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNsLookup: 31133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath context 31143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @prefix: the namespace prefix value 31153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 31163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Search in the namespace declaration array of the context for the given 31173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * namespace name associated to the given prefix 31183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 31193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the value or NULL if not found 31203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 31213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorconst xmlChar * 31223473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNsLookup(xmlXPathContextPtr ctxt, const xmlChar *prefix) { 31233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt == NULL) 31243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 31253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (prefix == NULL) 31263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 31273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 31283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef XML_XML_NAMESPACE 31293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (xmlStrEqual(prefix, (const xmlChar *) "xml")) 31303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(XML_XML_NAMESPACE); 31313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 31323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 3133c8f620ba7f95b3ceb687699e140eeaa33343e41aDaniel Veillard if (ctxt->namespaces != NULL) { 3134c8f620ba7f95b3ceb687699e140eeaa33343e41aDaniel Veillard int i; 3135c8f620ba7f95b3ceb687699e140eeaa33343e41aDaniel Veillard 3136c8f620ba7f95b3ceb687699e140eeaa33343e41aDaniel Veillard for (i = 0;i < ctxt->nsNr;i++) { 3137c8f620ba7f95b3ceb687699e140eeaa33343e41aDaniel Veillard if ((ctxt->namespaces[i] != NULL) && 3138c8f620ba7f95b3ceb687699e140eeaa33343e41aDaniel Veillard (xmlStrEqual(ctxt->namespaces[i]->prefix, prefix))) 3139c8f620ba7f95b3ceb687699e140eeaa33343e41aDaniel Veillard return(ctxt->namespaces[i]->href); 3140c8f620ba7f95b3ceb687699e140eeaa33343e41aDaniel Veillard } 3141c8f620ba7f95b3ceb687699e140eeaa33343e41aDaniel Veillard } 31423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 31433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return((const xmlChar *) xmlHashLookup(ctxt->nsHash, prefix)); 31443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 31453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 31463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 31475e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard * xmlXPathRegisteredNsCleanup: 31483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath context 31493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 31503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Cleanup the XPath context data associated to registered variables 31513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 31523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 31533473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathRegisteredNsCleanup(xmlXPathContextPtr ctxt) { 31543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt == NULL) 31553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return; 31563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 315742766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard xmlHashFree(ctxt->nsHash, (xmlHashDeallocator)xmlFree); 31583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ctxt->nsHash = NULL; 31593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 31603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 31613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/************************************************************************ 31623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * * 31633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Routines to handle Values * 31643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * * 31653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ************************************************************************/ 31663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 3167081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack/* Allocations are terrible, one needs to optimize all this !!! */ 31683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 31693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 31703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNewFloat: 31713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val: the double value 31723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 31733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Create a new xmlXPathObjectPtr of type double and of value @val 31743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 31753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the newly created object. 31763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 31773473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathObjectPtr 31783473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNewFloat(double val) { 31793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr ret; 31803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 31813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject)); 31823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ret == NULL) { 3183d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard xmlXPathErrMemory(NULL, "creating float object\n"); 31843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 31853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 31863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor memset(ret, 0 , (size_t) sizeof(xmlXPathObject)); 31873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->type = XPATH_NUMBER; 31883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->floatval = val; 31893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ret); 31903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 31913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 31923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 31933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNewBoolean: 31943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val: the boolean value 31953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 31963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Create a new xmlXPathObjectPtr of type boolean and of value @val 31973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 31983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the newly created object. 31993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 32003473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathObjectPtr 32013473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNewBoolean(int val) { 32023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr ret; 32033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 32043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject)); 32053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ret == NULL) { 3206d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard xmlXPathErrMemory(NULL, "creating boolean object\n"); 32073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 32083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 32093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor memset(ret, 0 , (size_t) sizeof(xmlXPathObject)); 32103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->type = XPATH_BOOLEAN; 32113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->boolval = (val != 0); 32123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ret); 32133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 32143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 32153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 32163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNewString: 32173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val: the xmlChar * value 32183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 32193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Create a new xmlXPathObjectPtr of type string and of value @val 32203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 32213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the newly created object. 32223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 32233473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathObjectPtr 32243473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNewString(const xmlChar *val) { 32253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr ret; 32263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 32273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject)); 32283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ret == NULL) { 3229d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard xmlXPathErrMemory(NULL, "creating string object\n"); 32303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 32313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 32323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor memset(ret, 0 , (size_t) sizeof(xmlXPathObject)); 32333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->type = XPATH_STRING; 32343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (val != NULL) 32353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->stringval = xmlStrdup(val); 32363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else 32373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->stringval = xmlStrdup((const xmlChar *)""); 32383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ret); 32393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 32403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 32413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 3242ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathWrapString: 3243ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @val: the xmlChar * value 3244ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3245ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Wraps the @val string into an XPath object. 3246ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3247ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns the newly created object. 3248ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */ 3249ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathObjectPtr 3250ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathWrapString (xmlChar *val) { 3251ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlXPathObjectPtr ret; 3252ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 3253ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject)); 3254ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard if (ret == NULL) { 3255d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard xmlXPathErrMemory(NULL, "creating string object\n"); 3256ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(NULL); 3257ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard } 3258ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard memset(ret, 0 , (size_t) sizeof(xmlXPathObject)); 3259ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret->type = XPATH_STRING; 3260ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret->stringval = val; 3261ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(ret); 3262ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard} 3263ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 3264ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/** 32653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNewCString: 32663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val: the char * value 32673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 32683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Create a new xmlXPathObjectPtr of type string and of value @val 32693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 32703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the newly created object. 32713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 32723473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathObjectPtr 32733473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNewCString(const char *val) { 32743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr ret; 32753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 32763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject)); 32773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ret == NULL) { 3278d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard xmlXPathErrMemory(NULL, "creating string object\n"); 32793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 32803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 32813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor memset(ret, 0 , (size_t) sizeof(xmlXPathObject)); 32823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->type = XPATH_STRING; 32833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->stringval = xmlStrdup(BAD_CAST val); 32843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ret); 32853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 32863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 32873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 3288ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathWrapCString: 3289ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @val: the char * value 3290ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3291ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Wraps a string into an XPath object. 3292ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3293ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns the newly created object. 3294ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */ 3295ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathObjectPtr 3296ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathWrapCString (char * val) { 3297ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(xmlXPathWrapString((xmlChar *)(val))); 3298ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard} 3299ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 3300ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/** 3301f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathWrapExternal: 3302f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @val: the user data 3303f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 3304f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Wraps the @val data into an XPath object. 3305f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 3306f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns the newly created object. 3307f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */ 3308f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathObjectPtr 3309f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathWrapExternal (void *val) { 3310f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathObjectPtr ret; 3311f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 3312f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject)); 3313f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (ret == NULL) { 3314d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard xmlXPathErrMemory(NULL, "creating user object\n"); 3315f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(NULL); 3316f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer } 3317f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer memset(ret, 0 , (size_t) sizeof(xmlXPathObject)); 3318f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer ret->type = XPATH_USERS; 3319f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer ret->user = val; 3320f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(ret); 3321f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer} 3322f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 3323f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/** 33243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathObjectCopy: 33253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val: the original object 33263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 33273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * allocate a new copy of a given object 33283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 33293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the newly created object. 33303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 33313473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathObjectPtr 33323473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathObjectCopy(xmlXPathObjectPtr val) { 33333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr ret; 33343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 33353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (val == NULL) 33363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 33373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 33383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject)); 33393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ret == NULL) { 3340d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard xmlXPathErrMemory(NULL, "copying object\n"); 33413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 33423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 33433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor memcpy(ret, val , (size_t) sizeof(xmlXPathObject)); 33443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor switch (val->type) { 33453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_BOOLEAN: 33463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_NUMBER: 33473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_POINT: 33483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_RANGE: 33493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 33503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_STRING: 33513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->stringval = xmlStrdup(val->stringval); 33523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 33533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_XSLT_TREE: 3354e9449c5d29d87b1dc51de7784ed947ae1e3da831William M. Brack#if 0 3355e9449c5d29d87b1dc51de7784ed947ae1e3da831William M. Brack/* 3356e9449c5d29d87b1dc51de7784ed947ae1e3da831William M. Brack Removed 11 July 2004 - the current handling of xslt tmpRVT nodes means that 3357e9449c5d29d87b1dc51de7784ed947ae1e3da831William M. Brack this previous handling is no longer correct, and can cause some serious 3358e9449c5d29d87b1dc51de7784ed947ae1e3da831William M. Brack problems (ref. bug 145547) 3359e9449c5d29d87b1dc51de7784ed947ae1e3da831William M. Brack*/ 33603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((val->nodesetval != NULL) && 33610ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard (val->nodesetval->nodeTab != NULL)) { 33629adc0469d4691e798ea4ad59b84c874cdea8b38dDaniel Veillard xmlNodePtr cur, tmp; 33639adc0469d4691e798ea4ad59b84c874cdea8b38dDaniel Veillard xmlDocPtr top; 3364ef0b45016373d65700ef6f7d494a200758b2e4c5Daniel Veillard 33650ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard ret->boolval = 1; 33669adc0469d4691e798ea4ad59b84c874cdea8b38dDaniel Veillard top = xmlNewDoc(NULL); 33679adc0469d4691e798ea4ad59b84c874cdea8b38dDaniel Veillard top->name = (char *) 33689adc0469d4691e798ea4ad59b84c874cdea8b38dDaniel Veillard xmlStrdup(val->nodesetval->nodeTab[0]->name); 3369ef0b45016373d65700ef6f7d494a200758b2e4c5Daniel Veillard ret->user = top; 3370ef0b45016373d65700ef6f7d494a200758b2e4c5Daniel Veillard if (top != NULL) { 33719adc0469d4691e798ea4ad59b84c874cdea8b38dDaniel Veillard top->doc = top; 3372ef0b45016373d65700ef6f7d494a200758b2e4c5Daniel Veillard cur = val->nodesetval->nodeTab[0]->children; 3373ef0b45016373d65700ef6f7d494a200758b2e4c5Daniel Veillard while (cur != NULL) { 33749adc0469d4691e798ea4ad59b84c874cdea8b38dDaniel Veillard tmp = xmlDocCopyNode(cur, top, 1); 33759adc0469d4691e798ea4ad59b84c874cdea8b38dDaniel Veillard xmlAddChild((xmlNodePtr) top, tmp); 3376ef0b45016373d65700ef6f7d494a200758b2e4c5Daniel Veillard cur = cur->next; 3377ef0b45016373d65700ef6f7d494a200758b2e4c5Daniel Veillard } 3378ef0b45016373d65700ef6f7d494a200758b2e4c5Daniel Veillard } 3379e9449c5d29d87b1dc51de7784ed947ae1e3da831William M. Brack 33809adc0469d4691e798ea4ad59b84c874cdea8b38dDaniel Veillard ret->nodesetval = xmlXPathNodeSetCreate((xmlNodePtr) top); 33810ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard } else 33823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->nodesetval = xmlXPathNodeSetCreate(NULL); 33830ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard /* Deallocate the copied tree value */ 33843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 3385e9449c5d29d87b1dc51de7784ed947ae1e3da831William M. Brack#endif 33863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_NODESET: 33873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->nodesetval = xmlXPathNodeSetMerge(NULL, val->nodesetval); 33880ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard /* Do not deallocate the copied tree value */ 33890ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard ret->boolval = 0; 33903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 33913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_LOCATIONSET: 33923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef LIBXML_XPTR_ENABLED 33933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor { 33943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlLocationSetPtr loc = val->user; 33953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->user = (void *) xmlXPtrLocationSetMerge(NULL, loc); 33963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 33973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 33983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 339947334c09f4373e4cff71334e60a623fee73a525fThomas Broyer case XPATH_USERS: 340047334c09f4373e4cff71334e60a623fee73a525fThomas Broyer ret->user = val->user; 340147334c09f4373e4cff71334e60a623fee73a525fThomas Broyer break; 340247334c09f4373e4cff71334e60a623fee73a525fThomas Broyer case XPATH_UNDEFINED: 34033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 34043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "xmlXPathObjectCopy: unsupported type %d\n", 34053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor val->type); 34063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 34073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 34083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ret); 34093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 34103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 34113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 34123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathFreeObject: 34133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @obj: the object to free 34143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 34153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Free up an xmlXPathObjectPtr object. 34163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 34173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 34183473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathFreeObject(xmlXPathObjectPtr obj) { 34193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (obj == NULL) return; 34200ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard if ((obj->type == XPATH_NODESET) || (obj->type == XPATH_XSLT_TREE)) { 342177851710aba3a0effdc6af67ea4caf212307420cDaniel Veillard if (obj->boolval) { 3422e9449c5d29d87b1dc51de7784ed947ae1e3da831William M. Brack#if 0 34230ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard if (obj->user != NULL) { 34240ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard xmlXPathFreeNodeSet(obj->nodesetval); 342538bf6f042507c6051bfa2db5cc9b6666cfc35c2aDaniel Veillard xmlFreeNodeList((xmlNodePtr) obj->user); 3426e9449c5d29d87b1dc51de7784ed947ae1e3da831William M. Brack } else 3427e9449c5d29d87b1dc51de7784ed947ae1e3da831William M. Brack#endif 3428e9449c5d29d87b1dc51de7784ed947ae1e3da831William M. Brack if (obj->nodesetval != NULL) 342977851710aba3a0effdc6af67ea4caf212307420cDaniel Veillard xmlXPathFreeValueTree(obj->nodesetval); 343077851710aba3a0effdc6af67ea4caf212307420cDaniel Veillard } else { 343177851710aba3a0effdc6af67ea4caf212307420cDaniel Veillard if (obj->nodesetval != NULL) 343277851710aba3a0effdc6af67ea4caf212307420cDaniel Veillard xmlXPathFreeNodeSet(obj->nodesetval); 343377851710aba3a0effdc6af67ea4caf212307420cDaniel Veillard } 34343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef LIBXML_XPTR_ENABLED 34353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else if (obj->type == XPATH_LOCATIONSET) { 34363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (obj->user != NULL) 34373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPtrFreeLocationSet(obj->user); 34383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 34393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else if (obj->type == XPATH_STRING) { 34403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (obj->stringval != NULL) 34413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(obj->stringval); 34423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 34433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 34443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(obj); 34453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 34463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 3447ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 3448ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/************************************************************************ 3449ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * * 3450ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Type Casting Routines * 3451ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * * 3452ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ************************************************************************/ 3453ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 3454ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/** 3455ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathCastBooleanToString: 3456ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @val: a boolean 3457ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3458ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts a boolean to its string value. 3459ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3460ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns a newly allocated string. 3461ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */ 3462ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlChar * 3463ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathCastBooleanToString (int val) { 3464ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlChar *ret; 3465ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard if (val) 3466ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = xmlStrdup((const xmlChar *) "true"); 3467ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard else 3468ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = xmlStrdup((const xmlChar *) "false"); 3469ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(ret); 3470ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard} 3471ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 3472ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/** 3473ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathCastNumberToString: 3474ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @val: a number 3475ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3476ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts a number to its string value. 3477ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3478ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns a newly allocated string. 3479ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */ 3480ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlChar * 3481ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathCastNumberToString (double val) { 3482ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlChar *ret; 3483cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard switch (xmlXPathIsInf(val)) { 3484ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case 1: 34855fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard ret = xmlStrdup((const xmlChar *) "Infinity"); 3486ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard break; 3487ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case -1: 3488ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = xmlStrdup((const xmlChar *) "-Infinity"); 3489ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard break; 3490ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard default: 3491cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard if (xmlXPathIsNaN(val)) { 3492ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = xmlStrdup((const xmlChar *) "NaN"); 3493d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard } else if (val == 0 && xmlXPathGetSign(val) != 0) { 3494d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret = xmlStrdup((const xmlChar *) "0"); 3495ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard } else { 3496ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard /* could be improved */ 3497ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard char buf[100]; 3498ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlXPathFormatNumber(val, buf, 100); 3499ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = xmlStrdup((const xmlChar *) buf); 3500ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard } 3501ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard } 3502ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(ret); 3503ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard} 3504ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 3505ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/** 3506ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathCastNodeToString: 3507ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @node: a node 3508ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3509ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts a node to its string value. 3510ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3511ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns a newly allocated string. 3512ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */ 3513ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlChar * 3514ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathCastNodeToString (xmlNodePtr node) { 3515ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(xmlNodeGetContent(node)); 3516ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard} 3517ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 3518ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/** 3519ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathCastNodeSetToString: 3520ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @ns: a node-set 3521ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3522ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts a node-set to its string value. 3523ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3524ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns a newly allocated string. 3525ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */ 3526ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlChar * 3527ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathCastNodeSetToString (xmlNodeSetPtr ns) { 3528ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard if ((ns == NULL) || (ns->nodeNr == 0) || (ns->nodeTab == NULL)) 3529ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(xmlStrdup((const xmlChar *) "")); 3530ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 3531ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlXPathNodeSetSort(ns); 3532ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(xmlXPathCastNodeToString(ns->nodeTab[0])); 3533ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard} 3534ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 3535ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/** 3536ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathCastToString: 3537ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @val: an XPath object 3538ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3539ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts an existing object to its string() equivalent 3540ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3541ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns the string value of the object, NULL in case of error. 3542cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * A new string is allocated only if needed (@val isn't a 3543ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * string object). 3544ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */ 3545ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlChar * 3546ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathCastToString(xmlXPathObjectPtr val) { 3547ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlChar *ret = NULL; 3548ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 3549ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard if (val == NULL) 3550ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(xmlStrdup((const xmlChar *) "")); 3551ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard switch (val->type) { 3552ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_UNDEFINED: 3553ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard#ifdef DEBUG_EXPR 3554ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlGenericError(xmlGenericErrorContext, "String: undefined\n"); 3555ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard#endif 3556ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = xmlStrdup((const xmlChar *) ""); 3557ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard break; 3558ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_NODESET: 35590c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack case XPATH_XSLT_TREE: 3560ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = xmlXPathCastNodeSetToString(val->nodesetval); 3561ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard break; 3562ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_STRING: 35634e2df54bb17645ef0d3f28b9665b2d2dde4b47a3Daniel Veillard return(xmlStrdup(val->stringval)); 3564ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_BOOLEAN: 3565ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = xmlXPathCastBooleanToString(val->boolval); 3566ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard break; 3567ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_NUMBER: { 3568ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = xmlXPathCastNumberToString(val->floatval); 3569ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard break; 3570ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard } 3571ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_USERS: 3572ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_POINT: 3573ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_RANGE: 3574ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_LOCATIONSET: 3575ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard TODO 3576ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = xmlStrdup((const xmlChar *) ""); 3577ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard break; 3578ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard } 3579ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(ret); 3580ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard} 3581ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 3582ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/** 3583ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathConvertString: 3584ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @val: an XPath object 3585ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3586ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts an existing object to its string() equivalent 3587ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3588ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns the new object, the old one is freed (or the operation 3589ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * is done directly on @val) 3590ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */ 3591ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathObjectPtr 3592ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathConvertString(xmlXPathObjectPtr val) { 3593ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlChar *res = NULL; 3594ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 3595ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard if (val == NULL) 3596ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(xmlXPathNewCString("")); 3597ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 3598ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard switch (val->type) { 3599ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_UNDEFINED: 3600ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard#ifdef DEBUG_EXPR 3601ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlGenericError(xmlGenericErrorContext, "STRING: undefined\n"); 3602ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard#endif 3603ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard break; 3604ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_NODESET: 36050c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack case XPATH_XSLT_TREE: 3606ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard res = xmlXPathCastNodeSetToString(val->nodesetval); 3607ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard break; 3608ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_STRING: 3609ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(val); 3610ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_BOOLEAN: 3611ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard res = xmlXPathCastBooleanToString(val->boolval); 3612ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard break; 3613ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_NUMBER: 3614ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard res = xmlXPathCastNumberToString(val->floatval); 3615ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard break; 3616ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_USERS: 3617ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_POINT: 3618ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_RANGE: 3619ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_LOCATIONSET: 3620ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard TODO; 3621ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard break; 3622ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard } 3623ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlXPathFreeObject(val); 3624ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard if (res == NULL) 3625ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(xmlXPathNewCString("")); 3626ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(xmlXPathWrapString(res)); 3627ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard} 3628ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 3629ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/** 3630ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathCastBooleanToNumber: 3631ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @val: a boolean 3632ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3633ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts a boolean to its number value 3634ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3635ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns the number value 3636ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */ 3637ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillarddouble 3638ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathCastBooleanToNumber(int val) { 3639ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard if (val) 3640ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(1.0); 3641ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(0.0); 3642ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard} 3643ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 3644ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/** 3645ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathCastStringToNumber: 3646ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @val: a string 3647ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3648ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts a string to its number value 3649ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3650ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns the number value 3651ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */ 3652ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillarddouble 3653ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathCastStringToNumber(const xmlChar * val) { 3654ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(xmlXPathStringEvalNumber(val)); 3655ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard} 3656ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 3657ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/** 3658ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathCastNodeToNumber: 3659ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @node: a node 3660ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3661ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts a node to its number value 3662ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3663ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns the number value 3664ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */ 3665ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillarddouble 3666ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathCastNodeToNumber (xmlNodePtr node) { 3667ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlChar *strval; 3668ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard double ret; 3669ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 3670ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard if (node == NULL) 3671ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(xmlXPathNAN); 3672ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard strval = xmlXPathCastNodeToString(node); 3673ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard if (strval == NULL) 3674ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(xmlXPathNAN); 3675ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = xmlXPathCastStringToNumber(strval); 3676ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlFree(strval); 3677ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 3678ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(ret); 3679ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard} 3680ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 3681ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/** 3682ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathCastNodeSetToNumber: 3683ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @ns: a node-set 3684ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3685ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts a node-set to its number value 3686ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3687ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns the number value 3688ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */ 3689ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillarddouble 3690ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathCastNodeSetToNumber (xmlNodeSetPtr ns) { 3691ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlChar *str; 3692ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard double ret; 3693ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 3694ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard if (ns == NULL) 3695ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(xmlXPathNAN); 3696ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard str = xmlXPathCastNodeSetToString(ns); 3697ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = xmlXPathCastStringToNumber(str); 3698ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlFree(str); 3699ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(ret); 3700ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard} 3701ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 3702ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/** 3703ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathCastToNumber: 3704ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @val: an XPath object 3705ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3706ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts an XPath object to its number value 3707ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3708ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns the number value 3709ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */ 3710ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillarddouble 3711ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathCastToNumber(xmlXPathObjectPtr val) { 3712ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard double ret = 0.0; 3713ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 3714ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard if (val == NULL) 3715ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(xmlXPathNAN); 3716ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard switch (val->type) { 3717ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_UNDEFINED: 3718ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard#ifdef DEGUB_EXPR 3719ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlGenericError(xmlGenericErrorContext, "NUMBER: undefined\n"); 3720ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard#endif 3721ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = xmlXPathNAN; 3722ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard break; 3723ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_NODESET: 37240c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack case XPATH_XSLT_TREE: 3725ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = xmlXPathCastNodeSetToNumber(val->nodesetval); 3726ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard break; 3727ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_STRING: 3728ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = xmlXPathCastStringToNumber(val->stringval); 3729ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard break; 3730ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_NUMBER: 3731ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = val->floatval; 3732ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard break; 3733ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_BOOLEAN: 3734ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = xmlXPathCastBooleanToNumber(val->boolval); 3735ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard break; 3736ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_USERS: 3737ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_POINT: 3738ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_RANGE: 3739ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_LOCATIONSET: 3740ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard TODO; 3741ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = xmlXPathNAN; 3742ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard break; 3743ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard } 3744ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(ret); 3745ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard} 3746ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 3747ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/** 3748ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathConvertNumber: 3749ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @val: an XPath object 3750ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3751ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts an existing object to its number() equivalent 3752ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3753ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns the new object, the old one is freed (or the operation 3754ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * is done directly on @val) 3755ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */ 3756ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathObjectPtr 3757ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathConvertNumber(xmlXPathObjectPtr val) { 3758ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlXPathObjectPtr ret; 3759ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 3760ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard if (val == NULL) 3761ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(xmlXPathNewFloat(0.0)); 3762ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard if (val->type == XPATH_NUMBER) 3763ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(val); 3764ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = xmlXPathNewFloat(xmlXPathCastToNumber(val)); 3765ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlXPathFreeObject(val); 3766ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(ret); 3767ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard} 3768ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 3769ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/** 3770ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathCastNumberToBoolean: 3771ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @val: a number 3772ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3773ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts a number to its boolean value 3774ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3775ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns the boolean value 3776ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */ 3777ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillardint 3778ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathCastNumberToBoolean (double val) { 3779cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard if (xmlXPathIsNaN(val) || (val == 0.0)) 3780ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(0); 3781ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(1); 3782ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard} 3783ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 3784ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/** 3785ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathCastStringToBoolean: 3786ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @val: a string 3787ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3788ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts a string to its boolean value 3789ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3790ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns the boolean value 3791ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */ 3792ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillardint 3793ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathCastStringToBoolean (const xmlChar *val) { 3794ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard if ((val == NULL) || (xmlStrlen(val) == 0)) 3795ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(0); 3796ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(1); 3797ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard} 3798ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 3799ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/** 3800ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathCastNodeSetToBoolean: 3801ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @ns: a node-set 3802ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3803ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts a node-set to its boolean value 3804ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3805ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns the boolean value 3806ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */ 3807ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillardint 3808ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathCastNodeSetToBoolean (xmlNodeSetPtr ns) { 3809ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard if ((ns == NULL) || (ns->nodeNr == 0)) 3810ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(0); 3811ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(1); 3812ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard} 3813ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 3814ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/** 38155e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard * xmlXPathCastToBoolean: 3816ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @val: an XPath object 3817ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3818ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts an XPath object to its boolean value 3819ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3820ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns the boolean value 3821ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */ 3822ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillardint 3823ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathCastToBoolean (xmlXPathObjectPtr val) { 3824ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard int ret = 0; 3825ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 3826ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard if (val == NULL) 3827ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(0); 3828ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard switch (val->type) { 3829ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_UNDEFINED: 3830ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard#ifdef DEBUG_EXPR 3831ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlGenericError(xmlGenericErrorContext, "BOOLEAN: undefined\n"); 3832ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard#endif 3833ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = 0; 3834ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard break; 3835ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_NODESET: 38360c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack case XPATH_XSLT_TREE: 3837ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = xmlXPathCastNodeSetToBoolean(val->nodesetval); 3838ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard break; 3839ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_STRING: 3840ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = xmlXPathCastStringToBoolean(val->stringval); 3841ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard break; 3842ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_NUMBER: 3843ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = xmlXPathCastNumberToBoolean(val->floatval); 3844ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard break; 3845ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_BOOLEAN: 3846ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = val->boolval; 3847ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard break; 3848ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_USERS: 3849ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_POINT: 3850ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_RANGE: 3851ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_LOCATIONSET: 3852ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard TODO; 3853ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = 0; 3854ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard break; 3855ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard } 3856ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(ret); 3857ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard} 3858ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 3859ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 3860ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/** 3861ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathConvertBoolean: 3862ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @val: an XPath object 3863ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3864ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts an existing object to its boolean() equivalent 3865ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3866ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns the new object, the old one is freed (or the operation 3867ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * is done directly on @val) 3868ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */ 3869ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathObjectPtr 3870ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathConvertBoolean(xmlXPathObjectPtr val) { 3871ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlXPathObjectPtr ret; 3872ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 3873ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard if (val == NULL) 3874ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(xmlXPathNewBoolean(0)); 3875ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard if (val->type == XPATH_BOOLEAN) 3876ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(val); 3877ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = xmlXPathNewBoolean(xmlXPathCastToBoolean(val)); 3878ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlXPathFreeObject(val); 3879ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(ret); 3880ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard} 3881ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 38823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/************************************************************************ 38833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * * 38843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Routines to handle XPath contexts * 38853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * * 38863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ************************************************************************/ 38873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 38883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 38893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNewContext: 38903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @doc: the XML document 38913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 38923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Create a new xmlXPathContext 38933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 3894af43f63aaabf0dc4b4a070773875d0927da3d8a2Daniel Veillard * Returns the xmlXPathContext just allocated. The caller will need to free it. 38953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 38963473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathContextPtr 38973473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNewContext(xmlDocPtr doc) { 38983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathContextPtr ret; 38993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 39003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = (xmlXPathContextPtr) xmlMalloc(sizeof(xmlXPathContext)); 39013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ret == NULL) { 3902d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard xmlXPathErrMemory(NULL, "creating context\n"); 39033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 39043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 39053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor memset(ret, 0 , (size_t) sizeof(xmlXPathContext)); 39063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->doc = doc; 39073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->node = NULL; 39083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 39093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->varHash = NULL; 39103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 39113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->nb_types = 0; 39123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->max_types = 0; 39133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->types = NULL; 39143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 39153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->funcHash = xmlHashCreate(0); 39163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 39173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->nb_axis = 0; 39183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->max_axis = 0; 39193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->axis = NULL; 39203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 39213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->nsHash = NULL; 39223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->user = NULL; 39233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 39243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->contextSize = -1; 39253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->proximityPosition = -1; 39263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 39273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisterAllFunctions(ret); 39283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 39293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ret); 39303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 39313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 39323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 39333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathFreeContext: 39343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the context to free 39353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 39363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Free up an xmlXPathContext 39373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 39383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 39393473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathFreeContext(xmlXPathContextPtr ctxt) { 39407eca35fbaef6bd06074c4b978d381303609fcb0bDaniel Veillard if (ctxt == NULL) return; 39417eca35fbaef6bd06074c4b978d381303609fcb0bDaniel Veillard 39423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisteredNsCleanup(ctxt); 39433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisteredFuncsCleanup(ctxt); 39443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisteredVariablesCleanup(ctxt); 39457eca35fbaef6bd06074c4b978d381303609fcb0bDaniel Veillard xmlResetError(&ctxt->lastError); 39463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(ctxt); 39473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 39483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 39493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/************************************************************************ 39503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * * 39513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Routines to handle XPath parser contexts * 39523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * * 39533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ************************************************************************/ 39543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 39553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define CHECK_CTXT(ctxt) \ 39563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt == NULL) { \ 3957f13f77f0e6a7876063d5fba15c096befb0827cedWilliam M. Brack __xmlRaiseError(NULL, NULL, NULL, \ 3958f13f77f0e6a7876063d5fba15c096befb0827cedWilliam M. Brack NULL, NULL, XML_FROM_XPATH, \ 3959f13f77f0e6a7876063d5fba15c096befb0827cedWilliam M. Brack XML_ERR_INTERNAL_ERROR, XML_ERR_FATAL, \ 3960f13f77f0e6a7876063d5fba15c096befb0827cedWilliam M. Brack __FILE__, __LINE__, \ 3961f13f77f0e6a7876063d5fba15c096befb0827cedWilliam M. Brack NULL, NULL, NULL, 0, 0, \ 3962f13f77f0e6a7876063d5fba15c096befb0827cedWilliam M. Brack "NULL context pointer\n"); \ 3963f13f77f0e6a7876063d5fba15c096befb0827cedWilliam M. Brack return(NULL); \ 39643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } \ 39653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 39663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 39673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define CHECK_CONTEXT(ctxt) \ 396857b2516af5e2e06c54750b6549723cf5b8edf8a4Daniel Veillard if ((ctxt == NULL) || (ctxt->doc == NULL) || \ 396957b2516af5e2e06c54750b6549723cf5b8edf8a4Daniel Veillard (ctxt->doc->children == NULL)) { \ 397057b2516af5e2e06c54750b6549723cf5b8edf8a4Daniel Veillard xmlXPatherror(ctxt, __FILE__, __LINE__, XPATH_INVALID_CTXT); \ 3971ce682bc24b79f1dd29b781d4c17f9bf169ce7e32Daniel Veillard return(NULL); \ 397257b2516af5e2e06c54750b6549723cf5b8edf8a4Daniel Veillard } 39733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 39743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 39753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 39763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNewParserContext: 39773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @str: the XPath expression 39783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath context 39793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 39803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Create a new xmlXPathParserContext 39813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 39823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the xmlXPathParserContext just allocated. 39833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 39843473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathParserContextPtr 39853473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNewParserContext(const xmlChar *str, xmlXPathContextPtr ctxt) { 39863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathParserContextPtr ret; 39873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 39883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = (xmlXPathParserContextPtr) xmlMalloc(sizeof(xmlXPathParserContext)); 39893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ret == NULL) { 3990d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard xmlXPathErrMemory(ctxt, "creating parser context\n"); 39913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 39923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 39933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor memset(ret, 0 , (size_t) sizeof(xmlXPathParserContext)); 39943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->cur = ret->base = str; 39953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->context = ctxt; 39963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 39979e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard ret->comp = xmlXPathNewCompExpr(); 39989e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (ret->comp == NULL) { 39999e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlFree(ret->valueTab); 40009e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlFree(ret); 40019e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard return(NULL); 40029e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } 40034773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard if ((ctxt != NULL) && (ctxt->dict != NULL)) { 40044773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard ret->comp->dict = ctxt->dict; 40054773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard xmlDictReference(ret->comp->dict); 40064773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard } 40079e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 40089e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard return(ret); 40099e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard} 40109e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 40119e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard/** 40129e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * xmlXPathCompParserContext: 40139e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * @comp: the XPath compiled expression 40149e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * @ctxt: the XPath context 40159e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * 40169e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * Create a new xmlXPathParserContext when processing a compiled expression 40179e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * 40189e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * Returns the xmlXPathParserContext just allocated. 40199e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard */ 402056a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic xmlXPathParserContextPtr 40219e7160d45a18bfa26d708e22ba991f7670d0128bDaniel VeillardxmlXPathCompParserContext(xmlXPathCompExprPtr comp, xmlXPathContextPtr ctxt) { 40229e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlXPathParserContextPtr ret; 40239e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 40249e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard ret = (xmlXPathParserContextPtr) xmlMalloc(sizeof(xmlXPathParserContext)); 40259e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (ret == NULL) { 4026d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard xmlXPathErrMemory(ctxt, "creating evaluation context\n"); 40279e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard return(NULL); 40289e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } 40299e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard memset(ret, 0 , (size_t) sizeof(xmlXPathParserContext)); 40309e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 40313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* Allocate the value stack */ 40323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->valueTab = (xmlXPathObjectPtr *) 40333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlMalloc(10 * sizeof(xmlXPathObjectPtr)); 40349e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (ret->valueTab == NULL) { 40359e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlFree(ret); 4036d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard xmlXPathErrMemory(ctxt, "creating evaluation context\n"); 40379e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard return(NULL); 40389e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } 40393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->valueNr = 0; 40403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->valueMax = 10; 40413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->value = NULL; 40429e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 4043fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard ret->context = ctxt; 40449e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard ret->comp = comp; 40459e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 40463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ret); 40473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 40483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 40493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 40503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathFreeParserContext: 40513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the context to free 40523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 40533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Free up an xmlXPathParserContext 40543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 40553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 40563473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathFreeParserContext(xmlXPathParserContextPtr ctxt) { 40573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->valueTab != NULL) { 40583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(ctxt->valueTab); 40593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 406056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard if (ctxt->comp != NULL) { 406156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard#ifdef XPATH_STREAMING 406256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard if (ctxt->comp->stream != NULL) { 406356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard xmlFreePatternList(ctxt->comp->stream); 406456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard ctxt->comp->stream = NULL; 406556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard } 406656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard#endif 40679e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlXPathFreeCompExpr(ctxt->comp); 406856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard } 40693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(ctxt); 40703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 40713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 40723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/************************************************************************ 40733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * * 40743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The implicit core function library * 40753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * * 40763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ************************************************************************/ 40773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 40783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 407901c13b5be2d249ef66d86585adee87901bb8efa2Daniel Veillard * xmlXPathNodeValHash: 4080f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * @node: a node pointer 4081f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * 4082f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Function computing the beginning of the string value of the node, 4083f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * used to speed up comparisons 4084f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * 4085f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Returns an int usable as a hash 4086f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 4087f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillardstatic unsigned int 4088f06307e2c172284bb41376c396f757bdac9bdd19Daniel VeillardxmlXPathNodeValHash(xmlNodePtr node) { 4089f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard int len = 2; 4090f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard const xmlChar * string = NULL; 4091f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlNodePtr tmp = NULL; 4092f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard unsigned int ret = 0; 4093f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 4094f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (node == NULL) 4095f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return(0); 4096f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 40979adc0469d4691e798ea4ad59b84c874cdea8b38dDaniel Veillard if (node->type == XML_DOCUMENT_NODE) { 40989adc0469d4691e798ea4ad59b84c874cdea8b38dDaniel Veillard tmp = xmlDocGetRootElement((xmlDocPtr) node); 40999adc0469d4691e798ea4ad59b84c874cdea8b38dDaniel Veillard if (tmp == NULL) 41009adc0469d4691e798ea4ad59b84c874cdea8b38dDaniel Veillard node = node->children; 41019adc0469d4691e798ea4ad59b84c874cdea8b38dDaniel Veillard else 41029adc0469d4691e798ea4ad59b84c874cdea8b38dDaniel Veillard node = tmp; 41039adc0469d4691e798ea4ad59b84c874cdea8b38dDaniel Veillard 41049adc0469d4691e798ea4ad59b84c874cdea8b38dDaniel Veillard if (node == NULL) 41059adc0469d4691e798ea4ad59b84c874cdea8b38dDaniel Veillard return(0); 41069adc0469d4691e798ea4ad59b84c874cdea8b38dDaniel Veillard } 4107f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 4108f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard switch (node->type) { 4109f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XML_COMMENT_NODE: 4110f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XML_PI_NODE: 4111f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XML_CDATA_SECTION_NODE: 4112f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XML_TEXT_NODE: 4113f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard string = node->content; 4114f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (string == NULL) 4115f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return(0); 4116f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (string[0] == 0) 4117f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return(0); 4118f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return(((unsigned int) string[0]) + 4119f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (((unsigned int) string[1]) << 8)); 4120f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XML_NAMESPACE_DECL: 4121f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard string = ((xmlNsPtr)node)->href; 4122f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (string == NULL) 4123f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return(0); 4124f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (string[0] == 0) 4125f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return(0); 4126f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return(((unsigned int) string[0]) + 4127f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (((unsigned int) string[1]) << 8)); 4128f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XML_ATTRIBUTE_NODE: 4129f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard tmp = ((xmlAttrPtr) node)->children; 4130f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 4131f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XML_ELEMENT_NODE: 4132f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard tmp = node->children; 4133f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 4134f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard default: 4135f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return(0); 4136f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 4137f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard while (tmp != NULL) { 4138f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard switch (tmp->type) { 4139f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XML_COMMENT_NODE: 4140f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XML_PI_NODE: 4141f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XML_CDATA_SECTION_NODE: 4142f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XML_TEXT_NODE: 4143f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard string = tmp->content; 4144f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 4145f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XML_NAMESPACE_DECL: 4146f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard string = ((xmlNsPtr)tmp)->href; 4147f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 4148f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard default: 4149f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 4150f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 4151f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((string != NULL) && (string[0] != 0)) { 4152f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (len == 1) { 4153f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return(ret + (((unsigned int) string[0]) << 8)); 4154f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 4155f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (string[1] == 0) { 4156f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard len = 1; 4157f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ret = (unsigned int) string[0]; 4158f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } else { 4159f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return(((unsigned int) string[0]) + 4160f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (((unsigned int) string[1]) << 8)); 4161f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 4162f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 4163f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* 4164f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Skip to next node 4165f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 4166f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((tmp->children != NULL) && (tmp->type != XML_DTD_NODE)) { 4167f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (tmp->children->type != XML_ENTITY_DECL) { 4168f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard tmp = tmp->children; 4169f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard continue; 4170f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 4171f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 4172f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (tmp == node) 4173f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 4174f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 4175f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (tmp->next != NULL) { 4176f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard tmp = tmp->next; 4177f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard continue; 4178f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 4179f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 4180f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard do { 4181f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard tmp = tmp->parent; 4182f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (tmp == NULL) 4183f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 4184f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (tmp == node) { 4185f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard tmp = NULL; 4186f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 4187f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 4188f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (tmp->next != NULL) { 4189f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard tmp = tmp->next; 4190f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 4191f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 4192f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } while (tmp != NULL); 4193f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 4194f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return(ret); 4195f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard} 4196f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 4197f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard/** 4198f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * xmlXPathStringHash: 4199f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * @string: a string 4200f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * 4201f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Function computing the beginning of the string value of the node, 4202f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * used to speed up comparisons 4203f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * 4204f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Returns an int usable as a hash 4205f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 4206f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillardstatic unsigned int 4207f06307e2c172284bb41376c396f757bdac9bdd19Daniel VeillardxmlXPathStringHash(const xmlChar * string) { 4208f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (string == NULL) 4209f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return((unsigned int) 0); 4210f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (string[0] == 0) 4211f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return(0); 4212f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return(((unsigned int) string[0]) + 4213f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (((unsigned int) string[1]) << 8)); 4214f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard} 4215f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 4216f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard/** 42173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathCompareNodeSetFloat: 42183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 42193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @inf: less than (1) or greater than (0) 42203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @strict: is the comparison strict 42213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @arg: the node set 42223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @f: the value 42233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 42243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the compare operation between a nodeset and a number 42253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ns < @val (1, 1, ... 42263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ns <= @val (1, 0, ... 42273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ns > @val (0, 1, ... 42283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ns >= @val (0, 0, ... 42293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 42303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * If one object to be compared is a node-set and the other is a number, 42313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * then the comparison will be true if and only if there is a node in the 42323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * node-set such that the result of performing the comparison on the number 42333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * to be compared and on the result of converting the string-value of that 42343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * node to a number using the number function is true. 42353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 42363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns 0 or 1 depending on the results of the test. 42373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 423856a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic int 42393473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathCompareNodeSetFloat(xmlXPathParserContextPtr ctxt, int inf, int strict, 42403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr arg, xmlXPathObjectPtr f) { 42413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int i, ret = 0; 42423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlNodeSetPtr ns; 42433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlChar *str2; 42443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 42453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((f == NULL) || (arg == NULL) || 42463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ((arg->type != XPATH_NODESET) && (arg->type != XPATH_XSLT_TREE))) { 42473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(arg); 42483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(f); 42493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(0); 42503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 42513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ns = arg->nodesetval; 4252911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard if (ns != NULL) { 4253911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard for (i = 0;i < ns->nodeNr;i++) { 4254ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard str2 = xmlXPathCastNodeToString(ns->nodeTab[i]); 4255911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard if (str2 != NULL) { 4256911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard valuePush(ctxt, 4257911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard xmlXPathNewString(str2)); 4258911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard xmlFree(str2); 4259911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard xmlXPathNumberFunction(ctxt, 1); 4260911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard valuePush(ctxt, xmlXPathObjectCopy(f)); 4261911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard ret = xmlXPathCompareValues(ctxt, inf, strict); 4262911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard if (ret) 4263911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard break; 4264911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard } 4265911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard } 42663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 42673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(arg); 42683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(f); 42693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ret); 42703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 42713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 42723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 42733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathCompareNodeSetString: 42743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 42753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @inf: less than (1) or greater than (0) 42763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @strict: is the comparison strict 42773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @arg: the node set 42783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @s: the value 42793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 42803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the compare operation between a nodeset and a string 42813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ns < @val (1, 1, ... 42823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ns <= @val (1, 0, ... 42833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ns > @val (0, 1, ... 42843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ns >= @val (0, 0, ... 42853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 42863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * If one object to be compared is a node-set and the other is a string, 42873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * then the comparison will be true if and only if there is a node in 42883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the node-set such that the result of performing the comparison on the 42893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * string-value of the node and the other string is true. 42903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 42913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns 0 or 1 depending on the results of the test. 42923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 429356a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic int 42943473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathCompareNodeSetString(xmlXPathParserContextPtr ctxt, int inf, int strict, 42953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr arg, xmlXPathObjectPtr s) { 42963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int i, ret = 0; 42973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlNodeSetPtr ns; 42983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlChar *str2; 42993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 43003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((s == NULL) || (arg == NULL) || 43013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ((arg->type != XPATH_NODESET) && (arg->type != XPATH_XSLT_TREE))) { 43023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(arg); 43033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(s); 43043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(0); 43053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 43063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ns = arg->nodesetval; 4307911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard if (ns != NULL) { 4308911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard for (i = 0;i < ns->nodeNr;i++) { 4309ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard str2 = xmlXPathCastNodeToString(ns->nodeTab[i]); 4310911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard if (str2 != NULL) { 4311911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard valuePush(ctxt, 4312911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard xmlXPathNewString(str2)); 4313911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard xmlFree(str2); 4314911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard valuePush(ctxt, xmlXPathObjectCopy(s)); 4315911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard ret = xmlXPathCompareValues(ctxt, inf, strict); 4316911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard if (ret) 4317911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard break; 4318911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard } 4319911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard } 43203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 43213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(arg); 43223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(s); 43233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ret); 43243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 43253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 43263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 43273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathCompareNodeSets: 4328ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @inf: less than (1) or greater than (0) 43293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @strict: is the comparison strict 4330cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * @arg1: the first node set object 43313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @arg2: the second node set object 43323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 43333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the compare operation on nodesets: 43343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 43353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * If both objects to be compared are node-sets, then the comparison 43363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * will be true if and only if there is a node in the first node-set 43373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * and a node in the second node-set such that the result of performing 43383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the comparison on the string-values of the two nodes is true. 43393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * .... 43403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * When neither object to be compared is a node-set and the operator 43413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * is <=, <, >= or >, then the objects are compared by converting both 43423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * objects to numbers and comparing the numbers according to IEEE 754. 43433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * .... 43443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The number function converts its argument to a number as follows: 43453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * - a string that consists of optional whitespace followed by an 43463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * optional minus sign followed by a Number followed by whitespace 43473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * is converted to the IEEE 754 number that is nearest (according 43483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * to the IEEE 754 round-to-nearest rule) to the mathematical value 43493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * represented by the string; any other string is converted to NaN 43503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 43513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Conclusion all nodes need to be converted first to their string value 43523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * and then the comparison must be done when possible 43533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 435456a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic int 435556a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel VeillardxmlXPathCompareNodeSets(int inf, int strict, 43563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr arg1, xmlXPathObjectPtr arg2) { 43573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int i, j, init = 0; 43583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor double val1; 43593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor double *values2; 43603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int ret = 0; 43613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlNodeSetPtr ns1; 43623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlNodeSetPtr ns2; 43633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 43643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((arg1 == NULL) || 43654dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard ((arg1->type != XPATH_NODESET) && (arg1->type != XPATH_XSLT_TREE))) { 43664dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard xmlXPathFreeObject(arg2); 43673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(0); 43684dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard } 43693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((arg2 == NULL) || 43704dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard ((arg2->type != XPATH_NODESET) && (arg2->type != XPATH_XSLT_TREE))) { 43714dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard xmlXPathFreeObject(arg1); 43724dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard xmlXPathFreeObject(arg2); 43733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(0); 43744dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard } 43753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 43763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ns1 = arg1->nodesetval; 43773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ns2 = arg2->nodesetval; 43783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 4379d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard if ((ns1 == NULL) || (ns1->nodeNr <= 0)) { 43804dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard xmlXPathFreeObject(arg1); 43814dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard xmlXPathFreeObject(arg2); 43823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(0); 43834dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard } 4384d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard if ((ns2 == NULL) || (ns2->nodeNr <= 0)) { 43854dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard xmlXPathFreeObject(arg1); 43864dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard xmlXPathFreeObject(arg2); 43873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(0); 43884dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard } 43893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 43903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor values2 = (double *) xmlMalloc(ns2->nodeNr * sizeof(double)); 43913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (values2 == NULL) { 4392d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard xmlXPathErrMemory(NULL, "comparing nodesets\n"); 43934dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard xmlXPathFreeObject(arg1); 43944dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard xmlXPathFreeObject(arg2); 43953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(0); 43963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 43973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor for (i = 0;i < ns1->nodeNr;i++) { 4398ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard val1 = xmlXPathCastNodeToNumber(ns1->nodeTab[i]); 4399cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard if (xmlXPathIsNaN(val1)) 44003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor continue; 44013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor for (j = 0;j < ns2->nodeNr;j++) { 44023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (init == 0) { 4403ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard values2[j] = xmlXPathCastNodeToNumber(ns2->nodeTab[j]); 44043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 4405cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard if (xmlXPathIsNaN(values2[j])) 44063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor continue; 44073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (inf && strict) 44083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = (val1 < values2[j]); 44093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else if (inf && !strict) 44103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = (val1 <= values2[j]); 44113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else if (!inf && strict) 44123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = (val1 > values2[j]); 44133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else if (!inf && !strict) 44143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = (val1 >= values2[j]); 44153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ret) 44163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 44173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 44183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ret) 44193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 44203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor init = 1; 44213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 44223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(values2); 44234dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard xmlXPathFreeObject(arg1); 44244dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard xmlXPathFreeObject(arg2); 44253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ret); 44263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 44273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 44283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 44293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathCompareNodeSetValue: 44303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 44313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @inf: less than (1) or greater than (0) 44323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @strict: is the comparison strict 44333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @arg: the node set 44343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val: the value 44353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 44363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the compare operation between a nodeset and a value 44373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ns < @val (1, 1, ... 44383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ns <= @val (1, 0, ... 44393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ns > @val (0, 1, ... 44403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ns >= @val (0, 0, ... 44413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 44423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * If one object to be compared is a node-set and the other is a boolean, 44433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * then the comparison will be true if and only if the result of performing 44443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the comparison on the boolean and on the result of converting 44453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the node-set to a boolean using the boolean function is true. 44463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 44473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns 0 or 1 depending on the results of the test. 44483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 444956a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic int 44503473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathCompareNodeSetValue(xmlXPathParserContextPtr ctxt, int inf, int strict, 44513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr arg, xmlXPathObjectPtr val) { 44523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((val == NULL) || (arg == NULL) || 44533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ((arg->type != XPATH_NODESET) && (arg->type != XPATH_XSLT_TREE))) 44543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(0); 44553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 44563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor switch(val->type) { 44573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_NUMBER: 44583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(xmlXPathCompareNodeSetFloat(ctxt, inf, strict, arg, val)); 44593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_NODESET: 44603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_XSLT_TREE: 446156a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillard return(xmlXPathCompareNodeSets(inf, strict, arg, val)); 44623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_STRING: 44633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(xmlXPathCompareNodeSetString(ctxt, inf, strict, arg, val)); 44643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_BOOLEAN: 44653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, arg); 44663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathBooleanFunction(ctxt, 1); 44673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, val); 44683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(xmlXPathCompareValues(ctxt, inf, strict)); 44693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor default: 44703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor TODO 44713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 44723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(0); 44733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 44743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 44753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 447601c13b5be2d249ef66d86585adee87901bb8efa2Daniel Veillard * xmlXPathEqualNodeSetString: 44773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @arg: the nodeset object argument 44783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @str: the string to compare to. 44790c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack * @neq: flag to show whether for '=' (0) or '!=' (1) 44803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 44813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the equal operation on XPath objects content: @arg1 == @arg2 44823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * If one object to be compared is a node-set and the other is a string, 44833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * then the comparison will be true if and only if there is a node in 44843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the node-set such that the result of performing the comparison on the 44853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * string-value of the node and the other string is true. 44863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 44873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns 0 or 1 depending on the results of the test. 44883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 448956a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic int 44900c022ad8234a9228288c651f5e6a9bce7efcd789William M. BrackxmlXPathEqualNodeSetString(xmlXPathObjectPtr arg, const xmlChar * str, int neq) 4491f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard{ 44923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int i; 44933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlNodeSetPtr ns; 44943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlChar *str2; 4495f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard unsigned int hash; 44963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 44973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((str == NULL) || (arg == NULL) || 4498f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ((arg->type != XPATH_NODESET) && (arg->type != XPATH_XSLT_TREE))) 4499f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (0); 45003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ns = arg->nodesetval; 4501c125a721a4b7856f5356334137d467f95e6bf4b2William M. Brack /* 4502c125a721a4b7856f5356334137d467f95e6bf4b2William M. Brack * A NULL nodeset compared with a string is always false 4503c125a721a4b7856f5356334137d467f95e6bf4b2William M. Brack * (since there is no node equal, and no node not equal) 4504c125a721a4b7856f5356334137d467f95e6bf4b2William M. Brack */ 4505c125a721a4b7856f5356334137d467f95e6bf4b2William M. Brack if ((ns == NULL) || (ns->nodeNr <= 0) ) 4506f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (0); 4507c125a721a4b7856f5356334137d467f95e6bf4b2William M. Brack hash = xmlXPathStringHash(str); 4508f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard for (i = 0; i < ns->nodeNr; i++) { 4509f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (xmlXPathNodeValHash(ns->nodeTab[i]) == hash) { 4510f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard str2 = xmlNodeGetContent(ns->nodeTab[i]); 4511f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((str2 != NULL) && (xmlStrEqual(str, str2))) { 4512f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlFree(str2); 45130c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack if (neq) 45140c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack continue; 4515f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (1); 45169adc0469d4691e798ea4ad59b84c874cdea8b38dDaniel Veillard } else if ((str2 == NULL) && (xmlStrEqual(str, BAD_CAST ""))) { 45179adc0469d4691e798ea4ad59b84c874cdea8b38dDaniel Veillard if (neq) 45189adc0469d4691e798ea4ad59b84c874cdea8b38dDaniel Veillard continue; 45199adc0469d4691e798ea4ad59b84c874cdea8b38dDaniel Veillard return (1); 45200c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack } else if (neq) { 45210c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack if (str2 != NULL) 45220c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack xmlFree(str2); 45230c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack return (1); 45240c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack } 4525f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (str2 != NULL) 4526f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlFree(str2); 45270c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack } else if (neq) 45280c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack return (1); 45293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 4530f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (0); 45313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 45323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 45333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 453401c13b5be2d249ef66d86585adee87901bb8efa2Daniel Veillard * xmlXPathEqualNodeSetFloat: 45353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @arg: the nodeset object argument 45363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @f: the float to compare to 45370c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack * @neq: flag to show whether to compare '=' (0) or '!=' (1) 45383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 45393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the equal operation on XPath objects content: @arg1 == @arg2 45403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * If one object to be compared is a node-set and the other is a number, 45413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * then the comparison will be true if and only if there is a node in 45423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the node-set such that the result of performing the comparison on the 45433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * number to be compared and on the result of converting the string-value 45443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * of that node to a number using the number function is true. 45453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 45463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns 0 or 1 depending on the results of the test. 45473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 454856a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic int 45490c022ad8234a9228288c651f5e6a9bce7efcd789William M. BrackxmlXPathEqualNodeSetFloat(xmlXPathParserContextPtr ctxt, 45500c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack xmlXPathObjectPtr arg, double f, int neq) { 45510c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack int i, ret=0; 45520c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack xmlNodeSetPtr ns; 45530c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack xmlChar *str2; 45540c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack xmlXPathObjectPtr val; 45550c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack double v; 45563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 45573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((arg == NULL) || 45583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ((arg->type != XPATH_NODESET) && (arg->type != XPATH_XSLT_TREE))) 45593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(0); 45603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 45610c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack ns = arg->nodesetval; 45620c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack if (ns != NULL) { 45630c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack for (i=0;i<ns->nodeNr;i++) { 45640c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack str2 = xmlXPathCastNodeToString(ns->nodeTab[i]); 45650c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack if (str2 != NULL) { 45660c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack valuePush(ctxt, xmlXPathNewString(str2)); 45670c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack xmlFree(str2); 45680c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack xmlXPathNumberFunction(ctxt, 1); 45690c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack val = valuePop(ctxt); 45700c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack v = val->floatval; 45710c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack xmlXPathFreeObject(val); 45720c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack if (!xmlXPathIsNaN(v)) { 45730c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack if ((!neq) && (v==f)) { 45740c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack ret = 1; 45750c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack break; 45760c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack } else if ((neq) && (v!=f)) { 45770c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack ret = 1; 45780c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack break; 45790c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack } 45800c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack } 45810c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack } 45820c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack } 45830c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack } 45840c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack 45850c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack return(ret); 45863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 45873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 45883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 45893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 459001c13b5be2d249ef66d86585adee87901bb8efa2Daniel Veillard * xmlXPathEqualNodeSets: 45913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @arg1: first nodeset object argument 45923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @arg2: second nodeset object argument 45930c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack * @neq: flag to show whether to test '=' (0) or '!=' (1) 45943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 45950c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack * Implement the equal / not equal operation on XPath nodesets: 45960c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack * @arg1 == @arg2 or @arg1 != @arg2 45973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * If both objects to be compared are node-sets, then the comparison 45983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * will be true if and only if there is a node in the first node-set and 45993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * a node in the second node-set such that the result of performing the 46003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * comparison on the string-values of the two nodes is true. 46013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 46023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * (needless to say, this is a costly operation) 46033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 46043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns 0 or 1 depending on the results of the test. 46053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 460656a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic int 46070c022ad8234a9228288c651f5e6a9bce7efcd789William M. BrackxmlXPathEqualNodeSets(xmlXPathObjectPtr arg1, xmlXPathObjectPtr arg2, int neq) { 46083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int i, j; 4609f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard unsigned int *hashs1; 4610f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard unsigned int *hashs2; 46113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlChar **values1; 46123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlChar **values2; 46133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int ret = 0; 46143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlNodeSetPtr ns1; 46153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlNodeSetPtr ns2; 46163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 46173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((arg1 == NULL) || 46183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ((arg1->type != XPATH_NODESET) && (arg1->type != XPATH_XSLT_TREE))) 46193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(0); 46203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((arg2 == NULL) || 46213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ((arg2->type != XPATH_NODESET) && (arg2->type != XPATH_XSLT_TREE))) 46223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(0); 46233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 46243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ns1 = arg1->nodesetval; 46253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ns2 = arg2->nodesetval; 46263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 4627911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard if ((ns1 == NULL) || (ns1->nodeNr <= 0)) 46283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(0); 4629911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard if ((ns2 == NULL) || (ns2->nodeNr <= 0)) 46303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(0); 46313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 46323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 46330c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack * for equal, check if there is a node pertaining to both sets 46343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 46350c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack if (neq == 0) 46360c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack for (i = 0;i < ns1->nodeNr;i++) 46370c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack for (j = 0;j < ns2->nodeNr;j++) 46380c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack if (ns1->nodeTab[i] == ns2->nodeTab[j]) 46390c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack return(1); 46403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 46413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor values1 = (xmlChar **) xmlMalloc(ns1->nodeNr * sizeof(xmlChar *)); 4642d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard if (values1 == NULL) { 4643d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard xmlXPathErrMemory(NULL, "comparing nodesets\n"); 46443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(0); 4645d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard } 4646f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard hashs1 = (unsigned int *) xmlMalloc(ns1->nodeNr * sizeof(unsigned int)); 4647f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (hashs1 == NULL) { 4648d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard xmlXPathErrMemory(NULL, "comparing nodesets\n"); 4649f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlFree(values1); 4650f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return(0); 4651f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 46523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor memset(values1, 0, ns1->nodeNr * sizeof(xmlChar *)); 46533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor values2 = (xmlChar **) xmlMalloc(ns2->nodeNr * sizeof(xmlChar *)); 46543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (values2 == NULL) { 4655d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard xmlXPathErrMemory(NULL, "comparing nodesets\n"); 4656f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlFree(hashs1); 46573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(values1); 46583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(0); 46593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 4660f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard hashs2 = (unsigned int *) xmlMalloc(ns2->nodeNr * sizeof(unsigned int)); 4661f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (hashs2 == NULL) { 4662d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard xmlXPathErrMemory(NULL, "comparing nodesets\n"); 4663f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlFree(hashs1); 4664f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlFree(values1); 4665f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlFree(values2); 4666f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return(0); 4667f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 46683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor memset(values2, 0, ns2->nodeNr * sizeof(xmlChar *)); 46693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor for (i = 0;i < ns1->nodeNr;i++) { 4670f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard hashs1[i] = xmlXPathNodeValHash(ns1->nodeTab[i]); 46713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor for (j = 0;j < ns2->nodeNr;j++) { 46723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (i == 0) 4673f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard hashs2[j] = xmlXPathNodeValHash(ns2->nodeTab[j]); 46740c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack if (hashs1[i] != hashs2[j]) { 46750c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack if (neq) { 46760c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack ret = 1; 46770c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack break; 46780c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack } 46790c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack } 46800c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack else { 4681f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (values1[i] == NULL) 4682f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard values1[i] = xmlNodeGetContent(ns1->nodeTab[i]); 4683f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (values2[j] == NULL) 4684f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard values2[j] = xmlNodeGetContent(ns2->nodeTab[j]); 46850c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack ret = xmlStrEqual(values1[i], values2[j]) ^ neq; 4686f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (ret) 4687f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 4688f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 46893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 46903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ret) 46913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 46923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 46933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor for (i = 0;i < ns1->nodeNr;i++) 46943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (values1[i] != NULL) 46953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(values1[i]); 46963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor for (j = 0;j < ns2->nodeNr;j++) 46973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (values2[j] != NULL) 46983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(values2[j]); 46993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(values1); 47003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(values2); 4701f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlFree(hashs1); 4702f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlFree(hashs2); 47033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ret); 47043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 47053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 47060c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brackstatic int 47070c022ad8234a9228288c651f5e6a9bce7efcd789William M. BrackxmlXPathEqualValuesCommon(xmlXPathParserContextPtr ctxt, 47080c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack xmlXPathObjectPtr arg1, xmlXPathObjectPtr arg2) { 47093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int ret = 0; 47100c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack /* 47110c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack *At this point we are assured neither arg1 nor arg2 47120c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack *is a nodeset, so we can just pick the appropriate routine. 47130c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack */ 47143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor switch (arg1->type) { 47153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_UNDEFINED: 47163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_EXPR 47173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 47183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "Equal: undefined\n"); 47193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 47203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 47213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_BOOLEAN: 47223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor switch (arg2->type) { 47233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_UNDEFINED: 47243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_EXPR 47253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 47263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "Equal: undefined\n"); 47273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 47283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 47293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_BOOLEAN: 47303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_EXPR 47313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 47323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "Equal: %d boolean %d \n", 47333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor arg1->boolval, arg2->boolval); 47343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 47353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = (arg1->boolval == arg2->boolval); 47363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 47373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_NUMBER: 4738ef61d208503e41688f4bf86f6e9023c70e65829bWilliam M. Brack ret = (arg1->boolval == 4739ef61d208503e41688f4bf86f6e9023c70e65829bWilliam M. Brack xmlXPathCastNumberToBoolean(arg2->floatval)); 47403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 47413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_STRING: 47423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((arg2->stringval == NULL) || 47433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor (arg2->stringval[0] == 0)) ret = 0; 47443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else 47453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = 1; 47463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = (arg1->boolval == ret); 47473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 47483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_USERS: 47493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_POINT: 47503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_RANGE: 47513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_LOCATIONSET: 47523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor TODO 47533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 47540c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack case XPATH_NODESET: 47550c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack case XPATH_XSLT_TREE: 47560c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack break; 47573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 47583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 47593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_NUMBER: 47603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor switch (arg2->type) { 47613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_UNDEFINED: 47623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_EXPR 47633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 47643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "Equal: undefined\n"); 47653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 47663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 47673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_BOOLEAN: 4768ef61d208503e41688f4bf86f6e9023c70e65829bWilliam M. Brack ret = (arg2->boolval== 4769ef61d208503e41688f4bf86f6e9023c70e65829bWilliam M. Brack xmlXPathCastNumberToBoolean(arg1->floatval)); 47703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 47713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_STRING: 47723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, arg2); 47733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathNumberFunction(ctxt, 1); 47743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor arg2 = valuePop(ctxt); 47753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* no break on purpose */ 47763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_NUMBER: 4777d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard /* Hand check NaN and Infinity equalities */ 4778081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack if (xmlXPathIsNaN(arg1->floatval) || 4779081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack xmlXPathIsNaN(arg2->floatval)) { 478021458c85e209cd2621ac3eadfee075ae2dc0121dDaniel Veillard ret = 0; 4781d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard } else if (xmlXPathIsInf(arg1->floatval) == 1) { 4782d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard if (xmlXPathIsInf(arg2->floatval) == 1) 4783d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret = 1; 4784d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard else 4785d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret = 0; 4786d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard } else if (xmlXPathIsInf(arg1->floatval) == -1) { 4787d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard if (xmlXPathIsInf(arg2->floatval) == -1) 4788d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret = 1; 4789d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard else 4790d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret = 0; 4791d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard } else if (xmlXPathIsInf(arg2->floatval) == 1) { 4792d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard if (xmlXPathIsInf(arg1->floatval) == 1) 4793d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret = 1; 4794d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard else 4795d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret = 0; 4796d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard } else if (xmlXPathIsInf(arg2->floatval) == -1) { 4797d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard if (xmlXPathIsInf(arg1->floatval) == -1) 4798d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret = 1; 4799d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard else 4800d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret = 0; 480121458c85e209cd2621ac3eadfee075ae2dc0121dDaniel Veillard } else { 480221458c85e209cd2621ac3eadfee075ae2dc0121dDaniel Veillard ret = (arg1->floatval == arg2->floatval); 480321458c85e209cd2621ac3eadfee075ae2dc0121dDaniel Veillard } 48043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 48053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_USERS: 48063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_POINT: 48073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_RANGE: 48083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_LOCATIONSET: 48093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor TODO 48103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 48110c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack case XPATH_NODESET: 48120c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack case XPATH_XSLT_TREE: 48130c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack break; 48143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 48153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 48163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_STRING: 48173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor switch (arg2->type) { 48183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_UNDEFINED: 48193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_EXPR 48203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 48213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "Equal: undefined\n"); 48223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 48233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 48243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_BOOLEAN: 48253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((arg1->stringval == NULL) || 48263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor (arg1->stringval[0] == 0)) ret = 0; 48273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else 48283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = 1; 48293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = (arg2->boolval == ret); 48303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 48313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_STRING: 48323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = xmlStrEqual(arg1->stringval, arg2->stringval); 48333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 48343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_NUMBER: 48353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, arg1); 48363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathNumberFunction(ctxt, 1); 48373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor arg1 = valuePop(ctxt); 4838d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard /* Hand check NaN and Infinity equalities */ 4839081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack if (xmlXPathIsNaN(arg1->floatval) || 4840081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack xmlXPathIsNaN(arg2->floatval)) { 484121458c85e209cd2621ac3eadfee075ae2dc0121dDaniel Veillard ret = 0; 4842d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard } else if (xmlXPathIsInf(arg1->floatval) == 1) { 4843d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard if (xmlXPathIsInf(arg2->floatval) == 1) 4844d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret = 1; 4845d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard else 4846d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret = 0; 4847d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard } else if (xmlXPathIsInf(arg1->floatval) == -1) { 4848d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard if (xmlXPathIsInf(arg2->floatval) == -1) 4849d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret = 1; 4850d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard else 4851d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret = 0; 4852d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard } else if (xmlXPathIsInf(arg2->floatval) == 1) { 4853d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard if (xmlXPathIsInf(arg1->floatval) == 1) 4854d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret = 1; 4855d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard else 4856d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret = 0; 4857d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard } else if (xmlXPathIsInf(arg2->floatval) == -1) { 4858d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard if (xmlXPathIsInf(arg1->floatval) == -1) 4859d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret = 1; 4860d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard else 4861d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret = 0; 486221458c85e209cd2621ac3eadfee075ae2dc0121dDaniel Veillard } else { 486321458c85e209cd2621ac3eadfee075ae2dc0121dDaniel Veillard ret = (arg1->floatval == arg2->floatval); 486421458c85e209cd2621ac3eadfee075ae2dc0121dDaniel Veillard } 48653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 48663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_USERS: 48673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_POINT: 48683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_RANGE: 48693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_LOCATIONSET: 48703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor TODO 48713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 48720c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack case XPATH_NODESET: 48730c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack case XPATH_XSLT_TREE: 48740c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack break; 48753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 48763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 48773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_USERS: 48783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_POINT: 48793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_RANGE: 48803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_LOCATIONSET: 48813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor TODO 48823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 48830c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack case XPATH_NODESET: 48840c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack case XPATH_XSLT_TREE: 48850c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack break; 48863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 48873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(arg1); 48883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(arg2); 48893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ret); 48903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 48913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 48920c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack/** 48930c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack * xmlXPathEqualValues: 48940c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack * @ctxt: the XPath Parser context 48950c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack * 48960c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack * Implement the equal operation on XPath objects content: @arg1 == @arg2 48970c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack * 48980c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack * Returns 0 or 1 depending on the results of the test. 48990c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack */ 49000c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brackint 49010c022ad8234a9228288c651f5e6a9bce7efcd789William M. BrackxmlXPathEqualValues(xmlXPathParserContextPtr ctxt) { 49020c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack xmlXPathObjectPtr arg1, arg2, argtmp; 49030c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack int ret = 0; 49040c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack 49056128c01ca6a5c1d67970b44cd11aa95a392d8a2dDaniel Veillard if ((ctxt == NULL) || (ctxt->context == NULL)) return(0); 49060c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack arg2 = valuePop(ctxt); 49070c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack arg1 = valuePop(ctxt); 49080c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack if ((arg1 == NULL) || (arg2 == NULL)) { 49090c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack if (arg1 != NULL) 49100c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack xmlXPathFreeObject(arg1); 49110c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack else 49120c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack xmlXPathFreeObject(arg2); 49130c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack XP_ERROR0(XPATH_INVALID_OPERAND); 49140c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack } 49150c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack 49160c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack if (arg1 == arg2) { 49170c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack#ifdef DEBUG_EXPR 49180c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack xmlGenericError(xmlGenericErrorContext, 49190c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack "Equal: by pointer\n"); 49200c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack#endif 49212c19a7bf2ee0f78485840cac50f2a989f5efe476William M. Brack xmlXPathFreeObject(arg1); 49220c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack return(1); 49230c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack } 49240c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack 49250c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack /* 49260c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack *If either argument is a nodeset, it's a 'special case' 49270c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack */ 49280c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack if ((arg2->type == XPATH_NODESET) || (arg2->type == XPATH_XSLT_TREE) || 49290c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack (arg1->type == XPATH_NODESET) || (arg1->type == XPATH_XSLT_TREE)) { 49300c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack /* 49310c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack *Hack it to assure arg1 is the nodeset 49320c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack */ 49330c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack if ((arg1->type != XPATH_NODESET) && (arg1->type != XPATH_XSLT_TREE)) { 49340c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack argtmp = arg2; 49350c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack arg2 = arg1; 49360c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack arg1 = argtmp; 49370c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack } 49380c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack switch (arg2->type) { 49390c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack case XPATH_UNDEFINED: 49400c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack#ifdef DEBUG_EXPR 49410c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack xmlGenericError(xmlGenericErrorContext, 49420c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack "Equal: undefined\n"); 49430c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack#endif 49440c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack break; 49450c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack case XPATH_NODESET: 49460c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack case XPATH_XSLT_TREE: 49470c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack ret = xmlXPathEqualNodeSets(arg1, arg2, 0); 49480c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack break; 49490c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack case XPATH_BOOLEAN: 49500c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack if ((arg1->nodesetval == NULL) || 49510c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack (arg1->nodesetval->nodeNr == 0)) ret = 0; 49520c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack else 49530c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack ret = 1; 49540c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack ret = (ret == arg2->boolval); 49550c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack break; 49560c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack case XPATH_NUMBER: 49570c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack ret = xmlXPathEqualNodeSetFloat(ctxt, arg1, arg2->floatval, 0); 49580c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack break; 49590c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack case XPATH_STRING: 49600c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack ret = xmlXPathEqualNodeSetString(arg1, arg2->stringval, 0); 49610c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack break; 49620c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack case XPATH_USERS: 49630c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack case XPATH_POINT: 49640c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack case XPATH_RANGE: 49650c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack case XPATH_LOCATIONSET: 49660c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack TODO 49670c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack break; 49680c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack } 49690c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack xmlXPathFreeObject(arg1); 49700c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack xmlXPathFreeObject(arg2); 49710c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack return(ret); 49720c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack } 49730c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack 49740c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack return (xmlXPathEqualValuesCommon(ctxt, arg1, arg2)); 49750c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack} 49760c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack 49770c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack/** 49780c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack * xmlXPathNotEqualValues: 49790c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack * @ctxt: the XPath Parser context 49800c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack * 49810c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack * Implement the equal operation on XPath objects content: @arg1 == @arg2 49820c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack * 49830c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack * Returns 0 or 1 depending on the results of the test. 49840c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack */ 49850c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brackint 49860c022ad8234a9228288c651f5e6a9bce7efcd789William M. BrackxmlXPathNotEqualValues(xmlXPathParserContextPtr ctxt) { 49870c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack xmlXPathObjectPtr arg1, arg2, argtmp; 49880c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack int ret = 0; 49890c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack 49906128c01ca6a5c1d67970b44cd11aa95a392d8a2dDaniel Veillard if ((ctxt == NULL) || (ctxt->context == NULL)) return(0); 49910c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack arg2 = valuePop(ctxt); 49920c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack arg1 = valuePop(ctxt); 49930c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack if ((arg1 == NULL) || (arg2 == NULL)) { 49940c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack if (arg1 != NULL) 49950c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack xmlXPathFreeObject(arg1); 49960c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack else 49970c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack xmlXPathFreeObject(arg2); 49980c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack XP_ERROR0(XPATH_INVALID_OPERAND); 49990c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack } 50000c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack 50010c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack if (arg1 == arg2) { 50020c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack#ifdef DEBUG_EXPR 50030c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack xmlGenericError(xmlGenericErrorContext, 50040c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack "NotEqual: by pointer\n"); 50050c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack#endif 50062c19a7bf2ee0f78485840cac50f2a989f5efe476William M. Brack xmlXPathFreeObject(arg1); 50070c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack return(0); 50080c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack } 50090c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack 50100c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack /* 50110c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack *If either argument is a nodeset, it's a 'special case' 50120c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack */ 50130c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack if ((arg2->type == XPATH_NODESET) || (arg2->type == XPATH_XSLT_TREE) || 50140c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack (arg1->type == XPATH_NODESET) || (arg1->type == XPATH_XSLT_TREE)) { 50150c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack /* 50160c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack *Hack it to assure arg1 is the nodeset 50170c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack */ 50180c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack if ((arg1->type != XPATH_NODESET) && (arg1->type != XPATH_XSLT_TREE)) { 50190c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack argtmp = arg2; 50200c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack arg2 = arg1; 50210c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack arg1 = argtmp; 50220c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack } 50230c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack switch (arg2->type) { 50240c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack case XPATH_UNDEFINED: 50250c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack#ifdef DEBUG_EXPR 50260c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack xmlGenericError(xmlGenericErrorContext, 50270c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack "NotEqual: undefined\n"); 50280c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack#endif 50290c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack break; 50300c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack case XPATH_NODESET: 50310c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack case XPATH_XSLT_TREE: 50320c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack ret = xmlXPathEqualNodeSets(arg1, arg2, 1); 50330c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack break; 50340c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack case XPATH_BOOLEAN: 50350c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack if ((arg1->nodesetval == NULL) || 50360c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack (arg1->nodesetval->nodeNr == 0)) ret = 0; 50370c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack else 50380c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack ret = 1; 5039ef61d208503e41688f4bf86f6e9023c70e65829bWilliam M. Brack ret = (ret != arg2->boolval); 50400c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack break; 50410c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack case XPATH_NUMBER: 50420c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack ret = xmlXPathEqualNodeSetFloat(ctxt, arg1, arg2->floatval, 1); 50430c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack break; 50440c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack case XPATH_STRING: 50450c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack ret = xmlXPathEqualNodeSetString(arg1, arg2->stringval,1); 50460c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack break; 50470c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack case XPATH_USERS: 50480c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack case XPATH_POINT: 50490c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack case XPATH_RANGE: 50500c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack case XPATH_LOCATIONSET: 50510c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack TODO 50520c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack break; 50530c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack } 50540c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack xmlXPathFreeObject(arg1); 50550c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack xmlXPathFreeObject(arg2); 50560c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack return(ret); 50570c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack } 50580c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack 50590c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack return (!xmlXPathEqualValuesCommon(ctxt, arg1, arg2)); 50600c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack} 50613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 50623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 50633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathCompareValues: 50643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 50653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @inf: less than (1) or greater than (0) 50663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @strict: is the comparison strict 50673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 50683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the compare operation on XPath objects: 50693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @arg1 < @arg2 (1, 1, ... 50703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @arg1 <= @arg2 (1, 0, ... 50713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @arg1 > @arg2 (0, 1, ... 50723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @arg1 >= @arg2 (0, 0, ... 50733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 50743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * When neither object to be compared is a node-set and the operator is 50753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * <=, <, >=, >, then the objects are compared by converted both objects 50763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * to numbers and comparing the numbers according to IEEE 754. The < 50773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * comparison will be true if and only if the first number is less than the 50783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * second number. The <= comparison will be true if and only if the first 50793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * number is less than or equal to the second number. The > comparison 50803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * will be true if and only if the first number is greater than the second 50813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * number. The >= comparison will be true if and only if the first number 50823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * is greater than or equal to the second number. 50833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 5084cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * Returns 1 if the comparison succeeded, 0 if it failed 50853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 50863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorint 50873473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathCompareValues(xmlXPathParserContextPtr ctxt, int inf, int strict) { 5088d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard int ret = 0, arg1i = 0, arg2i = 0; 50893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr arg1, arg2; 50903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 50916128c01ca6a5c1d67970b44cd11aa95a392d8a2dDaniel Veillard if ((ctxt == NULL) || (ctxt->context == NULL)) return(0); 50920c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack arg2 = valuePop(ctxt); 50933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor arg1 = valuePop(ctxt); 50940c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack if ((arg1 == NULL) || (arg2 == NULL)) { 50950c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack if (arg1 != NULL) 50960c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack xmlXPathFreeObject(arg1); 50970c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack else 50980c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack xmlXPathFreeObject(arg2); 50993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XP_ERROR0(XPATH_INVALID_OPERAND); 51003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 51013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 51020c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack if ((arg2->type == XPATH_NODESET) || (arg2->type == XPATH_XSLT_TREE) || 51030c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack (arg1->type == XPATH_NODESET) || (arg1->type == XPATH_XSLT_TREE)) { 5104d6e347e865b473f06fd431be926183c77596194aWilliam M. Brack /* 5105d6e347e865b473f06fd431be926183c77596194aWilliam M. Brack * If either argument is a XPATH_NODESET or XPATH_XSLT_TREE the two arguments 5106d6e347e865b473f06fd431be926183c77596194aWilliam M. Brack * are not freed from within this routine; they will be freed from the 5107d6e347e865b473f06fd431be926183c77596194aWilliam M. Brack * called routine, e.g. xmlXPathCompareNodeSets or xmlXPathCompareNodeSetValue 5108d6e347e865b473f06fd431be926183c77596194aWilliam M. Brack */ 51090c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack if (((arg2->type == XPATH_NODESET) || (arg2->type == XPATH_XSLT_TREE)) && 51100c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack ((arg1->type == XPATH_NODESET) || (arg1->type == XPATH_XSLT_TREE))){ 511156a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillard ret = xmlXPathCompareNodeSets(inf, strict, arg1, arg2); 51123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else { 51130c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack if ((arg1->type == XPATH_NODESET) || (arg1->type == XPATH_XSLT_TREE)) { 51144af6b6e801346d1c832cf19b7c3833a831871db2Daniel Veillard ret = xmlXPathCompareNodeSetValue(ctxt, inf, strict, 51154af6b6e801346d1c832cf19b7c3833a831871db2Daniel Veillard arg1, arg2); 51163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else { 51174af6b6e801346d1c832cf19b7c3833a831871db2Daniel Veillard ret = xmlXPathCompareNodeSetValue(ctxt, !inf, strict, 51184af6b6e801346d1c832cf19b7c3833a831871db2Daniel Veillard arg2, arg1); 51193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 51203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 51213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ret); 51223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 51233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 51243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (arg1->type != XPATH_NUMBER) { 51253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, arg1); 51263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathNumberFunction(ctxt, 1); 51273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor arg1 = valuePop(ctxt); 51283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 51293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (arg1->type != XPATH_NUMBER) { 51303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(arg1); 51313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(arg2); 51323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XP_ERROR0(XPATH_INVALID_OPERAND); 51333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 51343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (arg2->type != XPATH_NUMBER) { 51353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, arg2); 51363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathNumberFunction(ctxt, 1); 51373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor arg2 = valuePop(ctxt); 51383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 51393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (arg2->type != XPATH_NUMBER) { 51403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(arg1); 51413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(arg2); 51423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XP_ERROR0(XPATH_INVALID_OPERAND); 51433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 51443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 51453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Add tests for infinity and nan 51463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * => feedback on 3.4 for Inf and NaN 51473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 5148d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard /* Hand check NaN and Infinity comparisons */ 514921458c85e209cd2621ac3eadfee075ae2dc0121dDaniel Veillard if (xmlXPathIsNaN(arg1->floatval) || xmlXPathIsNaN(arg2->floatval)) { 5150d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret=0; 515121458c85e209cd2621ac3eadfee075ae2dc0121dDaniel Veillard } else { 5152d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard arg1i=xmlXPathIsInf(arg1->floatval); 5153d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard arg2i=xmlXPathIsInf(arg2->floatval); 5154d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard if (inf && strict) { 5155d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard if ((arg1i == -1 && arg2i != -1) || 5156d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard (arg2i == 1 && arg1i != 1)) { 5157d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret = 1; 5158d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard } else if (arg1i == 0 && arg2i == 0) { 5159d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret = (arg1->floatval < arg2->floatval); 5160d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard } else { 5161d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret = 0; 5162d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard } 5163d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard } 5164d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard else if (inf && !strict) { 5165d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard if (arg1i == -1 || arg2i == 1) { 5166d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret = 1; 5167d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard } else if (arg1i == 0 && arg2i == 0) { 5168d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret = (arg1->floatval <= arg2->floatval); 5169d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard } else { 5170d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret = 0; 5171d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard } 5172d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard } 5173d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard else if (!inf && strict) { 5174d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard if ((arg1i == 1 && arg2i != 1) || 5175d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard (arg2i == -1 && arg1i != -1)) { 5176d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret = 1; 5177d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard } else if (arg1i == 0 && arg2i == 0) { 5178d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret = (arg1->floatval > arg2->floatval); 5179d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard } else { 5180d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret = 0; 5181d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard } 5182d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard } 5183d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard else if (!inf && !strict) { 5184d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard if (arg1i == 1 || arg2i == -1) { 5185d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret = 1; 5186d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard } else if (arg1i == 0 && arg2i == 0) { 5187d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret = (arg1->floatval >= arg2->floatval); 5188d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard } else { 5189d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret = 0; 5190d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard } 5191d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard } 519221458c85e209cd2621ac3eadfee075ae2dc0121dDaniel Veillard } 51933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(arg1); 51943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(arg2); 51953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ret); 51963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 51973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 51983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 51993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathValueFlipSign: 52003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 52013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 52023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the unary - operation on an XPath object 52033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The numeric operators convert their operands to numbers as if 52043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * by calling the number function. 52053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 52063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 52073473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathValueFlipSign(xmlXPathParserContextPtr ctxt) { 5208a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard if ((ctxt == NULL) || (ctxt->context == NULL)) return; 5209ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard CAST_TO_NUMBER; 5210ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard CHECK_TYPE(XPATH_NUMBER); 5211eca82810f0fb81f3e9936d2018347e1e19de513aDaniel Veillard if (xmlXPathIsNaN(ctxt->value->floatval)) 5212eca82810f0fb81f3e9936d2018347e1e19de513aDaniel Veillard ctxt->value->floatval=xmlXPathNAN; 5213eca82810f0fb81f3e9936d2018347e1e19de513aDaniel Veillard else if (xmlXPathIsInf(ctxt->value->floatval) == 1) 5214eca82810f0fb81f3e9936d2018347e1e19de513aDaniel Veillard ctxt->value->floatval=xmlXPathNINF; 5215eca82810f0fb81f3e9936d2018347e1e19de513aDaniel Veillard else if (xmlXPathIsInf(ctxt->value->floatval) == -1) 5216eca82810f0fb81f3e9936d2018347e1e19de513aDaniel Veillard ctxt->value->floatval=xmlXPathPINF; 5217eca82810f0fb81f3e9936d2018347e1e19de513aDaniel Veillard else if (ctxt->value->floatval == 0) { 52185fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard if (xmlXPathGetSign(ctxt->value->floatval) == 0) 52195fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard ctxt->value->floatval = xmlXPathNZERO; 52205fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard else 52215fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard ctxt->value->floatval = 0; 52225fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard } 52235fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard else 52245fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard ctxt->value->floatval = - ctxt->value->floatval; 52253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 52263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 52273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 52283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathAddValues: 52293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 52303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 52313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the add operation on XPath objects: 52323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The numeric operators convert their operands to numbers as if 52333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * by calling the number function. 52343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 52353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 52363473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathAddValues(xmlXPathParserContextPtr ctxt) { 52373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr arg; 52383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor double val; 52393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 5240ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard arg = valuePop(ctxt); 5241ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard if (arg == NULL) 5242ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard XP_ERROR(XPATH_INVALID_OPERAND); 5243ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard val = xmlXPathCastToNumber(arg); 52443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(arg); 52453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 5246ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard CAST_TO_NUMBER; 5247ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard CHECK_TYPE(XPATH_NUMBER); 5248ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ctxt->value->floatval += val; 52493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 52503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 52513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 52523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathSubValues: 52533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 52543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 5255cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * Implement the subtraction operation on XPath objects: 52563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The numeric operators convert their operands to numbers as if 52573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * by calling the number function. 52583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 52593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 52603473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathSubValues(xmlXPathParserContextPtr ctxt) { 52613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr arg; 52623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor double val; 52633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 5264ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard arg = valuePop(ctxt); 5265ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard if (arg == NULL) 5266ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard XP_ERROR(XPATH_INVALID_OPERAND); 5267ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard val = xmlXPathCastToNumber(arg); 52683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(arg); 52693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 5270ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard CAST_TO_NUMBER; 5271ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard CHECK_TYPE(XPATH_NUMBER); 5272ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ctxt->value->floatval -= val; 52733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 52743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 52753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 52763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathMultValues: 52773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 52783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 52793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the multiply operation on XPath objects: 52803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The numeric operators convert their operands to numbers as if 52813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * by calling the number function. 52823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 52833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 52843473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathMultValues(xmlXPathParserContextPtr ctxt) { 52853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr arg; 52863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor double val; 52873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 5288ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard arg = valuePop(ctxt); 5289ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard if (arg == NULL) 5290ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard XP_ERROR(XPATH_INVALID_OPERAND); 5291ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard val = xmlXPathCastToNumber(arg); 52923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(arg); 52933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 5294ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard CAST_TO_NUMBER; 5295ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard CHECK_TYPE(XPATH_NUMBER); 5296ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ctxt->value->floatval *= val; 52973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 52983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 52993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 53003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathDivValues: 53013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 53023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 53033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the div operation on XPath objects @arg1 / @arg2: 53043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The numeric operators convert their operands to numbers as if 53053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * by calling the number function. 53063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 53073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 53083473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathDivValues(xmlXPathParserContextPtr ctxt) { 53093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr arg; 53103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor double val; 53113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 5312ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard arg = valuePop(ctxt); 5313ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard if (arg == NULL) 5314ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard XP_ERROR(XPATH_INVALID_OPERAND); 5315ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard val = xmlXPathCastToNumber(arg); 53163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(arg); 53173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 5318ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard CAST_TO_NUMBER; 5319ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard CHECK_TYPE(XPATH_NUMBER); 5320eca82810f0fb81f3e9936d2018347e1e19de513aDaniel Veillard if (xmlXPathIsNaN(val) || xmlXPathIsNaN(ctxt->value->floatval)) 5321eca82810f0fb81f3e9936d2018347e1e19de513aDaniel Veillard ctxt->value->floatval = xmlXPathNAN; 5322eca82810f0fb81f3e9936d2018347e1e19de513aDaniel Veillard else if (val == 0 && xmlXPathGetSign(val) != 0) { 53235fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard if (ctxt->value->floatval == 0) 53245fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard ctxt->value->floatval = xmlXPathNAN; 53255fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard else if (ctxt->value->floatval > 0) 53265fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard ctxt->value->floatval = xmlXPathNINF; 53275fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard else if (ctxt->value->floatval < 0) 53285fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard ctxt->value->floatval = xmlXPathPINF; 53295fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard } 53305fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard else if (val == 0) { 53315f4b5999b4eeda2ca68e6d9f54a3c534a8474b38Daniel Veillard if (ctxt->value->floatval == 0) 53325f4b5999b4eeda2ca68e6d9f54a3c534a8474b38Daniel Veillard ctxt->value->floatval = xmlXPathNAN; 53335f4b5999b4eeda2ca68e6d9f54a3c534a8474b38Daniel Veillard else if (ctxt->value->floatval > 0) 53345f4b5999b4eeda2ca68e6d9f54a3c534a8474b38Daniel Veillard ctxt->value->floatval = xmlXPathPINF; 53355f4b5999b4eeda2ca68e6d9f54a3c534a8474b38Daniel Veillard else if (ctxt->value->floatval < 0) 53365f4b5999b4eeda2ca68e6d9f54a3c534a8474b38Daniel Veillard ctxt->value->floatval = xmlXPathNINF; 53375f4b5999b4eeda2ca68e6d9f54a3c534a8474b38Daniel Veillard } else 53385f4b5999b4eeda2ca68e6d9f54a3c534a8474b38Daniel Veillard ctxt->value->floatval /= val; 53393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 53403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 53413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 53423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathModValues: 53433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 53443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 53453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the mod operation on XPath objects: @arg1 / @arg2 53463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The numeric operators convert their operands to numbers as if 53473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * by calling the number function. 53483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 53493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 53503473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathModValues(xmlXPathParserContextPtr ctxt) { 53513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr arg; 5352fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard double arg1, arg2; 53533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 5354ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard arg = valuePop(ctxt); 5355ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard if (arg == NULL) 5356ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard XP_ERROR(XPATH_INVALID_OPERAND); 53575fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard arg2 = xmlXPathCastToNumber(arg); 53583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(arg); 53593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 5360ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard CAST_TO_NUMBER; 5361ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard CHECK_TYPE(XPATH_NUMBER); 53625fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard arg1 = ctxt->value->floatval; 5363268fd1bc97f79b43290041cfda2287fb0b0ef2d6Daniel Veillard if (arg2 == 0) 5364268fd1bc97f79b43290041cfda2287fb0b0ef2d6Daniel Veillard ctxt->value->floatval = xmlXPathNAN; 53655fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard else { 5366fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard ctxt->value->floatval = fmod(arg1, arg2); 53675fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard } 53683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 53693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 53703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/************************************************************************ 53713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * * 53723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The traversal functions * 53733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * * 53743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ************************************************************************/ 53753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 53763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/* 53773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * A traversal function enumerates nodes along an axis. 53783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Initially it must be called with NULL, and it indicates 53793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * termination on the axis by returning NULL. 53803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 53813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylortypedef xmlNodePtr (*xmlXPathTraversalFunction) 53823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor (xmlXPathParserContextPtr ctxt, xmlNodePtr cur); 53833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 53843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 53853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNextSelf: 53863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 53873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur: the current node in the traversal 53883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 53893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Traversal function for the "self" direction 53903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The self axis contains just the context node itself 53913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 53923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the next element following that axis 53933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 53943473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNodePtr 53953473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNextSelf(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) { 5396a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard if ((ctxt == NULL) || (ctxt->context == NULL)) return(NULL); 53973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == NULL) 53983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ctxt->context->node); 53993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 54003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 54013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 54023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 54033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNextChild: 54043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 54053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur: the current node in the traversal 54063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 54073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Traversal function for the "child" direction 54083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The child axis contains the children of the context node in document order. 54093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 54103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the next element following that axis 54113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 54123473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNodePtr 54133473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNextChild(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) { 5414a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard if ((ctxt == NULL) || (ctxt->context == NULL)) return(NULL); 54153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == NULL) { 54163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->context->node == NULL) return(NULL); 54173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor switch (ctxt->context->node->type) { 54183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ELEMENT_NODE: 54193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_TEXT_NODE: 54203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_CDATA_SECTION_NODE: 54213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ENTITY_REF_NODE: 54223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ENTITY_NODE: 54233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_PI_NODE: 54243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_COMMENT_NODE: 54253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_NOTATION_NODE: 54263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_DTD_NODE: 54273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ctxt->context->node->children); 54283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_DOCUMENT_NODE: 54293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_DOCUMENT_TYPE_NODE: 54303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_DOCUMENT_FRAG_NODE: 54313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_HTML_DOCUMENT_NODE: 5432eae522a0d8aa9f830d2e447f29b504030dbb6bbdDaniel Veillard#ifdef LIBXML_DOCB_ENABLED 5433eae522a0d8aa9f830d2e447f29b504030dbb6bbdDaniel Veillard case XML_DOCB_DOCUMENT_NODE: 54343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 54353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(((xmlDocPtr) ctxt->context->node)->children); 54363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ELEMENT_DECL: 54373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ATTRIBUTE_DECL: 54383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ENTITY_DECL: 54393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ATTRIBUTE_NODE: 54403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_NAMESPACE_DECL: 54413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_XINCLUDE_START: 54423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_XINCLUDE_END: 54433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 54443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 54453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 54463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 54473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((cur->type == XML_DOCUMENT_NODE) || 54483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor (cur->type == XML_HTML_DOCUMENT_NODE)) 54493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 54503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(cur->next); 54513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 54523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 54533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 54543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNextDescendant: 54553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 54563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur: the current node in the traversal 54573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 54583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Traversal function for the "descendant" direction 54593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the descendant axis contains the descendants of the context node in document 54603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * order; a descendant is a child or a child of a child and so on. 54613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 54623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the next element following that axis 54633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 54643473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNodePtr 54653473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNextDescendant(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) { 5466a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard if ((ctxt == NULL) || (ctxt->context == NULL)) return(NULL); 54673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == NULL) { 54683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->context->node == NULL) 54693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 54703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((ctxt->context->node->type == XML_ATTRIBUTE_NODE) || 54713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor (ctxt->context->node->type == XML_NAMESPACE_DECL)) 54723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 54733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 54743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->context->node == (xmlNodePtr) ctxt->context->doc) 54753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ctxt->context->doc->children); 54763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ctxt->context->node->children); 54773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 54783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 5479567e1b48e8664163894742d5674c24baa4282f9eDaniel Veillard if (cur->children != NULL) { 548068e9e74af85ebbc30781787f247c361bc85adfa0Daniel Veillard /* 548168e9e74af85ebbc30781787f247c361bc85adfa0Daniel Veillard * Do not descend on entities declarations 548268e9e74af85ebbc30781787f247c361bc85adfa0Daniel Veillard */ 548368e9e74af85ebbc30781787f247c361bc85adfa0Daniel Veillard if (cur->children->type != XML_ENTITY_DECL) { 548468e9e74af85ebbc30781787f247c361bc85adfa0Daniel Veillard cur = cur->children; 548568e9e74af85ebbc30781787f247c361bc85adfa0Daniel Veillard /* 548668e9e74af85ebbc30781787f247c361bc85adfa0Daniel Veillard * Skip DTDs 548768e9e74af85ebbc30781787f247c361bc85adfa0Daniel Veillard */ 548868e9e74af85ebbc30781787f247c361bc85adfa0Daniel Veillard if (cur->type != XML_DTD_NODE) 548968e9e74af85ebbc30781787f247c361bc85adfa0Daniel Veillard return(cur); 549068e9e74af85ebbc30781787f247c361bc85adfa0Daniel Veillard } 5491567e1b48e8664163894742d5674c24baa4282f9eDaniel Veillard } 5492567e1b48e8664163894742d5674c24baa4282f9eDaniel Veillard 5493567e1b48e8664163894742d5674c24baa4282f9eDaniel Veillard if (cur == ctxt->context->node) return(NULL); 5494567e1b48e8664163894742d5674c24baa4282f9eDaniel Veillard 549568e9e74af85ebbc30781787f247c361bc85adfa0Daniel Veillard while (cur->next != NULL) { 549668e9e74af85ebbc30781787f247c361bc85adfa0Daniel Veillard cur = cur->next; 549768e9e74af85ebbc30781787f247c361bc85adfa0Daniel Veillard if ((cur->type != XML_ENTITY_DECL) && 549868e9e74af85ebbc30781787f247c361bc85adfa0Daniel Veillard (cur->type != XML_DTD_NODE)) 549968e9e74af85ebbc30781787f247c361bc85adfa0Daniel Veillard return(cur); 550068e9e74af85ebbc30781787f247c361bc85adfa0Daniel Veillard } 55013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 55023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor do { 55033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur = cur->parent; 55043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == NULL) return(NULL); 55053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == ctxt->context->node) return(NULL); 55063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur->next != NULL) { 55073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur = cur->next; 55083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(cur); 55093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 55103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } while (cur != NULL); 55113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(cur); 55123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 55133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 55143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 55153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNextDescendantOrSelf: 55163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 55173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur: the current node in the traversal 55183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 55193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Traversal function for the "descendant-or-self" direction 55203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the descendant-or-self axis contains the context node and the descendants 55213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * of the context node in document order; thus the context node is the first 55223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * node on the axis, and the first child of the context node is the second node 55233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * on the axis 55243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 55253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the next element following that axis 55263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 55273473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNodePtr 55283473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNextDescendantOrSelf(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) { 5529a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard if ((ctxt == NULL) || (ctxt->context == NULL)) return(NULL); 55303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == NULL) { 55313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->context->node == NULL) 55323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 55333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((ctxt->context->node->type == XML_ATTRIBUTE_NODE) || 55343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor (ctxt->context->node->type == XML_NAMESPACE_DECL)) 55353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 55363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ctxt->context->node); 55373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 55383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 55393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(xmlXPathNextDescendant(ctxt, cur)); 55403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 55413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 55423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 55433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNextParent: 55443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 55453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur: the current node in the traversal 55463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 55473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Traversal function for the "parent" direction 55483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The parent axis contains the parent of the context node, if there is one. 55493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 55503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the next element following that axis 55513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 55523473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNodePtr 55533473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNextParent(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) { 5554a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard if ((ctxt == NULL) || (ctxt->context == NULL)) return(NULL); 55553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 55563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the parent of an attribute or namespace node is the element 55573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * to which the attribute or namespace node is attached 55583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Namespace handling !!! 55593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 55603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == NULL) { 55613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->context->node == NULL) return(NULL); 55623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor switch (ctxt->context->node->type) { 55633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ELEMENT_NODE: 55643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_TEXT_NODE: 55653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_CDATA_SECTION_NODE: 55663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ENTITY_REF_NODE: 55673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ENTITY_NODE: 55683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_PI_NODE: 55693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_COMMENT_NODE: 55703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_NOTATION_NODE: 55713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_DTD_NODE: 55723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ELEMENT_DECL: 55733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ATTRIBUTE_DECL: 55743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_XINCLUDE_START: 55753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_XINCLUDE_END: 55763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ENTITY_DECL: 55773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->context->node->parent == NULL) 55783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return((xmlNodePtr) ctxt->context->doc); 55798e7e1c00ce5cc3ce959833b888c50ed9fd9d5aaeDaniel Veillard if ((ctxt->context->node->parent->type == XML_ELEMENT_NODE) && 5580652d8a949447833405cc0805f4b7ff1179e59ed2Daniel Veillard ((ctxt->context->node->parent->name[0] == ' ') || 5581652d8a949447833405cc0805f4b7ff1179e59ed2Daniel Veillard (xmlStrEqual(ctxt->context->node->parent->name, 5582652d8a949447833405cc0805f4b7ff1179e59ed2Daniel Veillard BAD_CAST "fake node libxslt")))) 55838e7e1c00ce5cc3ce959833b888c50ed9fd9d5aaeDaniel Veillard return(NULL); 55843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ctxt->context->node->parent); 55853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ATTRIBUTE_NODE: { 55863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlAttrPtr att = (xmlAttrPtr) ctxt->context->node; 55873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 55883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(att->parent); 55893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 55903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_DOCUMENT_NODE: 55913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_DOCUMENT_TYPE_NODE: 55923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_DOCUMENT_FRAG_NODE: 55933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_HTML_DOCUMENT_NODE: 5594eae522a0d8aa9f830d2e447f29b504030dbb6bbdDaniel Veillard#ifdef LIBXML_DOCB_ENABLED 5595eae522a0d8aa9f830d2e447f29b504030dbb6bbdDaniel Veillard case XML_DOCB_DOCUMENT_NODE: 55963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 55973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 5598044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard case XML_NAMESPACE_DECL: { 5599044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlNsPtr ns = (xmlNsPtr) ctxt->context->node; 5600044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard 5601044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if ((ns->next != NULL) && 5602044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard (ns->next->type != XML_NAMESPACE_DECL)) 5603044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard return((xmlNodePtr) ns->next); 56043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 5605044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } 56063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 56073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 56083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 56093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 56103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 56113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 56123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNextAncestor: 56133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 56143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur: the current node in the traversal 56153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 56163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Traversal function for the "ancestor" direction 56173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the ancestor axis contains the ancestors of the context node; the ancestors 56183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * of the context node consist of the parent of context node and the parent's 56193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * parent and so on; the nodes are ordered in reverse document order; thus the 56203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * parent is the first node on the axis, and the parent's parent is the second 56213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * node on the axis 56223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 56233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the next element following that axis 56243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 56253473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNodePtr 56263473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNextAncestor(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) { 5627a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard if ((ctxt == NULL) || (ctxt->context == NULL)) return(NULL); 56283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 56293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the parent of an attribute or namespace node is the element 56303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * to which the attribute or namespace node is attached 56313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * !!!!!!!!!!!!! 56323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 56333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == NULL) { 56343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->context->node == NULL) return(NULL); 56353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor switch (ctxt->context->node->type) { 56363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ELEMENT_NODE: 56373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_TEXT_NODE: 56383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_CDATA_SECTION_NODE: 56393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ENTITY_REF_NODE: 56403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ENTITY_NODE: 56413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_PI_NODE: 56423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_COMMENT_NODE: 56433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_DTD_NODE: 56443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ELEMENT_DECL: 56453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ATTRIBUTE_DECL: 56463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ENTITY_DECL: 56473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_NOTATION_NODE: 56483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_XINCLUDE_START: 56493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_XINCLUDE_END: 56503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->context->node->parent == NULL) 56513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return((xmlNodePtr) ctxt->context->doc); 56528e7e1c00ce5cc3ce959833b888c50ed9fd9d5aaeDaniel Veillard if ((ctxt->context->node->parent->type == XML_ELEMENT_NODE) && 5653652d8a949447833405cc0805f4b7ff1179e59ed2Daniel Veillard ((ctxt->context->node->parent->name[0] == ' ') || 5654652d8a949447833405cc0805f4b7ff1179e59ed2Daniel Veillard (xmlStrEqual(ctxt->context->node->parent->name, 5655652d8a949447833405cc0805f4b7ff1179e59ed2Daniel Veillard BAD_CAST "fake node libxslt")))) 56568e7e1c00ce5cc3ce959833b888c50ed9fd9d5aaeDaniel Veillard return(NULL); 56573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ctxt->context->node->parent); 56583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ATTRIBUTE_NODE: { 565956a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillard xmlAttrPtr tmp = (xmlAttrPtr) ctxt->context->node; 56603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 566156a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillard return(tmp->parent); 56623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 56633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_DOCUMENT_NODE: 56643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_DOCUMENT_TYPE_NODE: 56653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_DOCUMENT_FRAG_NODE: 56663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_HTML_DOCUMENT_NODE: 5667eae522a0d8aa9f830d2e447f29b504030dbb6bbdDaniel Veillard#ifdef LIBXML_DOCB_ENABLED 5668eae522a0d8aa9f830d2e447f29b504030dbb6bbdDaniel Veillard case XML_DOCB_DOCUMENT_NODE: 56693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 56703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 5671044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard case XML_NAMESPACE_DECL: { 5672044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlNsPtr ns = (xmlNsPtr) ctxt->context->node; 5673044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard 5674044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if ((ns->next != NULL) && 5675044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard (ns->next->type != XML_NAMESPACE_DECL)) 5676044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard return((xmlNodePtr) ns->next); 5677081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack /* Bad, how did that namespace end up here ? */ 56783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 5679044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } 56803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 56813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 56823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 56833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == ctxt->context->doc->children) 56843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return((xmlNodePtr) ctxt->context->doc); 56853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == (xmlNodePtr) ctxt->context->doc) 56863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 56873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor switch (cur->type) { 56883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ELEMENT_NODE: 56893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_TEXT_NODE: 56903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_CDATA_SECTION_NODE: 56913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ENTITY_REF_NODE: 56923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ENTITY_NODE: 56933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_PI_NODE: 56943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_COMMENT_NODE: 56953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_NOTATION_NODE: 56963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_DTD_NODE: 56973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ELEMENT_DECL: 56983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ATTRIBUTE_DECL: 56993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ENTITY_DECL: 57003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_XINCLUDE_START: 57013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_XINCLUDE_END: 57028e7e1c00ce5cc3ce959833b888c50ed9fd9d5aaeDaniel Veillard if (cur->parent == NULL) 57038e7e1c00ce5cc3ce959833b888c50ed9fd9d5aaeDaniel Veillard return(NULL); 57048e7e1c00ce5cc3ce959833b888c50ed9fd9d5aaeDaniel Veillard if ((cur->parent->type == XML_ELEMENT_NODE) && 5705652d8a949447833405cc0805f4b7ff1179e59ed2Daniel Veillard ((cur->parent->name[0] == ' ') || 5706652d8a949447833405cc0805f4b7ff1179e59ed2Daniel Veillard (xmlStrEqual(cur->parent->name, 5707652d8a949447833405cc0805f4b7ff1179e59ed2Daniel Veillard BAD_CAST "fake node libxslt")))) 57088e7e1c00ce5cc3ce959833b888c50ed9fd9d5aaeDaniel Veillard return(NULL); 57093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(cur->parent); 57103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ATTRIBUTE_NODE: { 57113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlAttrPtr att = (xmlAttrPtr) ctxt->context->node; 57123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 57133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(att->parent); 57143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 5715dffd5c8dbc7b9052db7ae69dce419a96e22acc68Aleksey Sanin case XML_NAMESPACE_DECL: { 5716dffd5c8dbc7b9052db7ae69dce419a96e22acc68Aleksey Sanin xmlNsPtr ns = (xmlNsPtr) ctxt->context->node; 5717dffd5c8dbc7b9052db7ae69dce419a96e22acc68Aleksey Sanin 5718dffd5c8dbc7b9052db7ae69dce419a96e22acc68Aleksey Sanin if ((ns->next != NULL) && 5719dffd5c8dbc7b9052db7ae69dce419a96e22acc68Aleksey Sanin (ns->next->type != XML_NAMESPACE_DECL)) 5720dffd5c8dbc7b9052db7ae69dce419a96e22acc68Aleksey Sanin return((xmlNodePtr) ns->next); 5721081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack /* Bad, how did that namespace end up here ? */ 5722dffd5c8dbc7b9052db7ae69dce419a96e22acc68Aleksey Sanin return(NULL); 5723dffd5c8dbc7b9052db7ae69dce419a96e22acc68Aleksey Sanin } 57243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_DOCUMENT_NODE: 57253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_DOCUMENT_TYPE_NODE: 57263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_DOCUMENT_FRAG_NODE: 57273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_HTML_DOCUMENT_NODE: 5728eae522a0d8aa9f830d2e447f29b504030dbb6bbdDaniel Veillard#ifdef LIBXML_DOCB_ENABLED 5729eae522a0d8aa9f830d2e447f29b504030dbb6bbdDaniel Veillard case XML_DOCB_DOCUMENT_NODE: 57303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 57313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 57323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 57333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 57343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 57353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 57363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 57373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNextAncestorOrSelf: 57383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 57393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur: the current node in the traversal 57403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 57413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Traversal function for the "ancestor-or-self" direction 57423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * he ancestor-or-self axis contains the context node and ancestors of 57433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the context node in reverse document order; thus the context node is 57443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the first node on the axis, and the context node's parent the second; 57453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * parent here is defined the same as with the parent axis. 57463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 57473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the next element following that axis 57483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 57493473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNodePtr 57503473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNextAncestorOrSelf(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) { 5751a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard if ((ctxt == NULL) || (ctxt->context == NULL)) return(NULL); 57523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == NULL) 57533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ctxt->context->node); 57543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(xmlXPathNextAncestor(ctxt, cur)); 57553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 57563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 57573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 57583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNextFollowingSibling: 57593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 57603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur: the current node in the traversal 57613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 57623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Traversal function for the "following-sibling" direction 57633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The following-sibling axis contains the following siblings of the context 57643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * node in document order. 57653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 57663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the next element following that axis 57673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 57683473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNodePtr 57693473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNextFollowingSibling(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) { 5770a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard if ((ctxt == NULL) || (ctxt->context == NULL)) return(NULL); 57713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((ctxt->context->node->type == XML_ATTRIBUTE_NODE) || 57723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor (ctxt->context->node->type == XML_NAMESPACE_DECL)) 57733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 57743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == (xmlNodePtr) ctxt->context->doc) 57753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 57763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == NULL) 57773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ctxt->context->node->next); 57783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(cur->next); 57793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 57803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 57813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 57823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNextPrecedingSibling: 57833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 57843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur: the current node in the traversal 57853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 57863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Traversal function for the "preceding-sibling" direction 57873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The preceding-sibling axis contains the preceding siblings of the context 57883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * node in reverse document order; the first preceding sibling is first on the 57893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * axis; the sibling preceding that node is the second on the axis and so on. 57903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 57913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the next element following that axis 57923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 57933473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNodePtr 57943473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNextPrecedingSibling(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) { 5795a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard if ((ctxt == NULL) || (ctxt->context == NULL)) return(NULL); 57963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((ctxt->context->node->type == XML_ATTRIBUTE_NODE) || 57973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor (ctxt->context->node->type == XML_NAMESPACE_DECL)) 57983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 57993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == (xmlNodePtr) ctxt->context->doc) 58003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 58013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == NULL) 58023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ctxt->context->node->prev); 5803f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((cur->prev != NULL) && (cur->prev->type == XML_DTD_NODE)) { 5804f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard cur = cur->prev; 5805f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (cur == NULL) 5806f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return(ctxt->context->node->prev); 5807f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 58083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(cur->prev); 58093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 58103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 58113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 58123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNextFollowing: 58133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 58143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur: the current node in the traversal 58153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 58163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Traversal function for the "following" direction 58173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The following axis contains all nodes in the same document as the context 58183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * node that are after the context node in document order, excluding any 58193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * descendants and excluding attribute nodes and namespace nodes; the nodes 58203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * are ordered in document order 58213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 58223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the next element following that axis 58233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 58243473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNodePtr 58253473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNextFollowing(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) { 5826a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard if ((ctxt == NULL) || (ctxt->context == NULL)) return(NULL); 58273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur != NULL && cur->children != NULL) 58283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return cur->children ; 58293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == NULL) cur = ctxt->context->node; 58303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == NULL) return(NULL) ; /* ERROR */ 58313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur->next != NULL) return(cur->next) ; 58323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor do { 58333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur = cur->parent; 58343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == NULL) return(NULL); 58353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == (xmlNodePtr) ctxt->context->doc) return(NULL); 58363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur->next != NULL) return(cur->next); 58373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } while (cur != NULL); 58383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(cur); 58393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 58403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 58413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/* 58423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathIsAncestor: 58433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ancestor: the ancestor node 58443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @node: the current node 58453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 58463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Check that @ancestor is a @node's ancestor 58473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 58483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * returns 1 if @ancestor is a @node's ancestor, 0 otherwise. 58493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 58503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorstatic int 58513473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathIsAncestor(xmlNodePtr ancestor, xmlNodePtr node) { 58523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((ancestor == NULL) || (node == NULL)) return(0); 58533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* nodes need to be in the same document */ 58543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ancestor->doc != node->doc) return(0); 58553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* avoid searching if ancestor or node is the root node */ 58563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ancestor == (xmlNodePtr) node->doc) return(1); 58573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (node == (xmlNodePtr) ancestor->doc) return(0); 58583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while (node->parent != NULL) { 58593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (node->parent == ancestor) 58603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(1); 58613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor node = node->parent; 58623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 58633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(0); 58643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 58653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 58663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 58673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNextPreceding: 58683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 58693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur: the current node in the traversal 58703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 58713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Traversal function for the "preceding" direction 58723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the preceding axis contains all nodes in the same document as the context 58733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * node that are before the context node in document order, excluding any 58743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * ancestors and excluding attribute nodes and namespace nodes; the nodes are 58753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * ordered in reverse document order 58763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 58773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the next element following that axis 58783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 58793473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNodePtr 5880f06307e2c172284bb41376c396f757bdac9bdd19Daniel VeillardxmlXPathNextPreceding(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) 5881f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard{ 5882a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard if ((ctxt == NULL) || (ctxt->context == NULL)) return(NULL); 5883f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (cur == NULL) 5884f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard cur = ctxt->context->node; 58853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == NULL) 5886f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (NULL); 5887f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((cur->prev != NULL) && (cur->prev->type == XML_DTD_NODE)) 5888f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard cur = cur->prev; 58893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor do { 58903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur->prev != NULL) { 5891f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard for (cur = cur->prev; cur->last != NULL; cur = cur->last) ; 5892f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (cur); 58933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 58943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 58953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur = cur->parent; 5896f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (cur == NULL) 5897f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (NULL); 5898f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (cur == ctxt->context->doc->children) 5899f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (NULL); 59003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } while (xmlXPathIsAncestor(cur, ctxt->context->node)); 5901f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (cur); 5902f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard} 5903f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 5904f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard/** 5905f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * xmlXPathNextPrecedingInternal: 5906f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * @ctxt: the XPath Parser context 5907f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * @cur: the current node in the traversal 5908f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * 5909f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Traversal function for the "preceding" direction 5910f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * the preceding axis contains all nodes in the same document as the context 5911f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * node that are before the context node in document order, excluding any 5912f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * ancestors and excluding attribute nodes and namespace nodes; the nodes are 5913f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * ordered in reverse document order 5914f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * This is a faster implementation but internal only since it requires a 5915f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * state kept in the parser context: ctxt->ancestor. 5916f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * 5917f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Returns the next element following that axis 5918f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 5919f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillardstatic xmlNodePtr 5920f06307e2c172284bb41376c396f757bdac9bdd19Daniel VeillardxmlXPathNextPrecedingInternal(xmlXPathParserContextPtr ctxt, 5921f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlNodePtr cur) 5922f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard{ 5923a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard if ((ctxt == NULL) || (ctxt->context == NULL)) return(NULL); 5924f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (cur == NULL) { 5925f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard cur = ctxt->context->node; 5926f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (cur == NULL) 5927f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (NULL); 592840c22b472b3d24ecc2f5b843aa3fffad6ed5cf5eWilliam M. Brack if (cur->type == XML_NAMESPACE_DECL) 592940c22b472b3d24ecc2f5b843aa3fffad6ed5cf5eWilliam M. Brack cur = (xmlNodePtr)((xmlNsPtr)cur)->next; 5930f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->ancestor = cur->parent; 5931f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 5932f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((cur->prev != NULL) && (cur->prev->type == XML_DTD_NODE)) 5933f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard cur = cur->prev; 5934f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard while (cur->prev == NULL) { 5935f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard cur = cur->parent; 5936f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (cur == NULL) 5937f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (NULL); 5938f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (cur == ctxt->context->doc->children) 5939f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (NULL); 5940f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (cur != ctxt->ancestor) 5941f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (cur); 5942f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->ancestor = cur->parent; 5943f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 5944f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard cur = cur->prev; 5945f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard while (cur->last != NULL) 5946f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard cur = cur->last; 5947f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (cur); 59483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 59493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 59503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 59513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNextNamespace: 59523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 59533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur: the current attribute in the traversal 59543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 59553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Traversal function for the "namespace" direction 59563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the namespace axis contains the namespace nodes of the context node; 59573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the order of nodes on this axis is implementation-defined; the axis will 59583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * be empty unless the context node is an element 59593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 596020ee8c03107e5d5724765da513d595fdaf290dceDaniel Veillard * We keep the XML namespace node at the end of the list. 596120ee8c03107e5d5724765da513d595fdaf290dceDaniel Veillard * 59623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the next element following that axis 59633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 59643473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNodePtr 59653473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNextNamespace(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) { 5966a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard if ((ctxt == NULL) || (ctxt->context == NULL)) return(NULL); 59673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->context->node->type != XML_ELEMENT_NODE) return(NULL); 5968fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard if (ctxt->context->tmpNsList == NULL && cur != (xmlNodePtr) xmlXPathXMLNamespace) { 59697d7e37919fc6c7f257769c867122d885d2aae26fDaniel Veillard if (ctxt->context->tmpNsList != NULL) 59707d7e37919fc6c7f257769c867122d885d2aae26fDaniel Veillard xmlFree(ctxt->context->tmpNsList); 59717d7e37919fc6c7f257769c867122d885d2aae26fDaniel Veillard ctxt->context->tmpNsList = 59723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGetNsList(ctxt->context->doc, ctxt->context->node); 59737d7e37919fc6c7f257769c867122d885d2aae26fDaniel Veillard ctxt->context->tmpNsNr = 0; 5974fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard if (ctxt->context->tmpNsList != NULL) { 5975fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard while (ctxt->context->tmpNsList[ctxt->context->tmpNsNr] != NULL) { 5976fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard ctxt->context->tmpNsNr++; 5977fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard } 5978fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard } 5979fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard return((xmlNodePtr) xmlXPathXMLNamespace); 59807d7e37919fc6c7f257769c867122d885d2aae26fDaniel Veillard } 5981fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard if (ctxt->context->tmpNsNr > 0) { 5982fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard return (xmlNodePtr)ctxt->context->tmpNsList[--ctxt->context->tmpNsNr]; 5983fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard } else { 5984fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard if (ctxt->context->tmpNsList != NULL) 5985fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard xmlFree(ctxt->context->tmpNsList); 59867d7e37919fc6c7f257769c867122d885d2aae26fDaniel Veillard ctxt->context->tmpNsList = NULL; 5987fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard return(NULL); 59883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 59893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 59903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 59913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 59923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNextAttribute: 59933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 59943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur: the current attribute in the traversal 59953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 59963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Traversal function for the "attribute" direction 59973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * TODO: support DTD inherited default attributes 59983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 59993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the next element following that axis 60003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 60013473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNodePtr 60023473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNextAttribute(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) { 6003a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard if ((ctxt == NULL) || (ctxt->context == NULL)) return(NULL); 6004e470df7fdd3505c6232d6498f3b8834ebfce522dDaniel Veillard if (ctxt->context->node == NULL) 6005e470df7fdd3505c6232d6498f3b8834ebfce522dDaniel Veillard return(NULL); 6006e470df7fdd3505c6232d6498f3b8834ebfce522dDaniel Veillard if (ctxt->context->node->type != XML_ELEMENT_NODE) 6007e470df7fdd3505c6232d6498f3b8834ebfce522dDaniel Veillard return(NULL); 60083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == NULL) { 60093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->context->node == (xmlNodePtr) ctxt->context->doc) 60103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 60113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return((xmlNodePtr)ctxt->context->node->properties); 60123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 60133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return((xmlNodePtr)cur->next); 60143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 60153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 60163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/************************************************************************ 60173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * * 60183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * NodeTest Functions * 60193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * * 60203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ************************************************************************/ 60213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 60223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define IS_FUNCTION 200 60233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 6024d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard 6025d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard/************************************************************************ 6026d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * * 6027d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * Implicit tree core function library * 6028d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * * 6029d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard ************************************************************************/ 6030d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard 60313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 6032d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * xmlXPathRoot: 60333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 60343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 6035d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * Initialize the context to the root of the document 60363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 6037d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillardvoid 6038d8df6c0e8c883e1d618388d266015dda36731440Daniel VeillardxmlXPathRoot(xmlXPathParserContextPtr ctxt) { 6039a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard if ((ctxt == NULL) || (ctxt->context == NULL)) return; 6040d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard ctxt->context->node = (xmlNodePtr) ctxt->context->doc; 6041d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard valuePush(ctxt, xmlXPathNewNodeSet(ctxt->context->node)); 6042d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard} 60433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 6044d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard/************************************************************************ 6045d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * * 6046d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * The explicit core function library * 6047d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard *http://www.w3.org/Style/XSL/Group/1999/07/xpath-19990705.html#corelib * 6048d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * * 6049d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard ************************************************************************/ 60503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 6051d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard 6052d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard/** 6053d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * xmlXPathLastFunction: 6054d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * @ctxt: the XPath Parser context 6055d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * @nargs: the number of arguments 6056d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * 6057d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * Implement the last() XPath function 6058d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * number last() 6059d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * The last function returns the number of nodes in the context node list. 6060d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard */ 6061d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillardvoid 6062d8df6c0e8c883e1d618388d266015dda36731440Daniel VeillardxmlXPathLastFunction(xmlXPathParserContextPtr ctxt, int nargs) { 6063d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard CHECK_ARITY(0); 6064d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard if (ctxt->context->contextSize >= 0) { 6065d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard valuePush(ctxt, xmlXPathNewFloat((double) ctxt->context->contextSize)); 6066d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_EXPR 6067d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard xmlGenericError(xmlGenericErrorContext, 6068d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard "last() : %d\n", ctxt->context->contextSize); 60693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 6070d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard } else { 6071d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard XP_ERROR(XPATH_INVALID_CTXT_SIZE); 60723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 6073d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard} 60743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 6075d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard/** 6076d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * xmlXPathPositionFunction: 6077d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * @ctxt: the XPath Parser context 6078d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * @nargs: the number of arguments 6079d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * 6080d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * Implement the position() XPath function 6081d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * number position() 6082d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * The position function returns the position of the context node in the 6083cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * context node list. The first position is 1, and so the last position 6084d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * will be equal to last(). 6085d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard */ 6086d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillardvoid 6087d8df6c0e8c883e1d618388d266015dda36731440Daniel VeillardxmlXPathPositionFunction(xmlXPathParserContextPtr ctxt, int nargs) { 6088d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard CHECK_ARITY(0); 6089d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard if (ctxt->context->proximityPosition >= 0) { 6090d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard valuePush(ctxt, 6091d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard xmlXPathNewFloat((double) ctxt->context->proximityPosition)); 6092d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_EXPR 6093d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard xmlGenericError(xmlGenericErrorContext, "position() : %d\n", 6094d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard ctxt->context->proximityPosition); 60953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 6096d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard } else { 6097d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard XP_ERROR(XPATH_INVALID_CTXT_POSITION); 6098d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard } 6099d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard} 61003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 61013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 61023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathCountFunction: 61033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 61043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs: the number of arguments 61053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 61063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the count() XPath function 61073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * number count(node-set) 61083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 61093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 61103473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathCountFunction(xmlXPathParserContextPtr ctxt, int nargs) { 61113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr cur; 61123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 61133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ARITY(1); 61143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((ctxt->value == NULL) || 61153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ((ctxt->value->type != XPATH_NODESET) && 61163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor (ctxt->value->type != XPATH_XSLT_TREE))) 61173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XP_ERROR(XPATH_INVALID_TYPE); 61183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur = valuePop(ctxt); 61193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 6120911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard if ((cur == NULL) || (cur->nodesetval == NULL)) 6121911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard valuePush(ctxt, xmlXPathNewFloat((double) 0)); 61220c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack else if ((cur->type == XPATH_NODESET) || (cur->type == XPATH_XSLT_TREE)) { 6123911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard valuePush(ctxt, xmlXPathNewFloat((double) cur->nodesetval->nodeNr)); 6124fe70332f7f29f146a364c73450729a8b3274daeeDaniel Veillard } else { 6125fe70332f7f29f146a364c73450729a8b3274daeeDaniel Veillard if ((cur->nodesetval->nodeNr != 1) || 6126fe70332f7f29f146a364c73450729a8b3274daeeDaniel Veillard (cur->nodesetval->nodeTab == NULL)) { 6127fe70332f7f29f146a364c73450729a8b3274daeeDaniel Veillard valuePush(ctxt, xmlXPathNewFloat((double) 0)); 6128fe70332f7f29f146a364c73450729a8b3274daeeDaniel Veillard } else { 6129fe70332f7f29f146a364c73450729a8b3274daeeDaniel Veillard xmlNodePtr tmp; 6130fe70332f7f29f146a364c73450729a8b3274daeeDaniel Veillard int i = 0; 6131fe70332f7f29f146a364c73450729a8b3274daeeDaniel Veillard 6132fe70332f7f29f146a364c73450729a8b3274daeeDaniel Veillard tmp = cur->nodesetval->nodeTab[0]; 6133fe70332f7f29f146a364c73450729a8b3274daeeDaniel Veillard if (tmp != NULL) { 6134fe70332f7f29f146a364c73450729a8b3274daeeDaniel Veillard tmp = tmp->children; 6135fe70332f7f29f146a364c73450729a8b3274daeeDaniel Veillard while (tmp != NULL) { 6136fe70332f7f29f146a364c73450729a8b3274daeeDaniel Veillard tmp = tmp->next; 6137fe70332f7f29f146a364c73450729a8b3274daeeDaniel Veillard i++; 6138fe70332f7f29f146a364c73450729a8b3274daeeDaniel Veillard } 6139fe70332f7f29f146a364c73450729a8b3274daeeDaniel Veillard } 6140fe70332f7f29f146a364c73450729a8b3274daeeDaniel Veillard valuePush(ctxt, xmlXPathNewFloat((double) i)); 6141fe70332f7f29f146a364c73450729a8b3274daeeDaniel Veillard } 6142fe70332f7f29f146a364c73450729a8b3274daeeDaniel Veillard } 61433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(cur); 61443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 61453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 61463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 6147ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathGetElementsByIds: 6148ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @doc: the document 6149ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @ids: a whitespace separated list of IDs 6150ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 6151ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Selects elements by their unique ID. 6152ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 6153ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns a node-set of selected elements. 6154ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */ 6155ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillardstatic xmlNodeSetPtr 6156ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathGetElementsByIds (xmlDocPtr doc, const xmlChar *ids) { 6157ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlNodeSetPtr ret; 6158ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard const xmlChar *cur = ids; 6159ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlChar *ID; 6160ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlAttrPtr attr; 6161ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlNodePtr elem = NULL; 6162ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 61637a985a18c2fee0aa9b490792dd990b75506e3740Daniel Veillard if (ids == NULL) return(NULL); 61647a985a18c2fee0aa9b490792dd990b75506e3740Daniel Veillard 6165ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = xmlXPathNodeSetCreate(NULL); 6166ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 616776e95df05556c9610b564b14cf578c8f9e34c9c1William M. Brack while (IS_BLANK_CH(*cur)) cur++; 6168ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard while (*cur != 0) { 616976e95df05556c9610b564b14cf578c8f9e34c9c1William M. Brack while ((!IS_BLANK_CH(*cur)) && (*cur != 0)) 6170e209b330558d170da195acb3a7618b0048d22c9eDaniel Veillard cur++; 6171ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 6172ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ID = xmlStrndup(ids, cur - ids); 6173e209b330558d170da195acb3a7618b0048d22c9eDaniel Veillard if (ID != NULL) { 617468cb4b2498088cf920ed6c9490b134ce7f38909fDaniel Veillard /* 617568cb4b2498088cf920ed6c9490b134ce7f38909fDaniel Veillard * We used to check the fact that the value passed 617668cb4b2498088cf920ed6c9490b134ce7f38909fDaniel Veillard * was an NCName, but this generated much troubles for 617768cb4b2498088cf920ed6c9490b134ce7f38909fDaniel Veillard * me and Aleksey Sanin, people blatantly violated that 617868cb4b2498088cf920ed6c9490b134ce7f38909fDaniel Veillard * constaint, like Visa3D spec. 617968cb4b2498088cf920ed6c9490b134ce7f38909fDaniel Veillard * if (xmlValidateNCName(ID, 1) == 0) 618068cb4b2498088cf920ed6c9490b134ce7f38909fDaniel Veillard */ 618168cb4b2498088cf920ed6c9490b134ce7f38909fDaniel Veillard attr = xmlGetID(doc, ID); 618268cb4b2498088cf920ed6c9490b134ce7f38909fDaniel Veillard if (attr != NULL) { 618368cb4b2498088cf920ed6c9490b134ce7f38909fDaniel Veillard if (attr->type == XML_ATTRIBUTE_NODE) 618468cb4b2498088cf920ed6c9490b134ce7f38909fDaniel Veillard elem = attr->parent; 618568cb4b2498088cf920ed6c9490b134ce7f38909fDaniel Veillard else if (attr->type == XML_ELEMENT_NODE) 618668cb4b2498088cf920ed6c9490b134ce7f38909fDaniel Veillard elem = (xmlNodePtr) attr; 618768cb4b2498088cf920ed6c9490b134ce7f38909fDaniel Veillard else 618868cb4b2498088cf920ed6c9490b134ce7f38909fDaniel Veillard elem = NULL; 618968cb4b2498088cf920ed6c9490b134ce7f38909fDaniel Veillard if (elem != NULL) 619068cb4b2498088cf920ed6c9490b134ce7f38909fDaniel Veillard xmlXPathNodeSetAdd(ret, elem); 6191e209b330558d170da195acb3a7618b0048d22c9eDaniel Veillard } 6192ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlFree(ID); 6193e209b330558d170da195acb3a7618b0048d22c9eDaniel Veillard } 6194ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 619576e95df05556c9610b564b14cf578c8f9e34c9c1William M. Brack while (IS_BLANK_CH(*cur)) cur++; 6196ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ids = cur; 6197ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard } 6198ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(ret); 6199ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard} 6200ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 6201ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/** 62023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathIdFunction: 62033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 62043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs: the number of arguments 62053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 62063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the id() XPath function 62073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * node-set id(object) 62083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The id function selects elements by their unique ID 62093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * (see [5.2.1 Unique IDs]). When the argument to id is of type node-set, 62103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * then the result is the union of the result of applying id to the 62113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * string value of each of the nodes in the argument node-set. When the 62123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * argument to id is of any other type, the argument is converted to a 62133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * string as if by a call to the string function; the string is split 62143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * into a whitespace-separated list of tokens (whitespace is any sequence 62153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * of characters matching the production S); the result is a node-set 62163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * containing the elements in the same document as the context node that 62173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * have a unique ID equal to any of the tokens in the list. 62183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 62193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 62203473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathIdFunction(xmlXPathParserContextPtr ctxt, int nargs) { 6221ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlChar *tokens; 6222ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlNodeSetPtr ret; 6223ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlXPathObjectPtr obj; 62243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 62253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ARITY(1); 62263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor obj = valuePop(ctxt); 62273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (obj == NULL) XP_ERROR(XPATH_INVALID_OPERAND); 62280c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack if ((obj->type == XPATH_NODESET) || (obj->type == XPATH_XSLT_TREE)) { 6229ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlNodeSetPtr ns; 62303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int i; 62313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 6232ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = xmlXPathNodeSetCreate(NULL); 62333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 6234911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard if (obj->nodesetval != NULL) { 6235911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard for (i = 0; i < obj->nodesetval->nodeNr; i++) { 6236ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard tokens = 6237ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlXPathCastNodeToString(obj->nodesetval->nodeTab[i]); 6238ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ns = xmlXPathGetElementsByIds(ctxt->context->doc, tokens); 6239ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = xmlXPathNodeSetMerge(ret, ns); 6240ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlXPathFreeNodeSet(ns); 6241ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard if (tokens != NULL) 6242ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlFree(tokens); 6243911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard } 62443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 62453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 62463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(obj); 6247ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard valuePush(ctxt, xmlXPathWrapNodeSet(ret)); 62483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return; 62493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 6250ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard obj = xmlXPathConvertString(obj); 62513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 6252ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = xmlXPathGetElementsByIds(ctxt->context->doc, obj->stringval); 6253ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard valuePush(ctxt, xmlXPathWrapNodeSet(ret)); 62543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 62553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(obj); 62563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return; 62573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 62583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 62593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 62603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathLocalNameFunction: 62613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 62623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs: the number of arguments 62633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 62643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the local-name() XPath function 62653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * string local-name(node-set?) 62663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The local-name function returns a string containing the local part 62673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * of the name of the node in the argument node-set that is first in 62683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * document order. If the node-set is empty or the first node has no 62693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * name, an empty string is returned. If the argument is omitted it 62703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * defaults to the context node. 62713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 62723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 62733473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathLocalNameFunction(xmlXPathParserContextPtr ctxt, int nargs) { 62743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr cur; 62753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 6276a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard if (ctxt == NULL) return; 6277a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard 62783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (nargs == 0) { 62793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, xmlXPathNewNodeSet(ctxt->context->node)); 62803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor nargs = 1; 62813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 62823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 62833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ARITY(1); 62843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((ctxt->value == NULL) || 62853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ((ctxt->value->type != XPATH_NODESET) && 62863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor (ctxt->value->type != XPATH_XSLT_TREE))) 62873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XP_ERROR(XPATH_INVALID_TYPE); 62883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur = valuePop(ctxt); 62893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 6290911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard if ((cur->nodesetval == NULL) || (cur->nodesetval->nodeNr == 0)) { 62913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, xmlXPathNewCString("")); 62923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else { 62933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int i = 0; /* Should be first in document order !!!!! */ 62943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor switch (cur->nodesetval->nodeTab[i]->type) { 62953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ELEMENT_NODE: 62963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ATTRIBUTE_NODE: 62973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_PI_NODE: 6298652d8a949447833405cc0805f4b7ff1179e59ed2Daniel Veillard if (cur->nodesetval->nodeTab[i]->name[0] == ' ') 6299652d8a949447833405cc0805f4b7ff1179e59ed2Daniel Veillard valuePush(ctxt, xmlXPathNewCString("")); 6300652d8a949447833405cc0805f4b7ff1179e59ed2Daniel Veillard else 6301652d8a949447833405cc0805f4b7ff1179e59ed2Daniel Veillard valuePush(ctxt, 63023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathNewString(cur->nodesetval->nodeTab[i]->name)); 63033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 63043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_NAMESPACE_DECL: 63053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, xmlXPathNewString( 63063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ((xmlNsPtr)cur->nodesetval->nodeTab[i])->prefix)); 63073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 63083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor default: 63093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, xmlXPathNewCString("")); 63103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 63113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 63123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(cur); 63133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 63143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 63153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 63163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNamespaceURIFunction: 63173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 63183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs: the number of arguments 63193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 63203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the namespace-uri() XPath function 63213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * string namespace-uri(node-set?) 63223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The namespace-uri function returns a string containing the 63233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * namespace URI of the expanded name of the node in the argument 63243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * node-set that is first in document order. If the node-set is empty, 63253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the first node has no name, or the expanded name has no namespace 63263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * URI, an empty string is returned. If the argument is omitted it 63273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * defaults to the context node. 63283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 63293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 63303473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNamespaceURIFunction(xmlXPathParserContextPtr ctxt, int nargs) { 63313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr cur; 63323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 6333a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard if (ctxt == NULL) return; 6334a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard 63353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (nargs == 0) { 63363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, xmlXPathNewNodeSet(ctxt->context->node)); 63373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor nargs = 1; 63383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 63393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ARITY(1); 63403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((ctxt->value == NULL) || 63413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ((ctxt->value->type != XPATH_NODESET) && 63423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor (ctxt->value->type != XPATH_XSLT_TREE))) 63433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XP_ERROR(XPATH_INVALID_TYPE); 63443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur = valuePop(ctxt); 63453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 6346911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard if ((cur->nodesetval == NULL) || (cur->nodesetval->nodeNr == 0)) { 63473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, xmlXPathNewCString("")); 63483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else { 63493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int i = 0; /* Should be first in document order !!!!! */ 63503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor switch (cur->nodesetval->nodeTab[i]->type) { 63513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ELEMENT_NODE: 63523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ATTRIBUTE_NODE: 63533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur->nodesetval->nodeTab[i]->ns == NULL) 63543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, xmlXPathNewCString("")); 63553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else 63563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, xmlXPathNewString( 63573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur->nodesetval->nodeTab[i]->ns->href)); 63583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 63593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor default: 63603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, xmlXPathNewCString("")); 63613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 63623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 63633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(cur); 63643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 63653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 63663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 63673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNameFunction: 63683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 63693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs: the number of arguments 63703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 63713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the name() XPath function 63723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * string name(node-set?) 63733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The name function returns a string containing a QName representing 6374cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * the name of the node in the argument node-set that is first in document 63753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * order. The QName must represent the name with respect to the namespace 63763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * declarations in effect on the node whose name is being represented. 63773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Typically, this will be the form in which the name occurred in the XML 63783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * source. This need not be the case if there are namespace declarations 63793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * in effect on the node that associate multiple prefixes with the same 63803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * namespace. However, an implementation may include information about 63813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the original prefix in its representation of nodes; in this case, an 63823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * implementation can ensure that the returned string is always the same 63833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * as the QName used in the XML source. If the argument it omitted it 63843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * defaults to the context node. 63853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Libxml keep the original prefix so the "real qualified name" used is 63863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * returned. 63873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 638856a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic void 63890438375d2e6be47d0179826271081ae64df94f8bDaniel VeillardxmlXPathNameFunction(xmlXPathParserContextPtr ctxt, int nargs) 63900438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard{ 63913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr cur; 63923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 63933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (nargs == 0) { 63940438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard valuePush(ctxt, xmlXPathNewNodeSet(ctxt->context->node)); 63950438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard nargs = 1; 63963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 63973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 63983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ARITY(1); 63990438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard if ((ctxt->value == NULL) || 64000438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard ((ctxt->value->type != XPATH_NODESET) && 64010438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard (ctxt->value->type != XPATH_XSLT_TREE))) 64020438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard XP_ERROR(XPATH_INVALID_TYPE); 64033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur = valuePop(ctxt); 64043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 6405911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard if ((cur->nodesetval == NULL) || (cur->nodesetval->nodeNr == 0)) { 64060438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard valuePush(ctxt, xmlXPathNewCString("")); 64073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else { 64080438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard int i = 0; /* Should be first in document order !!!!! */ 64093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 64100438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard switch (cur->nodesetval->nodeTab[i]->type) { 64110438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard case XML_ELEMENT_NODE: 64120438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard case XML_ATTRIBUTE_NODE: 6413652d8a949447833405cc0805f4b7ff1179e59ed2Daniel Veillard if (cur->nodesetval->nodeTab[i]->name[0] == ' ') 6414652d8a949447833405cc0805f4b7ff1179e59ed2Daniel Veillard valuePush(ctxt, xmlXPathNewCString("")); 6415652d8a949447833405cc0805f4b7ff1179e59ed2Daniel Veillard else if ((cur->nodesetval->nodeTab[i]->ns == NULL) || 6416652d8a949447833405cc0805f4b7ff1179e59ed2Daniel Veillard (cur->nodesetval->nodeTab[i]->ns->prefix == NULL)) { 64170438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard valuePush(ctxt, 6418c00cda8c065beba24706c9e8719f08e9de420274Daniel Veillard xmlXPathNewString(cur->nodesetval->nodeTab[i]->name)); 64190438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard 6420652d8a949447833405cc0805f4b7ff1179e59ed2Daniel Veillard } else { 6421c00cda8c065beba24706c9e8719f08e9de420274Daniel Veillard xmlChar *fullname; 6422c00cda8c065beba24706c9e8719f08e9de420274Daniel Veillard 6423c00cda8c065beba24706c9e8719f08e9de420274Daniel Veillard fullname = xmlBuildQName(cur->nodesetval->nodeTab[i]->name, 6424c00cda8c065beba24706c9e8719f08e9de420274Daniel Veillard cur->nodesetval->nodeTab[i]->ns->prefix, 6425c00cda8c065beba24706c9e8719f08e9de420274Daniel Veillard NULL, 0); 6426c00cda8c065beba24706c9e8719f08e9de420274Daniel Veillard if (fullname == cur->nodesetval->nodeTab[i]->name) 6427c00cda8c065beba24706c9e8719f08e9de420274Daniel Veillard fullname = xmlStrdup(cur->nodesetval->nodeTab[i]->name); 6428c00cda8c065beba24706c9e8719f08e9de420274Daniel Veillard if (fullname == NULL) { 6429c00cda8c065beba24706c9e8719f08e9de420274Daniel Veillard XP_ERROR(XPATH_MEMORY_ERROR); 6430c00cda8c065beba24706c9e8719f08e9de420274Daniel Veillard } 6431c00cda8c065beba24706c9e8719f08e9de420274Daniel Veillard valuePush(ctxt, xmlXPathWrapString(fullname)); 64320438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard } 64330438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard break; 64340438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard default: 64350438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard valuePush(ctxt, 64360438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard xmlXPathNewNodeSet(cur->nodesetval->nodeTab[i])); 64370438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard xmlXPathLocalNameFunction(ctxt, 1); 64380438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard } 64393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 64403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(cur); 64413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 64423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 6443fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard 6444fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard/** 64453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathStringFunction: 64463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 64473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs: the number of arguments 64483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 64493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the string() XPath function 64503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * string string(object?) 6451081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack * The string function converts an object to a string as follows: 64523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * - A node-set is converted to a string by returning the value of 64533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the node in the node-set that is first in document order. 64543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * If the node-set is empty, an empty string is returned. 64553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * - A number is converted to a string as follows 64563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * + NaN is converted to the string NaN 64573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * + positive zero is converted to the string 0 64583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * + negative zero is converted to the string 0 64593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * + positive infinity is converted to the string Infinity 64603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * + negative infinity is converted to the string -Infinity 64613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * + if the number is an integer, the number is represented in 64623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * decimal form as a Number with no decimal point and no leading 64633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * zeros, preceded by a minus sign (-) if the number is negative 64643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * + otherwise, the number is represented in decimal form as a 64653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Number including a decimal point with at least one digit 64663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * before the decimal point and at least one digit after the 64673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * decimal point, preceded by a minus sign (-) if the number 64683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * is negative; there must be no leading zeros before the decimal 6469cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * point apart possibly from the one required digit immediately 64703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * before the decimal point; beyond the one required digit 64713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * after the decimal point there must be as many, but only as 64723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * many, more digits as are needed to uniquely distinguish the 64733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * number from all other IEEE 754 numeric values. 64743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * - The boolean false value is converted to the string false. 64753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The boolean true value is converted to the string true. 64763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 64773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * If the argument is omitted, it defaults to a node-set with the 64783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * context node as its only member. 64793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 64803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 64813473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathStringFunction(xmlXPathParserContextPtr ctxt, int nargs) { 64823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr cur; 64833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 6484a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard if (ctxt == NULL) return; 64853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (nargs == 0) { 6486ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard valuePush(ctxt, 6487ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlXPathWrapString( 6488ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlXPathCastNodeToString(ctxt->context->node))); 6489ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return; 64903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 64913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 64923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ARITY(1); 64933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur = valuePop(ctxt); 64943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == NULL) XP_ERROR(XPATH_INVALID_OPERAND); 6495fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard cur = xmlXPathConvertString(cur); 6496fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard valuePush(ctxt, cur); 64973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 64983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 64993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 65003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathStringLengthFunction: 65013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 65023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs: the number of arguments 65033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 65043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the string-length() XPath function 65053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * number string-length(string?) 65063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The string-length returns the number of characters in the string 65073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * (see [3.6 Strings]). If the argument is omitted, it defaults to 65083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the context node converted to a string, in other words the value 65093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * of the context node. 65103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 65113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 65123473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathStringLengthFunction(xmlXPathParserContextPtr ctxt, int nargs) { 65133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr cur; 65143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 65153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (nargs == 0) { 6516a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard if ((ctxt == NULL) || (ctxt->context == NULL)) 6517a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard return; 65183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->context->node == NULL) { 65193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, xmlXPathNewFloat(0)); 65203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else { 65213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlChar *content; 65223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 6523ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard content = xmlXPathCastNodeToString(ctxt->context->node); 6524e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard valuePush(ctxt, xmlXPathNewFloat(xmlUTF8Strlen(content))); 65253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(content); 65263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 65273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return; 65283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 65293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ARITY(1); 65303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CAST_TO_STRING; 65313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_TYPE(XPATH_STRING); 65323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur = valuePop(ctxt); 6533e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard valuePush(ctxt, xmlXPathNewFloat(xmlUTF8Strlen(cur->stringval))); 65343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(cur); 65353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 65363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 65373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 65383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathConcatFunction: 65393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 65403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs: the number of arguments 65413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 65423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the concat() XPath function 65433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * string concat(string, string, string*) 65443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The concat function returns the concatenation of its arguments. 65453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 65463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 65473473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathConcatFunction(xmlXPathParserContextPtr ctxt, int nargs) { 65483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr cur, newobj; 65493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlChar *tmp; 65503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 6551a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard if (ctxt == NULL) return; 65523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (nargs < 2) { 65533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ARITY(2); 65543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 65553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 65563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CAST_TO_STRING; 65573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur = valuePop(ctxt); 65583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((cur == NULL) || (cur->type != XPATH_STRING)) { 65593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(cur); 65603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return; 65613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 65623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor nargs--; 65633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 65643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while (nargs > 0) { 65653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CAST_TO_STRING; 65663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor newobj = valuePop(ctxt); 65673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((newobj == NULL) || (newobj->type != XPATH_STRING)) { 65683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(newobj); 65693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(cur); 65703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XP_ERROR(XPATH_INVALID_TYPE); 65713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 65723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor tmp = xmlStrcat(newobj->stringval, cur->stringval); 65733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor newobj->stringval = cur->stringval; 65743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur->stringval = tmp; 65753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 65763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(newobj); 65773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor nargs--; 65783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 65793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, cur); 65803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 65813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 65823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 65833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathContainsFunction: 65843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 65853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs: the number of arguments 65863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 65873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the contains() XPath function 65883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * boolean contains(string, string) 65893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The contains function returns true if the first argument string 65903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * contains the second argument string, and otherwise returns false. 65913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 65923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 65933473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathContainsFunction(xmlXPathParserContextPtr ctxt, int nargs) { 65943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr hay, needle; 65953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 65963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ARITY(2); 65973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CAST_TO_STRING; 65983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_TYPE(XPATH_STRING); 65993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor needle = valuePop(ctxt); 66003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CAST_TO_STRING; 66013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor hay = valuePop(ctxt); 66023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((hay == NULL) || (hay->type != XPATH_STRING)) { 66033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(hay); 66043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(needle); 66053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XP_ERROR(XPATH_INVALID_TYPE); 66063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 66073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (xmlStrstr(hay->stringval, needle->stringval)) 66083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, xmlXPathNewBoolean(1)); 66093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else 66103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, xmlXPathNewBoolean(0)); 66113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(hay); 66123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(needle); 66133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 66143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 66153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 66163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathStartsWithFunction: 66173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 66183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs: the number of arguments 66193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 66203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the starts-with() XPath function 66213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * boolean starts-with(string, string) 66223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The starts-with function returns true if the first argument string 66233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * starts with the second argument string, and otherwise returns false. 66243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 66253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 66263473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathStartsWithFunction(xmlXPathParserContextPtr ctxt, int nargs) { 66273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr hay, needle; 66283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int n; 66293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 66303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ARITY(2); 66313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CAST_TO_STRING; 66323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_TYPE(XPATH_STRING); 66333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor needle = valuePop(ctxt); 66343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CAST_TO_STRING; 66353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor hay = valuePop(ctxt); 66363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((hay == NULL) || (hay->type != XPATH_STRING)) { 66373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(hay); 66383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(needle); 66393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XP_ERROR(XPATH_INVALID_TYPE); 66403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 66413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor n = xmlStrlen(needle->stringval); 66423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (xmlStrncmp(hay->stringval, needle->stringval, n)) 66433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, xmlXPathNewBoolean(0)); 66443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else 66453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, xmlXPathNewBoolean(1)); 66463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(hay); 66473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(needle); 66483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 66493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 66503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 66513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathSubstringFunction: 66523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 66533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs: the number of arguments 66543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 66553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the substring() XPath function 66563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * string substring(string, number, number?) 66573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The substring function returns the substring of the first argument 66583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * starting at the position specified in the second argument with 66593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * length specified in the third argument. For example, 66603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * substring("12345",2,3) returns "234". If the third argument is not 66613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * specified, it returns the substring starting at the position specified 66623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * in the second argument and continuing to the end of the string. For 66633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * example, substring("12345",2) returns "2345". More precisely, each 66643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * character in the string (see [3.6 Strings]) is considered to have a 66653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * numeric position: the position of the first character is 1, the position 66663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * of the second character is 2 and so on. The returned substring contains 66673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * those characters for which the position of the character is greater than 66683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * or equal to the second argument and, if the third argument is specified, 66693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * less than the sum of the second and third arguments; the comparisons 66703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * and addition used for the above follow the standard IEEE 754 rules. Thus: 66713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * - substring("12345", 1.5, 2.6) returns "234" 66723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * - substring("12345", 0, 3) returns "12" 66733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * - substring("12345", 0 div 0, 3) returns "" 66743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * - substring("12345", 1, 0 div 0) returns "" 66753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * - substring("12345", -42, 1 div 0) returns "12345" 66763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * - substring("12345", -1 div 0, 1 div 0) returns "" 66773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 66783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 66793473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathSubstringFunction(xmlXPathParserContextPtr ctxt, int nargs) { 66803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr str, start, len; 668197ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard double le=0, in; 668297ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard int i, l, m; 66833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlChar *ret; 66843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 66853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (nargs < 2) { 66863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ARITY(2); 66873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 66883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (nargs > 3) { 66893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ARITY(3); 66903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 669197ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard /* 669297ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard * take care of possible last (position) argument 669397ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard */ 66943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (nargs == 3) { 66953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CAST_TO_NUMBER; 66963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_TYPE(XPATH_NUMBER); 66973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor len = valuePop(ctxt); 66983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor le = len->floatval; 66993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(len); 67003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 670197ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard 67023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CAST_TO_NUMBER; 67033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_TYPE(XPATH_NUMBER); 67043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor start = valuePop(ctxt); 67053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor in = start->floatval; 67063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(start); 67073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CAST_TO_STRING; 67083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_TYPE(XPATH_STRING); 67093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor str = valuePop(ctxt); 671097ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard m = xmlUTF8Strlen((const unsigned char *)str->stringval); 671197ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard 671297ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard /* 671397ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard * If last pos not present, calculate last position 671497ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard */ 67159e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard if (nargs != 3) { 67169e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard le = (double)m; 67179e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard if (in < 1.0) 67189e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard in = 1.0; 67199e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard } 672097ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard 67210eafdef9881c396ce4c014359d8f497cc088cfabDaniel Veillard /* Need to check for the special cases where either 67220eafdef9881c396ce4c014359d8f497cc088cfabDaniel Veillard * the index is NaN, the length is NaN, or both 67230eafdef9881c396ce4c014359d8f497cc088cfabDaniel Veillard * arguments are infinity (relying on Inf + -Inf = NaN) 672497ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard */ 67259e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard if (!xmlXPathIsNaN(in + le) && !xmlXPathIsInf(in)) { 67260eafdef9881c396ce4c014359d8f497cc088cfabDaniel Veillard /* 67279e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard * To meet the requirements of the spec, the arguments 67289e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard * must be converted to integer format before 67299e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard * initial index calculations are done 67300eafdef9881c396ce4c014359d8f497cc088cfabDaniel Veillard * 67319e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard * First we go to integer form, rounding up 67329e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard * and checking for special cases 67330eafdef9881c396ce4c014359d8f497cc088cfabDaniel Veillard */ 67340eafdef9881c396ce4c014359d8f497cc088cfabDaniel Veillard i = (int) in; 67359e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard if (((double)i)+0.5 <= in) i++; 67369e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard 67379e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard if (xmlXPathIsInf(le) == 1) { 67389e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard l = m; 67399e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard if (i < 1) 67409e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard i = 1; 67419e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard } 67429e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard else if (xmlXPathIsInf(le) == -1 || le < 0.0) 67439e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard l = 0; 67449e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard else { 67459e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard l = (int) le; 67469e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard if (((double)l)+0.5 <= le) l++; 67479e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard } 67480eafdef9881c396ce4c014359d8f497cc088cfabDaniel Veillard 67499e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard /* Now we normalize inidices */ 67509e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard i -= 1; 67519e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard l += i; 67529e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard if (i < 0) 67539e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard i = 0; 67549e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard if (l > m) 67559e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard l = m; 67563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 67570eafdef9881c396ce4c014359d8f497cc088cfabDaniel Veillard /* number of chars to copy */ 67580eafdef9881c396ce4c014359d8f497cc088cfabDaniel Veillard l -= i; 67593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 67600eafdef9881c396ce4c014359d8f497cc088cfabDaniel Veillard ret = xmlUTF8Strsub(str->stringval, i, l); 67610eafdef9881c396ce4c014359d8f497cc088cfabDaniel Veillard } 67620eafdef9881c396ce4c014359d8f497cc088cfabDaniel Veillard else { 67630eafdef9881c396ce4c014359d8f497cc088cfabDaniel Veillard ret = NULL; 67640eafdef9881c396ce4c014359d8f497cc088cfabDaniel Veillard } 67653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 67663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ret == NULL) 67673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, xmlXPathNewCString("")); 67683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else { 67693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, xmlXPathNewString(ret)); 67703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(ret); 67713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 677297ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard 67733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(str); 67743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 67753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 67763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 67773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathSubstringBeforeFunction: 67783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 67793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs: the number of arguments 67803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 67813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the substring-before() XPath function 67823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * string substring-before(string, string) 67833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The substring-before function returns the substring of the first 67843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * argument string that precedes the first occurrence of the second 67853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * argument string in the first argument string, or the empty string 67863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * if the first argument string does not contain the second argument 67873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * string. For example, substring-before("1999/04/01","/") returns 1999. 67883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 67893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 67903473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathSubstringBeforeFunction(xmlXPathParserContextPtr ctxt, int nargs) { 67913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr str; 67923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr find; 67933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlBufferPtr target; 67943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor const xmlChar *point; 67953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int offset; 67963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 67973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ARITY(2); 67983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CAST_TO_STRING; 67993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor find = valuePop(ctxt); 68003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CAST_TO_STRING; 68013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor str = valuePop(ctxt); 68023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 68033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor target = xmlBufferCreate(); 68043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (target) { 68053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor point = xmlStrstr(str->stringval, find->stringval); 68063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (point) { 68073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor offset = (int)(point - str->stringval); 68083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlBufferAdd(target, str->stringval, offset); 68093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 68103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, xmlXPathNewString(xmlBufferContent(target))); 68113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlBufferFree(target); 68123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 68133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 68143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(str); 68153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(find); 68163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 68173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 68183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 68193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathSubstringAfterFunction: 68203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 68213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs: the number of arguments 68223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 68233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the substring-after() XPath function 68243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * string substring-after(string, string) 68253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The substring-after function returns the substring of the first 68263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * argument string that follows the first occurrence of the second 68273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * argument string in the first argument string, or the empty stringi 68283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * if the first argument string does not contain the second argument 68293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * string. For example, substring-after("1999/04/01","/") returns 04/01, 68303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * and substring-after("1999/04/01","19") returns 99/04/01. 68313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 68323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 68333473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathSubstringAfterFunction(xmlXPathParserContextPtr ctxt, int nargs) { 68343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr str; 68353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr find; 68363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlBufferPtr target; 68373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor const xmlChar *point; 68383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int offset; 68393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 68403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ARITY(2); 68413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CAST_TO_STRING; 68423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor find = valuePop(ctxt); 68433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CAST_TO_STRING; 68443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor str = valuePop(ctxt); 68453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 68463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor target = xmlBufferCreate(); 68473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (target) { 68483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor point = xmlStrstr(str->stringval, find->stringval); 68493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (point) { 68503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor offset = (int)(point - str->stringval) + xmlStrlen(find->stringval); 68513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlBufferAdd(target, &str->stringval[offset], 68523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlStrlen(str->stringval) - offset); 68533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 68543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, xmlXPathNewString(xmlBufferContent(target))); 68553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlBufferFree(target); 68563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 68573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 68583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(str); 68593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(find); 68603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 68613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 68623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 68633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNormalizeFunction: 68643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 68653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs: the number of arguments 68663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 68673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the normalize-space() XPath function 68683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * string normalize-space(string?) 68693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The normalize-space function returns the argument string with white 68703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * space normalized by stripping leading and trailing whitespace 68713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * and replacing sequences of whitespace characters by a single 68723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * space. Whitespace characters are the same allowed by the S production 68733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * in XML. If the argument is omitted, it defaults to the context 68743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * node converted to a string, in other words the value of the context node. 68753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 68763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 68773473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNormalizeFunction(xmlXPathParserContextPtr ctxt, int nargs) { 68783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr obj = NULL; 68793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlChar *source = NULL; 68803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlBufferPtr target; 68813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlChar blank; 68823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 6883a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard if (ctxt == NULL) return; 68843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (nargs == 0) { 68853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* Use current context node */ 6886ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard valuePush(ctxt, 6887ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlXPathWrapString( 6888ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlXPathCastNodeToString(ctxt->context->node))); 68893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor nargs = 1; 68903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 68913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 68923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ARITY(1); 68933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CAST_TO_STRING; 68943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_TYPE(XPATH_STRING); 68953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor obj = valuePop(ctxt); 68963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor source = obj->stringval; 68973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 68983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor target = xmlBufferCreate(); 68993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (target && source) { 69003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 69013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* Skip leading whitespaces */ 690276e95df05556c9610b564b14cf578c8f9e34c9c1William M. Brack while (IS_BLANK_CH(*source)) 69033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor source++; 69043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 69053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* Collapse intermediate whitespaces, and skip trailing whitespaces */ 69063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor blank = 0; 69073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while (*source) { 690876e95df05556c9610b564b14cf578c8f9e34c9c1William M. Brack if (IS_BLANK_CH(*source)) { 690997ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard blank = 0x20; 69103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else { 69113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (blank) { 69123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlBufferAdd(target, &blank, 1); 69133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor blank = 0; 69143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 69153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlBufferAdd(target, source, 1); 69163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 69173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor source++; 69183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 69193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 69203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, xmlXPathNewString(xmlBufferContent(target))); 69213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlBufferFree(target); 69223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 69233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(obj); 69243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 69253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 69263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 69273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathTranslateFunction: 69283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 69293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs: the number of arguments 69303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 69313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the translate() XPath function 69323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * string translate(string, string, string) 69333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The translate function returns the first argument string with 69343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * occurrences of characters in the second argument string replaced 69353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * by the character at the corresponding position in the third argument 69363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * string. For example, translate("bar","abc","ABC") returns the string 69373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * BAr. If there is a character in the second argument string with no 69383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * character at a corresponding position in the third argument string 69393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * (because the second argument string is longer than the third argument 69403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * string), then occurrences of that character in the first argument 69413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * string are removed. For example, translate("--aaa--","abc-","ABC") 69423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * returns "AAA". If a character occurs more than once in second 69433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * argument string, then the first occurrence determines the replacement 69443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * character. If the third argument string is longer than the second 69453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * argument string, then excess characters are ignored. 69463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 69473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 69483473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathTranslateFunction(xmlXPathParserContextPtr ctxt, int nargs) { 6949e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard xmlXPathObjectPtr str; 6950e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard xmlXPathObjectPtr from; 6951e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard xmlXPathObjectPtr to; 6952e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard xmlBufferPtr target; 695397ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard int offset, max; 6954e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard xmlChar ch; 6955b031cef5b537d8eda30f508627f08bc642bbd31dWilliam M. Brack const xmlChar *point; 695697ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard xmlChar *cptr; 69573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 6958e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard CHECK_ARITY(3); 69593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 6960e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard CAST_TO_STRING; 6961e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard to = valuePop(ctxt); 6962e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard CAST_TO_STRING; 6963e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard from = valuePop(ctxt); 6964e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard CAST_TO_STRING; 6965e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard str = valuePop(ctxt); 69663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 6967e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard target = xmlBufferCreate(); 6968e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard if (target) { 696997ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard max = xmlUTF8Strlen(to->stringval); 697097ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard for (cptr = str->stringval; (ch=*cptr); ) { 697197ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard offset = xmlUTF8Strloc(from->stringval, cptr); 697297ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard if (offset >= 0) { 697397ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard if (offset < max) { 697497ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard point = xmlUTF8Strpos(to->stringval, offset); 697597ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard if (point) 697697ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard xmlBufferAdd(target, point, xmlUTF8Strsize(point, 1)); 697797ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard } 697897ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard } else 697997ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard xmlBufferAdd(target, cptr, xmlUTF8Strsize(cptr, 1)); 698097ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard 698197ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard /* Step to next character in input */ 698297ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard cptr++; 698397ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard if ( ch & 0x80 ) { 698497ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard /* if not simple ascii, verify proper format */ 698597ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard if ( (ch & 0xc0) != 0xc0 ) { 698697ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard xmlGenericError(xmlGenericErrorContext, 698797ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard "xmlXPathTranslateFunction: Invalid UTF8 string\n"); 698897ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard break; 698997ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard } 699097ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard /* then skip over remaining bytes for this char */ 699197ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard while ( (ch <<= 1) & 0x80 ) 699297ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard if ( (*cptr++ & 0xc0) != 0x80 ) { 699397ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard xmlGenericError(xmlGenericErrorContext, 699497ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard "xmlXPathTranslateFunction: Invalid UTF8 string\n"); 699597ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard break; 699697ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard } 699797ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard if (ch & 0x80) /* must have had error encountered */ 699897ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard break; 699997ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard } 7000e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard } 70013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 7002e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard valuePush(ctxt, xmlXPathNewString(xmlBufferContent(target))); 7003e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard xmlBufferFree(target); 7004e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard xmlXPathFreeObject(str); 7005e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard xmlXPathFreeObject(from); 7006e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard xmlXPathFreeObject(to); 70073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 70083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 70093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 7010fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * xmlXPathBooleanFunction: 7011fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * @ctxt: the XPath Parser context 7012fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * @nargs: the number of arguments 7013fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * 7014fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * Implement the boolean() XPath function 7015fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * boolean boolean(object) 7016081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack * The boolean function converts its argument to a boolean as follows: 7017fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * - a number is true if and only if it is neither positive or 7018fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * negative zero nor NaN 7019fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * - a node-set is true if and only if it is non-empty 7020fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * - a string is true if and only if its length is non-zero 7021fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard */ 7022fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillardvoid 7023fbf8a2d0c8145b713099df63d174154a8442e60dDaniel VeillardxmlXPathBooleanFunction(xmlXPathParserContextPtr ctxt, int nargs) { 7024fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard xmlXPathObjectPtr cur; 7025fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard 7026fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard CHECK_ARITY(1); 7027fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard cur = valuePop(ctxt); 7028fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard if (cur == NULL) XP_ERROR(XPATH_INVALID_OPERAND); 7029fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard cur = xmlXPathConvertBoolean(cur); 7030fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard valuePush(ctxt, cur); 70313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 70323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 70333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 70343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNotFunction: 70353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 70363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs: the number of arguments 70373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 70383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the not() XPath function 70393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * boolean not(boolean) 70403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The not function returns true if its argument is false, 70413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * and false otherwise. 70423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 70433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 70443473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNotFunction(xmlXPathParserContextPtr ctxt, int nargs) { 70453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ARITY(1); 70463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CAST_TO_BOOLEAN; 70473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_TYPE(XPATH_BOOLEAN); 70483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ctxt->value->boolval = ! ctxt->value->boolval; 70493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 70503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 70513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 70523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathTrueFunction: 70533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 70543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs: the number of arguments 70553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 70563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the true() XPath function 70573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * boolean true() 70583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 70593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 70603473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathTrueFunction(xmlXPathParserContextPtr ctxt, int nargs) { 70613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ARITY(0); 70623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, xmlXPathNewBoolean(1)); 70633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 70643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 70653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 70663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathFalseFunction: 70673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 70683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs: the number of arguments 70693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 70703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the false() XPath function 70713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * boolean false() 70723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 70733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 70743473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathFalseFunction(xmlXPathParserContextPtr ctxt, int nargs) { 70753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ARITY(0); 70763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, xmlXPathNewBoolean(0)); 70773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 70783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 70793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 70803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathLangFunction: 70813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 70823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs: the number of arguments 70833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 70843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the lang() XPath function 70853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * boolean lang(string) 70863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The lang function returns true or false depending on whether the 70873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * language of the context node as specified by xml:lang attributes 70883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * is the same as or is a sublanguage of the language specified by 70893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the argument string. The language of the context node is determined 70903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * by the value of the xml:lang attribute on the context node, or, if 70913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the context node has no xml:lang attribute, by the value of the 70923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xml:lang attribute on the nearest ancestor of the context node that 70933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * has an xml:lang attribute. If there is no such attribute, then lang 70943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * returns false. If there is such an attribute, then lang returns 70953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * true if the attribute value is equal to the argument ignoring case, 70963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * or if there is some suffix starting with - such that the attribute 70973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * value is equal to the argument ignoring that suffix of the attribute 70983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * value and ignoring case. 70993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 71003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 71013473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathLangFunction(xmlXPathParserContextPtr ctxt, int nargs) { 71024ddaa56d7af6638c20a4446c47b02b299987be65Daniel Veillard xmlXPathObjectPtr val = NULL; 71034ddaa56d7af6638c20a4446c47b02b299987be65Daniel Veillard const xmlChar *theLang = NULL; 71043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor const xmlChar *lang; 71053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int ret = 0; 71063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int i; 71073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 71083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ARITY(1); 71093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CAST_TO_STRING; 71103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_TYPE(XPATH_STRING); 71113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor val = valuePop(ctxt); 71123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor lang = val->stringval; 71133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor theLang = xmlNodeGetLang(ctxt->context->node); 71143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((theLang != NULL) && (lang != NULL)) { 71153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor for (i = 0;lang[i] != 0;i++) 71163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (toupper(lang[i]) != toupper(theLang[i])) 71173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor goto not_equal; 71184ddaa56d7af6638c20a4446c47b02b299987be65Daniel Veillard if ((theLang[i] == 0) || (theLang[i] == '-')) 71194ddaa56d7af6638c20a4446c47b02b299987be65Daniel Veillard ret = 1; 71203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 71213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylornot_equal: 71224ddaa56d7af6638c20a4446c47b02b299987be65Daniel Veillard if (theLang != NULL) 71234ddaa56d7af6638c20a4446c47b02b299987be65Daniel Veillard xmlFree((void *)theLang); 71243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(val); 71253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, xmlXPathNewBoolean(ret)); 71263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 71273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 71283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 71293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNumberFunction: 71303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 71313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs: the number of arguments 71323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 71333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the number() XPath function 71343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * number number(object?) 71353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 71363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 71373473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNumberFunction(xmlXPathParserContextPtr ctxt, int nargs) { 71383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr cur; 71393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor double res; 71403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 7141a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard if (ctxt == NULL) return; 71423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (nargs == 0) { 71433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->context->node == NULL) { 71443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, xmlXPathNewFloat(0.0)); 71453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else { 71463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlChar* content = xmlNodeGetContent(ctxt->context->node); 71473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 71483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor res = xmlXPathStringEvalNumber(content); 71493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, xmlXPathNewFloat(res)); 71503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(content); 71513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 71523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return; 71533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 71543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 71553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ARITY(1); 71563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur = valuePop(ctxt); 7157fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard cur = xmlXPathConvertNumber(cur); 7158fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard valuePush(ctxt, cur); 71593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 71603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 71613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 71623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathSumFunction: 71633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 71643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs: the number of arguments 71653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 71663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the sum() XPath function 71673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * number sum(node-set) 71683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The sum function returns the sum of the values of the nodes in 71693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the argument node-set. 71703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 71713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 71723473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathSumFunction(xmlXPathParserContextPtr ctxt, int nargs) { 71733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr cur; 71743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int i; 7175ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard double res = 0.0; 71763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 71773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ARITY(1); 71783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((ctxt->value == NULL) || 71793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ((ctxt->value->type != XPATH_NODESET) && 71803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor (ctxt->value->type != XPATH_XSLT_TREE))) 71813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XP_ERROR(XPATH_INVALID_TYPE); 71823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur = valuePop(ctxt); 71833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 7184081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack if ((cur->nodesetval != NULL) && (cur->nodesetval->nodeNr != 0)) { 7185ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard for (i = 0; i < cur->nodesetval->nodeNr; i++) { 7186ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard res += xmlXPathCastNodeToNumber(cur->nodesetval->nodeTab[i]); 71873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 71883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 7189081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack valuePush(ctxt, xmlXPathNewFloat(res)); 71903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(cur); 71913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 71923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 71933d426663629a53180f3f54282ba27f3d070eef24William M. Brack/* 71943d426663629a53180f3f54282ba27f3d070eef24William M. Brack * To assure working code on multiple platforms, we want to only depend 71953d426663629a53180f3f54282ba27f3d070eef24William M. Brack * upon the characteristic truncation of converting a floating point value 71963d426663629a53180f3f54282ba27f3d070eef24William M. Brack * to an integer. Unfortunately, because of the different storage sizes 71973d426663629a53180f3f54282ba27f3d070eef24William M. Brack * of our internal floating point value (double) and integer (int), we 71983d426663629a53180f3f54282ba27f3d070eef24William M. Brack * can't directly convert (see bug 301162). This macro is a messy 71993d426663629a53180f3f54282ba27f3d070eef24William M. Brack * 'workaround' 72003d426663629a53180f3f54282ba27f3d070eef24William M. Brack */ 72013d426663629a53180f3f54282ba27f3d070eef24William M. Brack#define XTRUNC(f, v) \ 72023d426663629a53180f3f54282ba27f3d070eef24William M. Brack f = fmod((v), INT_MAX); \ 72033d426663629a53180f3f54282ba27f3d070eef24William M. Brack f = (v) - (f) + (double)((int)(f)); 72043d426663629a53180f3f54282ba27f3d070eef24William M. Brack 72053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 72063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathFloorFunction: 72073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 72083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs: the number of arguments 72093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 72103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the floor() XPath function 72113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * number floor(number) 72123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The floor function returns the largest (closest to positive infinity) 72133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * number that is not greater than the argument and that is an integer. 72143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 72153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 72163473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathFloorFunction(xmlXPathParserContextPtr ctxt, int nargs) { 721756cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard double f; 721856cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard 72193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ARITY(1); 72203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CAST_TO_NUMBER; 72213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_TYPE(XPATH_NUMBER); 722256cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard 72233d426663629a53180f3f54282ba27f3d070eef24William M. Brack XTRUNC(f, ctxt->value->floatval); 722456cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard if (f != ctxt->value->floatval) { 722556cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard if (ctxt->value->floatval > 0) 722656cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard ctxt->value->floatval = f; 722756cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard else 722856cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard ctxt->value->floatval = f - 1; 722956cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard } 72303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 72313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 72323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 72333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathCeilingFunction: 72343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 72353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs: the number of arguments 72363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 72373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the ceiling() XPath function 72383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * number ceiling(number) 72393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The ceiling function returns the smallest (closest to negative infinity) 72403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * number that is not less than the argument and that is an integer. 72413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 72423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 72433473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathCeilingFunction(xmlXPathParserContextPtr ctxt, int nargs) { 72443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor double f; 72453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 72463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ARITY(1); 72473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CAST_TO_NUMBER; 72483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_TYPE(XPATH_NUMBER); 72493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 72503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#if 0 72513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ctxt->value->floatval = ceil(ctxt->value->floatval); 72523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#else 72533d426663629a53180f3f54282ba27f3d070eef24William M. Brack XTRUNC(f, ctxt->value->floatval); 725456cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard if (f != ctxt->value->floatval) { 725556cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard if (ctxt->value->floatval > 0) 725656cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard ctxt->value->floatval = f + 1; 72575fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard else { 72585fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard if (ctxt->value->floatval < 0 && f == 0) 72595fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard ctxt->value->floatval = xmlXPathNZERO; 72605fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard else 72615fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard ctxt->value->floatval = f; 72625fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard } 72635fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard 726456cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard } 72653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 72663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 72673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 72683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 72693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathRoundFunction: 72703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 72713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs: the number of arguments 72723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 72733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the round() XPath function 72743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * number round(number) 72753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The round function returns the number that is closest to the 72763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * argument and that is an integer. If there are two such numbers, 72773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * then the one that is even is returned. 72783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 72793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 72803473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathRoundFunction(xmlXPathParserContextPtr ctxt, int nargs) { 72813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor double f; 72823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 72833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ARITY(1); 72843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CAST_TO_NUMBER; 72853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_TYPE(XPATH_NUMBER); 72863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 7287cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard if ((xmlXPathIsNaN(ctxt->value->floatval)) || 7288cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard (xmlXPathIsInf(ctxt->value->floatval) == 1) || 7289cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard (xmlXPathIsInf(ctxt->value->floatval) == -1) || 72903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor (ctxt->value->floatval == 0.0)) 72913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return; 72923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 72933d426663629a53180f3f54282ba27f3d070eef24William M. Brack XTRUNC(f, ctxt->value->floatval); 729456cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard if (ctxt->value->floatval < 0) { 729556cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard if (ctxt->value->floatval < f - 0.5) 729656cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard ctxt->value->floatval = f - 1; 729756cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard else 729856cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard ctxt->value->floatval = f; 72995fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard if (ctxt->value->floatval == 0) 73005fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard ctxt->value->floatval = xmlXPathNZERO; 730156cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard } else { 730256cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard if (ctxt->value->floatval < f + 0.5) 730356cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard ctxt->value->floatval = f; 730456cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard else 730556cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard ctxt->value->floatval = f + 1; 730656cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard } 73073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 73083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 73093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/************************************************************************ 73103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * * 73113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The Parser * 73123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * * 73133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ************************************************************************/ 73143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 73153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/* 7316081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack * a few forward declarations since we use a recursive call based 73173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * implementation. 73183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 7319afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void xmlXPathCompileExpr(xmlXPathParserContextPtr ctxt); 7320d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillardstatic void xmlXPathCompPredicate(xmlXPathParserContextPtr ctxt, int filter); 7321afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void xmlXPathCompLocationPath(xmlXPathParserContextPtr ctxt); 7322afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void xmlXPathCompRelativeLocationPath(xmlXPathParserContextPtr ctxt); 73232156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillardstatic xmlChar * xmlXPathParseNameComplex(xmlXPathParserContextPtr ctxt, 73242156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard int qualified); 73253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 73263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 732761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard * xmlXPathCurrentChar: 732861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard * @ctxt: the XPath parser context 732961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard * @cur: pointer to the beginning of the char 733061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard * @len: pointer to the length of the char read 733161d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard * 7332cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * The current char value, if using UTF-8 this may actually span multiple 733361d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard * bytes in the input buffer. 733461d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard * 733560087f30f3b4cf21de48f39181736e7d71e7a661Daniel Veillard * Returns the current char value and its length 733661d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard */ 733761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard 733861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillardstatic int 733961d80a2822b2678dee885ac2850295cc96277c63Daniel VeillardxmlXPathCurrentChar(xmlXPathParserContextPtr ctxt, int *len) { 734061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard unsigned char c; 734161d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard unsigned int val; 734261d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard const xmlChar *cur; 734361d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard 734461d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard if (ctxt == NULL) 734561d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard return(0); 734661d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard cur = ctxt->cur; 734761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard 734861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard /* 734961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard * We are supposed to handle UTF8, check it's valid 735061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard * From rfc2044: encoding of the Unicode values on UTF-8: 735161d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard * 735261d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard * UCS-4 range (hex.) UTF-8 octet sequence (binary) 735361d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard * 0000 0000-0000 007F 0xxxxxxx 735461d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard * 0000 0080-0000 07FF 110xxxxx 10xxxxxx 735561d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard * 0000 0800-0000 FFFF 1110xxxx 10xxxxxx 10xxxxxx 735661d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard * 735761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard * Check for the 0x110000 limit too 735861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard */ 735961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard c = *cur; 736061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard if (c & 0x80) { 736161d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard if ((cur[1] & 0xc0) != 0x80) 736261d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard goto encoding_error; 736361d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard if ((c & 0xe0) == 0xe0) { 736461d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard 736561d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard if ((cur[2] & 0xc0) != 0x80) 736661d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard goto encoding_error; 736761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard if ((c & 0xf0) == 0xf0) { 736861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard if (((c & 0xf8) != 0xf0) || 736961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard ((cur[3] & 0xc0) != 0x80)) 737061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard goto encoding_error; 737161d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard /* 4-byte code */ 737261d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard *len = 4; 737361d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard val = (cur[0] & 0x7) << 18; 737461d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard val |= (cur[1] & 0x3f) << 12; 737561d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard val |= (cur[2] & 0x3f) << 6; 737661d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard val |= cur[3] & 0x3f; 737761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard } else { 737861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard /* 3-byte code */ 737961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard *len = 3; 738061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard val = (cur[0] & 0xf) << 12; 738161d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard val |= (cur[1] & 0x3f) << 6; 738261d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard val |= cur[2] & 0x3f; 738361d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard } 738461d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard } else { 738561d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard /* 2-byte code */ 738661d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard *len = 2; 738761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard val = (cur[0] & 0x1f) << 6; 738861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard val |= cur[1] & 0x3f; 738961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard } 739061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard if (!IS_CHAR(val)) { 739161d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard XP_ERROR0(XPATH_INVALID_CHAR_ERROR); 739261d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard } 739361d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard return(val); 739461d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard } else { 739561d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard /* 1-byte code */ 739661d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard *len = 1; 739761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard return((int) *cur); 739861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard } 739961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillardencoding_error: 740061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard /* 7401081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack * If we detect an UTF8 error that probably means that the 7402081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack * input encoding didn't get properly advertised in the 740361d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard * declaration header. Report the error and switch the encoding 740461d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard * to ISO-Latin-1 (if you don't like this policy, just declare the 740561d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard * encoding !) 740661d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard */ 740742596ad20cdf1925dd79ea801cbe598b6e7b7aecDaniel Veillard *len = 0; 740861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard XP_ERROR0(XPATH_ENCODING_ERROR); 740961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard} 741061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard 741161d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard/** 74123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathParseNCName: 74133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 74143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 74153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * parse an XML namespace non qualified name. 74163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 74173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [NS 3] NCName ::= (Letter | '_') (NCNameChar)* 74183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 74193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [NS 4] NCNameChar ::= Letter | Digit | '.' | '-' | '_' | 74203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * CombiningChar | Extender 74213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 74223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the namespace name or NULL 74233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 74243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 74253473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlChar * 74263473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathParseNCName(xmlXPathParserContextPtr ctxt) { 74272156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard const xmlChar *in; 74282156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard xmlChar *ret; 74292156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard int count = 0; 74303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 7431a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard if ((ctxt == NULL) || (ctxt->cur == NULL)) return(NULL); 74322156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard /* 74332156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard * Accelerator for simple ASCII names 74342156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard */ 74352156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard in = ctxt->cur; 74362156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard if (((*in >= 0x61) && (*in <= 0x7A)) || 74372156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard ((*in >= 0x41) && (*in <= 0x5A)) || 74382156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard (*in == '_')) { 74392156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard in++; 74402156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard while (((*in >= 0x61) && (*in <= 0x7A)) || 74412156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard ((*in >= 0x41) && (*in <= 0x5A)) || 74422156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard ((*in >= 0x30) && (*in <= 0x39)) || 74439a89a8ab80bc021deec9da7d79bda20995c4e78dDaniel Veillard (*in == '_') || (*in == '.') || 74449a89a8ab80bc021deec9da7d79bda20995c4e78dDaniel Veillard (*in == '-')) 74452156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard in++; 74462156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard if ((*in == ' ') || (*in == '>') || (*in == '/') || 74472156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard (*in == '[') || (*in == ']') || (*in == ':') || 74482156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard (*in == '@') || (*in == '*')) { 74492156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard count = in - ctxt->cur; 74502156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard if (count == 0) 74512156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard return(NULL); 74522156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard ret = xmlStrndup(ctxt->cur, count); 74532156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard ctxt->cur = in; 74542156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard return(ret); 74552156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard } 74562156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard } 74572156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard return(xmlXPathParseNameComplex(ctxt, 0)); 74583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 74593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 74602156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard 74613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 74623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathParseQName: 74633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 74643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @prefix: a xmlChar ** 74653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 74663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * parse an XML qualified name 74673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 74683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [NS 5] QName ::= (Prefix ':')? LocalPart 74693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 74703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [NS 6] Prefix ::= NCName 74713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 74723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [NS 7] LocalPart ::= NCName 74733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 74743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the function returns the local part, and prefix is updated 74753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * to get the Prefix if any. 74763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 74773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 747856a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic xmlChar * 74793473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathParseQName(xmlXPathParserContextPtr ctxt, xmlChar **prefix) { 74803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlChar *ret = NULL; 74813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 74823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *prefix = NULL; 74833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = xmlXPathParseNCName(ctxt); 74843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (CUR == ':') { 74853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *prefix = ret; 74863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 74873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = xmlXPathParseNCName(ctxt); 74883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 74893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ret); 74903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 74913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 74923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 74933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathParseName: 74943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 74953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 74963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * parse an XML name 74973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 74983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [4] NameChar ::= Letter | Digit | '.' | '-' | '_' | ':' | 74993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * CombiningChar | Extender 75003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 75013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [5] Name ::= (Letter | '_' | ':') (NameChar)* 75023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 75033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the namespace name or NULL 75043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 75053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 75063473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlChar * 75073473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathParseName(xmlXPathParserContextPtr ctxt) { 750861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard const xmlChar *in; 750961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard xmlChar *ret; 751061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard int count = 0; 75113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 7512a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard if ((ctxt == NULL) || (ctxt->cur == NULL)) return(NULL); 751361d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard /* 751461d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard * Accelerator for simple ASCII names 751561d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard */ 751661d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard in = ctxt->cur; 751761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard if (((*in >= 0x61) && (*in <= 0x7A)) || 751861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard ((*in >= 0x41) && (*in <= 0x5A)) || 751961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard (*in == '_') || (*in == ':')) { 752061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard in++; 752161d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard while (((*in >= 0x61) && (*in <= 0x7A)) || 752261d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard ((*in >= 0x41) && (*in <= 0x5A)) || 752361d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard ((*in >= 0x30) && (*in <= 0x39)) || 752476d66f416d2d0d5db4a09d212b4e43087e9cdae7Daniel Veillard (*in == '_') || (*in == '-') || 752576d66f416d2d0d5db4a09d212b4e43087e9cdae7Daniel Veillard (*in == ':') || (*in == '.')) 752661d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard in++; 752776d66f416d2d0d5db4a09d212b4e43087e9cdae7Daniel Veillard if ((*in > 0) && (*in < 0x80)) { 752861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard count = in - ctxt->cur; 752961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard ret = xmlStrndup(ctxt->cur, count); 753061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard ctxt->cur = in; 753161d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard return(ret); 753261d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard } 753361d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard } 75342156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard return(xmlXPathParseNameComplex(ctxt, 1)); 753561d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard} 75363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 753761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillardstatic xmlChar * 75382156a56bcbf5d83fb3d694123be01beebf84d273Daniel VeillardxmlXPathParseNameComplex(xmlXPathParserContextPtr ctxt, int qualified) { 753961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard xmlChar buf[XML_MAX_NAMELEN + 5]; 754061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard int len = 0, l; 754161d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard int c; 75423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 754361d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard /* 754461d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard * Handler for more complex cases 754561d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard */ 754661d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard c = CUR_CHAR(l); 754761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard if ((c == ' ') || (c == '>') || (c == '/') || /* accelerators */ 75482156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard (c == '[') || (c == ']') || (c == '@') || /* accelerators */ 75492156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard (c == '*') || /* accelerators */ 755061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard (!IS_LETTER(c) && (c != '_') && 75512156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard ((qualified) && (c != ':')))) { 755261d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard return(NULL); 755361d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard } 75543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 755561d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard while ((c != ' ') && (c != '>') && (c != '/') && /* test bigname.xml */ 755661d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard ((IS_LETTER(c)) || (IS_DIGIT(c)) || 755761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard (c == '.') || (c == '-') || 75582156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard (c == '_') || ((qualified) && (c == ':')) || 755961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard (IS_COMBINING(c)) || 756061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard (IS_EXTENDER(c)))) { 756161d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard COPY_BUF(l,buf,len,c); 756261d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard NEXTL(l); 756361d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard c = CUR_CHAR(l); 756461d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard if (len >= XML_MAX_NAMELEN) { 756561d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard /* 756661d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard * Okay someone managed to make a huge name, so he's ready to pay 756761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard * for the processing speed. 756861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard */ 756961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard xmlChar *buffer; 757061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard int max = len * 2; 757161d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard 75723c908dca479ed50dca24b8593bca90e40dbde6b8Daniel Veillard buffer = (xmlChar *) xmlMallocAtomic(max * sizeof(xmlChar)); 757361d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard if (buffer == NULL) { 757461d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard XP_ERROR0(XPATH_MEMORY_ERROR); 757561d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard } 757661d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard memcpy(buffer, buf, len); 757761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard while ((IS_LETTER(c)) || (IS_DIGIT(c)) || /* test bigname.xml */ 757861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard (c == '.') || (c == '-') || 75792156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard (c == '_') || ((qualified) && (c == ':')) || 758061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard (IS_COMBINING(c)) || 758161d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard (IS_EXTENDER(c))) { 758261d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard if (len + 10 > max) { 758361d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard max *= 2; 758461d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard buffer = (xmlChar *) xmlRealloc(buffer, 758561d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard max * sizeof(xmlChar)); 758661d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard if (buffer == NULL) { 758761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard XP_ERROR0(XPATH_MEMORY_ERROR); 758861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard } 758961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard } 759061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard COPY_BUF(l,buffer,len,c); 759161d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard NEXTL(l); 759261d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard c = CUR_CHAR(l); 759361d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard } 759461d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard buffer[len] = 0; 759561d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard return(buffer); 759661d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard } 759761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard } 75982156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard if (len == 0) 75992156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard return(NULL); 760061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard return(xmlStrndup(buf, len)); 760161d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard} 76023cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard 76033cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard#define MAX_FRAC 20 76043cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard 7605372a445479b859bd0fe24df54e9b3db34d113d5aWilliam M. Brack/* 7606372a445479b859bd0fe24df54e9b3db34d113d5aWilliam M. Brack * These are used as divisors for the fractional part of a number. 7607372a445479b859bd0fe24df54e9b3db34d113d5aWilliam M. Brack * Since the table includes 1.0 (representing '0' fractional digits), 7608372a445479b859bd0fe24df54e9b3db34d113d5aWilliam M. Brack * it must be dimensioned at MAX_FRAC+1 (bug 133921) 7609372a445479b859bd0fe24df54e9b3db34d113d5aWilliam M. Brack */ 7610372a445479b859bd0fe24df54e9b3db34d113d5aWilliam M. Brackstatic double my_pow10[MAX_FRAC+1] = { 76113cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard 1.0, 10.0, 100.0, 1000.0, 10000.0, 76123cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard 100000.0, 1000000.0, 10000000.0, 100000000.0, 1000000000.0, 76133cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard 10000000000.0, 100000000000.0, 1000000000000.0, 10000000000000.0, 76143cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard 100000000000000.0, 76153cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard 1000000000000000.0, 10000000000000000.0, 100000000000000000.0, 7616372a445479b859bd0fe24df54e9b3db34d113d5aWilliam M. Brack 1000000000000000000.0, 10000000000000000000.0, 100000000000000000000.0 76173cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard}; 76183cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard 76193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 76203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathStringEvalNumber: 76213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @str: A string to scan 76223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 762370a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese * [30a] Float ::= Number ('e' Digits?)? 762470a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese * 76253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [30] Number ::= Digits ('.' Digits?)? 76263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | '.' Digits 76273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [31] Digits ::= [0-9]+ 76283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 7629afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile a Number in the string 76303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * In complement of the Number expression, this function also handles 76313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * negative values : '-' Number. 76323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 76333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the double value. 76343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 76353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylordouble 76363473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathStringEvalNumber(const xmlChar *str) { 76373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor const xmlChar *cur = str; 76387b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard double ret; 7639b06c61455f86758511aa050a06ff1bbd33f8c3c3Daniel Veillard int ok = 0; 76403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int isneg = 0; 764170a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese int exponent = 0; 764270a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese int is_exponent_negative = 0; 7643b06c61455f86758511aa050a06ff1bbd33f8c3c3Daniel Veillard#ifdef __GNUC__ 7644b06c61455f86758511aa050a06ff1bbd33f8c3c3Daniel Veillard unsigned long tmp = 0; 76457b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard double temp; 7646b06c61455f86758511aa050a06ff1bbd33f8c3c3Daniel Veillard#endif 7647eca82810f0fb81f3e9936d2018347e1e19de513aDaniel Veillard if (cur == NULL) return(0); 764876e95df05556c9610b564b14cf578c8f9e34c9c1William M. Brack while (IS_BLANK_CH(*cur)) cur++; 76493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((*cur != '.') && ((*cur < '0') || (*cur > '9')) && (*cur != '-')) { 76503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(xmlXPathNAN); 76513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 76523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (*cur == '-') { 76533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor isneg = 1; 76543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur++; 76553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 7656b06c61455f86758511aa050a06ff1bbd33f8c3c3Daniel Veillard 7657b06c61455f86758511aa050a06ff1bbd33f8c3c3Daniel Veillard#ifdef __GNUC__ 7658d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard /* 76597b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard * tmp/temp is a workaround against a gcc compiler bug 76607b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard * http://veillard.com/gcc.bug 7661d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard */ 76627b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard ret = 0; 76633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while ((*cur >= '0') && (*cur <= '9')) { 76647b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard ret = ret * 10; 76657b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard tmp = (*cur - '0'); 76663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ok = 1; 76673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur++; 76687b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard temp = (double) tmp; 76697b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard ret = ret + temp; 76703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 7671b06c61455f86758511aa050a06ff1bbd33f8c3c3Daniel Veillard#else 76727b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard ret = 0; 7673b06c61455f86758511aa050a06ff1bbd33f8c3c3Daniel Veillard while ((*cur >= '0') && (*cur <= '9')) { 7674b06c61455f86758511aa050a06ff1bbd33f8c3c3Daniel Veillard ret = ret * 10 + (*cur - '0'); 7675b06c61455f86758511aa050a06ff1bbd33f8c3c3Daniel Veillard ok = 1; 7676b06c61455f86758511aa050a06ff1bbd33f8c3c3Daniel Veillard cur++; 7677b06c61455f86758511aa050a06ff1bbd33f8c3c3Daniel Veillard } 7678b06c61455f86758511aa050a06ff1bbd33f8c3c3Daniel Veillard#endif 7679d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard 76803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (*cur == '.') { 76813cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard int v, frac = 0; 76823cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard double fraction = 0; 76833cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard 76843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur++; 76853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (((*cur < '0') || (*cur > '9')) && (!ok)) { 76863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(xmlXPathNAN); 76873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 76883cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard while (((*cur >= '0') && (*cur <= '9')) && (frac < MAX_FRAC)) { 76893cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard v = (*cur - '0'); 76903cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard fraction = fraction * 10 + v; 76913cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard frac = frac + 1; 76923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur++; 76933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 76943cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard fraction /= my_pow10[frac]; 76953cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard ret = ret + fraction; 76963cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard while ((*cur >= '0') && (*cur <= '9')) 76973cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard cur++; 76983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 769970a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese if ((*cur == 'e') || (*cur == 'E')) { 770070a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese cur++; 770170a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese if (*cur == '-') { 770270a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese is_exponent_negative = 1; 770370a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese cur++; 77049912705b82cbf3fbff43e19dd95dd0a6ec494d2dWilliam M. Brack } else if (*cur == '+') { 77059912705b82cbf3fbff43e19dd95dd0a6ec494d2dWilliam M. Brack cur++; 770670a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese } 770770a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese while ((*cur >= '0') && (*cur <= '9')) { 770870a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese exponent = exponent * 10 + (*cur - '0'); 770970a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese cur++; 771070a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese } 771170a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese } 771276e95df05556c9610b564b14cf578c8f9e34c9c1William M. Brack while (IS_BLANK_CH(*cur)) cur++; 77133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (*cur != 0) return(xmlXPathNAN); 77143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (isneg) ret = -ret; 771570a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese if (is_exponent_negative) exponent = -exponent; 771670a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese ret *= pow(10.0, (double)exponent); 77173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ret); 77183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 77193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 77203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 7721afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompNumber: 77223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 77233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 77243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [30] Number ::= Digits ('.' Digits?)? 77253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | '.' Digits 77263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [31] Digits ::= [0-9]+ 77273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 7728afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile a Number, then push it on the stack 77293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 77303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 7731afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void 7732d79bcd1b36412a7996ace1900ab613e38a609b60Daniel VeillardxmlXPathCompNumber(xmlXPathParserContextPtr ctxt) 7733d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard{ 77343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor double ret = 0.0; 77353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor double mult = 1; 77367b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard int ok = 0; 773770a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese int exponent = 0; 773870a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese int is_exponent_negative = 0; 77397b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard#ifdef __GNUC__ 77407b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard unsigned long tmp = 0; 77417b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard double temp; 77427b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard#endif 77433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 77443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ERROR; 77453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((CUR != '.') && ((CUR < '0') || (CUR > '9'))) { 77463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XP_ERROR(XPATH_NUMBER_ERROR); 77473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 77487b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard#ifdef __GNUC__ 7749d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard /* 77507b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard * tmp/temp is a workaround against a gcc compiler bug 77517b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard * http://veillard.com/gcc.bug 7752d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard */ 77537b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard ret = 0; 77543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while ((CUR >= '0') && (CUR <= '9')) { 77557b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard ret = ret * 10; 77567b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard tmp = (CUR - '0'); 7757d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard ok = 1; 7758d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard NEXT; 77597b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard temp = (double) tmp; 77607b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard ret = ret + temp; 77613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 77627b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard#else 77637b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard ret = 0; 77647b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard while ((CUR >= '0') && (CUR <= '9')) { 77657b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard ret = ret * 10 + (CUR - '0'); 77667b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard ok = 1; 77677b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard NEXT; 77687b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard } 77697b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard#endif 77703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (CUR == '.') { 77713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 7772d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard if (((CUR < '0') || (CUR > '9')) && (!ok)) { 7773d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard XP_ERROR(XPATH_NUMBER_ERROR); 7774d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard } 7775d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard while ((CUR >= '0') && (CUR <= '9')) { 7776d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard mult /= 10; 7777d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard ret = ret + (CUR - '0') * mult; 7778d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard NEXT; 7779d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard } 77803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 778170a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese if ((CUR == 'e') || (CUR == 'E')) { 7782d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard NEXT; 7783d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard if (CUR == '-') { 7784d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard is_exponent_negative = 1; 7785d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard NEXT; 77869912705b82cbf3fbff43e19dd95dd0a6ec494d2dWilliam M. Brack } else if (CUR == '+') { 77879912705b82cbf3fbff43e19dd95dd0a6ec494d2dWilliam M. Brack NEXT; 77889912705b82cbf3fbff43e19dd95dd0a6ec494d2dWilliam M. Brack } 7789d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard while ((CUR >= '0') && (CUR <= '9')) { 7790d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard exponent = exponent * 10 + (CUR - '0'); 7791d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard NEXT; 7792d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard } 7793d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard if (is_exponent_negative) 7794d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard exponent = -exponent; 7795d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard ret *= pow(10.0, (double) exponent); 779670a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese } 77979e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard PUSH_LONG_EXPR(XPATH_OP_VALUE, XPATH_NUMBER, 0, 0, 7798d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard xmlXPathNewFloat(ret), NULL); 77993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 78003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 78013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 7802fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * xmlXPathParseLiteral: 7803fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * @ctxt: the XPath Parser context 7804fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * 7805fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * Parse a Literal 7806fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * 7807fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * [29] Literal ::= '"' [^"]* '"' 7808fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * | "'" [^']* "'" 7809fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * 7810fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * Returns the value found or NULL in case of error 7811fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard */ 7812fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillardstatic xmlChar * 7813fbf8a2d0c8145b713099df63d174154a8442e60dDaniel VeillardxmlXPathParseLiteral(xmlXPathParserContextPtr ctxt) { 7814fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard const xmlChar *q; 7815fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard xmlChar *ret = NULL; 7816fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard 7817fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard if (CUR == '"') { 7818fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard NEXT; 7819fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard q = CUR_PTR; 782076e95df05556c9610b564b14cf578c8f9e34c9c1William M. Brack while ((IS_CHAR_CH(CUR)) && (CUR != '"')) 7821fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard NEXT; 782276e95df05556c9610b564b14cf578c8f9e34c9c1William M. Brack if (!IS_CHAR_CH(CUR)) { 7823fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard XP_ERROR0(XPATH_UNFINISHED_LITERAL_ERROR); 7824fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard } else { 7825fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard ret = xmlStrndup(q, CUR_PTR - q); 7826fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard NEXT; 7827fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard } 7828fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard } else if (CUR == '\'') { 7829fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard NEXT; 7830fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard q = CUR_PTR; 783176e95df05556c9610b564b14cf578c8f9e34c9c1William M. Brack while ((IS_CHAR_CH(CUR)) && (CUR != '\'')) 7832fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard NEXT; 783376e95df05556c9610b564b14cf578c8f9e34c9c1William M. Brack if (!IS_CHAR_CH(CUR)) { 7834fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard XP_ERROR0(XPATH_UNFINISHED_LITERAL_ERROR); 7835fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard } else { 7836fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard ret = xmlStrndup(q, CUR_PTR - q); 7837fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard NEXT; 7838fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard } 7839fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard } else { 7840fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard XP_ERROR0(XPATH_START_LITERAL_ERROR); 7841fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard } 7842fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard return(ret); 7843fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard} 7844fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard 7845fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard/** 7846afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompLiteral: 78473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 78483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 78493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Parse a Literal and push it on the stack. 78503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 78513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [29] Literal ::= '"' [^"]* '"' 78523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | "'" [^']* "'" 78533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 7854afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * TODO: xmlXPathCompLiteral memory allocation could be improved. 78553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 7856afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void 7857afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompLiteral(xmlXPathParserContextPtr ctxt) { 78583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor const xmlChar *q; 78593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlChar *ret = NULL; 78603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 78613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (CUR == '"') { 78623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 78633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor q = CUR_PTR; 786476e95df05556c9610b564b14cf578c8f9e34c9c1William M. Brack while ((IS_CHAR_CH(CUR)) && (CUR != '"')) 78653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 786676e95df05556c9610b564b14cf578c8f9e34c9c1William M. Brack if (!IS_CHAR_CH(CUR)) { 78673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XP_ERROR(XPATH_UNFINISHED_LITERAL_ERROR); 78683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else { 78693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = xmlStrndup(q, CUR_PTR - q); 78703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 78713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 78723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else if (CUR == '\'') { 78733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 78743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor q = CUR_PTR; 787576e95df05556c9610b564b14cf578c8f9e34c9c1William M. Brack while ((IS_CHAR_CH(CUR)) && (CUR != '\'')) 78763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 787776e95df05556c9610b564b14cf578c8f9e34c9c1William M. Brack if (!IS_CHAR_CH(CUR)) { 78783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XP_ERROR(XPATH_UNFINISHED_LITERAL_ERROR); 78793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else { 78803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = xmlStrndup(q, CUR_PTR - q); 78813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 78823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 78833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else { 78843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XP_ERROR(XPATH_START_LITERAL_ERROR); 78853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 78863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ret == NULL) return; 78879e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard PUSH_LONG_EXPR(XPATH_OP_VALUE, XPATH_STRING, 0, 0, 78889e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlXPathNewString(ret), NULL); 78893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(ret); 78903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 78913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 78923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 7893afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompVariableReference: 78943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 78953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 78963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Parse a VariableReference, evaluate it and push it on the stack. 78973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 78983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The variable bindings consist of a mapping from variable names 7899081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack * to variable values. The value of a variable is an object, which can be 79003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * of any of the types that are possible for the value of an expression, 79013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * and may also be of additional types not specified here. 79023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 79033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Early evaluation is possible since: 79043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The variable bindings [...] used to evaluate a subexpression are 79053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * always the same as those used to evaluate the containing expression. 79063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 79073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [36] VariableReference ::= '$' QName 79083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 7909afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void 7910afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompVariableReference(xmlXPathParserContextPtr ctxt) { 79113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlChar *name; 79123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlChar *prefix; 79133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 79143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 79153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (CUR != '$') { 79163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XP_ERROR(XPATH_VARIABLE_REF_ERROR); 79173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 79183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 79193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor name = xmlXPathParseQName(ctxt, &prefix); 79203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (name == NULL) { 79213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XP_ERROR(XPATH_VARIABLE_REF_ERROR); 79223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 7923fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard ctxt->comp->last = -1; 79249e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard PUSH_LONG_EXPR(XPATH_OP_VARIABLE, 0, 0, 0, 79259e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard name, prefix); 79263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 79273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 79283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 79293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 79303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathIsNodeType: 79313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @name: a name string 79323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 79333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Is the name given a NodeType one. 79343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 79353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [38] NodeType ::= 'comment' 79363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | 'text' 79373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | 'processing-instruction' 79383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | 'node' 79393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 79403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns 1 if true 0 otherwise 79413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 79423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorint 79433473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathIsNodeType(const xmlChar *name) { 79443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (name == NULL) 79453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(0); 79463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 79471971ee2698cb84c7699c96d3302f00e20d42c0d3Daniel Veillard if (xmlStrEqual(name, BAD_CAST "node")) 79483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(1); 79493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (xmlStrEqual(name, BAD_CAST "text")) 79503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(1); 79511971ee2698cb84c7699c96d3302f00e20d42c0d3Daniel Veillard if (xmlStrEqual(name, BAD_CAST "comment")) 79523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(1); 79531971ee2698cb84c7699c96d3302f00e20d42c0d3Daniel Veillard if (xmlStrEqual(name, BAD_CAST "processing-instruction")) 79543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(1); 79553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(0); 79563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 79573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 79583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 7959afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompFunctionCall: 79603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 79613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 79623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [16] FunctionCall ::= FunctionName '(' ( Argument ( ',' Argument)*)? ')' 79633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [17] Argument ::= Expr 79643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 7965afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile a function call, the evaluation of all arguments are 79663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * pushed on the stack 79673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 7968afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void 7969afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompFunctionCall(xmlXPathParserContextPtr ctxt) { 79703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlChar *name; 79713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlChar *prefix; 79723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int nbargs = 0; 79733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 79743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor name = xmlXPathParseQName(ctxt, &prefix); 79753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (name == NULL) { 79763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XP_ERROR(XPATH_EXPR_ERROR); 79773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 79783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 79793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_EXPR 79803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (prefix == NULL) 79813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, "Calling function %s\n", 79823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor name); 79833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else 79843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, "Calling function %s:%s\n", 79853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor prefix, name); 79863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 79873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 79883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (CUR != '(') { 79893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XP_ERROR(XPATH_EXPR_ERROR); 79903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 79913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 79923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 79933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 79949e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard ctxt->comp->last = -1; 799571f9d7310c1f8c587f518ec685b1448160df7336Daniel Veillard if (CUR != ')') { 799671f9d7310c1f8c587f518ec685b1448160df7336Daniel Veillard while (CUR != 0) { 799771f9d7310c1f8c587f518ec685b1448160df7336Daniel Veillard int op1 = ctxt->comp->last; 799871f9d7310c1f8c587f518ec685b1448160df7336Daniel Veillard ctxt->comp->last = -1; 799971f9d7310c1f8c587f518ec685b1448160df7336Daniel Veillard xmlXPathCompileExpr(ctxt); 800071f9d7310c1f8c587f518ec685b1448160df7336Daniel Veillard CHECK_ERROR; 800171f9d7310c1f8c587f518ec685b1448160df7336Daniel Veillard PUSH_BINARY_EXPR(XPATH_OP_ARG, op1, ctxt->comp->last, 0, 0); 800271f9d7310c1f8c587f518ec685b1448160df7336Daniel Veillard nbargs++; 800371f9d7310c1f8c587f518ec685b1448160df7336Daniel Veillard if (CUR == ')') break; 800471f9d7310c1f8c587f518ec685b1448160df7336Daniel Veillard if (CUR != ',') { 800571f9d7310c1f8c587f518ec685b1448160df7336Daniel Veillard XP_ERROR(XPATH_EXPR_ERROR); 800671f9d7310c1f8c587f518ec685b1448160df7336Daniel Veillard } 800771f9d7310c1f8c587f518ec685b1448160df7336Daniel Veillard NEXT; 800871f9d7310c1f8c587f518ec685b1448160df7336Daniel Veillard SKIP_BLANKS; 80093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 80103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 80119e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard PUSH_LONG_EXPR(XPATH_OP_FUNCTION, nbargs, 0, 0, 80129e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard name, prefix); 80133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 80143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 80153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 80163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 80173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 8018afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompPrimaryExpr: 80193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 80203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 80213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [15] PrimaryExpr ::= VariableReference 80223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | '(' Expr ')' 80233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | Literal 80243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | Number 80253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | FunctionCall 80263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 8027afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile a primary expression. 80283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 8029afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void 8030afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompPrimaryExpr(xmlXPathParserContextPtr ctxt) { 80313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 8032afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard if (CUR == '$') xmlXPathCompVariableReference(ctxt); 80333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else if (CUR == '(') { 80343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 80353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 8036afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompileExpr(ctxt); 803750fe8b1732048003f47b32b009507fe6cdecd39fAleksey Sanin CHECK_ERROR; 80383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (CUR != ')') { 80393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XP_ERROR(XPATH_EXPR_ERROR); 80403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 80413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 80423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 8043d1757abcb891e01a9017f4aad041cc306d0d467bWilliam M. Brack } else if (IS_ASCII_DIGIT(CUR) || (CUR == '.' && IS_ASCII_DIGIT(NXT(1)))) { 8044afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompNumber(ctxt); 80453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else if ((CUR == '\'') || (CUR == '"')) { 8046afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompLiteral(ctxt); 80473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else { 8048afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompFunctionCall(ctxt); 80493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 80503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 80513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 80523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 80533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 8054afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompFilterExpr: 80553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 80563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 80573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [20] FilterExpr ::= PrimaryExpr 80583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | FilterExpr Predicate 80593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 8060afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile a filter expression. 80613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Square brackets are used to filter expressions in the same way that 80623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * they are used in location paths. It is an error if the expression to 80633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * be filtered does not evaluate to a node-set. The context node list 80643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * used for evaluating the expression in square brackets is the node-set 80653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * to be filtered listed in document order. 80663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 80673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 8068afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void 8069afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompFilterExpr(xmlXPathParserContextPtr ctxt) { 8070afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompPrimaryExpr(ctxt); 80713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ERROR; 80723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 80733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 80743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while (CUR == '[') { 8075d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard xmlXPathCompPredicate(ctxt, 1); 80763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 80773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 80783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 80793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 80803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 80813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 80823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 80833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathScanName: 80843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 80853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 80863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Trickery: parse an XML name but without consuming the input flow 80873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Needed to avoid insanity in the parser state. 80883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 80893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [4] NameChar ::= Letter | Digit | '.' | '-' | '_' | ':' | 80903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * CombiningChar | Extender 80913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 80923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [5] Name ::= (Letter | '_' | ':') (NameChar)* 80933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 80943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [6] Names ::= Name (S Name)* 80953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 80963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the Name parsed or NULL 80973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 80983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 809956a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic xmlChar * 81003473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathScanName(xmlXPathParserContextPtr ctxt) { 8101032268145fad72bbf00c944c1f6a067e5da4a1e0Daniel Veillard int len = 0, l; 8102032268145fad72bbf00c944c1f6a067e5da4a1e0Daniel Veillard int c; 8103032268145fad72bbf00c944c1f6a067e5da4a1e0Daniel Veillard const xmlChar *cur; 8104032268145fad72bbf00c944c1f6a067e5da4a1e0Daniel Veillard xmlChar *ret; 81053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 8106032268145fad72bbf00c944c1f6a067e5da4a1e0Daniel Veillard cur = ctxt->cur; 8107032268145fad72bbf00c944c1f6a067e5da4a1e0Daniel Veillard 8108032268145fad72bbf00c944c1f6a067e5da4a1e0Daniel Veillard c = CUR_CHAR(l); 8109032268145fad72bbf00c944c1f6a067e5da4a1e0Daniel Veillard if ((c == ' ') || (c == '>') || (c == '/') || /* accelerators */ 8110032268145fad72bbf00c944c1f6a067e5da4a1e0Daniel Veillard (!IS_LETTER(c) && (c != '_') && 8111032268145fad72bbf00c944c1f6a067e5da4a1e0Daniel Veillard (c != ':'))) { 81123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 81133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 81143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 8115032268145fad72bbf00c944c1f6a067e5da4a1e0Daniel Veillard while ((c != ' ') && (c != '>') && (c != '/') && /* test bigname.xml */ 8116032268145fad72bbf00c944c1f6a067e5da4a1e0Daniel Veillard ((IS_LETTER(c)) || (IS_DIGIT(c)) || 8117032268145fad72bbf00c944c1f6a067e5da4a1e0Daniel Veillard (c == '.') || (c == '-') || 8118032268145fad72bbf00c944c1f6a067e5da4a1e0Daniel Veillard (c == '_') || (c == ':') || 8119032268145fad72bbf00c944c1f6a067e5da4a1e0Daniel Veillard (IS_COMBINING(c)) || 8120032268145fad72bbf00c944c1f6a067e5da4a1e0Daniel Veillard (IS_EXTENDER(c)))) { 8121032268145fad72bbf00c944c1f6a067e5da4a1e0Daniel Veillard len += l; 8122032268145fad72bbf00c944c1f6a067e5da4a1e0Daniel Veillard NEXTL(l); 8123032268145fad72bbf00c944c1f6a067e5da4a1e0Daniel Veillard c = CUR_CHAR(l); 81243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 8125032268145fad72bbf00c944c1f6a067e5da4a1e0Daniel Veillard ret = xmlStrndup(cur, ctxt->cur - cur); 8126032268145fad72bbf00c944c1f6a067e5da4a1e0Daniel Veillard ctxt->cur = cur; 8127032268145fad72bbf00c944c1f6a067e5da4a1e0Daniel Veillard return(ret); 81283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 81293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 81303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 8131afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompPathExpr: 81323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 81333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 81343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [19] PathExpr ::= LocationPath 81353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | FilterExpr 81363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | FilterExpr '/' RelativeLocationPath 81373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | FilterExpr '//' RelativeLocationPath 81383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 8139afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile a path expression. 81403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The / operator and // operators combine an arbitrary expression 81413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * and a relative location path. It is an error if the expression 81423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * does not evaluate to a node-set. 81433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The / operator does composition in the same way as when / is 81443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * used in a location path. As in location paths, // is short for 81453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * /descendant-or-self::node()/. 81463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 81473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 8148afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void 8149afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompPathExpr(xmlXPathParserContextPtr ctxt) { 81503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int lc = 1; /* Should we branch to LocationPath ? */ 81513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlChar *name = NULL; /* we may have to preparse a name to find out */ 81523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 81533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 8154d1757abcb891e01a9017f4aad041cc306d0d467bWilliam M. Brack if ((CUR == '$') || (CUR == '(') || 8155d1757abcb891e01a9017f4aad041cc306d0d467bWilliam M. Brack (IS_ASCII_DIGIT(CUR)) || 8156d1757abcb891e01a9017f4aad041cc306d0d467bWilliam M. Brack (CUR == '\'') || (CUR == '"') || 8157d1757abcb891e01a9017f4aad041cc306d0d467bWilliam M. Brack (CUR == '.' && IS_ASCII_DIGIT(NXT(1)))) { 81583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor lc = 0; 81593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else if (CUR == '*') { 81603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* relative or absolute location path */ 81613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor lc = 1; 81623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else if (CUR == '/') { 81633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* relative or absolute location path */ 81643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor lc = 1; 81653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else if (CUR == '@') { 81663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* relative abbreviated attribute location path */ 81673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor lc = 1; 81683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else if (CUR == '.') { 81693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* relative abbreviated attribute location path */ 81703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor lc = 1; 81713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else { 81723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 81733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Problem is finding if we have a name here whether it's: 81743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * - a nodetype 81753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * - a function call in which case it's followed by '(' 81763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * - an axis in which case it's followed by ':' 81773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * - a element name 81783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * We do an a priori analysis here rather than having to 81793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * maintain parsed token content through the recursive function 8180081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack * calls. This looks uglier but makes the code easier to 81813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * read/write/debug. 81823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 81833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 81843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor name = xmlXPathScanName(ctxt); 81853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((name != NULL) && (xmlStrstr(name, (xmlChar *) "::") != NULL)) { 81863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_STEP 81873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 81883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "PathExpr: Axis\n"); 81893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 81903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor lc = 1; 81913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(name); 81923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else if (name != NULL) { 81933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int len =xmlStrlen(name); 81943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 81953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 81963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while (NXT(len) != 0) { 81973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (NXT(len) == '/') { 81983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* element name */ 81993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_STEP 82003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 82013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "PathExpr: AbbrRelLocation\n"); 82023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 82033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor lc = 1; 82043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 820576e95df05556c9610b564b14cf578c8f9e34c9c1William M. Brack } else if (IS_BLANK_CH(NXT(len))) { 820678637da0ea1c833dfdfad87a9aa5bea14510d08aWilliam M. Brack /* ignore blanks */ 820778637da0ea1c833dfdfad87a9aa5bea14510d08aWilliam M. Brack ; 82083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else if (NXT(len) == ':') { 82093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_STEP 82103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 82113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "PathExpr: AbbrRelLocation\n"); 82123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 82133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor lc = 1; 82143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 82153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else if ((NXT(len) == '(')) { 82163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* Note Type or Function */ 82173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (xmlXPathIsNodeType(name)) { 82183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_STEP 82193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 82203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "PathExpr: Type search\n"); 82213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 82223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor lc = 1; 82233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else { 82243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_STEP 82253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 82263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "PathExpr: function call\n"); 82273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 82283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor lc = 0; 82293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 82303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 82313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else if ((NXT(len) == '[')) { 82323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* element name */ 82333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_STEP 82343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 82353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "PathExpr: AbbrRelLocation\n"); 82363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 82373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor lc = 1; 82383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 82393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else if ((NXT(len) == '<') || (NXT(len) == '>') || 82403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor (NXT(len) == '=')) { 82413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor lc = 1; 82423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 82433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else { 82443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor lc = 1; 82453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 82463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 82473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor len++; 82483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 82493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (NXT(len) == 0) { 82503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_STEP 82513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 82523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "PathExpr: AbbrRelLocation\n"); 82533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 82543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* element name */ 82553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor lc = 1; 82563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 82573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(name); 82583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else { 8259081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack /* make sure all cases are covered explicitly */ 82603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XP_ERROR(XPATH_EXPR_ERROR); 82613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 82623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 82633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 82643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (lc) { 82659e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (CUR == '/') { 82669e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard PUSH_LEAVE_EXPR(XPATH_OP_ROOT, 0, 0); 82679e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } else { 82689e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard PUSH_LEAVE_EXPR(XPATH_OP_NODE, 0, 0); 82693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 8270afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompLocationPath(ctxt); 82713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else { 8272afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompFilterExpr(ctxt); 82733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ERROR; 82743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((CUR == '/') && (NXT(1) == '/')) { 82753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP(2); 82763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 82779e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 82789e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard PUSH_LONG_EXPR(XPATH_OP_COLLECT, AXIS_DESCENDANT_OR_SELF, 82799e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard NODE_TEST_TYPE, NODE_TYPE_NODE, NULL, NULL); 82809e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard PUSH_UNARY_EXPR(XPATH_OP_RESET, ctxt->comp->last, 1, 0); 82819e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 8282afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompRelativeLocationPath(ctxt); 82833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else if (CUR == '/') { 8284afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompRelativeLocationPath(ctxt); 82853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 82863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 82873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 82883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 82893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 82903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 8291afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompUnionExpr: 82923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 82933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 82943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [18] UnionExpr ::= PathExpr 82953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | UnionExpr '|' PathExpr 82963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 8297afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile an union expression. 82983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 82993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 8300afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void 8301afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompUnionExpr(xmlXPathParserContextPtr ctxt) { 8302afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompPathExpr(ctxt); 83033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ERROR; 83043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 83053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while (CUR == '|') { 83069e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard int op1 = ctxt->comp->last; 83079e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard PUSH_LEAVE_EXPR(XPATH_OP_NODE, 0, 0); 83083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 83093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 83103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 8311afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompPathExpr(ctxt); 83123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 83139e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard PUSH_BINARY_EXPR(XPATH_OP_UNION, op1, ctxt->comp->last, 0, 0); 83149e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 83153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 83163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 83173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 83183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 83193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 8320afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompUnaryExpr: 83213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 83223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 83233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [27] UnaryExpr ::= UnionExpr 83243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | '-' UnaryExpr 83253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 8326afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile an unary expression. 83273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 83283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 8329afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void 8330afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompUnaryExpr(xmlXPathParserContextPtr ctxt) { 83313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int minus = 0; 83329e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard int found = 0; 83333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 83343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 833568d7b67ada0941ad7e1d02602f48de4015a67af3Daniel Veillard while (CUR == '-') { 833668d7b67ada0941ad7e1d02602f48de4015a67af3Daniel Veillard minus = 1 - minus; 83379e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard found = 1; 83383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 83393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 83403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 83419e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 8342afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompUnionExpr(ctxt); 83433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ERROR; 83449e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (found) { 83459e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (minus) 83469e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard PUSH_UNARY_EXPR(XPATH_OP_PLUS, ctxt->comp->last, 2, 0); 83479e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard else 83489e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard PUSH_UNARY_EXPR(XPATH_OP_PLUS, ctxt->comp->last, 3, 0); 83493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 83503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 83513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 83523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 8353afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompMultiplicativeExpr: 83543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 83553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 83563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [26] MultiplicativeExpr ::= UnaryExpr 83573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | MultiplicativeExpr MultiplyOperator UnaryExpr 83583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | MultiplicativeExpr 'div' UnaryExpr 83593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | MultiplicativeExpr 'mod' UnaryExpr 83603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [34] MultiplyOperator ::= '*' 83613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 8362afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile an Additive expression. 83633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 83643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 8365afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void 8366afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompMultiplicativeExpr(xmlXPathParserContextPtr ctxt) { 8367afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompUnaryExpr(ctxt); 83683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ERROR; 83693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 83703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while ((CUR == '*') || 83713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ((CUR == 'd') && (NXT(1) == 'i') && (NXT(2) == 'v')) || 83723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ((CUR == 'm') && (NXT(1) == 'o') && (NXT(2) == 'd'))) { 83733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int op = -1; 83749e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard int op1 = ctxt->comp->last; 83753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 83763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (CUR == '*') { 83773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor op = 0; 83783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 83793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else if (CUR == 'd') { 83803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor op = 1; 83813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP(3); 83823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else if (CUR == 'm') { 83833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor op = 2; 83843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP(3); 83853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 83863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 8387afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompUnaryExpr(ctxt); 83883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ERROR; 83899e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard PUSH_BINARY_EXPR(XPATH_OP_MULT, op1, ctxt->comp->last, op, 0); 83903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 83913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 83923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 83933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 83943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 8395afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompAdditiveExpr: 83963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 83973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 83983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [25] AdditiveExpr ::= MultiplicativeExpr 83993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | AdditiveExpr '+' MultiplicativeExpr 84003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | AdditiveExpr '-' MultiplicativeExpr 84013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 8402afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile an Additive expression. 84033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 84043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 8405afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void 8406afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompAdditiveExpr(xmlXPathParserContextPtr ctxt) { 84079e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 8408afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompMultiplicativeExpr(ctxt); 84093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ERROR; 84103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 84113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while ((CUR == '+') || (CUR == '-')) { 84123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int plus; 84139e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard int op1 = ctxt->comp->last; 84143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 84153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (CUR == '+') plus = 1; 84163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else plus = 0; 84173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 84183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 8419afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompMultiplicativeExpr(ctxt); 84203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ERROR; 84219e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard PUSH_BINARY_EXPR(XPATH_OP_PLUS, op1, ctxt->comp->last, plus, 0); 84223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 84233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 84243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 84253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 84263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 8427afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompRelationalExpr: 84283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 84293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 84303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [24] RelationalExpr ::= AdditiveExpr 84313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | RelationalExpr '<' AdditiveExpr 84323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | RelationalExpr '>' AdditiveExpr 84333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | RelationalExpr '<=' AdditiveExpr 84343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | RelationalExpr '>=' AdditiveExpr 84353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 84363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * A <= B > C is allowed ? Answer from James, yes with 84373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * (AdditiveExpr <= AdditiveExpr) > AdditiveExpr 84383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * which is basically what got implemented. 84393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 8440afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile a Relational expression, then push the result 84413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * on the stack 84423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 84433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 8444afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void 8445afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompRelationalExpr(xmlXPathParserContextPtr ctxt) { 8446afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompAdditiveExpr(ctxt); 84473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ERROR; 84483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 84493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while ((CUR == '<') || 84503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor (CUR == '>') || 84513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ((CUR == '<') && (NXT(1) == '=')) || 84523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ((CUR == '>') && (NXT(1) == '='))) { 84539e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard int inf, strict; 84549e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard int op1 = ctxt->comp->last; 84553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 84563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (CUR == '<') inf = 1; 84573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else inf = 0; 84583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (NXT(1) == '=') strict = 0; 84593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else strict = 1; 84603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 84613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (!strict) NEXT; 84623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 8463afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompAdditiveExpr(ctxt); 84643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ERROR; 84659e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard PUSH_BINARY_EXPR(XPATH_OP_CMP, op1, ctxt->comp->last, inf, strict); 84663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 84673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 84683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 84693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 84703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 8471afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompEqualityExpr: 84723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 84733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 84743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [23] EqualityExpr ::= RelationalExpr 84753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | EqualityExpr '=' RelationalExpr 84763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | EqualityExpr '!=' RelationalExpr 84773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 84783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * A != B != C is allowed ? Answer from James, yes with 84793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * (RelationalExpr = RelationalExpr) = RelationalExpr 84803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * (RelationalExpr != RelationalExpr) != RelationalExpr 84813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * which is basically what got implemented. 84823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 8483afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile an Equality expression. 84843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 84853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 8486afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void 8487afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompEqualityExpr(xmlXPathParserContextPtr ctxt) { 8488afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompRelationalExpr(ctxt); 84893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ERROR; 84903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 84913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while ((CUR == '=') || ((CUR == '!') && (NXT(1) == '='))) { 84929e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard int eq; 84939e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard int op1 = ctxt->comp->last; 84943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 84953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (CUR == '=') eq = 1; 84963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else eq = 0; 84973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 84983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (!eq) NEXT; 84993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 8500afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompRelationalExpr(ctxt); 85013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ERROR; 85029e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard PUSH_BINARY_EXPR(XPATH_OP_EQUAL, op1, ctxt->comp->last, eq, 0); 85033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 85043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 85053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 85063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 85073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 8508afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompAndExpr: 85093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 85103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 85113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [22] AndExpr ::= EqualityExpr 85123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | AndExpr 'and' EqualityExpr 85133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 8514afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile an AND expression. 85153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 85163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 8517afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void 8518afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompAndExpr(xmlXPathParserContextPtr ctxt) { 8519afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompEqualityExpr(ctxt); 85203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ERROR; 85213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 85223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while ((CUR == 'a') && (NXT(1) == 'n') && (NXT(2) == 'd')) { 85239e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard int op1 = ctxt->comp->last; 85243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP(3); 85253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 8526afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompEqualityExpr(ctxt); 85273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ERROR; 85289e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard PUSH_BINARY_EXPR(XPATH_OP_AND, op1, ctxt->comp->last, 0, 0); 85293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 85303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 85313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 85323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 85333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 8534591b4be0fe1986b5e71d54c5c063493987ef4285Daniel Veillard * xmlXPathCompileExpr: 85353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 85363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 85373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [14] Expr ::= OrExpr 85383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [21] OrExpr ::= AndExpr 85393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | OrExpr 'or' AndExpr 85403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 8541afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Parse and compile an expression 85423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 8543afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void 8544afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompileExpr(xmlXPathParserContextPtr ctxt) { 8545afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompAndExpr(ctxt); 85463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ERROR; 85473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 85483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while ((CUR == 'o') && (NXT(1) == 'r')) { 85499e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard int op1 = ctxt->comp->last; 85503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP(2); 85513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 8552afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompAndExpr(ctxt); 85533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ERROR; 85549e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard PUSH_BINARY_EXPR(XPATH_OP_OR, op1, ctxt->comp->last, 0, 0); 85559e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard op1 = ctxt->comp->nbStep; 85563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 85573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 85589e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (ctxt->comp->steps[ctxt->comp->last].op != XPATH_OP_VALUE) { 85599e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard /* more ops could be optimized too */ 85609e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard PUSH_UNARY_EXPR(XPATH_OP_SORT, ctxt->comp->last , 0, 0); 85619e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } 85623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 85633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 85643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 8565afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompPredicate: 85663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 8567d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * @filter: act as a filter 85683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 85693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [8] Predicate ::= '[' PredicateExpr ']' 85703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [9] PredicateExpr ::= Expr 85713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 8572afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile a predicate expression 85739e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard */ 8574afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void 8575d8df6c0e8c883e1d618388d266015dda36731440Daniel VeillardxmlXPathCompPredicate(xmlXPathParserContextPtr ctxt, int filter) { 85769e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard int op1 = ctxt->comp->last; 85779e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 85789e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard SKIP_BLANKS; 85799e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (CUR != '[') { 85809e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard XP_ERROR(XPATH_INVALID_PREDICATE_ERROR); 85819e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } 85829e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard NEXT; 85839e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard SKIP_BLANKS; 85849e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 85859e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard ctxt->comp->last = -1; 8586afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompileExpr(ctxt); 85879e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard CHECK_ERROR; 85889e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 85899e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (CUR != ']') { 85909e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard XP_ERROR(XPATH_INVALID_PREDICATE_ERROR); 85919e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } 85929e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 8593d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard if (filter) 8594d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard PUSH_BINARY_EXPR(XPATH_OP_FILTER, op1, ctxt->comp->last, 0, 0); 8595d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard else 8596d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard PUSH_BINARY_EXPR(XPATH_OP_PREDICATE, op1, ctxt->comp->last, 0, 0); 85979e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 85989e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard NEXT; 85999e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard SKIP_BLANKS; 86009e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard} 86019e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 86029e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard/** 8603afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompNodeTest: 86043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 86053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @test: pointer to a xmlXPathTestVal 86063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @type: pointer to a xmlXPathTypeVal 86073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @prefix: placeholder for a possible name prefix 86083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 86093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [7] NodeTest ::= NameTest 86103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | NodeType '(' ')' 86113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | 'processing-instruction' '(' Literal ')' 86123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 86133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [37] NameTest ::= '*' 86143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | NCName ':' '*' 86153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | QName 86163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [38] NodeType ::= 'comment' 86173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | 'text' 86183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | 'processing-instruction' 86193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | 'node' 86203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 8621081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack * Returns the name found and updates @test, @type and @prefix appropriately 86223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 862356a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic xmlChar * 8624afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompNodeTest(xmlXPathParserContextPtr ctxt, xmlXPathTestVal *test, 8625afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathTypeVal *type, const xmlChar **prefix, 8626afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlChar *name) { 86273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int blanks; 86283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 86293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((test == NULL) || (type == NULL) || (prefix == NULL)) { 86303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor STRANGE; 86313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 86323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 863378637da0ea1c833dfdfad87a9aa5bea14510d08aWilliam M. Brack *type = (xmlXPathTypeVal) 0; 863478637da0ea1c833dfdfad87a9aa5bea14510d08aWilliam M. Brack *test = (xmlXPathTestVal) 0; 86353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *prefix = NULL; 86363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 86373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 86383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((name == NULL) && (CUR == '*')) { 86393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 86403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * All elements 86413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 86423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 86433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *test = NODE_TEST_ALL; 86443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 86453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 86463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 86473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (name == NULL) 86483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor name = xmlXPathParseNCName(ctxt); 86493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (name == NULL) { 86503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XP_ERROR0(XPATH_EXPR_ERROR); 86513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 86523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 865376e95df05556c9610b564b14cf578c8f9e34c9c1William M. Brack blanks = IS_BLANK_CH(CUR); 86543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 86553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (CUR == '(') { 86563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 86573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 86583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * NodeType or PI search 86593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 86603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (xmlStrEqual(name, BAD_CAST "comment")) 86613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *type = NODE_TYPE_COMMENT; 86623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else if (xmlStrEqual(name, BAD_CAST "node")) 86633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *type = NODE_TYPE_NODE; 86643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else if (xmlStrEqual(name, BAD_CAST "processing-instruction")) 86653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *type = NODE_TYPE_PI; 86663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else if (xmlStrEqual(name, BAD_CAST "text")) 86673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *type = NODE_TYPE_TEXT; 86683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else { 86693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (name != NULL) 86703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(name); 86713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XP_ERROR0(XPATH_EXPR_ERROR); 86723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 86733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 86743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *test = NODE_TEST_TYPE; 86753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 86763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 86773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (*type == NODE_TYPE_PI) { 86783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 86793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Specific case: search a PI by name. 86803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 86813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (name != NULL) 86823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(name); 868382e4971dc2f470c9b6f19cf8b15ff32781067167Daniel Veillard name = NULL; 868482e4971dc2f470c9b6f19cf8b15ff32781067167Daniel Veillard if (CUR != ')') { 868582e4971dc2f470c9b6f19cf8b15ff32781067167Daniel Veillard name = xmlXPathParseLiteral(ctxt); 868682e4971dc2f470c9b6f19cf8b15ff32781067167Daniel Veillard CHECK_ERROR 0; 8687ed23b7dc73f6c1146701ece20ed3f03d68366516Daniel Veillard *test = NODE_TEST_PI; 868882e4971dc2f470c9b6f19cf8b15ff32781067167Daniel Veillard SKIP_BLANKS; 868982e4971dc2f470c9b6f19cf8b15ff32781067167Daniel Veillard } 86903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 86913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (CUR != ')') { 86923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (name != NULL) 86933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(name); 86943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XP_ERROR0(XPATH_UNCLOSED_ERROR); 86953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 86963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 86973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(name); 86983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 86993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *test = NODE_TEST_NAME; 87003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((!blanks) && (CUR == ':')) { 87013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 87023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 87033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 8704fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * Since currently the parser context don't have a 8705fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * namespace list associated: 8706fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * The namespace name for this prefix can be computed 8707fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * only at evaluation time. The compilation is done 8708fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * outside of any context. 87093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 8710fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard#if 0 87113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *prefix = xmlXPathNsLookup(ctxt->context, name); 87123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (name != NULL) 87133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(name); 87143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (*prefix == NULL) { 87153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XP_ERROR0(XPATH_UNDEF_PREFIX_ERROR); 87163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 8717fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard#else 8718fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard *prefix = name; 8719fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard#endif 87203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 87213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (CUR == '*') { 87223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 87233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * All elements 87243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 87253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 87263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *test = NODE_TEST_ALL; 87273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 87283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 87293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 87303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor name = xmlXPathParseNCName(ctxt); 87313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (name == NULL) { 87323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XP_ERROR0(XPATH_EXPR_ERROR); 87333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 87343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 87353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(name); 87363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 87373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 87383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 87393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathIsAxisName: 87403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @name: a preparsed name token 87413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 87423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [6] AxisName ::= 'ancestor' 87433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | 'ancestor-or-self' 87443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | 'attribute' 87453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | 'child' 87463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | 'descendant' 87473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | 'descendant-or-self' 87483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | 'following' 87493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | 'following-sibling' 87503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | 'namespace' 87513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | 'parent' 87523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | 'preceding' 87533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | 'preceding-sibling' 87543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | 'self' 87553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 87563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the axis or 0 87573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 875856a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic xmlXPathAxisVal 87593473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathIsAxisName(const xmlChar *name) { 876078637da0ea1c833dfdfad87a9aa5bea14510d08aWilliam M. Brack xmlXPathAxisVal ret = (xmlXPathAxisVal) 0; 87613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor switch (name[0]) { 87623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case 'a': 87633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (xmlStrEqual(name, BAD_CAST "ancestor")) 87643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = AXIS_ANCESTOR; 87653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (xmlStrEqual(name, BAD_CAST "ancestor-or-self")) 87663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = AXIS_ANCESTOR_OR_SELF; 87673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (xmlStrEqual(name, BAD_CAST "attribute")) 87683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = AXIS_ATTRIBUTE; 87693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 87703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case 'c': 87713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (xmlStrEqual(name, BAD_CAST "child")) 87723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = AXIS_CHILD; 87733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 87743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case 'd': 87753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (xmlStrEqual(name, BAD_CAST "descendant")) 87763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = AXIS_DESCENDANT; 87773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (xmlStrEqual(name, BAD_CAST "descendant-or-self")) 87783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = AXIS_DESCENDANT_OR_SELF; 87793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 87803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case 'f': 87813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (xmlStrEqual(name, BAD_CAST "following")) 87823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = AXIS_FOLLOWING; 87833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (xmlStrEqual(name, BAD_CAST "following-sibling")) 87843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = AXIS_FOLLOWING_SIBLING; 87853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 87863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case 'n': 87873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (xmlStrEqual(name, BAD_CAST "namespace")) 87883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = AXIS_NAMESPACE; 87893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 87903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case 'p': 87913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (xmlStrEqual(name, BAD_CAST "parent")) 87923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = AXIS_PARENT; 87933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (xmlStrEqual(name, BAD_CAST "preceding")) 87943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = AXIS_PRECEDING; 87953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (xmlStrEqual(name, BAD_CAST "preceding-sibling")) 87963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = AXIS_PRECEDING_SIBLING; 87973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 87983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case 's': 87993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (xmlStrEqual(name, BAD_CAST "self")) 88003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = AXIS_SELF; 88013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 88023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 88033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ret); 88043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 88053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 88063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 8807afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompStep: 88083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 88093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 88103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [4] Step ::= AxisSpecifier NodeTest Predicate* 88113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | AbbreviatedStep 88123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 88133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [12] AbbreviatedStep ::= '.' | '..' 88143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 88153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [5] AxisSpecifier ::= AxisName '::' 88163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | AbbreviatedAxisSpecifier 88173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 88183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [13] AbbreviatedAxisSpecifier ::= '@'? 88193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 88203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Modified for XPtr range support as: 88213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 88223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [4xptr] Step ::= AxisSpecifier NodeTest Predicate* 88233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | AbbreviatedStep 88243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | 'range-to' '(' Expr ')' Predicate* 88253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 8826afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile one step in a Location Path 88273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * A location step of . is short for self::node(). This is 88283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * particularly useful in conjunction with //. For example, the 88293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * location path .//para is short for 88303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * self::node()/descendant-or-self::node()/child::para 88313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * and so will select all para descendant elements of the context 88323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * node. 88333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Similarly, a location step of .. is short for parent::node(). 88343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * For example, ../title is short for parent::node()/child::title 88353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * and so will select the title children of the parent of the context 88363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * node. 88373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 8838afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void 8839afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompStep(xmlXPathParserContextPtr ctxt) { 8840fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard#ifdef LIBXML_XPTR_ENABLED 8841fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard int rangeto = 0; 8842fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard int op2 = -1; 8843fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard#endif 8844fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard 88453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 88463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((CUR == '.') && (NXT(1) == '.')) { 88473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP(2); 88483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 88499e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard PUSH_LONG_EXPR(XPATH_OP_COLLECT, AXIS_PARENT, 88509e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard NODE_TEST_TYPE, NODE_TYPE_NODE, NULL, NULL); 88513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else if (CUR == '.') { 88523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 88533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 88543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else { 88553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlChar *name = NULL; 88563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor const xmlChar *prefix = NULL; 88573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathTestVal test; 885878637da0ea1c833dfdfad87a9aa5bea14510d08aWilliam M. Brack xmlXPathAxisVal axis = (xmlXPathAxisVal) 0; 88593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathTypeVal type; 8860d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard int op1; 88613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 88623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 88633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The modification needed for XPointer change to the production 88643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 88653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef LIBXML_XPTR_ENABLED 8866fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard if (ctxt->xptr) { 88673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor name = xmlXPathParseNCName(ctxt); 88683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((name != NULL) && (xmlStrEqual(name, BAD_CAST "range-to"))) { 8869fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard op2 = ctxt->comp->last; 88703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(name); 88713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 88723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (CUR != '(') { 88733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XP_ERROR(XPATH_EXPR_ERROR); 88743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 88753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 88763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 88773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 8878afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompileExpr(ctxt); 8879fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard /* PUSH_BINARY_EXPR(XPATH_OP_RANGETO, op2, ctxt->comp->last, 0, 0); */ 88803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ERROR; 88813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 88823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 88833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (CUR != ')') { 88843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XP_ERROR(XPATH_EXPR_ERROR); 88853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 88863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 8887fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard rangeto = 1; 88883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor goto eval_predicates; 88893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 88903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 88913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 88922156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard if (CUR == '*') { 88932156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard axis = AXIS_CHILD; 88942156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard } else { 88952156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard if (name == NULL) 88962156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard name = xmlXPathParseNCName(ctxt); 88972156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard if (name != NULL) { 88982156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard axis = xmlXPathIsAxisName(name); 88992156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard if (axis != 0) { 89002156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard SKIP_BLANKS; 89012156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard if ((CUR == ':') && (NXT(1) == ':')) { 89022156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard SKIP(2); 89032156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard xmlFree(name); 89042156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard name = NULL; 89052156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard } else { 89062156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard /* an element name can conflict with an axis one :-\ */ 89072156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard axis = AXIS_CHILD; 89082156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard } 89093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else { 89103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor axis = AXIS_CHILD; 89113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 89122156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard } else if (CUR == '@') { 89132156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard NEXT; 89142156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard axis = AXIS_ATTRIBUTE; 89153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else { 89162156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard axis = AXIS_CHILD; 89173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 89183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 89193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 89203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ERROR; 89213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 8922afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard name = xmlXPathCompNodeTest(ctxt, &test, &type, &prefix, name); 89233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (test == 0) 89243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return; 89253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 89263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_STEP 89273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 89283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "Basis : computing new set\n"); 89293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 89309e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 89313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_STEP 89323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, "Basis : "); 8933fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard if (ctxt->value == NULL) 8934fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard xmlGenericError(xmlGenericErrorContext, "no value\n"); 8935fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard else if (ctxt->value->nodesetval == NULL) 8936fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard xmlGenericError(xmlGenericErrorContext, "Empty\n"); 8937fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard else 8938fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard xmlGenericErrorContextNodeSet(stdout, ctxt->value->nodesetval); 89393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 89403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 89415bb9ccd56a812b65e94e71477389be7826203649Daniel Veillard#ifdef LIBXML_XPTR_ENABLED 89423473f88a7abdf4e585e267288fb77e898c580d2bOwen Tayloreval_predicates: 89435bb9ccd56a812b65e94e71477389be7826203649Daniel Veillard#endif 8944d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard op1 = ctxt->comp->last; 8945d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard ctxt->comp->last = -1; 8946d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard 89473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 89483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while (CUR == '[') { 8949d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard xmlXPathCompPredicate(ctxt, 0); 89503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 8951d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard 8952fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard#ifdef LIBXML_XPTR_ENABLED 8953fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard if (rangeto) { 8954fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard PUSH_BINARY_EXPR(XPATH_OP_RANGETO, op2, op1, 0, 0); 8955fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard } else 8956fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard#endif 8957fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard PUSH_FULL_EXPR(XPATH_OP_COLLECT, op1, ctxt->comp->last, axis, 8958fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard test, type, (void *)prefix, (void *)name); 8959d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard 89603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 89613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_STEP 89623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, "Step : "); 8963fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard if (ctxt->value == NULL) 8964fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard xmlGenericError(xmlGenericErrorContext, "no value\n"); 8965fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard else if (ctxt->value->nodesetval == NULL) 8966fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard xmlGenericError(xmlGenericErrorContext, "Empty\n"); 8967fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard else 8968fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard xmlGenericErrorContextNodeSet(xmlGenericErrorContext, 8969fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard ctxt->value->nodesetval); 89703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 89713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 89723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 89733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 8974afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompRelativeLocationPath: 89753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 89763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 89773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [3] RelativeLocationPath ::= Step 89783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | RelativeLocationPath '/' Step 89793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | AbbreviatedRelativeLocationPath 89803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [11] AbbreviatedRelativeLocationPath ::= RelativeLocationPath '//' Step 89813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 8982afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile a relative location path. 89833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 8984afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void 8985afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompRelativeLocationPath 89863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor(xmlXPathParserContextPtr ctxt) { 89873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 89883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((CUR == '/') && (NXT(1) == '/')) { 89893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP(2); 89903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 89919e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard PUSH_LONG_EXPR(XPATH_OP_COLLECT, AXIS_DESCENDANT_OR_SELF, 89929e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard NODE_TEST_TYPE, NODE_TYPE_NODE, NULL, NULL); 89933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else if (CUR == '/') { 89943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 89953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 89963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 8997afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompStep(ctxt); 89983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 89993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while (CUR == '/') { 90003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((CUR == '/') && (NXT(1) == '/')) { 90013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP(2); 90023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 90039e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard PUSH_LONG_EXPR(XPATH_OP_COLLECT, AXIS_DESCENDANT_OR_SELF, 90043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NODE_TEST_TYPE, NODE_TYPE_NODE, NULL, NULL); 9005afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompStep(ctxt); 90063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else if (CUR == '/') { 90073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 90083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 9009afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompStep(ctxt); 90103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 90113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 90123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 90133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 90143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 90153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 9016afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompLocationPath: 90173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 90183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 90193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [1] LocationPath ::= RelativeLocationPath 90203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | AbsoluteLocationPath 90213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [2] AbsoluteLocationPath ::= '/' RelativeLocationPath? 90223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | AbbreviatedAbsoluteLocationPath 90233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [10] AbbreviatedAbsoluteLocationPath ::= 90243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * '//' RelativeLocationPath 90253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 9026afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile a location path 9027afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * 90283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * // is short for /descendant-or-self::node()/. For example, 90293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * //para is short for /descendant-or-self::node()/child::para and 90303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * so will select any para element in the document (even a para element 90313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * that is a document element will be selected by //para since the 90323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * document element node is a child of the root node); div//para is 90333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * short for div/descendant-or-self::node()/child::para and so will 90343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * select all para descendants of div children. 90353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 9036afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void 9037afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompLocationPath(xmlXPathParserContextPtr ctxt) { 90383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 90393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (CUR != '/') { 9040afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompRelativeLocationPath(ctxt); 90413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else { 90423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while (CUR == '/') { 90433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((CUR == '/') && (NXT(1) == '/')) { 90443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP(2); 90453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 90469e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard PUSH_LONG_EXPR(XPATH_OP_COLLECT, AXIS_DESCENDANT_OR_SELF, 90479e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard NODE_TEST_TYPE, NODE_TYPE_NODE, NULL, NULL); 9048afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompRelativeLocationPath(ctxt); 90493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else if (CUR == '/') { 90503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 9051608ad0791b3b35072c8021ea4f66cf9d700394b9Daniel Veillard SKIP_BLANKS; 9052608ad0791b3b35072c8021ea4f66cf9d700394b9Daniel Veillard if ((CUR != 0 ) && 9053d1757abcb891e01a9017f4aad041cc306d0d467bWilliam M. Brack ((IS_ASCII_LETTER(CUR)) || (CUR == '_') || (CUR == '.') || 9054608ad0791b3b35072c8021ea4f66cf9d700394b9Daniel Veillard (CUR == '@') || (CUR == '*'))) 9055afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompRelativeLocationPath(ctxt); 90563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 90573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 90583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 90593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 90603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 90619e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard/************************************************************************ 90629e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * * 90639e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * XPath precompiled expression evaluation * 90649e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * * 90659e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard ************************************************************************/ 90669e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 9067f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillardstatic int 9068d8df6c0e8c883e1d618388d266015dda36731440Daniel VeillardxmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op); 9069d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard 90709e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard/** 9071d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * xmlXPathNodeCollectAndTest: 9072d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * @ctxt: the XPath Parser context 9073d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * @op: the XPath precompiled step operation 9074f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * @first: pointer to the first element in document order 9075f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * @last: pointer to the last element in document order 90769e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * 9077d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * This is the function implementing a step: based on the current list 9078d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * of nodes, it builds up a new list, looking at all nodes under that 9079081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack * axis and selecting them. It also does the predicate filtering 9080d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * 9081d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * Pushes the new NodeSet resulting from the search. 9082f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * 9083081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack * Returns the number of nodes traversed 90849e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard */ 9085f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillardstatic int 9086d8df6c0e8c883e1d618388d266015dda36731440Daniel VeillardxmlXPathNodeCollectAndTest(xmlXPathParserContextPtr ctxt, 9087f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathStepOpPtr op, 9088f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlNodePtr * first, xmlNodePtr * last) 9089f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard{ 909078637da0ea1c833dfdfad87a9aa5bea14510d08aWilliam M. Brack xmlXPathAxisVal axis = (xmlXPathAxisVal) op->value; 909178637da0ea1c833dfdfad87a9aa5bea14510d08aWilliam M. Brack xmlXPathTestVal test = (xmlXPathTestVal) op->value2; 909278637da0ea1c833dfdfad87a9aa5bea14510d08aWilliam M. Brack xmlXPathTypeVal type = (xmlXPathTypeVal) op->value3; 9093d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard const xmlChar *prefix = op->value4; 9094d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard const xmlChar *name = op->value5; 9095e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard const xmlChar *URI = NULL; 90969e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 9097d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP 9098f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard int n = 0; 9099d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif 9100f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard int i, t = 0; 9101d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard xmlNodeSetPtr ret, list; 9102d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard xmlXPathTraversalFunction next = NULL; 9103f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard void (*addNode) (xmlNodeSetPtr, xmlNodePtr); 910475be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard xmlNodeSetPtr (*mergeNodeSet) (xmlNodeSetPtr, xmlNodeSetPtr); 9105d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard xmlNodePtr cur = NULL; 9106d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard xmlXPathObjectPtr obj; 9107d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard xmlNodeSetPtr nodelist; 9108d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard xmlNodePtr tmp; 9109d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard 9110f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard CHECK_TYPE0(XPATH_NODESET); 9111d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard obj = valuePop(ctxt); 9112d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard addNode = xmlXPathNodeSetAdd; 911375be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard mergeNodeSet = xmlXPathNodeSetMerge; 9114e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard if (prefix != NULL) { 9115f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard URI = xmlXPathNsLookup(ctxt->context, prefix); 91162c19a7bf2ee0f78485840cac50f2a989f5efe476William M. Brack if (URI == NULL) { 91172c19a7bf2ee0f78485840cac50f2a989f5efe476William M. Brack xmlXPathFreeObject(obj); 9118f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard XP_ERROR0(XPATH_UNDEF_PREFIX_ERROR); 91192c19a7bf2ee0f78485840cac50f2a989f5efe476William M. Brack } 9120e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard } 9121d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP 9122f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, "new step : "); 9123d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif 9124d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard switch (axis) { 9125d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard case AXIS_ANCESTOR: 9126d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP 9127f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, "axis 'ancestors' "); 9128d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif 9129f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard first = NULL; 9130f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard next = xmlXPathNextAncestor; 9131f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9132d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard case AXIS_ANCESTOR_OR_SELF: 9133d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP 9134f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, 9135f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard "axis 'ancestors-or-self' "); 9136d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif 9137f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard first = NULL; 9138f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard next = xmlXPathNextAncestorOrSelf; 9139f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9140d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard case AXIS_ATTRIBUTE: 9141d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP 9142f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, "axis 'attributes' "); 9143d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif 9144f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard first = NULL; 9145f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard last = NULL; 9146f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard next = xmlXPathNextAttribute; 914775be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard mergeNodeSet = xmlXPathNodeSetMergeUnique; 9148f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9149d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard case AXIS_CHILD: 9150d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP 9151f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, "axis 'child' "); 9152d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif 9153f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard last = NULL; 9154f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard next = xmlXPathNextChild; 915575be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard mergeNodeSet = xmlXPathNodeSetMergeUnique; 9156f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9157d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard case AXIS_DESCENDANT: 9158d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP 9159f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, "axis 'descendant' "); 9160d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif 9161f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard last = NULL; 9162f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard next = xmlXPathNextDescendant; 9163f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9164d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard case AXIS_DESCENDANT_OR_SELF: 9165d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP 9166f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, 9167f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard "axis 'descendant-or-self' "); 9168d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif 9169f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard last = NULL; 9170f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard next = xmlXPathNextDescendantOrSelf; 9171f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9172d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard case AXIS_FOLLOWING: 9173d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP 9174f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, "axis 'following' "); 9175d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif 9176f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard last = NULL; 9177f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard next = xmlXPathNextFollowing; 9178f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9179d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard case AXIS_FOLLOWING_SIBLING: 9180d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP 9181f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, 9182f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard "axis 'following-siblings' "); 9183d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif 9184f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard last = NULL; 9185f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard next = xmlXPathNextFollowingSibling; 9186f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9187d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard case AXIS_NAMESPACE: 9188d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP 9189f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, "axis 'namespace' "); 9190d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif 9191f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard first = NULL; 9192f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard last = NULL; 9193f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard next = (xmlXPathTraversalFunction) xmlXPathNextNamespace; 919475be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard mergeNodeSet = xmlXPathNodeSetMergeUnique; 9195f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9196d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard case AXIS_PARENT: 9197d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP 9198f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, "axis 'parent' "); 9199d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif 9200f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard first = NULL; 9201f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard next = xmlXPathNextParent; 9202f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9203d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard case AXIS_PRECEDING: 9204d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP 9205f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, "axis 'preceding' "); 9206d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif 9207f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard first = NULL; 9208f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard next = xmlXPathNextPrecedingInternal; 9209f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9210d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard case AXIS_PRECEDING_SIBLING: 9211d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP 9212f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, 9213f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard "axis 'preceding-sibling' "); 9214d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif 9215f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard first = NULL; 9216f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard next = xmlXPathNextPrecedingSibling; 9217f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9218d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard case AXIS_SELF: 9219d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP 9220f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, "axis 'self' "); 9221d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif 9222f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard first = NULL; 9223f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard last = NULL; 9224f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard next = xmlXPathNextSelf; 922575be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard mergeNodeSet = xmlXPathNodeSetMergeUnique; 9226f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9227d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard } 92282c19a7bf2ee0f78485840cac50f2a989f5efe476William M. Brack if (next == NULL) { 92292c19a7bf2ee0f78485840cac50f2a989f5efe476William M. Brack xmlXPathFreeObject(obj); 9230f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return(0); 92312c19a7bf2ee0f78485840cac50f2a989f5efe476William M. Brack } 9232d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard 9233d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard nodelist = obj->nodesetval; 9234d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard if (nodelist == NULL) { 9235f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathFreeObject(obj); 9236f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard valuePush(ctxt, xmlXPathWrapNodeSet(NULL)); 9237f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return(0); 9238d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard } 9239d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard addNode = xmlXPathNodeSetAddUnique; 9240d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard ret = NULL; 9241d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP 9242d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard xmlGenericError(xmlGenericErrorContext, 9243f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard " context contains %d nodes\n", nodelist->nodeNr); 9244d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard switch (test) { 9245f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case NODE_TEST_NONE: 9246f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, 9247f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard " searching for none !!!\n"); 9248f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9249f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case NODE_TEST_TYPE: 9250f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, 9251f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard " searching for type %d\n", type); 9252f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9253f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case NODE_TEST_PI: 9254f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, 9255f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard " searching for PI !!!\n"); 9256f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9257f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case NODE_TEST_ALL: 9258f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, 9259f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard " searching for *\n"); 9260f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9261f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case NODE_TEST_NS: 9262f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, 9263f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard " searching for namespace %s\n", 9264f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard prefix); 9265f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9266f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case NODE_TEST_NAME: 9267f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, 9268f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard " searching for name %s\n", name); 9269f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (prefix != NULL) 9270f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, 9271f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard " with namespace %s\n", prefix); 9272f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9273d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard } 9274d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard xmlGenericError(xmlGenericErrorContext, "Testing : "); 9275d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif 9276d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard /* 9277d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * 2.3 Node Tests 9278d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * - For the attribute axis, the principal node type is attribute. 9279d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * - For the namespace axis, the principal node type is namespace. 9280d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * - For other axes, the principal node type is element. 9281d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * 9282d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * A node test * is true for any node of the 9283cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * principal node type. For example, child::* will 9284d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * select all element children of the context node 9285d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard */ 9286d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard tmp = ctxt->context->node; 9287f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard for (i = 0; i < nodelist->nodeNr; i++) { 9288d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard ctxt->context->node = nodelist->nodeTab[i]; 9289d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard 9290f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard cur = NULL; 9291f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard list = xmlXPathNodeSetCreate(NULL); 9292f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard do { 9293f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard cur = next(ctxt, cur); 9294f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (cur == NULL) 9295f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9296f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((first != NULL) && (*first == cur)) 9297f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9298f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (((t % 256) == 0) && 9299f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (first != NULL) && (*first != NULL) && 9300f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (xmlXPathCmpNodes(*first, cur) >= 0)) 9301f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9302f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((last != NULL) && (*last == cur)) 9303f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9304f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (((t % 256) == 0) && 9305f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (last != NULL) && (*last != NULL) && 9306f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (xmlXPathCmpNodes(cur, *last) >= 0)) 9307f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9308d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard t++; 9309f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#ifdef DEBUG_STEP 9310d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard xmlGenericError(xmlGenericErrorContext, " %s", cur->name); 9311d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif 9312f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard switch (test) { 9313d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard case NODE_TEST_NONE: 9314f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->node = tmp; 93152c19a7bf2ee0f78485840cac50f2a989f5efe476William M. Brack xmlXPathFreeObject(obj); 9316f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard STRANGE return(t); 9317d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard case NODE_TEST_TYPE: 9318f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((cur->type == type) || 9319f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ((type == NODE_TYPE_NODE) && 9320f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ((cur->type == XML_DOCUMENT_NODE) || 9321f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (cur->type == XML_HTML_DOCUMENT_NODE) || 9322f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (cur->type == XML_ELEMENT_NODE) || 9323f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin (cur->type == XML_NAMESPACE_DECL) || 9324f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin (cur->type == XML_ATTRIBUTE_NODE) || 9325f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (cur->type == XML_PI_NODE) || 9326f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (cur->type == XML_COMMENT_NODE) || 9327f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (cur->type == XML_CDATA_SECTION_NODE) || 93287583a59b5a0792599a181f77aaf0a39749fada27Daniel Veillard (cur->type == XML_TEXT_NODE))) || 93297583a59b5a0792599a181f77aaf0a39749fada27Daniel Veillard ((type == NODE_TYPE_TEXT) && 93307583a59b5a0792599a181f77aaf0a39749fada27Daniel Veillard (cur->type == XML_CDATA_SECTION_NODE))) { 9331d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP 9332d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard n++; 9333d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif 9334f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard addNode(list, cur); 9335f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9336f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9337d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard case NODE_TEST_PI: 9338f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (cur->type == XML_PI_NODE) { 9339f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((name != NULL) && 9340f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (!xmlStrEqual(name, cur->name))) 9341f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9342d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP 9343f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard n++; 9344d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif 9345f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard addNode(list, cur); 9346f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9347f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9348d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard case NODE_TEST_ALL: 9349f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (axis == AXIS_ATTRIBUTE) { 9350f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (cur->type == XML_ATTRIBUTE_NODE) { 9351d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP 9352f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard n++; 9353d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif 9354f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard addNode(list, cur); 9355f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9356f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } else if (axis == AXIS_NAMESPACE) { 9357f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (cur->type == XML_NAMESPACE_DECL) { 9358d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP 9359f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard n++; 9360d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif 9361044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlXPathNodeSetAddNs(list, ctxt->context->node, 9362044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard (xmlNsPtr) cur); 9363f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9364f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } else { 9365f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (cur->type == XML_ELEMENT_NODE) { 9366f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (prefix == NULL) { 9367d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP 9368f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard n++; 9369d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif 9370f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard addNode(list, cur); 9371f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } else if ((cur->ns != NULL) && 9372f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (xmlStrEqual(URI, cur->ns->href))) { 9373d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP 9374f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard n++; 9375d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif 9376f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard addNode(list, cur); 9377f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9378f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9379f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9380f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9381f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case NODE_TEST_NS:{ 9382f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard TODO; 9383f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9384f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9385d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard case NODE_TEST_NAME: 9386f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard switch (cur->type) { 9387f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XML_ELEMENT_NODE: 9388f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (xmlStrEqual(name, cur->name)) { 9389f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (prefix == NULL) { 9390f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (cur->ns == NULL) { 9391d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP 9392f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard n++; 9393d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif 9394f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard addNode(list, cur); 9395f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9396f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } else { 9397f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((cur->ns != NULL) && 9398f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (xmlStrEqual(URI, 9399f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard cur->ns->href))) { 9400d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP 9401f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard n++; 9402d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif 9403f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard addNode(list, cur); 9404f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9405f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9406f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9407f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9408f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XML_ATTRIBUTE_NODE:{ 9409f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlAttrPtr attr = (xmlAttrPtr) cur; 9410f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 9411f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (xmlStrEqual(name, attr->name)) { 9412f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (prefix == NULL) { 9413f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((attr->ns == NULL) || 9414f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (attr->ns->prefix == NULL)) { 9415d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP 9416f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard n++; 9417d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif 9418f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard addNode(list, 9419f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (xmlNodePtr) attr); 9420f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9421f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } else { 9422f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((attr->ns != NULL) && 9423f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (xmlStrEqual(URI, 9424f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard attr->ns-> 9425f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard href))) { 9426d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP 9427f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard n++; 9428d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif 9429f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard addNode(list, 9430f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (xmlNodePtr) attr); 9431f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9432f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9433f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9434f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9435f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9436f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XML_NAMESPACE_DECL: 9437f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (cur->type == XML_NAMESPACE_DECL) { 9438f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlNsPtr ns = (xmlNsPtr) cur; 9439f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 9440f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((ns->prefix != NULL) && (name != NULL) 9441f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard && (xmlStrEqual(ns->prefix, name))) { 94428b8d2254fa1604efd37b3ba92eaeb2e40b2909a8Daniel Veillard#ifdef DEBUG_STEP 9443f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard n++; 94448b8d2254fa1604efd37b3ba92eaeb2e40b2909a8Daniel Veillard#endif 9445044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlXPathNodeSetAddNs(list, 9446044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard ctxt->context->node, (xmlNsPtr) cur); 9447f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9448f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9449f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9450f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard default: 9451f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9452f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9453f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9454f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9455f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9456f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } while (cur != NULL); 9457f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 9458f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* 9459f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * If there is some predicate filtering do it now 9460f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 94616fbcf42aa301dca50737c65fb738752328ca3a4cDaniel Veillard if ((op->ch2 != -1) && (list != NULL) && (list->nodeNr > 0)) { 9462f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathObjectPtr obj2; 9463f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 9464f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard valuePush(ctxt, xmlXPathWrapNodeSet(list)); 9465f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathCompOpEval(ctxt, &ctxt->comp->steps[op->ch2]); 9466f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard CHECK_TYPE0(XPATH_NODESET); 9467f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard obj2 = valuePop(ctxt); 9468f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard list = obj2->nodesetval; 9469f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard obj2->nodesetval = NULL; 9470f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathFreeObject(obj2); 94712c19a7bf2ee0f78485840cac50f2a989f5efe476William M. Brack if (ctxt->error != XPATH_EXPRESSION_OK) { 94722c19a7bf2ee0f78485840cac50f2a989f5efe476William M. Brack xmlXPathFreeObject(obj); 94732c19a7bf2ee0f78485840cac50f2a989f5efe476William M. Brack xmlXPathFreeNodeSet(list); 94742c19a7bf2ee0f78485840cac50f2a989f5efe476William M. Brack return(0); 94752c19a7bf2ee0f78485840cac50f2a989f5efe476William M. Brack } 9476f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9477f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (ret == NULL) { 9478f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ret = list; 9479f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } else { 948075be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard ret = mergeNodeSet(ret, list); 9481f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathFreeNodeSet(list); 9482f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9483d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard } 9484d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard ctxt->context->node = tmp; 9485d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP 9486d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard xmlGenericError(xmlGenericErrorContext, 9487f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard "\nExamined %d nodes, found %d nodes at that step\n", 9488f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard t, n); 9489d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif 9490d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard valuePush(ctxt, xmlXPathWrapNodeSet(ret)); 94910ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard if ((obj->boolval) && (obj->user != NULL)) { 94920ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard ctxt->value->boolval = 1; 94930ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard ctxt->value->user = obj->user; 94940ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard obj->user = NULL; 94950ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard obj->boolval = 0; 94960ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard } 94970ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard xmlXPathFreeObject(obj); 9498f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return(t); 9499d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard} 9500d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard 9501d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard/** 9502f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * xmlXPathNodeCollectAndTestNth: 9503f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * @ctxt: the XPath Parser context 9504f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * @op: the XPath precompiled step operation 9505f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * @indx: the index to collect 9506f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * @first: pointer to the first element in document order 9507f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * @last: pointer to the last element in document order 9508f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * 9509f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * This is the function implementing a step: based on the current list 9510f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * of nodes, it builds up a new list, looking at all nodes under that 9511081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack * axis and selecting them. It also does the predicate filtering 9512f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * 9513f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Pushes the new NodeSet resulting from the search. 9514f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Returns the number of node traversed 9515f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 9516f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillardstatic int 9517f06307e2c172284bb41376c396f757bdac9bdd19Daniel VeillardxmlXPathNodeCollectAndTestNth(xmlXPathParserContextPtr ctxt, 9518f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathStepOpPtr op, int indx, 9519f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlNodePtr * first, xmlNodePtr * last) 9520f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard{ 952178637da0ea1c833dfdfad87a9aa5bea14510d08aWilliam M. Brack xmlXPathAxisVal axis = (xmlXPathAxisVal) op->value; 952278637da0ea1c833dfdfad87a9aa5bea14510d08aWilliam M. Brack xmlXPathTestVal test = (xmlXPathTestVal) op->value2; 952378637da0ea1c833dfdfad87a9aa5bea14510d08aWilliam M. Brack xmlXPathTypeVal type = (xmlXPathTypeVal) op->value3; 9524f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard const xmlChar *prefix = op->value4; 9525f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard const xmlChar *name = op->value5; 9526f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard const xmlChar *URI = NULL; 9527f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard int n = 0, t = 0; 9528f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 9529f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard int i; 9530f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlNodeSetPtr list; 9531f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathTraversalFunction next = NULL; 9532f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard void (*addNode) (xmlNodeSetPtr, xmlNodePtr); 9533f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlNodePtr cur = NULL; 9534f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathObjectPtr obj; 9535f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlNodeSetPtr nodelist; 9536f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlNodePtr tmp; 9537f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 9538f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard CHECK_TYPE0(XPATH_NODESET); 9539f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard obj = valuePop(ctxt); 9540f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard addNode = xmlXPathNodeSetAdd; 9541f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (prefix != NULL) { 9542f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard URI = xmlXPathNsLookup(ctxt->context, prefix); 95432c19a7bf2ee0f78485840cac50f2a989f5efe476William M. Brack if (URI == NULL) { 95442c19a7bf2ee0f78485840cac50f2a989f5efe476William M. Brack xmlXPathFreeObject(obj); 9545f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard XP_ERROR0(XPATH_UNDEF_PREFIX_ERROR); 95462c19a7bf2ee0f78485840cac50f2a989f5efe476William M. Brack } 9547f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9548f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#ifdef DEBUG_STEP_NTH 9549f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, "new step : "); 9550f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (first != NULL) { 9551f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (*first != NULL) 9552f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, "first = %s ", 9553f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (*first)->name); 9554f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard else 9555f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, "first = NULL "); 9556f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9557f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (last != NULL) { 9558f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (*last != NULL) 9559f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, "last = %s ", 9560f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (*last)->name); 9561f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard else 9562f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, "last = NULL "); 9563f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9564f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#endif 9565f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard switch (axis) { 9566f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case AXIS_ANCESTOR: 9567f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#ifdef DEBUG_STEP_NTH 9568f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, "axis 'ancestors' "); 9569f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#endif 9570f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard first = NULL; 9571f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard next = xmlXPathNextAncestor; 9572f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9573f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case AXIS_ANCESTOR_OR_SELF: 9574f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#ifdef DEBUG_STEP_NTH 9575f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, 9576f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard "axis 'ancestors-or-self' "); 9577f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#endif 9578f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard first = NULL; 9579f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard next = xmlXPathNextAncestorOrSelf; 9580f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9581f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case AXIS_ATTRIBUTE: 9582f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#ifdef DEBUG_STEP_NTH 9583f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, "axis 'attributes' "); 9584f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#endif 9585f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard first = NULL; 9586f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard last = NULL; 9587f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard next = xmlXPathNextAttribute; 9588f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9589f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case AXIS_CHILD: 9590f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#ifdef DEBUG_STEP_NTH 9591f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, "axis 'child' "); 9592f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#endif 9593f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard last = NULL; 9594f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard next = xmlXPathNextChild; 9595f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9596f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case AXIS_DESCENDANT: 9597f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#ifdef DEBUG_STEP_NTH 9598f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, "axis 'descendant' "); 9599f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#endif 9600f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard last = NULL; 9601f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard next = xmlXPathNextDescendant; 9602f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9603f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case AXIS_DESCENDANT_OR_SELF: 9604f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#ifdef DEBUG_STEP_NTH 9605f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, 9606f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard "axis 'descendant-or-self' "); 9607f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#endif 9608f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard last = NULL; 9609f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard next = xmlXPathNextDescendantOrSelf; 9610f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9611f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case AXIS_FOLLOWING: 9612f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#ifdef DEBUG_STEP_NTH 9613f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, "axis 'following' "); 9614f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#endif 9615f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard last = NULL; 9616f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard next = xmlXPathNextFollowing; 9617f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9618f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case AXIS_FOLLOWING_SIBLING: 9619f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#ifdef DEBUG_STEP_NTH 9620f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, 9621f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard "axis 'following-siblings' "); 9622f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#endif 9623f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard last = NULL; 9624f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard next = xmlXPathNextFollowingSibling; 9625f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9626f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case AXIS_NAMESPACE: 9627f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#ifdef DEBUG_STEP_NTH 9628f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, "axis 'namespace' "); 9629f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#endif 9630f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard last = NULL; 9631f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard first = NULL; 9632f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard next = (xmlXPathTraversalFunction) xmlXPathNextNamespace; 9633f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9634f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case AXIS_PARENT: 9635f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#ifdef DEBUG_STEP_NTH 9636f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, "axis 'parent' "); 9637f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#endif 9638f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard first = NULL; 9639f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard next = xmlXPathNextParent; 9640f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9641f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case AXIS_PRECEDING: 9642f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#ifdef DEBUG_STEP_NTH 9643f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, "axis 'preceding' "); 9644f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#endif 9645f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard first = NULL; 9646f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard next = xmlXPathNextPrecedingInternal; 9647f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9648f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case AXIS_PRECEDING_SIBLING: 9649f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#ifdef DEBUG_STEP_NTH 9650f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, 9651f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard "axis 'preceding-sibling' "); 9652f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#endif 9653f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard first = NULL; 9654f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard next = xmlXPathNextPrecedingSibling; 9655f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9656f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case AXIS_SELF: 9657f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#ifdef DEBUG_STEP_NTH 9658f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, "axis 'self' "); 9659f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#endif 9660f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard first = NULL; 9661f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard last = NULL; 9662f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard next = xmlXPathNextSelf; 9663f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9664f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 96652c19a7bf2ee0f78485840cac50f2a989f5efe476William M. Brack if (next == NULL) { 96662c19a7bf2ee0f78485840cac50f2a989f5efe476William M. Brack xmlXPathFreeObject(obj); 9667f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return(0); 96682c19a7bf2ee0f78485840cac50f2a989f5efe476William M. Brack } 9669f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 9670f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard nodelist = obj->nodesetval; 9671f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (nodelist == NULL) { 9672f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathFreeObject(obj); 9673f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard valuePush(ctxt, xmlXPathWrapNodeSet(NULL)); 9674f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return(0); 9675f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9676f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard addNode = xmlXPathNodeSetAddUnique; 9677f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#ifdef DEBUG_STEP_NTH 9678f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, 9679f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard " context contains %d nodes\n", nodelist->nodeNr); 9680f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard switch (test) { 9681f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case NODE_TEST_NONE: 9682f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, 9683f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard " searching for none !!!\n"); 9684f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9685f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case NODE_TEST_TYPE: 9686f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, 9687f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard " searching for type %d\n", type); 9688f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9689f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case NODE_TEST_PI: 9690f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, 9691f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard " searching for PI !!!\n"); 9692f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9693f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case NODE_TEST_ALL: 9694f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, 9695f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard " searching for *\n"); 9696f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9697f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case NODE_TEST_NS: 9698f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, 9699f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard " searching for namespace %s\n", 9700f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard prefix); 9701f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9702f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case NODE_TEST_NAME: 9703f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, 9704f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard " searching for name %s\n", name); 9705f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (prefix != NULL) 9706f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, 9707f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard " with namespace %s\n", prefix); 9708f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9709f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9710f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, "Testing : "); 9711f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#endif 9712f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* 9713f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * 2.3 Node Tests 9714f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * - For the attribute axis, the principal node type is attribute. 9715f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * - For the namespace axis, the principal node type is namespace. 9716f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * - For other axes, the principal node type is element. 9717f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * 9718f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * A node test * is true for any node of the 9719cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * principal node type. For example, child::* will 9720f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * select all element children of the context node 9721f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 9722f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard tmp = ctxt->context->node; 9723f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard list = xmlXPathNodeSetCreate(NULL); 9724f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard for (i = 0; i < nodelist->nodeNr; i++) { 9725f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->node = nodelist->nodeTab[i]; 9726f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 9727f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard cur = NULL; 9728f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard n = 0; 9729f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard do { 9730f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard cur = next(ctxt, cur); 9731f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (cur == NULL) 9732f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9733f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((first != NULL) && (*first == cur)) 9734f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9735f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (((t % 256) == 0) && 9736f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (first != NULL) && (*first != NULL) && 9737f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (xmlXPathCmpNodes(*first, cur) >= 0)) 9738f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9739f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((last != NULL) && (*last == cur)) 9740f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9741f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (((t % 256) == 0) && 9742f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (last != NULL) && (*last != NULL) && 9743f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (xmlXPathCmpNodes(cur, *last) >= 0)) 9744f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9745f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard t++; 9746f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard switch (test) { 9747f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case NODE_TEST_NONE: 9748f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->node = tmp; 9749f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard STRANGE return(0); 9750f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case NODE_TEST_TYPE: 9751f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((cur->type == type) || 9752f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ((type == NODE_TYPE_NODE) && 9753f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ((cur->type == XML_DOCUMENT_NODE) || 9754f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (cur->type == XML_HTML_DOCUMENT_NODE) || 9755f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (cur->type == XML_ELEMENT_NODE) || 9756f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (cur->type == XML_PI_NODE) || 9757f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (cur->type == XML_COMMENT_NODE) || 9758f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (cur->type == XML_CDATA_SECTION_NODE) || 97598606bbbc0a04293afd7541033d6a83c4943a6f02Daniel Veillard (cur->type == XML_TEXT_NODE))) || 97608606bbbc0a04293afd7541033d6a83c4943a6f02Daniel Veillard ((type == NODE_TYPE_TEXT) && 97618606bbbc0a04293afd7541033d6a83c4943a6f02Daniel Veillard (cur->type == XML_CDATA_SECTION_NODE))) { 9762f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard n++; 9763f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (n == indx) 9764f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard addNode(list, cur); 9765f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9766f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9767f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case NODE_TEST_PI: 9768f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (cur->type == XML_PI_NODE) { 9769f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((name != NULL) && 9770f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (!xmlStrEqual(name, cur->name))) 9771f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9772f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard n++; 9773f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (n == indx) 9774f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard addNode(list, cur); 9775f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9776f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9777f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case NODE_TEST_ALL: 9778f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (axis == AXIS_ATTRIBUTE) { 9779f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (cur->type == XML_ATTRIBUTE_NODE) { 9780f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard n++; 9781f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (n == indx) 9782f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard addNode(list, cur); 9783f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9784f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } else if (axis == AXIS_NAMESPACE) { 9785f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (cur->type == XML_NAMESPACE_DECL) { 9786f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard n++; 9787f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (n == indx) 9788044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlXPathNodeSetAddNs(list, ctxt->context->node, 9789044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard (xmlNsPtr) cur); 9790f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9791f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } else { 9792f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (cur->type == XML_ELEMENT_NODE) { 9793f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (prefix == NULL) { 9794f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard n++; 9795f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (n == indx) 9796f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard addNode(list, cur); 9797f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } else if ((cur->ns != NULL) && 9798f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (xmlStrEqual(URI, cur->ns->href))) { 9799f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard n++; 9800f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (n == indx) 9801f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard addNode(list, cur); 9802f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9803f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9804f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9805f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9806f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case NODE_TEST_NS:{ 9807f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard TODO; 9808f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9809f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9810f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case NODE_TEST_NAME: 9811f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard switch (cur->type) { 9812f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XML_ELEMENT_NODE: 9813f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (xmlStrEqual(name, cur->name)) { 9814f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (prefix == NULL) { 9815f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (cur->ns == NULL) { 9816f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard n++; 9817f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (n == indx) 9818f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard addNode(list, cur); 9819f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9820f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } else { 9821f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((cur->ns != NULL) && 9822f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (xmlStrEqual(URI, 9823f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard cur->ns->href))) { 9824f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard n++; 9825f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (n == indx) 9826f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard addNode(list, cur); 9827f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9828f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9829f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9830f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9831f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XML_ATTRIBUTE_NODE:{ 9832f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlAttrPtr attr = (xmlAttrPtr) cur; 9833f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 9834f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (xmlStrEqual(name, attr->name)) { 9835f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (prefix == NULL) { 9836f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((attr->ns == NULL) || 9837f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (attr->ns->prefix == NULL)) { 9838f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard n++; 9839f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (n == indx) 9840f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard addNode(list, cur); 9841f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9842f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } else { 9843f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((attr->ns != NULL) && 9844f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (xmlStrEqual(URI, 9845f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard attr->ns-> 9846f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard href))) { 9847f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard n++; 9848f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (n == indx) 9849f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard addNode(list, cur); 9850f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9851f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9852f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9853f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9854f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9855f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XML_NAMESPACE_DECL: 9856f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (cur->type == XML_NAMESPACE_DECL) { 9857f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlNsPtr ns = (xmlNsPtr) cur; 9858f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 9859f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((ns->prefix != NULL) && (name != NULL) 9860f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard && (xmlStrEqual(ns->prefix, name))) { 9861f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard n++; 9862f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (n == indx) 9863044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlXPathNodeSetAddNs(list, 9864044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard ctxt->context->node, (xmlNsPtr) cur); 9865f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9866f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9867f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9868f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard default: 9869f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9870f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9871f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9872f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9873f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9874f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } while (n < indx); 9875f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9876f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->node = tmp; 9877f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#ifdef DEBUG_STEP_NTH 9878f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, 9879f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard "\nExamined %d nodes, found %d nodes at that step\n", 9880f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard t, list->nodeNr); 9881f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#endif 9882f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard valuePush(ctxt, xmlXPathWrapNodeSet(list)); 98830ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard if ((obj->boolval) && (obj->user != NULL)) { 98840ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard ctxt->value->boolval = 1; 98850ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard ctxt->value->user = obj->user; 98860ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard obj->user = NULL; 98870ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard obj->boolval = 0; 98880ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard } 98890ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard xmlXPathFreeObject(obj); 9890f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return(t); 9891f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard} 9892f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 9893f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard/** 9894f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * xmlXPathCompOpEvalFirst: 9895d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * @ctxt: the XPath parser context with the compiled expression 9896d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * @op: an XPath compiled operation 9897f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * @first: the first elem found so far 9898d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * 9899f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Evaluate the Precompiled XPath operation searching only the first 9900f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * element in document order 9901f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * 9902f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Returns the number of examined objects. 9903d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard */ 9904f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillardstatic int 9905f06307e2c172284bb41376c396f757bdac9bdd19Daniel VeillardxmlXPathCompOpEvalFirst(xmlXPathParserContextPtr ctxt, 9906f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathStepOpPtr op, xmlNodePtr * first) 9907f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard{ 9908f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard int total = 0, cur; 9909d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard xmlXPathCompExprPtr comp; 9910d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard xmlXPathObjectPtr arg1, arg2; 9911d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard 9912556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 9913d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard comp = ctxt->comp; 9914d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard switch (op->op) { 9915f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_END: 9916f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (0); 9917f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_UNION: 9918f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total = 9919f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathCompOpEvalFirst(ctxt, &comp->steps[op->ch1], 9920f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard first); 9921556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 9922f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((ctxt->value != NULL) 9923f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard && (ctxt->value->type == XPATH_NODESET) 9924f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard && (ctxt->value->nodesetval != NULL) 9925f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard && (ctxt->value->nodesetval->nodeNr >= 1)) { 9926f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* 9927f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * limit tree traversing to first node in the result 9928f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 9929f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathNodeSetSort(ctxt->value->nodesetval); 9930f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard *first = ctxt->value->nodesetval->nodeTab[0]; 9931f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9932f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard cur = 9933f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathCompOpEvalFirst(ctxt, &comp->steps[op->ch2], 9934f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard first); 9935556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 9936f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard CHECK_TYPE0(XPATH_NODESET); 9937f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard arg2 = valuePop(ctxt); 9938f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 9939f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard CHECK_TYPE0(XPATH_NODESET); 9940f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard arg1 = valuePop(ctxt); 9941f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 9942f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard arg1->nodesetval = xmlXPathNodeSetMerge(arg1->nodesetval, 9943f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard arg2->nodesetval); 9944f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard valuePush(ctxt, arg1); 9945f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathFreeObject(arg2); 9946f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* optimizer */ 9947f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (total > cur) 9948f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathCompSwap(op); 9949f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total + cur); 9950f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_ROOT: 9951f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathRoot(ctxt); 9952f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (0); 9953f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_NODE: 9954f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch1 != -1) 9955f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]); 9956556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 9957f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch2 != -1) 9958f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]); 9959556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 9960f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard valuePush(ctxt, xmlXPathNewNodeSet(ctxt->context->node)); 9961f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 9962f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_RESET: 9963f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch1 != -1) 9964f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]); 9965556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 9966f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch2 != -1) 9967f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]); 9968556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 9969f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->node = NULL; 9970f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 9971f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_COLLECT:{ 9972f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch1 == -1) 9973f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 9974f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 9975f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total = xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]); 9976556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 9977f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 9978f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* 9979f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Optimization for [n] selection where n is a number 9980f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 9981f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((op->ch2 != -1) && 9982f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (comp->steps[op->ch2].op == XPATH_OP_PREDICATE) && 9983f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (comp->steps[op->ch2].ch1 == -1) && 9984f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (comp->steps[op->ch2].ch2 != -1) && 9985f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (comp->steps[comp->steps[op->ch2].ch2].op == 9986f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard XPATH_OP_VALUE)) { 9987f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathObjectPtr val; 9988f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 9989f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard val = comp->steps[comp->steps[op->ch2].ch2].value4; 9990f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((val != NULL) && (val->type == XPATH_NUMBER)) { 9991f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard int indx = (int) val->floatval; 9992f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 9993f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (val->floatval == (float) indx) { 9994f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathNodeCollectAndTestNth(ctxt, op, indx, 9995f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard first, NULL); 9996f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 9997f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9998f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9999f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10000f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathNodeCollectAndTest(ctxt, op, first, NULL); 10001f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 10002f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10003f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_VALUE: 10004f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard valuePush(ctxt, 10005f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathObjectCopy((xmlXPathObjectPtr) op->value4)); 10006f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (0); 10007f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_SORT: 10008f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch1 != -1) 10009f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += 10010f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathCompOpEvalFirst(ctxt, &comp->steps[op->ch1], 10011f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard first); 10012556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 10013f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((ctxt->value != NULL) 10014f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard && (ctxt->value->type == XPATH_NODESET) 10015f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard && (ctxt->value->nodesetval != NULL)) 10016f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathNodeSetSort(ctxt->value->nodesetval); 10017f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 10018f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard default: 10019f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (xmlXPathCompOpEval(ctxt, op)); 10020f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10021f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard} 1002242596ad20cdf1925dd79ea801cbe598b6e7b7aecDaniel Veillard 10023f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard/** 10024f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * xmlXPathCompOpEvalLast: 10025f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * @ctxt: the XPath parser context with the compiled expression 10026f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * @op: an XPath compiled operation 10027f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * @last: the last elem found so far 10028f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * 10029f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Evaluate the Precompiled XPath operation searching only the last 10030f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * element in document order 10031f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * 10032081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack * Returns the number of nodes traversed 10033f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 10034f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillardstatic int 10035f06307e2c172284bb41376c396f757bdac9bdd19Daniel VeillardxmlXPathCompOpEvalLast(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op, 10036f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlNodePtr * last) 10037f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard{ 10038f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard int total = 0, cur; 10039f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathCompExprPtr comp; 10040f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathObjectPtr arg1, arg2; 10041ce4fc56e1b56253ae794b47515948f3bc3142024William M. Brack xmlNodePtr bak; 10042ce4fc56e1b56253ae794b47515948f3bc3142024William M. Brack xmlDocPtr bakd; 10043ce4fc56e1b56253ae794b47515948f3bc3142024William M. Brack int pp; 10044ce4fc56e1b56253ae794b47515948f3bc3142024William M. Brack int cs; 100459e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 10046556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 10047f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard comp = ctxt->comp; 10048f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard switch (op->op) { 10049f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_END: 10050f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (0); 10051f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_UNION: 10052ce4fc56e1b56253ae794b47515948f3bc3142024William M. Brack bakd = ctxt->context->doc; 10053ce4fc56e1b56253ae794b47515948f3bc3142024William M. Brack bak = ctxt->context->node; 10054ce4fc56e1b56253ae794b47515948f3bc3142024William M. Brack pp = ctxt->context->proximityPosition; 10055ce4fc56e1b56253ae794b47515948f3bc3142024William M. Brack cs = ctxt->context->contextSize; 10056f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total = 10057f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathCompOpEvalLast(ctxt, &comp->steps[op->ch1], last); 10058556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 10059f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((ctxt->value != NULL) 10060f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard && (ctxt->value->type == XPATH_NODESET) 10061f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard && (ctxt->value->nodesetval != NULL) 10062f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard && (ctxt->value->nodesetval->nodeNr >= 1)) { 10063f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* 10064f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * limit tree traversing to first node in the result 10065f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 10066f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathNodeSetSort(ctxt->value->nodesetval); 10067f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard *last = 10068f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->value->nodesetval->nodeTab[ctxt->value-> 10069f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard nodesetval->nodeNr - 10070f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 1]; 10071f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10072ce4fc56e1b56253ae794b47515948f3bc3142024William M. Brack ctxt->context->doc = bakd; 10073ce4fc56e1b56253ae794b47515948f3bc3142024William M. Brack ctxt->context->node = bak; 10074ce4fc56e1b56253ae794b47515948f3bc3142024William M. Brack ctxt->context->proximityPosition = pp; 10075ce4fc56e1b56253ae794b47515948f3bc3142024William M. Brack ctxt->context->contextSize = cs; 10076f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard cur = 10077f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathCompOpEvalLast(ctxt, &comp->steps[op->ch2], last); 10078556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 10079f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((ctxt->value != NULL) 10080f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard && (ctxt->value->type == XPATH_NODESET) 10081f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard && (ctxt->value->nodesetval != NULL) 10082f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard && (ctxt->value->nodesetval->nodeNr >= 1)) { 10083f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10084f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard CHECK_TYPE0(XPATH_NODESET); 10085f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard arg2 = valuePop(ctxt); 10086f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10087f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard CHECK_TYPE0(XPATH_NODESET); 10088f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard arg1 = valuePop(ctxt); 10089f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10090f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard arg1->nodesetval = xmlXPathNodeSetMerge(arg1->nodesetval, 10091f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard arg2->nodesetval); 10092f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard valuePush(ctxt, arg1); 10093f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathFreeObject(arg2); 10094f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* optimizer */ 10095f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (total > cur) 10096f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathCompSwap(op); 10097f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total + cur); 10098f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_ROOT: 10099f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathRoot(ctxt); 10100f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (0); 10101f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_NODE: 10102f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch1 != -1) 10103f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]); 10104556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 10105f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch2 != -1) 10106f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]); 10107556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 10108f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard valuePush(ctxt, xmlXPathNewNodeSet(ctxt->context->node)); 10109f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 10110f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_RESET: 10111f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch1 != -1) 10112f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]); 10113556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 10114f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch2 != -1) 10115f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]); 10116556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 10117f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->node = NULL; 10118f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 10119f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_COLLECT:{ 10120f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch1 == -1) 10121f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (0); 10122f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10123f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]); 10124556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 10125f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10126f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* 10127f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Optimization for [n] selection where n is a number 10128f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 10129f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((op->ch2 != -1) && 10130f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (comp->steps[op->ch2].op == XPATH_OP_PREDICATE) && 10131f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (comp->steps[op->ch2].ch1 == -1) && 10132f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (comp->steps[op->ch2].ch2 != -1) && 10133f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (comp->steps[comp->steps[op->ch2].ch2].op == 10134f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard XPATH_OP_VALUE)) { 10135f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathObjectPtr val; 10136f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10137f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard val = comp->steps[comp->steps[op->ch2].ch2].value4; 10138f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((val != NULL) && (val->type == XPATH_NUMBER)) { 10139f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard int indx = (int) val->floatval; 10140f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10141f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (val->floatval == (float) indx) { 10142f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += 10143f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathNodeCollectAndTestNth(ctxt, op, 10144f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard indx, NULL, 10145f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard last); 10146f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 10147f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10148f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10149f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10150f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathNodeCollectAndTest(ctxt, op, NULL, last); 10151f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 10152f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10153f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_VALUE: 10154f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard valuePush(ctxt, 10155f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathObjectCopy((xmlXPathObjectPtr) op->value4)); 10156f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (0); 10157f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_SORT: 10158f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch1 != -1) 10159f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += 10160f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathCompOpEvalLast(ctxt, &comp->steps[op->ch1], 10161f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard last); 10162556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 10163f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((ctxt->value != NULL) 10164f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard && (ctxt->value->type == XPATH_NODESET) 10165f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard && (ctxt->value->nodesetval != NULL)) 10166f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathNodeSetSort(ctxt->value->nodesetval); 10167f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 10168f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard default: 10169f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (xmlXPathCompOpEval(ctxt, op)); 10170f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10171f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard} 101729e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 10173f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard/** 10174f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * xmlXPathCompOpEval: 10175f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * @ctxt: the XPath parser context with the compiled expression 10176f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * @op: an XPath compiled operation 10177f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * 10178f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Evaluate the Precompiled XPath operation 10179081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack * Returns the number of nodes traversed 10180f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 10181f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillardstatic int 10182f06307e2c172284bb41376c396f757bdac9bdd19Daniel VeillardxmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op) 10183f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard{ 10184f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard int total = 0; 10185f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard int equal, ret; 10186f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathCompExprPtr comp; 10187f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathObjectPtr arg1, arg2; 101887089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard xmlNodePtr bak; 101897089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard xmlDocPtr bakd; 101906000af549b49464a3b1947fc582998a1c9ff7c79William M. Brack int pp; 10191692092b5886073a8cd1c97bb7d57579e4a9cfc3fWilliam M. Brack int cs; 101929e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 10193556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 10194f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard comp = ctxt->comp; 10195f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard switch (op->op) { 10196f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_END: 10197f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (0); 10198f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_AND: 101997089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard bakd = ctxt->context->doc; 102007089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard bak = ctxt->context->node; 102016000af549b49464a3b1947fc582998a1c9ff7c79William M. Brack pp = ctxt->context->proximityPosition; 10202692092b5886073a8cd1c97bb7d57579e4a9cfc3fWilliam M. Brack cs = ctxt->context->contextSize; 10203f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]); 10204556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 10205f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathBooleanFunction(ctxt, 1); 10206f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((ctxt->value == NULL) || (ctxt->value->boolval == 0)) 10207f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 10208f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard arg2 = valuePop(ctxt); 102097089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard ctxt->context->doc = bakd; 102107089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard ctxt->context->node = bak; 102116000af549b49464a3b1947fc582998a1c9ff7c79William M. Brack ctxt->context->proximityPosition = pp; 10212692092b5886073a8cd1c97bb7d57579e4a9cfc3fWilliam M. Brack ctxt->context->contextSize = cs; 10213f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]); 10214556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard if (ctxt->error) { 10215556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard xmlXPathFreeObject(arg2); 10216556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard return(0); 10217556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard } 10218f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathBooleanFunction(ctxt, 1); 10219f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard arg1 = valuePop(ctxt); 10220f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard arg1->boolval &= arg2->boolval; 10221f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard valuePush(ctxt, arg1); 10222f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathFreeObject(arg2); 10223f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 10224f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_OR: 102257089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard bakd = ctxt->context->doc; 102267089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard bak = ctxt->context->node; 102276000af549b49464a3b1947fc582998a1c9ff7c79William M. Brack pp = ctxt->context->proximityPosition; 10228692092b5886073a8cd1c97bb7d57579e4a9cfc3fWilliam M. Brack cs = ctxt->context->contextSize; 10229f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]); 10230556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 10231f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathBooleanFunction(ctxt, 1); 10232f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((ctxt->value == NULL) || (ctxt->value->boolval == 1)) 10233f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 10234f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard arg2 = valuePop(ctxt); 102357089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard ctxt->context->doc = bakd; 102367089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard ctxt->context->node = bak; 102376000af549b49464a3b1947fc582998a1c9ff7c79William M. Brack ctxt->context->proximityPosition = pp; 10238692092b5886073a8cd1c97bb7d57579e4a9cfc3fWilliam M. Brack ctxt->context->contextSize = cs; 10239f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]); 10240556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard if (ctxt->error) { 10241556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard xmlXPathFreeObject(arg2); 10242556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard return(0); 10243556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard } 10244f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathBooleanFunction(ctxt, 1); 10245f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard arg1 = valuePop(ctxt); 10246f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard arg1->boolval |= arg2->boolval; 10247f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard valuePush(ctxt, arg1); 10248f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathFreeObject(arg2); 10249f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 10250f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_EQUAL: 102517089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard bakd = ctxt->context->doc; 102527089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard bak = ctxt->context->node; 102536000af549b49464a3b1947fc582998a1c9ff7c79William M. Brack pp = ctxt->context->proximityPosition; 10254692092b5886073a8cd1c97bb7d57579e4a9cfc3fWilliam M. Brack cs = ctxt->context->contextSize; 10255f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]); 10256556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 102577089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard ctxt->context->doc = bakd; 102587089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard ctxt->context->node = bak; 102596000af549b49464a3b1947fc582998a1c9ff7c79William M. Brack ctxt->context->proximityPosition = pp; 10260692092b5886073a8cd1c97bb7d57579e4a9cfc3fWilliam M. Brack ctxt->context->contextSize = cs; 10261f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]); 10262556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 102630c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack if (op->value) 102640c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack equal = xmlXPathEqualValues(ctxt); 102650c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack else 102660c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack equal = xmlXPathNotEqualValues(ctxt); 102670c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack valuePush(ctxt, xmlXPathNewBoolean(equal)); 10268f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 10269f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_CMP: 102707089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard bakd = ctxt->context->doc; 102717089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard bak = ctxt->context->node; 102726000af549b49464a3b1947fc582998a1c9ff7c79William M. Brack pp = ctxt->context->proximityPosition; 10273692092b5886073a8cd1c97bb7d57579e4a9cfc3fWilliam M. Brack cs = ctxt->context->contextSize; 10274f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]); 10275556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 102767089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard ctxt->context->doc = bakd; 102777089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard ctxt->context->node = bak; 102786000af549b49464a3b1947fc582998a1c9ff7c79William M. Brack ctxt->context->proximityPosition = pp; 10279692092b5886073a8cd1c97bb7d57579e4a9cfc3fWilliam M. Brack ctxt->context->contextSize = cs; 10280f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]); 10281556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 10282f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ret = xmlXPathCompareValues(ctxt, op->value, op->value2); 10283f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard valuePush(ctxt, xmlXPathNewBoolean(ret)); 10284f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 10285f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_PLUS: 102867089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard bakd = ctxt->context->doc; 102877089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard bak = ctxt->context->node; 102886000af549b49464a3b1947fc582998a1c9ff7c79William M. Brack pp = ctxt->context->proximityPosition; 10289692092b5886073a8cd1c97bb7d57579e4a9cfc3fWilliam M. Brack cs = ctxt->context->contextSize; 10290f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]); 10291556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 102927089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard if (op->ch2 != -1) { 102937089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard ctxt->context->doc = bakd; 102947089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard ctxt->context->node = bak; 102956000af549b49464a3b1947fc582998a1c9ff7c79William M. Brack ctxt->context->proximityPosition = pp; 10296692092b5886073a8cd1c97bb7d57579e4a9cfc3fWilliam M. Brack ctxt->context->contextSize = cs; 10297f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]); 102987089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard } 10299556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 10300f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->value == 0) 10301f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathSubValues(ctxt); 10302f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard else if (op->value == 1) 10303f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathAddValues(ctxt); 10304f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard else if (op->value == 2) 10305f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathValueFlipSign(ctxt); 10306f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard else if (op->value == 3) { 10307f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard CAST_TO_NUMBER; 10308f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard CHECK_TYPE0(XPATH_NUMBER); 10309f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10310f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 10311f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_MULT: 103127089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard bakd = ctxt->context->doc; 103137089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard bak = ctxt->context->node; 103146000af549b49464a3b1947fc582998a1c9ff7c79William M. Brack pp = ctxt->context->proximityPosition; 10315692092b5886073a8cd1c97bb7d57579e4a9cfc3fWilliam M. Brack cs = ctxt->context->contextSize; 10316f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]); 10317556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 103187089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard ctxt->context->doc = bakd; 103197089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard ctxt->context->node = bak; 103206000af549b49464a3b1947fc582998a1c9ff7c79William M. Brack ctxt->context->proximityPosition = pp; 10321692092b5886073a8cd1c97bb7d57579e4a9cfc3fWilliam M. Brack ctxt->context->contextSize = cs; 10322f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]); 10323556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 10324f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->value == 0) 10325f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathMultValues(ctxt); 10326f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard else if (op->value == 1) 10327f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathDivValues(ctxt); 10328f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard else if (op->value == 2) 10329f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathModValues(ctxt); 10330f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 10331f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_UNION: 103327089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard bakd = ctxt->context->doc; 103337089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard bak = ctxt->context->node; 103346000af549b49464a3b1947fc582998a1c9ff7c79William M. Brack pp = ctxt->context->proximityPosition; 10335692092b5886073a8cd1c97bb7d57579e4a9cfc3fWilliam M. Brack cs = ctxt->context->contextSize; 10336f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]); 10337556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 103387089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard ctxt->context->doc = bakd; 103397089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard ctxt->context->node = bak; 103406000af549b49464a3b1947fc582998a1c9ff7c79William M. Brack ctxt->context->proximityPosition = pp; 10341692092b5886073a8cd1c97bb7d57579e4a9cfc3fWilliam M. Brack ctxt->context->contextSize = cs; 10342f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]); 10343556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 10344f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard CHECK_TYPE0(XPATH_NODESET); 10345f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard arg2 = valuePop(ctxt); 10346f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10347f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard CHECK_TYPE0(XPATH_NODESET); 10348f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard arg1 = valuePop(ctxt); 10349f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10350f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard arg1->nodesetval = xmlXPathNodeSetMerge(arg1->nodesetval, 10351f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard arg2->nodesetval); 10352f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard valuePush(ctxt, arg1); 10353f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathFreeObject(arg2); 10354f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 10355f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_ROOT: 10356f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathRoot(ctxt); 10357f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 10358f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_NODE: 10359f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch1 != -1) 10360f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]); 10361556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 10362f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch2 != -1) 10363f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]); 10364556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 10365f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard valuePush(ctxt, xmlXPathNewNodeSet(ctxt->context->node)); 10366f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 10367f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_RESET: 10368f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch1 != -1) 10369f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]); 10370556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 10371f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch2 != -1) 10372f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]); 10373556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 10374f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->node = NULL; 10375f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 10376f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_COLLECT:{ 10377f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch1 == -1) 10378f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 10379f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10380f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]); 10381556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 10382f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10383f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* 10384f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Optimization for [n] selection where n is a number 10385f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 10386f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((op->ch2 != -1) && 10387f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (comp->steps[op->ch2].op == XPATH_OP_PREDICATE) && 10388f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (comp->steps[op->ch2].ch1 == -1) && 10389f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (comp->steps[op->ch2].ch2 != -1) && 10390f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (comp->steps[comp->steps[op->ch2].ch2].op == 10391f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard XPATH_OP_VALUE)) { 10392f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathObjectPtr val; 10393f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10394f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard val = comp->steps[comp->steps[op->ch2].ch2].value4; 10395f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((val != NULL) && (val->type == XPATH_NUMBER)) { 10396f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard int indx = (int) val->floatval; 10397f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10398f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (val->floatval == (float) indx) { 10399f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += 10400f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathNodeCollectAndTestNth(ctxt, op, 10401f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard indx, NULL, 10402f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard NULL); 10403f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 10404f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10405f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10406f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10407f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathNodeCollectAndTest(ctxt, op, NULL, NULL); 10408f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 10409f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10410f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_VALUE: 10411f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard valuePush(ctxt, 10412f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathObjectCopy((xmlXPathObjectPtr) op->value4)); 10413f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 10414f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_VARIABLE:{ 10415556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard xmlXPathObjectPtr val; 10416556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard 10417f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch1 != -1) 10418f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += 10419f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]); 10420556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard if (op->value5 == NULL) { 10421556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard val = xmlXPathVariableLookup(ctxt->context, op->value4); 10422556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard if (val == NULL) { 10423556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard ctxt->error = XPATH_UNDEF_VARIABLE_ERROR; 10424556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard return(0); 10425556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard } 10426556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard valuePush(ctxt, val); 10427556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard } else { 10428f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard const xmlChar *URI; 10429f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10430f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard URI = xmlXPathNsLookup(ctxt->context, op->value5); 10431f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (URI == NULL) { 10432f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, 10433cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard "xmlXPathCompOpEval: variable %s bound to undefined prefix %s\n", 10434f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard op->value4, op->value5); 10435f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 10436f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10437556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard val = xmlXPathVariableLookupNS(ctxt->context, 10438556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard op->value4, URI); 10439556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard if (val == NULL) { 10440556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard ctxt->error = XPATH_UNDEF_VARIABLE_ERROR; 10441556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard return(0); 10442556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard } 10443556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard valuePush(ctxt, val); 10444f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10445f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 10446f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10447f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_FUNCTION:{ 10448f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathFunction func; 10449f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard const xmlChar *oldFunc, *oldFuncURI; 10450556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard int i; 10451f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10452f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch1 != -1) 10453f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += 10454f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]); 10455556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard if (ctxt->valueNr < op->value) { 10456556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, 10457cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard "xmlXPathCompOpEval: parameter error\n"); 10458556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard ctxt->error = XPATH_INVALID_OPERAND; 10459556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard return (total); 10460556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard } 10461556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard for (i = 0; i < op->value; i++) 10462556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard if (ctxt->valueTab[(ctxt->valueNr - 1) - i] == NULL) { 10463556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, 10464cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard "xmlXPathCompOpEval: parameter error\n"); 10465556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard ctxt->error = XPATH_INVALID_OPERAND; 10466556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard return (total); 10467556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard } 10468f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->cache != NULL) 10469ad0e67c57f26f691fc120d5c5336cee9885cf324William M. Brack XML_CAST_FPTR(func) = op->cache; 10470f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard else { 10471f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard const xmlChar *URI = NULL; 10472f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10473f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->value5 == NULL) 10474f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard func = 10475f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathFunctionLookup(ctxt->context, 10476f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard op->value4); 10477f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard else { 10478f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard URI = xmlXPathNsLookup(ctxt->context, op->value5); 10479f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (URI == NULL) { 10480f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, 10481cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard "xmlXPathCompOpEval: function %s bound to undefined prefix %s\n", 10482f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard op->value4, op->value5); 10483f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 10484f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10485f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard func = xmlXPathFunctionLookupNS(ctxt->context, 10486f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard op->value4, URI); 10487f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10488f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (func == NULL) { 10489f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, 10490cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard "xmlXPathCompOpEval: function %s not found\n", 10491f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard op->value4); 10492f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard XP_ERROR0(XPATH_UNKNOWN_FUNC_ERROR); 10493f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10494ad0e67c57f26f691fc120d5c5336cee9885cf324William M. Brack op->cache = XML_CAST_FPTR(func); 10495f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard op->cacheURI = (void *) URI; 10496f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10497f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard oldFunc = ctxt->context->function; 10498f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard oldFuncURI = ctxt->context->functionURI; 10499f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->function = op->value4; 10500f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->functionURI = op->cacheURI; 10501f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard func(ctxt, op->value); 10502f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->function = oldFunc; 10503f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->functionURI = oldFuncURI; 10504f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 10505f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10506f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_ARG: 10507088bf1163080cbbb72ba9d4a52ab08cc7c8ff6c7Daniel Veillard bakd = ctxt->context->doc; 10508088bf1163080cbbb72ba9d4a52ab08cc7c8ff6c7Daniel Veillard bak = ctxt->context->node; 10509645a924a9d50d8e0eced5dd7277214a65756c2e1William M. Brack pp = ctxt->context->proximityPosition; 10510645a924a9d50d8e0eced5dd7277214a65756c2e1William M. Brack cs = ctxt->context->contextSize; 10511f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch1 != -1) 10512f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]); 10513645a924a9d50d8e0eced5dd7277214a65756c2e1William M. Brack ctxt->context->contextSize = cs; 10514645a924a9d50d8e0eced5dd7277214a65756c2e1William M. Brack ctxt->context->proximityPosition = pp; 10515088bf1163080cbbb72ba9d4a52ab08cc7c8ff6c7Daniel Veillard ctxt->context->node = bak; 10516645a924a9d50d8e0eced5dd7277214a65756c2e1William M. Brack ctxt->context->doc = bakd; 10517556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 1051872ee48d55f9002544d011826e2897b5054b7e32cWilliam M. Brack if (op->ch2 != -1) { 10519f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]); 1052072ee48d55f9002544d011826e2897b5054b7e32cWilliam M. Brack ctxt->context->doc = bakd; 1052172ee48d55f9002544d011826e2897b5054b7e32cWilliam M. Brack ctxt->context->node = bak; 1052272ee48d55f9002544d011826e2897b5054b7e32cWilliam M. Brack CHECK_ERROR0; 1052372ee48d55f9002544d011826e2897b5054b7e32cWilliam M. Brack } 10524f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 10525f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_PREDICATE: 10526f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_FILTER:{ 10527f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathObjectPtr res; 10528f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathObjectPtr obj, tmp; 10529f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlNodeSetPtr newset = NULL; 10530f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlNodeSetPtr oldset; 10531f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlNodePtr oldnode; 105323794b9e84ac51072830a0b34d1ddd0378c0f7cb6William M. Brack xmlDocPtr oldDoc; 10533f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard int i; 10534f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10535f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* 10536f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Optimization for ()[1] selection i.e. the first elem 10537f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 10538f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((op->ch1 != -1) && (op->ch2 != -1) && 10539f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (comp->steps[op->ch1].op == XPATH_OP_SORT) && 10540f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (comp->steps[op->ch2].op == XPATH_OP_VALUE)) { 10541f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathObjectPtr val; 10542f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10543f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard val = comp->steps[op->ch2].value4; 10544f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((val != NULL) && (val->type == XPATH_NUMBER) && 10545f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (val->floatval == 1.0)) { 10546f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlNodePtr first = NULL; 10547f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10548f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += 10549f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathCompOpEvalFirst(ctxt, 10550f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard &comp->steps[op->ch1], 10551f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard &first); 10552556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 10553f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* 10554f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * The nodeset should be in document order, 10555f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Keep only the first value 10556f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 10557f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((ctxt->value != NULL) && 10558f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (ctxt->value->type == XPATH_NODESET) && 10559f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (ctxt->value->nodesetval != NULL) && 10560f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (ctxt->value->nodesetval->nodeNr > 1)) 10561f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->value->nodesetval->nodeNr = 1; 10562f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 10563f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10564f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10565f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* 10566f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Optimization for ()[last()] selection i.e. the last elem 10567f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 10568f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((op->ch1 != -1) && (op->ch2 != -1) && 10569f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (comp->steps[op->ch1].op == XPATH_OP_SORT) && 10570f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (comp->steps[op->ch2].op == XPATH_OP_SORT)) { 10571f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard int f = comp->steps[op->ch2].ch1; 10572f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10573f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((f != -1) && 10574f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (comp->steps[f].op == XPATH_OP_FUNCTION) && 10575f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (comp->steps[f].value5 == NULL) && 10576f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (comp->steps[f].value == 0) && 10577f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (comp->steps[f].value4 != NULL) && 10578f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (xmlStrEqual 10579f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (comp->steps[f].value4, BAD_CAST "last"))) { 10580f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlNodePtr last = NULL; 10581f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10582f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += 10583f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathCompOpEvalLast(ctxt, 10584f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard &comp->steps[op->ch1], 10585f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard &last); 10586556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 10587f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* 10588f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * The nodeset should be in document order, 10589f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Keep only the last value 10590f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 10591f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((ctxt->value != NULL) && 10592f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (ctxt->value->type == XPATH_NODESET) && 10593f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (ctxt->value->nodesetval != NULL) && 10594f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (ctxt->value->nodesetval->nodeTab != NULL) && 10595f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (ctxt->value->nodesetval->nodeNr > 1)) { 10596f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->value->nodesetval->nodeTab[0] = 10597f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->value->nodesetval->nodeTab[ctxt-> 10598f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard value-> 10599f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard nodesetval-> 10600f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard nodeNr - 10601f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 1]; 10602f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->value->nodesetval->nodeNr = 1; 10603f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10604f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 10605f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10606f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10607f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10608f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch1 != -1) 10609f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += 10610f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]); 10611556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 10612f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch2 == -1) 10613f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 10614f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (ctxt->value == NULL) 10615f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 10616f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10617f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard oldnode = ctxt->context->node; 106189e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 10619f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#ifdef LIBXML_XPTR_ENABLED 10620f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* 10621f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Hum are we filtering the result of an XPointer expression 10622f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 10623f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (ctxt->value->type == XPATH_LOCATIONSET) { 10624f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlLocationSetPtr newlocset = NULL; 10625f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlLocationSetPtr oldlocset; 10626f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10627f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* 10628f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Extract the old locset, and then evaluate the result of the 10629f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * expression for all the element in the locset. use it to grow 10630f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * up a new locset. 10631f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 10632f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard CHECK_TYPE0(XPATH_LOCATIONSET); 10633f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard obj = valuePop(ctxt); 10634f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard oldlocset = obj->user; 10635f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->node = NULL; 10636f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10637f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((oldlocset == NULL) || (oldlocset->locNr == 0)) { 10638f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->contextSize = 0; 10639f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->proximityPosition = 0; 10640f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch2 != -1) 10641f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += 10642f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathCompOpEval(ctxt, 10643f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard &comp->steps[op->ch2]); 10644f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard res = valuePop(ctxt); 10645f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (res != NULL) 10646f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathFreeObject(res); 10647f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard valuePush(ctxt, obj); 10648f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard CHECK_ERROR0; 10649f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 10650f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10651f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard newlocset = xmlXPtrLocationSetCreate(NULL); 10652f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10653f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard for (i = 0; i < oldlocset->locNr; i++) { 10654f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* 10655f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Run the evaluation with a node list made of a 10656f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * single item in the nodelocset. 10657f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 10658f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->node = oldlocset->locTab[i]->user; 10659f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->contextSize = oldlocset->locNr; 10660f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->proximityPosition = i + 1; 10661f7eb794c142e31ca895f2d7743f872a809e514abWilliam M. Brack tmp = xmlXPathNewNodeSet(ctxt->context->node); 10662f7eb794c142e31ca895f2d7743f872a809e514abWilliam M. Brack valuePush(ctxt, tmp); 10663f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10664f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch2 != -1) 10665f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += 10666f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathCompOpEval(ctxt, 10667f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard &comp->steps[op->ch2]); 106682c19a7bf2ee0f78485840cac50f2a989f5efe476William M. Brack if (ctxt->error != XPATH_EXPRESSION_OK) { 106692c19a7bf2ee0f78485840cac50f2a989f5efe476William M. Brack xmlXPathFreeObject(obj); 106702c19a7bf2ee0f78485840cac50f2a989f5efe476William M. Brack return(0); 106712c19a7bf2ee0f78485840cac50f2a989f5efe476William M. Brack } 10672f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10673f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* 10674f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * The result of the evaluation need to be tested to 10675f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * decided whether the filter succeeded or not 10676f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 10677f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard res = valuePop(ctxt); 10678f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (xmlXPathEvaluatePredicateResult(ctxt, res)) { 10679f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPtrLocationSetAdd(newlocset, 10680f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathObjectCopy 10681f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (oldlocset->locTab[i])); 10682f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10683f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10684f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* 10685f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Cleanup 10686f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 10687f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (res != NULL) 10688f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathFreeObject(res); 10689f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (ctxt->value == tmp) { 10690f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard res = valuePop(ctxt); 10691f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathFreeObject(res); 10692f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10693f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10694f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->node = NULL; 10695f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10696f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10697f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* 10698f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * The result is used as the new evaluation locset. 10699f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 10700f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathFreeObject(obj); 10701f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->node = NULL; 10702f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->contextSize = -1; 10703f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->proximityPosition = -1; 10704f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard valuePush(ctxt, xmlXPtrWrapLocationSet(newlocset)); 10705f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->node = oldnode; 10706f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 10707f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 107089e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard#endif /* LIBXML_XPTR_ENABLED */ 107099e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 10710f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* 10711f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Extract the old set, and then evaluate the result of the 10712f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * expression for all the element in the set. use it to grow 10713f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * up a new set. 10714f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 10715f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard CHECK_TYPE0(XPATH_NODESET); 10716f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard obj = valuePop(ctxt); 10717f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard oldset = obj->nodesetval; 10718f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10719f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard oldnode = ctxt->context->node; 107203794b9e84ac51072830a0b34d1ddd0378c0f7cb6William M. Brack oldDoc = ctxt->context->doc; 10721f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->node = NULL; 10722f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10723f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((oldset == NULL) || (oldset->nodeNr == 0)) { 10724f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->contextSize = 0; 10725f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->proximityPosition = 0; 107268fad8bff2c2e0b064a6d48d4eeb663804de5545fWilliam M. Brack/* 10727f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch2 != -1) 10728f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += 10729f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathCompOpEval(ctxt, 10730f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard &comp->steps[op->ch2]); 10731556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 10732f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard res = valuePop(ctxt); 10733f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (res != NULL) 10734f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathFreeObject(res); 107358fad8bff2c2e0b064a6d48d4eeb663804de5545fWilliam M. Brack*/ 10736f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard valuePush(ctxt, obj); 10737f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->node = oldnode; 10738f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard CHECK_ERROR0; 10739f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } else { 10740f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* 10741f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Initialize the new set. 107423794b9e84ac51072830a0b34d1ddd0378c0f7cb6William M. Brack * Also set the xpath document in case things like 107433794b9e84ac51072830a0b34d1ddd0378c0f7cb6William M. Brack * key() evaluation are attempted on the predicate 10744f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 10745f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard newset = xmlXPathNodeSetCreate(NULL); 10746f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10747f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard for (i = 0; i < oldset->nodeNr; i++) { 10748f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* 10749f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Run the evaluation with a node list made of 10750f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * a single item in the nodeset. 10751f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 10752f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->node = oldset->nodeTab[i]; 107533794b9e84ac51072830a0b34d1ddd0378c0f7cb6William M. Brack if ((oldset->nodeTab[i]->type != XML_NAMESPACE_DECL) && 107543794b9e84ac51072830a0b34d1ddd0378c0f7cb6William M. Brack (oldset->nodeTab[i]->doc != NULL)) 107553794b9e84ac51072830a0b34d1ddd0378c0f7cb6William M. Brack ctxt->context->doc = oldset->nodeTab[i]->doc; 10756f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard tmp = xmlXPathNewNodeSet(ctxt->context->node); 10757f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard valuePush(ctxt, tmp); 10758f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->contextSize = oldset->nodeNr; 10759f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->proximityPosition = i + 1; 10760f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10761f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch2 != -1) 10762f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += 10763f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathCompOpEval(ctxt, 10764f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard &comp->steps[op->ch2]); 107652c19a7bf2ee0f78485840cac50f2a989f5efe476William M. Brack if (ctxt->error != XPATH_EXPRESSION_OK) { 107662c19a7bf2ee0f78485840cac50f2a989f5efe476William M. Brack xmlXPathFreeNodeSet(newset); 107672c19a7bf2ee0f78485840cac50f2a989f5efe476William M. Brack xmlXPathFreeObject(obj); 107682c19a7bf2ee0f78485840cac50f2a989f5efe476William M. Brack return(0); 107692c19a7bf2ee0f78485840cac50f2a989f5efe476William M. Brack } 10770f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10771f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* 10772081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack * The result of the evaluation needs to be tested to 10773081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack * decide whether the filter succeeded or not 10774f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 10775f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard res = valuePop(ctxt); 10776f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (xmlXPathEvaluatePredicateResult(ctxt, res)) { 10777f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathNodeSetAdd(newset, oldset->nodeTab[i]); 10778f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10779f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10780f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* 10781f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Cleanup 10782f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 10783f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (res != NULL) 10784f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathFreeObject(res); 10785f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (ctxt->value == tmp) { 10786f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard res = valuePop(ctxt); 10787f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathFreeObject(res); 10788f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10789f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10790f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->node = NULL; 10791f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10792f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10793f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* 10794f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * The result is used as the new evaluation set. 10795f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 10796f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathFreeObject(obj); 10797f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->node = NULL; 10798f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->contextSize = -1; 10799f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->proximityPosition = -1; 108003794b9e84ac51072830a0b34d1ddd0378c0f7cb6William M. Brack /* may want to move this past the '}' later */ 108013794b9e84ac51072830a0b34d1ddd0378c0f7cb6William M. Brack ctxt->context->doc = oldDoc; 10802f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard valuePush(ctxt, xmlXPathWrapNodeSet(newset)); 10803f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10804f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->node = oldnode; 10805f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 10806f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10807f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_SORT: 10808f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch1 != -1) 10809f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]); 10810556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 10811f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((ctxt->value != NULL) && 10812f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (ctxt->value->type == XPATH_NODESET) && 10813f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (ctxt->value->nodesetval != NULL)) 10814f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathNodeSetSort(ctxt->value->nodesetval); 10815f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 108169e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard#ifdef LIBXML_XPTR_ENABLED 10817f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_RANGETO:{ 10818f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathObjectPtr range; 10819f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathObjectPtr res, obj; 10820f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathObjectPtr tmp; 10821081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack xmlLocationSetPtr newlocset = NULL; 10822081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack xmlLocationSetPtr oldlocset; 10823f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlNodeSetPtr oldset; 1082472ee48d55f9002544d011826e2897b5054b7e32cWilliam M. Brack int i, j; 10825f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10826f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch1 != -1) 10827f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += 10828f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]); 10829f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch2 == -1) 10830f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 10831f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10832081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack if (ctxt->value->type == XPATH_LOCATIONSET) { 10833081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack /* 10834081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack * Extract the old locset, and then evaluate the result of the 10835081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack * expression for all the element in the locset. use it to grow 10836081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack * up a new locset. 10837081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack */ 10838081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack CHECK_TYPE0(XPATH_LOCATIONSET); 10839081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack obj = valuePop(ctxt); 10840081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack oldlocset = obj->user; 10841f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10842081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack if ((oldlocset == NULL) || (oldlocset->locNr == 0)) { 1084372ee48d55f9002544d011826e2897b5054b7e32cWilliam M. Brack ctxt->context->node = NULL; 10844081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack ctxt->context->contextSize = 0; 10845081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack ctxt->context->proximityPosition = 0; 10846081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack total += xmlXPathCompOpEval(ctxt,&comp->steps[op->ch2]); 10847081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack res = valuePop(ctxt); 10848081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack if (res != NULL) 10849081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack xmlXPathFreeObject(res); 10850081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack valuePush(ctxt, obj); 10851081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack CHECK_ERROR0; 10852081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack return (total); 10853081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack } 10854081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack newlocset = xmlXPtrLocationSetCreate(NULL); 10855f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10856081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack for (i = 0; i < oldlocset->locNr; i++) { 10857f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* 10858081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack * Run the evaluation with a node list made of a 10859081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack * single item in the nodelocset. 10860f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 10861f7eb794c142e31ca895f2d7743f872a809e514abWilliam M. Brack ctxt->context->node = oldlocset->locTab[i]->user; 10862f7eb794c142e31ca895f2d7743f872a809e514abWilliam M. Brack ctxt->context->contextSize = oldlocset->locNr; 10863f7eb794c142e31ca895f2d7743f872a809e514abWilliam M. Brack ctxt->context->proximityPosition = i + 1; 10864f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard tmp = xmlXPathNewNodeSet(ctxt->context->node); 10865f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard valuePush(ctxt, tmp); 10866f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10867f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch2 != -1) 10868f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += 10869f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathCompOpEval(ctxt, 10870f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard &comp->steps[op->ch2]); 108712c19a7bf2ee0f78485840cac50f2a989f5efe476William M. Brack if (ctxt->error != XPATH_EXPRESSION_OK) { 108722c19a7bf2ee0f78485840cac50f2a989f5efe476William M. Brack xmlXPathFreeObject(obj); 108732c19a7bf2ee0f78485840cac50f2a989f5efe476William M. Brack return(0); 108742c19a7bf2ee0f78485840cac50f2a989f5efe476William M. Brack } 10875f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10876f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard res = valuePop(ctxt); 1087772ee48d55f9002544d011826e2897b5054b7e32cWilliam M. Brack if (res->type == XPATH_LOCATIONSET) { 1087872ee48d55f9002544d011826e2897b5054b7e32cWilliam M. Brack xmlLocationSetPtr rloc = 1087972ee48d55f9002544d011826e2897b5054b7e32cWilliam M. Brack (xmlLocationSetPtr)res->user; 1088072ee48d55f9002544d011826e2897b5054b7e32cWilliam M. Brack for (j=0; j<rloc->locNr; j++) { 1088172ee48d55f9002544d011826e2897b5054b7e32cWilliam M. Brack range = xmlXPtrNewRange( 1088272ee48d55f9002544d011826e2897b5054b7e32cWilliam M. Brack oldlocset->locTab[i]->user, 1088372ee48d55f9002544d011826e2897b5054b7e32cWilliam M. Brack oldlocset->locTab[i]->index, 1088472ee48d55f9002544d011826e2897b5054b7e32cWilliam M. Brack rloc->locTab[j]->user2, 1088572ee48d55f9002544d011826e2897b5054b7e32cWilliam M. Brack rloc->locTab[j]->index2); 1088672ee48d55f9002544d011826e2897b5054b7e32cWilliam M. Brack if (range != NULL) { 1088772ee48d55f9002544d011826e2897b5054b7e32cWilliam M. Brack xmlXPtrLocationSetAdd(newlocset, range); 1088872ee48d55f9002544d011826e2897b5054b7e32cWilliam M. Brack } 1088972ee48d55f9002544d011826e2897b5054b7e32cWilliam M. Brack } 1089072ee48d55f9002544d011826e2897b5054b7e32cWilliam M. Brack } else { 1089172ee48d55f9002544d011826e2897b5054b7e32cWilliam M. Brack range = xmlXPtrNewRangeNodeObject( 1089272ee48d55f9002544d011826e2897b5054b7e32cWilliam M. Brack (xmlNodePtr)oldlocset->locTab[i]->user, res); 1089372ee48d55f9002544d011826e2897b5054b7e32cWilliam M. Brack if (range != NULL) { 1089472ee48d55f9002544d011826e2897b5054b7e32cWilliam M. Brack xmlXPtrLocationSetAdd(newlocset,range); 1089572ee48d55f9002544d011826e2897b5054b7e32cWilliam M. Brack } 10896f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10897f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10898f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* 10899f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Cleanup 10900f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 10901f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (res != NULL) 10902f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathFreeObject(res); 10903f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (ctxt->value == tmp) { 10904f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard res = valuePop(ctxt); 10905f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathFreeObject(res); 10906f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10907f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10908f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->node = NULL; 10909f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 1091072ee48d55f9002544d011826e2897b5054b7e32cWilliam M. Brack } else { /* Not a location set */ 10911081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack CHECK_TYPE0(XPATH_NODESET); 10912081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack obj = valuePop(ctxt); 10913081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack oldset = obj->nodesetval; 10914081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack ctxt->context->node = NULL; 10915081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack 10916081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack newlocset = xmlXPtrLocationSetCreate(NULL); 10917081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack 10918081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack if (oldset != NULL) { 10919081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack for (i = 0; i < oldset->nodeNr; i++) { 10920081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack /* 10921081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack * Run the evaluation with a node list made of a single item 10922081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack * in the nodeset. 10923081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack */ 10924081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack ctxt->context->node = oldset->nodeTab[i]; 10925081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack tmp = xmlXPathNewNodeSet(ctxt->context->node); 10926081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack valuePush(ctxt, tmp); 10927081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack 10928081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack if (op->ch2 != -1) 10929081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack total += 10930081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack xmlXPathCompOpEval(ctxt, 10931081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack &comp->steps[op->ch2]); 109322c19a7bf2ee0f78485840cac50f2a989f5efe476William M. Brack if (ctxt->error != XPATH_EXPRESSION_OK) { 109332c19a7bf2ee0f78485840cac50f2a989f5efe476William M. Brack xmlXPathFreeObject(obj); 109342c19a7bf2ee0f78485840cac50f2a989f5efe476William M. Brack return(0); 109352c19a7bf2ee0f78485840cac50f2a989f5efe476William M. Brack } 10936081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack 10937081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack res = valuePop(ctxt); 10938081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack range = 10939081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack xmlXPtrNewRangeNodeObject(oldset->nodeTab[i], 10940081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack res); 10941081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack if (range != NULL) { 10942081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack xmlXPtrLocationSetAdd(newlocset, range); 10943081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack } 10944081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack 10945081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack /* 10946081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack * Cleanup 10947081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack */ 10948081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack if (res != NULL) 10949081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack xmlXPathFreeObject(res); 10950081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack if (ctxt->value == tmp) { 10951081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack res = valuePop(ctxt); 10952081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack xmlXPathFreeObject(res); 10953081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack } 10954081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack 10955081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack ctxt->context->node = NULL; 10956081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack } 10957081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack } 10958f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10959f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10960f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* 10961f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * The result is used as the new evaluation set. 10962f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 10963f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathFreeObject(obj); 10964f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->node = NULL; 10965f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->contextSize = -1; 10966f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->proximityPosition = -1; 10967081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack valuePush(ctxt, xmlXPtrWrapLocationSet(newlocset)); 10968f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 10969f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 109709e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard#endif /* LIBXML_XPTR_ENABLED */ 109719e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } 109729e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlGenericError(xmlGenericErrorContext, 10973f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard "XPath: unknown precompiled operation %d\n", op->op); 10974f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 109759e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard} 109769e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 1097756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard#ifdef XPATH_STREAMING 1097856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard/** 1097956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard * xmlXPathRunStreamEval: 1098056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard * @ctxt: the XPath parser context with the compiled expression 1098156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard * 1098256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard * Evaluate the Precompiled Streamable XPath expression in the given context. 1098356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard */ 1098456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillardstatic xmlXPathObjectPtr 1098556de87ee0d147d04a041eb1ec95048566375bc3fDaniel VeillardxmlXPathRunStreamEval(xmlXPathContextPtr ctxt, xmlPatternPtr comp) { 1098656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard int max_depth; 1098756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard int from_root; 1098856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard int ret, depth; 1098912d37ab63441baf9e03db70168cc1d0d6f1c2373William M. Brack xmlNodePtr cur = NULL, limit = NULL; 1099056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard xmlXPathObjectPtr retval; 1099156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard xmlStreamCtxtPtr patstream; 1099256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard 1099356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard int nb_nodes = 0; 1099456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard 1099556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard if ((ctxt == NULL) || (comp == NULL)) 1099656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard return(NULL); 1099756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard max_depth = xmlPatternMaxDepth(comp); 1099856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard if (max_depth == -1) 1099956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard return(NULL); 1100056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard if (max_depth == -2) 1100156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard max_depth = 10000; 1100256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard from_root = xmlPatternFromRoot(comp); 1100356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard if (from_root < 0) 1100456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard return(NULL); 11005fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard#if 0 11006fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard printf("stream eval: depth %d from root %d\n", max_depth, from_root); 11007fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard#endif 1100856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard 1100956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard retval = xmlXPathNewNodeSet(NULL); 1101056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard if (retval == NULL) 1101156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard return(NULL); 1101256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard 1101356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard if ((from_root) && (max_depth == 0)) { 1101456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard xmlXPathNodeSetAddUnique(retval->nodesetval, (xmlNodePtr) ctxt->doc); 1101556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard return(retval); 1101656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard } else if (max_depth == 0) { 1101756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard xmlXPathNodeSetAddUnique(retval->nodesetval, ctxt->node); 1101856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard return(retval); 1101956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard } 1102056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard if (from_root) { 1102112d37ab63441baf9e03db70168cc1d0d6f1c2373William M. Brack cur = (xmlNodePtr)ctxt->doc; 1102256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard } else if (ctxt->node != NULL) { 1102356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard switch (ctxt->node->type) { 1102456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard case XML_ELEMENT_NODE: 1102556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard case XML_DOCUMENT_NODE: 1102656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard case XML_DOCUMENT_FRAG_NODE: 1102756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard case XML_HTML_DOCUMENT_NODE: 1102856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard#ifdef LIBXML_DOCB_ENABLED 1102956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard case XML_DOCB_DOCUMENT_NODE: 1103056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard#endif 1103156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard cur = ctxt->node; 1103256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard break; 1103356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard case XML_ATTRIBUTE_NODE: 1103456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard case XML_TEXT_NODE: 1103556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard case XML_CDATA_SECTION_NODE: 1103656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard case XML_ENTITY_REF_NODE: 1103756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard case XML_ENTITY_NODE: 1103856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard case XML_PI_NODE: 1103956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard case XML_COMMENT_NODE: 1104056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard case XML_NOTATION_NODE: 1104156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard case XML_DTD_NODE: 1104256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard case XML_DOCUMENT_TYPE_NODE: 1104356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard case XML_ELEMENT_DECL: 1104456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard case XML_ATTRIBUTE_DECL: 1104556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard case XML_ENTITY_DECL: 1104656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard case XML_NAMESPACE_DECL: 1104756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard case XML_XINCLUDE_START: 1104856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard case XML_XINCLUDE_END: 1104956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard break; 1105056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard } 1105156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard limit = cur; 1105256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard } 1105356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard if (cur == NULL) 1105456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard return(retval); 1105556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard 1105656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard patstream = xmlPatternGetStreamCtxt(comp); 1105756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard if (patstream == NULL) { 1105856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard return(retval); 1105956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard } 1106056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard 1106156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard if (from_root) { 1106256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard ret = xmlStreamPush(patstream, NULL, NULL); 1106356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard if (ret < 0) { 1106456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard } else if (ret == 1) { 1106556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard xmlXPathNodeSetAddUnique(retval->nodesetval, cur); 1106656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard } 1106756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard } 1106856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard 1106956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard depth = 0; 1107056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard goto scan_children; 1107156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard do { 1107256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillardnext_node: 1107356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard nb_nodes++; 1107456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard if (cur->type == XML_ELEMENT_NODE) { 1107556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard ret = xmlStreamPush(patstream, cur->name, 1107656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard (cur->ns ? cur->ns->href : NULL)); 1107756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard if (ret < 0) { 1107856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard } else if (ret == 1) { 1107956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard xmlXPathNodeSetAddUnique(retval->nodesetval, cur); 1108056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard } 1108156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard if ((cur->children == NULL) || (depth >= max_depth)) { 1108256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard ret = xmlStreamPop(patstream); 11083fbb619f4762fd50630e3ec22589838d089cd2f08William M. Brack while (cur->next != NULL) { 11084fbb619f4762fd50630e3ec22589838d089cd2f08William M. Brack cur = cur->next; 11085fbb619f4762fd50630e3ec22589838d089cd2f08William M. Brack if ((cur->type != XML_ENTITY_DECL) && 11086fbb619f4762fd50630e3ec22589838d089cd2f08William M. Brack (cur->type != XML_DTD_NODE)) 11087fbb619f4762fd50630e3ec22589838d089cd2f08William M. Brack goto next_node; 11088fbb619f4762fd50630e3ec22589838d089cd2f08William M. Brack } 1108956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard } 1109056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard } 1109156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard 1109256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillardscan_children: 1109356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard if ((cur->children != NULL) && (depth < max_depth)) { 1109456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard /* 1109556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard * Do not descend on entities declarations 1109656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard */ 1109756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard if (cur->children->type != XML_ENTITY_DECL) { 1109856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard cur = cur->children; 1109956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard depth++; 1110056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard /* 1110156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard * Skip DTDs 1110256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard */ 1110356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard if (cur->type != XML_DTD_NODE) 1110456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard continue; 1110556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard } 1110656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard } 1110756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard 1110856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard if (cur == limit) 1110956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard break; 1111056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard 1111156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard while (cur->next != NULL) { 1111256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard cur = cur->next; 1111356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard if ((cur->type != XML_ENTITY_DECL) && 1111456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard (cur->type != XML_DTD_NODE)) 1111556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard goto next_node; 1111656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard } 1111756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard 1111856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard do { 1111956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard cur = cur->parent; 1112056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard depth--; 1112156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard if ((cur == NULL) || (cur == limit)) 1112256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard goto done; 11123fbb619f4762fd50630e3ec22589838d089cd2f08William M. Brack if (cur->type == XML_ELEMENT_NODE) 11124fbb619f4762fd50630e3ec22589838d089cd2f08William M. Brack ret = xmlStreamPop(patstream); 1112556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard if (cur->next != NULL) { 1112656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard cur = cur->next; 1112756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard break; 1112856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard } 1112956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard } while (cur != NULL); 1113056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard 1113156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard } while ((cur != NULL) && (depth >= 0)); 1113256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillarddone: 11133fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard#if 0 11134fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard printf("stream eval: checked %d nodes selected %d\n", 11135fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard nb_nodes, retval->nodesetval->nodeNr); 11136fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard#endif 1113756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard xmlFreeStreamCtxt(patstream); 1113856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard return(retval); 1113956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard} 1114056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard#endif /* XPATH_STREAMING */ 1114156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard 111429e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard/** 111439e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * xmlXPathRunEval: 111449e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * @ctxt: the XPath parser context with the compiled expression 111459e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * 111469e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * Evaluate the Precompiled XPath expression in the given context. 111479e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard */ 11148fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillardstatic void 111499e7160d45a18bfa26d708e22ba991f7670d0128bDaniel VeillardxmlXPathRunEval(xmlXPathParserContextPtr ctxt) { 111509e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlXPathCompExprPtr comp; 111519e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 111529e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if ((ctxt == NULL) || (ctxt->comp == NULL)) 111539e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard return; 111549e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 111559e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (ctxt->valueTab == NULL) { 111569e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard /* Allocate the value stack */ 111579e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard ctxt->valueTab = (xmlXPathObjectPtr *) 111589e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlMalloc(10 * sizeof(xmlXPathObjectPtr)); 111599e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (ctxt->valueTab == NULL) { 11160d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard xmlXPathPErrMemory(ctxt, "creating evaluation context\n"); 111619e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlFree(ctxt); 111629e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } 111639e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard ctxt->valueNr = 0; 111649e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard ctxt->valueMax = 10; 111659e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard ctxt->value = NULL; 111669e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } 1116756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard#ifdef XPATH_STREAMING 1116856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard if (ctxt->comp->stream) { 1116956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard xmlXPathObjectPtr ret; 1117056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard ret = xmlXPathRunStreamEval(ctxt->context, ctxt->comp->stream); 1117156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard if (ret != NULL) { 1117256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard valuePush(ctxt, ret); 1117356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard return; 1117456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard } 1117556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard } 1117656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard#endif 111779e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard comp = ctxt->comp; 1117829b6f76c5326616aed5dcff9cb55145137863e97Aleksey Sanin if(comp->last < 0) { 1117929b6f76c5326616aed5dcff9cb55145137863e97Aleksey Sanin xmlGenericError(xmlGenericErrorContext, 1118029b6f76c5326616aed5dcff9cb55145137863e97Aleksey Sanin "xmlXPathRunEval: last is less than zero\n"); 1118129b6f76c5326616aed5dcff9cb55145137863e97Aleksey Sanin return; 1118229b6f76c5326616aed5dcff9cb55145137863e97Aleksey Sanin } 111839e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlXPathCompOpEval(ctxt, &comp->steps[comp->last]); 111849e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard} 111859e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 11186afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard/************************************************************************ 11187afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * * 11188afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Public interfaces * 11189afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * * 11190afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard ************************************************************************/ 11191afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard 11192afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard/** 11193fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * xmlXPathEvalPredicate: 11194fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * @ctxt: the XPath context 11195fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * @res: the Predicate Expression evaluation result 11196fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * 11197fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * Evaluate a predicate result for the current node. 11198fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * A PredicateExpr is evaluated by evaluating the Expr and converting 11199fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * the result to a boolean. If the result is a number, the result will 11200fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * be converted to true if the number is equal to the position of the 11201fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * context node in the context node list (as returned by the position 11202fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * function) and will be converted to false otherwise; if the result 11203fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * is not a number, then the result will be converted as if by a call 11204fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * to the boolean function. 11205fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * 11206cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * Returns 1 if predicate is true, 0 otherwise 11207fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard */ 11208fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillardint 11209fbf8a2d0c8145b713099df63d174154a8442e60dDaniel VeillardxmlXPathEvalPredicate(xmlXPathContextPtr ctxt, xmlXPathObjectPtr res) { 11210ce682bc24b79f1dd29b781d4c17f9bf169ce7e32Daniel Veillard if ((ctxt == NULL) || (res == NULL)) return(0); 11211fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard switch (res->type) { 11212fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard case XPATH_BOOLEAN: 11213fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard return(res->boolval); 11214fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard case XPATH_NUMBER: 11215fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard return(res->floatval == ctxt->proximityPosition); 11216fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard case XPATH_NODESET: 11217fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard case XPATH_XSLT_TREE: 11218d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard if (res->nodesetval == NULL) 11219d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard return(0); 11220fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard return(res->nodesetval->nodeNr != 0); 11221fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard case XPATH_STRING: 11222fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard return((res->stringval != NULL) && 11223fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard (xmlStrlen(res->stringval) != 0)); 11224fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard default: 11225fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard STRANGE 11226fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard } 11227fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard return(0); 11228fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard} 11229fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard 11230fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard/** 11231afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathEvaluatePredicateResult: 11232afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * @ctxt: the XPath Parser context 11233afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * @res: the Predicate Expression evaluation result 11234afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * 11235afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Evaluate a predicate result for the current node. 11236afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * A PredicateExpr is evaluated by evaluating the Expr and converting 11237afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * the result to a boolean. If the result is a number, the result will 11238afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * be converted to true if the number is equal to the position of the 11239afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * context node in the context node list (as returned by the position 11240afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * function) and will be converted to false otherwise; if the result 11241afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * is not a number, then the result will be converted as if by a call 11242afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * to the boolean function. 11243afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * 11244cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * Returns 1 if predicate is true, 0 otherwise 11245afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard */ 11246afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardint 11247afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathEvaluatePredicateResult(xmlXPathParserContextPtr ctxt, 11248afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathObjectPtr res) { 11249ce682bc24b79f1dd29b781d4c17f9bf169ce7e32Daniel Veillard if ((ctxt == NULL) || (res == NULL)) return(0); 11250afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard switch (res->type) { 11251afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard case XPATH_BOOLEAN: 11252afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard return(res->boolval); 11253afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard case XPATH_NUMBER: 112549ea6231ecef04c848b688355b8f7532dd5e4c6f8Daniel Veillard#if defined(__BORLANDC__) || (defined(_MSC_VER) && (_MSC_VER == 1200)) 112557c4eb63bb01d754b17860cd7dc2ab2fef81f6a08Daniel Veillard return((res->floatval == ctxt->context->proximityPosition) && 112567c4eb63bb01d754b17860cd7dc2ab2fef81f6a08Daniel Veillard (!xmlXPathIsNaN(res->floatval))); /* MSC pbm Mark Vakoc !*/ 112572582a338bff77569b5aadbba8f40e1f3862d090dDaniel Veillard#else 11258afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard return(res->floatval == ctxt->context->proximityPosition); 112592582a338bff77569b5aadbba8f40e1f3862d090dDaniel Veillard#endif 11260afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard case XPATH_NODESET: 11261afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard case XPATH_XSLT_TREE: 1126273639a73c5a51c3739595f54c338bb531c1319c2Daniel Veillard if (res->nodesetval == NULL) 11263911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard return(0); 11264afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard return(res->nodesetval->nodeNr != 0); 11265afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard case XPATH_STRING: 11266afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard return((res->stringval != NULL) && 11267afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard (xmlStrlen(res->stringval) != 0)); 11268081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack#ifdef LIBXML_XPTR_ENABLED 11269081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack case XPATH_LOCATIONSET:{ 11270081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack xmlLocationSetPtr ptr = res->user; 11271081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack if (ptr == NULL) 11272081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack return(0); 11273081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack return (ptr->locNr != 0); 11274081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack } 11275081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack#endif 11276afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard default: 11277afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard STRANGE 11278afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard } 11279afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard return(0); 11280afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard} 11281afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard 1128256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard#ifdef XPATH_STREAMING 1128356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard/** 1128456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard * xmlXPathTryStreamCompile: 1128556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard * @ctxt: an XPath context 1128656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard * @str: the XPath expression 1128756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard * 1128856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard * Try to compile the XPath expression as a streamable subset. 1128956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard * 1129056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard * Returns the compiled expression or NULL if failed to compile. 1129156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard */ 1129256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillardstatic xmlXPathCompExprPtr 1129356de87ee0d147d04a041eb1ec95048566375bc3fDaniel VeillardxmlXPathTryStreamCompile(xmlXPathContextPtr ctxt, const xmlChar *str) { 1129456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard /* 1129556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard * Optimization: use streaming patterns when the XPath expression can 1129656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard * be compiled to a stream lookup 1129756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard */ 1129856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard xmlPatternPtr stream; 1129956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard xmlXPathCompExprPtr comp; 1130056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard xmlDictPtr dict = NULL; 1130156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard const xmlChar **namespaces = NULL; 1130256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard xmlNsPtr ns; 1130356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard int i, j; 1130456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard 1130556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard if ((!xmlStrchr(str, '[')) && (!xmlStrchr(str, '(')) && 1130656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard (!xmlStrchr(str, '@'))) { 1130756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard if (ctxt != NULL) { 1130856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard dict = ctxt->dict; 1130956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard if (ctxt->nsNr > 0) { 11310dbfe05aff4d242e31fcd7621a4901a6fa10b988eDaniel Veillard namespaces = xmlMalloc(2 * (ctxt->nsNr + 1) * sizeof(xmlChar*)); 1131156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard if (namespaces == NULL) { 1131256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard xmlXPathErrMemory(ctxt, "allocating namespaces array\n"); 1131356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard return(NULL); 1131456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard } 1131556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard for (i = 0, j = 0; (j < ctxt->nsNr); j++) { 1131656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard ns = ctxt->namespaces[j]; 1131756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard namespaces[i++] = ns->href; 1131856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard namespaces[i++] = ns->prefix; 1131956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard } 1132056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard namespaces[i++] = NULL; 1132156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard namespaces[i++] = NULL; 1132256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard } 1132356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard } 1132456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard 11325ea152c05b3f3d9e47b282b88ffdb16fcb8c779c1William M. Brack stream = xmlPatterncompile(str, dict, XML_PATTERN_XPATH, 11326ea152c05b3f3d9e47b282b88ffdb16fcb8c779c1William M. Brack &namespaces[0]); 1132756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard if ((stream != NULL) && (xmlPatternStreamable(stream) == 1)) { 1132856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard comp = xmlXPathNewCompExpr(); 1132956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard if (comp == NULL) { 1133056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard xmlXPathErrMemory(ctxt, "allocating streamable expression\n"); 1133156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard return(NULL); 1133256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard } 1133356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard comp->stream = stream; 1133456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard comp->dict = dict; 1133556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard if (comp->dict) 1133656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard xmlDictReference(comp->dict); 1133756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard return(comp); 1133856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard } 1133956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard xmlFreePattern(stream); 1134056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard } 1134156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard return(NULL); 1134256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard} 1134356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard#endif /* XPATH_STREAMING */ 1134456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard 11345afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard/** 113464773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard * xmlXPathCtxtCompile: 113474773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard * @ctxt: an XPath context 11348afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * @str: the XPath expression 11349afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * 11350afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile an XPath expression 11351afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * 11352591b4be0fe1986b5e71d54c5c063493987ef4285Daniel Veillard * Returns the xmlXPathCompExprPtr resulting from the compilation or NULL. 11353afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * the caller has to free the object. 11354afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard */ 11355afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompExprPtr 113564773df2a58be83e1b9b1b55840371acf37386820Daniel VeillardxmlXPathCtxtCompile(xmlXPathContextPtr ctxt, const xmlChar *str) { 113574773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard xmlXPathParserContextPtr pctxt; 11358afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompExprPtr comp; 11359afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard 1136056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard#ifdef XPATH_STREAMING 1136156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard comp = xmlXPathTryStreamCompile(ctxt, str); 1136256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard if (comp != NULL) 1136356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard return(comp); 1136456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard#endif 1136556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard 11366afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathInit(); 11367afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard 113684773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard pctxt = xmlXPathNewParserContext(str, ctxt); 113694773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard xmlXPathCompileExpr(pctxt); 11370ae9733aeaf99e5d967b6b2cd961c98bf58cfbb4cDaniel Veillard 113714773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard if( pctxt->error != XPATH_EXPRESSION_OK ) 11372ae9733aeaf99e5d967b6b2cd961c98bf58cfbb4cDaniel Veillard { 113734773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard xmlXPathFreeParserContext(pctxt); 11374ae9733aeaf99e5d967b6b2cd961c98bf58cfbb4cDaniel Veillard return (0); 11375ae9733aeaf99e5d967b6b2cd961c98bf58cfbb4cDaniel Veillard } 11376ae9733aeaf99e5d967b6b2cd961c98bf58cfbb4cDaniel Veillard 113774773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard if (*pctxt->cur != 0) { 1137850fe8b1732048003f47b32b009507fe6cdecd39fAleksey Sanin /* 1137950fe8b1732048003f47b32b009507fe6cdecd39fAleksey Sanin * aleksey: in some cases this line prints *second* error message 1138050fe8b1732048003f47b32b009507fe6cdecd39fAleksey Sanin * (see bug #78858) and probably this should be fixed. 1138150fe8b1732048003f47b32b009507fe6cdecd39fAleksey Sanin * However, we are not sure that all error messages are printed 1138250fe8b1732048003f47b32b009507fe6cdecd39fAleksey Sanin * out in other places. It's not critical so we leave it as-is for now 1138350fe8b1732048003f47b32b009507fe6cdecd39fAleksey Sanin */ 113844773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard xmlXPatherror(pctxt, __FILE__, __LINE__, XPATH_EXPR_ERROR); 1138540af649f9b5b32f97879f10432c56bb5ef60c958Daniel Veillard comp = NULL; 1138640af649f9b5b32f97879f10432c56bb5ef60c958Daniel Veillard } else { 113874773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard comp = pctxt->comp; 113884773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard pctxt->comp = NULL; 1138940af649f9b5b32f97879f10432c56bb5ef60c958Daniel Veillard } 113904773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard xmlXPathFreeParserContext(pctxt); 11391f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (comp != NULL) { 11392ceb09b956efa2cf1ec41c1887394396e5a6030f2Daniel Veillard comp->expr = xmlStrdup(str); 11393ceb09b956efa2cf1ec41c1887394396e5a6030f2Daniel Veillard#ifdef DEBUG_EVAL_COUNTS 11394f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard comp->string = xmlStrdup(str); 11395f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard comp->nb = 0; 11396f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#endif 11397ceb09b956efa2cf1ec41c1887394396e5a6030f2Daniel Veillard } 11398afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard return(comp); 11399afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard} 11400afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard 114019e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard/** 114024773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard * xmlXPathCompile: 114034773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard * @str: the XPath expression 114044773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard * 114054773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard * Compile an XPath expression 114064773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard * 114074773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard * Returns the xmlXPathCompExprPtr resulting from the compilation or NULL. 114084773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard * the caller has to free the object. 114094773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard */ 114104773df2a58be83e1b9b1b55840371acf37386820Daniel VeillardxmlXPathCompExprPtr 114114773df2a58be83e1b9b1b55840371acf37386820Daniel VeillardxmlXPathCompile(const xmlChar *str) { 114124773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard return(xmlXPathCtxtCompile(NULL, str)); 114134773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard} 114144773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard 114154773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard/** 114169e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * xmlXPathCompiledEval: 114179e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * @comp: the compiled XPath expression 114189e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * @ctx: the XPath context 114199e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * 114209e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * Evaluate the Precompiled XPath expression in the given context. 114219e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * 11422cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * Returns the xmlXPathObjectPtr resulting from the evaluation or NULL. 114239e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * the caller has to free the object. 114249e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard */ 114259e7160d45a18bfa26d708e22ba991f7670d0128bDaniel VeillardxmlXPathObjectPtr 114269e7160d45a18bfa26d708e22ba991f7670d0128bDaniel VeillardxmlXPathCompiledEval(xmlXPathCompExprPtr comp, xmlXPathContextPtr ctx) { 114279e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlXPathParserContextPtr ctxt; 114289e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlXPathObjectPtr res, tmp, init = NULL; 114299e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard int stack = 0; 114308146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard#ifndef LIBXML_THREAD_ENABLED 114318146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard static int reentance = 0; 114328146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard#endif 114339e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 11434f13f77f0e6a7876063d5fba15c096befb0827cedWilliam M. Brack CHECK_CTXT(ctx) 11435f13f77f0e6a7876063d5fba15c096befb0827cedWilliam M. Brack 11436f13f77f0e6a7876063d5fba15c096befb0827cedWilliam M. Brack if (comp == NULL) 114379e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard return(NULL); 114389e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlXPathInit(); 114399e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 114408146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard#ifndef LIBXML_THREAD_ENABLED 114418146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard reentance++; 114428146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard if (reentance > 1) 114438146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard xmlXPathDisableOptimizer = 1; 114448146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard#endif 114458146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard 11446f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#ifdef DEBUG_EVAL_COUNTS 11447f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard comp->nb++; 11448f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((comp->string != NULL) && (comp->nb > 100)) { 11449f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard fprintf(stderr, "100 x %s\n", comp->string); 11450f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard comp->nb = 0; 11451f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 11452f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#endif 114539e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard ctxt = xmlXPathCompParserContext(comp, ctx); 114549e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlXPathRunEval(ctxt); 114559e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 114569e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (ctxt->value == NULL) { 114579e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlGenericError(xmlGenericErrorContext, 11458cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard "xmlXPathCompiledEval: evaluation failed\n"); 114599e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard res = NULL; 114609e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } else { 114619e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard res = valuePop(ctxt); 114629e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } 114639e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 11464f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 114659e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard do { 114669e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard tmp = valuePop(ctxt); 114679e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (tmp != NULL) { 114689e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (tmp != init) 114699e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard stack++; 114709e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlXPathFreeObject(tmp); 114719e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } 114729e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } while (tmp != NULL); 114739e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if ((stack != 0) && (res != NULL)) { 114749e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlGenericError(xmlGenericErrorContext, 11475cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard "xmlXPathCompiledEval: %d object left on the stack\n", 114769e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard stack); 114779e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } 114789e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (ctxt->error != XPATH_EXPRESSION_OK) { 114799e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlXPathFreeObject(res); 114809e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard res = NULL; 114819e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } 114829e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 114839e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 11484afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard ctxt->comp = NULL; 114859e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlXPathFreeParserContext(ctxt); 114868146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard#ifndef LIBXML_THREAD_ENABLED 114878146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard reentance--; 114888146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard#endif 114899e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard return(res); 114909e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard} 114919e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 11492afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard/** 11493afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathEvalExpr: 11494afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * @ctxt: the XPath Parser context 11495afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * 11496afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Parse and evaluate an XPath expression in the given context, 11497afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * then push the result on the context stack 11498afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard */ 11499afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardvoid 11500afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathEvalExpr(xmlXPathParserContextPtr ctxt) { 1150156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard#ifdef XPATH_STREAMING 1150256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard xmlXPathCompExprPtr comp; 1150356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard#endif 1150456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard 11505a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard if (ctxt == NULL) return; 1150656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard 1150756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard#ifdef XPATH_STREAMING 1150856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard comp = xmlXPathTryStreamCompile(ctxt->context, ctxt->base); 1150956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard if (comp != NULL) { 1151056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard if (ctxt->comp != NULL) 1151156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard xmlXPathFreeCompExpr(ctxt->comp); 1151256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard ctxt->comp = comp; 1151356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard if (ctxt->cur != NULL) 1151456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard while (*ctxt->cur != 0) ctxt->cur++; 1151556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard } else 1151656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard#endif 1151756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard { 1151856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard xmlXPathCompileExpr(ctxt); 1151956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard } 1152050fe8b1732048003f47b32b009507fe6cdecd39fAleksey Sanin CHECK_ERROR; 11521afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathRunEval(ctxt); 11522afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard} 115239e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 115243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 115253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathEval: 115263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @str: the XPath expression 115273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctx: the XPath context 115283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 115293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Evaluate the XPath Location Path in the given context. 115303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 11531cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * Returns the xmlXPathObjectPtr resulting from the evaluation or NULL. 115323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the caller has to free the object. 115333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 115343473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathObjectPtr 115353473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathEval(const xmlChar *str, xmlXPathContextPtr ctx) { 115363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathParserContextPtr ctxt; 115373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr res, tmp, init = NULL; 115383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int stack = 0; 115393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 11540f13f77f0e6a7876063d5fba15c096befb0827cedWilliam M. Brack CHECK_CTXT(ctx) 115413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 11542f13f77f0e6a7876063d5fba15c096befb0827cedWilliam M. Brack xmlXPathInit(); 115433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 115443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ctxt = xmlXPathNewParserContext(str, ctx); 115453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathEvalExpr(ctxt); 115463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 115473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->value == NULL) { 115483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 115493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "xmlXPathEval: evaluation failed\n"); 115503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor res = NULL; 1155156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard } else if ((*ctxt->cur != 0) && (ctxt->comp != NULL) 1155256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard#ifdef XPATH_STREAMING 1155356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard && (ctxt->comp->stream == NULL) 1155456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard#endif 1155556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard ) { 115563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPatherror(ctxt, __FILE__, __LINE__, XPATH_EXPR_ERROR); 115573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor res = NULL; 115583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else { 115593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor res = valuePop(ctxt); 115603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 115613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 115623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor do { 115633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor tmp = valuePop(ctxt); 115643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (tmp != NULL) { 115653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (tmp != init) 115663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor stack++; 115673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(tmp); 115683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 115693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } while (tmp != NULL); 115703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((stack != 0) && (res != NULL)) { 115713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 115723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "xmlXPathEval: %d object left on the stack\n", 115733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor stack); 115743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 115753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->error != XPATH_EXPRESSION_OK) { 115763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(res); 115773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor res = NULL; 115783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 115799e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 115803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeParserContext(ctxt); 115813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(res); 115823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 115833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 115843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 115853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathEvalExpression: 115863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @str: the XPath expression 115873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath context 115883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 115893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Evaluate the XPath expression in the given context. 115903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 115913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the xmlXPathObjectPtr resulting from the evaluation or NULL. 115923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the caller has to free the object. 115933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 115943473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathObjectPtr 115953473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathEvalExpression(const xmlChar *str, xmlXPathContextPtr ctxt) { 115963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathParserContextPtr pctxt; 115973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr res, tmp; 115983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int stack = 0; 115993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 11600f13f77f0e6a7876063d5fba15c096befb0827cedWilliam M. Brack CHECK_CTXT(ctxt) 116013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 11602f13f77f0e6a7876063d5fba15c096befb0827cedWilliam M. Brack xmlXPathInit(); 116033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 116043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor pctxt = xmlXPathNewParserContext(str, ctxt); 116053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathEvalExpr(pctxt); 116063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 116073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (*pctxt->cur != 0) { 116083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPatherror(pctxt, __FILE__, __LINE__, XPATH_EXPR_ERROR); 116093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor res = NULL; 116103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else { 116113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor res = valuePop(pctxt); 116123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 116133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor do { 116143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor tmp = valuePop(pctxt); 116153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (tmp != NULL) { 116163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(tmp); 116173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor stack++; 116183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 116193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } while (tmp != NULL); 116203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((stack != 0) && (res != NULL)) { 116213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 116223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "xmlXPathEvalExpression: %d object left on the stack\n", 116233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor stack); 116243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 116253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeParserContext(pctxt); 116263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(res); 116273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 116283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1162942766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard/************************************************************************ 1163042766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * * 1163142766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * Extra functions not pertaining to the XPath spec * 1163242766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * * 1163342766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard ************************************************************************/ 1163442766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard/** 1163542766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * xmlXPathEscapeUriFunction: 1163642766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * @ctxt: the XPath Parser context 1163742766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * @nargs: the number of arguments 1163842766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * 1163942766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * Implement the escape-uri() XPath function 1164042766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * string escape-uri(string $str, bool $escape-reserved) 1164142766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * 1164242766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * This function applies the URI escaping rules defined in section 2 of [RFC 1164342766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * 2396] to the string supplied as $uri-part, which typically represents all 1164442766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * or part of a URI. The effect of the function is to replace any special 1164542766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * character in the string by an escape sequence of the form %xx%yy..., 1164642766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * where xxyy... is the hexadecimal representation of the octets used to 1164742766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * represent the character in UTF-8. 1164842766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * 1164942766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * The set of characters that are escaped depends on the setting of the 1165042766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * boolean argument $escape-reserved. 1165142766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * 1165242766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * If $escape-reserved is true, all characters are escaped other than lower 1165342766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * case letters a-z, upper case letters A-Z, digits 0-9, and the characters 1165442766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * referred to in [RFC 2396] as "marks": specifically, "-" | "_" | "." | "!" 1165542766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * | "~" | "*" | "'" | "(" | ")". The "%" character itself is escaped only 1165642766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * if it is not followed by two hexadecimal digits (that is, 0-9, a-f, and 1165742766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * A-F). 1165842766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * 1165942766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * If $escape-reserved is false, the behavior differs in that characters 1166042766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * referred to in [RFC 2396] as reserved characters are not escaped. These 1166142766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * characters are ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" | "$" | ",". 1166242766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * 1166342766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * [RFC 2396] does not define whether escaped URIs should use lower case or 1166442766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * upper case for hexadecimal digits. To ensure that escaped URIs can be 1166542766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * compared using string comparison functions, this function must always use 1166642766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * the upper-case letters A-F. 1166742766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * 1166842766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * Generally, $escape-reserved should be set to true when escaping a string 1166942766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * that is to form a single part of a URI, and to false when escaping an 1167042766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * entire URI or URI reference. 1167142766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * 1167242766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * In the case of non-ascii characters, the string is encoded according to 1167342766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * utf-8 and then converted according to RFC 2396. 1167442766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * 1167542766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * Examples 1167642766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * xf:escape-uri ("gopher://spinaltap.micro.umn.edu/00/Weather/California/Los%20Angeles#ocean"), true()) 1167742766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * returns "gopher%3A%2F%2Fspinaltap.micro.umn.edu%2F00%2FWeather%2FCalifornia%2FLos%20Angeles%23ocean" 1167842766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * xf:escape-uri ("gopher://spinaltap.micro.umn.edu/00/Weather/California/Los%20Angeles#ocean"), false()) 1167942766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * returns "gopher://spinaltap.micro.umn.edu/00/Weather/California/Los%20Angeles%23ocean" 1168042766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * 1168142766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard */ 11682118aed78f360f51d182770e62b251ef324707aa2Daniel Veillardstatic void 1168342766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel VeillardxmlXPathEscapeUriFunction(xmlXPathParserContextPtr ctxt, int nargs) { 1168442766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard xmlXPathObjectPtr str; 1168542766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard int escape_reserved; 1168642766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard xmlBufferPtr target; 1168742766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard xmlChar *cptr; 1168842766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard xmlChar escape[4]; 1168942766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard 1169042766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard CHECK_ARITY(2); 1169142766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard 1169242766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard escape_reserved = xmlXPathPopBoolean(ctxt); 1169342766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard 1169442766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard CAST_TO_STRING; 1169542766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard str = valuePop(ctxt); 1169642766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard 1169742766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard target = xmlBufferCreate(); 1169842766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard 1169942766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard escape[0] = '%'; 1170042766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard escape[3] = 0; 1170142766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard 1170242766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard if (target) { 1170342766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard for (cptr = str->stringval; *cptr; cptr++) { 1170442766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard if ((*cptr >= 'A' && *cptr <= 'Z') || 1170542766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard (*cptr >= 'a' && *cptr <= 'z') || 1170642766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard (*cptr >= '0' && *cptr <= '9') || 1170742766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard *cptr == '-' || *cptr == '_' || *cptr == '.' || 1170842766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard *cptr == '!' || *cptr == '~' || *cptr == '*' || 1170942766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard *cptr == '\''|| *cptr == '(' || *cptr == ')' || 1171042766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard (*cptr == '%' && 1171142766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard ((cptr[1] >= 'A' && cptr[1] <= 'F') || 1171242766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard (cptr[1] >= 'a' && cptr[1] <= 'f') || 1171342766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard (cptr[1] >= '0' && cptr[1] <= '9')) && 1171442766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard ((cptr[2] >= 'A' && cptr[2] <= 'F') || 1171542766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard (cptr[2] >= 'a' && cptr[2] <= 'f') || 1171642766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard (cptr[2] >= '0' && cptr[2] <= '9'))) || 1171742766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard (!escape_reserved && 1171842766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard (*cptr == ';' || *cptr == '/' || *cptr == '?' || 1171942766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard *cptr == ':' || *cptr == '@' || *cptr == '&' || 1172042766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard *cptr == '=' || *cptr == '+' || *cptr == '$' || 1172142766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard *cptr == ','))) { 1172242766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard xmlBufferAdd(target, cptr, 1); 1172342766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard } else { 1172442766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard if ((*cptr >> 4) < 10) 1172542766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard escape[1] = '0' + (*cptr >> 4); 1172642766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard else 1172742766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard escape[1] = 'A' - 10 + (*cptr >> 4); 1172842766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard if ((*cptr & 0xF) < 10) 1172942766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard escape[2] = '0' + (*cptr & 0xF); 1173042766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard else 1173142766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard escape[2] = 'A' - 10 + (*cptr & 0xF); 1173242766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard 1173342766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard xmlBufferAdd(target, &escape[0], 3); 1173442766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard } 1173542766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard } 1173642766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard } 1173742766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard valuePush(ctxt, xmlXPathNewString(xmlBufferContent(target))); 1173842766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard xmlBufferFree(target); 1173942766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard xmlXPathFreeObject(str); 1174042766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard} 1174142766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard 117423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 117433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathRegisterAllFunctions: 117443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath context 117453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 117463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Registers all default XPath functions in this context 117473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 117483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 117493473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathRegisterAllFunctions(xmlXPathContextPtr ctxt) 117503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor{ 117513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisterFunc(ctxt, (const xmlChar *)"boolean", 117523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathBooleanFunction); 117533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisterFunc(ctxt, (const xmlChar *)"ceiling", 117543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathCeilingFunction); 117553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisterFunc(ctxt, (const xmlChar *)"count", 117563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathCountFunction); 117573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisterFunc(ctxt, (const xmlChar *)"concat", 117583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathConcatFunction); 117593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisterFunc(ctxt, (const xmlChar *)"contains", 117603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathContainsFunction); 117613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisterFunc(ctxt, (const xmlChar *)"id", 117623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathIdFunction); 117633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisterFunc(ctxt, (const xmlChar *)"false", 117643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFalseFunction); 117653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisterFunc(ctxt, (const xmlChar *)"floor", 117663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFloorFunction); 117673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisterFunc(ctxt, (const xmlChar *)"last", 117683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathLastFunction); 117693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisterFunc(ctxt, (const xmlChar *)"lang", 117703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathLangFunction); 117713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisterFunc(ctxt, (const xmlChar *)"local-name", 117723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathLocalNameFunction); 117733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisterFunc(ctxt, (const xmlChar *)"not", 117743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathNotFunction); 117753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisterFunc(ctxt, (const xmlChar *)"name", 117763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathNameFunction); 117773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisterFunc(ctxt, (const xmlChar *)"namespace-uri", 117783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathNamespaceURIFunction); 117793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisterFunc(ctxt, (const xmlChar *)"normalize-space", 117803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathNormalizeFunction); 117813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisterFunc(ctxt, (const xmlChar *)"number", 117823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathNumberFunction); 117833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisterFunc(ctxt, (const xmlChar *)"position", 117843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathPositionFunction); 117853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisterFunc(ctxt, (const xmlChar *)"round", 117863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRoundFunction); 117873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisterFunc(ctxt, (const xmlChar *)"string", 117883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathStringFunction); 117893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisterFunc(ctxt, (const xmlChar *)"string-length", 117903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathStringLengthFunction); 117913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisterFunc(ctxt, (const xmlChar *)"starts-with", 117923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathStartsWithFunction); 117933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisterFunc(ctxt, (const xmlChar *)"substring", 117943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathSubstringFunction); 117953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisterFunc(ctxt, (const xmlChar *)"substring-before", 117963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathSubstringBeforeFunction); 117973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisterFunc(ctxt, (const xmlChar *)"substring-after", 117983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathSubstringAfterFunction); 117993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisterFunc(ctxt, (const xmlChar *)"sum", 118003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathSumFunction); 118013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisterFunc(ctxt, (const xmlChar *)"true", 118023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathTrueFunction); 118033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisterFunc(ctxt, (const xmlChar *)"translate", 118043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathTranslateFunction); 1180542766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard 1180642766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard xmlXPathRegisterFuncNS(ctxt, (const xmlChar *)"escape-uri", 1180742766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard (const xmlChar *)"http://www.w3.org/2002/08/xquery-functions", 1180842766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard xmlXPathEscapeUriFunction); 118093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 118103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 118113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif /* LIBXML_XPATH_ENABLED */ 118125d4644ef6e38479a648615eca758c5e962a141d5Daniel Veillard#define bottom_xpath 118135d4644ef6e38479a648615eca758c5e962a141d5Daniel Veillard#include "elfgcchack.h" 11814