xpath.c revision 4432df239b7aba6bff86c838e0be11d08f283b76
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> 543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 554432df239b7aba6bff86c838e0be11d08f283b76Daniel Veillard#if defined(LIBXML_SCHEMAS_ENABLED) || defined(LIBXML_XPATH_ENABLED) 569e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard/************************************************************************ 579e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * * 589e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * Floating point stuff * 599e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * * 609e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard ************************************************************************/ 619e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 62c0631a608f62902eca453096f0b2fc5b449b0b0aDaniel Veillard#ifndef TRIO_REPLACE_STDIO 63cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard#define TRIO_PUBLIC static 64c0631a608f62902eca453096f0b2fc5b449b0b0aDaniel Veillard#endif 65cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard#include "trionan.c" 66cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard 673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/* 683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The lack of portability of this section of the libc is annoying ! 693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylordouble xmlXPathNAN = 0; 713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylordouble xmlXPathPINF = 1; 723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylordouble xmlXPathNINF = -1; 735fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillarddouble xmlXPathNZERO = 0; 7420ee8c03107e5d5724765da513d595fdaf290dceDaniel Veillardstatic int xmlXPathInitialized = 0; 753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathInit: 783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Initialize the XPath environment 803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 823473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathInit(void) { 8320ee8c03107e5d5724765da513d595fdaf290dceDaniel Veillard if (xmlXPathInitialized) return; 843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 85450296070e14629141738fbb34b9a0ad13af1f02Bjorn Reese xmlXPathPINF = trio_pinf(); 86450296070e14629141738fbb34b9a0ad13af1f02Bjorn Reese xmlXPathNINF = trio_ninf(); 87450296070e14629141738fbb34b9a0ad13af1f02Bjorn Reese xmlXPathNAN = trio_nan(); 885fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard xmlXPathNZERO = trio_nzero(); 893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 9020ee8c03107e5d5724765da513d595fdaf290dceDaniel Veillard xmlXPathInitialized = 1; 913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 93cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard/** 94cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * xmlXPathIsNaN: 95cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * @val: a double value 96cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * 97cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * Provides a portable isnan() function to detect whether a double 98cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * is a NotaNumber. Based on trio code 99cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * http://sourceforge.net/projects/ctrio/ 100cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * 101cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * Returns 1 if the value is a NaN, 0 otherwise 102cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard */ 103cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillardint 104cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel VeillardxmlXPathIsNaN(double val) { 105cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard return(trio_isnan(val)); 106cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard} 107cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard 108cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard/** 109cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * xmlXPathIsInf: 110cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * @val: a double value 111cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * 112cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * Provides a portable isinf() function to detect whether a double 113cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * is a +Infinite or -Infinite. Based on trio code 114cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * http://sourceforge.net/projects/ctrio/ 115cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * 116cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * Returns 1 vi the value is +Infinite, -1 if -Infinite, 0 otherwise 117cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard */ 118cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillardint 119cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel VeillardxmlXPathIsInf(double val) { 120cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard return(trio_isinf(val)); 121cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard} 122cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard 1234432df239b7aba6bff86c838e0be11d08f283b76Daniel Veillard#endif /* SCHEMAS or XPATH */ 1244432df239b7aba6bff86c838e0be11d08f283b76Daniel Veillard#ifdef LIBXML_XPATH_ENABLED 1255fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard/** 1265fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard * xmlXPathGetSign: 1275fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard * @val: a double value 1285fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard * 1295fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard * Provides a portable function to detect the sign of a double 1305fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard * Modified from trio code 1315fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard * http://sourceforge.net/projects/ctrio/ 1325fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard * 1335fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard * Returns 1 if the value is Negative, 0 if positive 1345fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard */ 13521458c85e209cd2621ac3eadfee075ae2dc0121dDaniel Veillardstatic int 1365fc1f0893af6ffe76453ac16817204a866bdeab2Daniel VeillardxmlXPathGetSign(double val) { 13721458c85e209cd2621ac3eadfee075ae2dc0121dDaniel Veillard return(trio_signbit(val)); 1385fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard} 1395fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard 1405fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard 141d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillard/* 142d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillard * TODO: when compatibility allows remove all "fake node libxslt" strings 143d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillard * the test should just be name[0] = ' ' 144d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillard */ 145d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillard/* #define DEBUG */ 146d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillard/* #define DEBUG_STEP */ 147d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillard/* #define DEBUG_STEP_NTH */ 148d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillard/* #define DEBUG_EXPR */ 149d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillard/* #define DEBUG_EVAL_COUNTS */ 150d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillard 151d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillardstatic xmlNs xmlXPathXMLNamespaceStruct = { 152d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillard NULL, 153d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillard XML_NAMESPACE_DECL, 154d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillard XML_XML_NAMESPACE, 155d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillard BAD_CAST "xml", 156d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillard NULL 157d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillard}; 158d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillardstatic xmlNsPtr xmlXPathXMLNamespace = &xmlXPathXMLNamespaceStruct; 159d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillard#ifndef LIBXML_THREAD_ENABLED 160d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillard/* 161d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillard * Optimizer is disabled only when threaded apps are detected while 162d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillard * the library ain't compiled for thread safety. 163d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillard */ 164d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillardstatic int xmlXPathDisableOptimizer = 0; 165d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillard#endif 166d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillard 1673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/************************************************************************ 1689e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * * 1699e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * Parser Types * 1709e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * * 1719e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard ************************************************************************/ 1729e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 1739e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard/* 1749e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * Types are private: 1759e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard */ 1769e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 1779e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillardtypedef enum { 1789e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard XPATH_OP_END=0, 1799e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard XPATH_OP_AND, 1809e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard XPATH_OP_OR, 1819e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard XPATH_OP_EQUAL, 1829e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard XPATH_OP_CMP, 1839e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard XPATH_OP_PLUS, 1849e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard XPATH_OP_MULT, 1859e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard XPATH_OP_UNION, 1869e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard XPATH_OP_ROOT, 1879e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard XPATH_OP_NODE, 1889e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard XPATH_OP_RESET, 1899e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard XPATH_OP_COLLECT, 1909e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard XPATH_OP_VALUE, 1919e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard XPATH_OP_VARIABLE, 1929e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard XPATH_OP_FUNCTION, 1939e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard XPATH_OP_ARG, 1949e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard XPATH_OP_PREDICATE, 195d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard XPATH_OP_FILTER, 1969e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard XPATH_OP_SORT 1979e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard#ifdef LIBXML_XPTR_ENABLED 1989e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard ,XPATH_OP_RANGETO 1999e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard#endif 2009e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard} xmlXPathOp; 2019e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 2029e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillardtypedef enum { 2039e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard AXIS_ANCESTOR = 1, 2049e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard AXIS_ANCESTOR_OR_SELF, 2059e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard AXIS_ATTRIBUTE, 2069e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard AXIS_CHILD, 2079e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard AXIS_DESCENDANT, 2089e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard AXIS_DESCENDANT_OR_SELF, 2099e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard AXIS_FOLLOWING, 2109e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard AXIS_FOLLOWING_SIBLING, 2119e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard AXIS_NAMESPACE, 2129e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard AXIS_PARENT, 2139e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard AXIS_PRECEDING, 2149e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard AXIS_PRECEDING_SIBLING, 2159e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard AXIS_SELF 2169e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard} xmlXPathAxisVal; 2179e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 2189e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillardtypedef enum { 2199e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard NODE_TEST_NONE = 0, 2209e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard NODE_TEST_TYPE = 1, 2219e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard NODE_TEST_PI = 2, 2229e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard NODE_TEST_ALL = 3, 2239e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard NODE_TEST_NS = 4, 2249e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard NODE_TEST_NAME = 5 2259e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard} xmlXPathTestVal; 2269e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 2279e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillardtypedef enum { 2289e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard NODE_TYPE_NODE = 0, 2299e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard NODE_TYPE_COMMENT = XML_COMMENT_NODE, 2309e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard NODE_TYPE_TEXT = XML_TEXT_NODE, 2319e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard NODE_TYPE_PI = XML_PI_NODE 2329e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard} xmlXPathTypeVal; 2339e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 2349e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 2359e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillardtypedef struct _xmlXPathStepOp xmlXPathStepOp; 2369e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillardtypedef xmlXPathStepOp *xmlXPathStepOpPtr; 2379e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillardstruct _xmlXPathStepOp { 2389e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlXPathOp op; 2399e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard int ch1; 2409e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard int ch2; 2419e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard int value; 2429e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard int value2; 2439e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard int value3; 2449e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard void *value4; 2459e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard void *value5; 246e39a93d0d3df9907cf3538cd3f1fbbe4106e893dDaniel Veillard void *cache; 24742596ad20cdf1925dd79ea801cbe598b6e7b7aecDaniel Veillard void *cacheURI; 2489e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard}; 2499e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 2509e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillardstruct _xmlXPathCompExpr { 2519e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard int nbStep; 2529e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard int maxStep; 2539e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlXPathStepOp *steps; /* ops for computation */ 2549e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard int last; 255118aed78f360f51d182770e62b251ef324707aa2Daniel Veillard xmlChar *expr; 256f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#ifdef DEBUG_EVAL_COUNTS 257f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard int nb; 258f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlChar *string; 259f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#endif 2609e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard}; 2619e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 2629e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard/************************************************************************ 2639e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * * 2649e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * Parser Type functions * 2659e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * * 2669e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard ************************************************************************/ 2679e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 2689e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard/** 2699e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * xmlXPathNewCompExpr: 2709e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * 2719e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * Create a new Xpath component 2729e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * 2739e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * Returns the newly allocated xmlXPathCompExprPtr or NULL in case of error 2749e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard */ 27556a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic xmlXPathCompExprPtr 2769e7160d45a18bfa26d708e22ba991f7670d0128bDaniel VeillardxmlXPathNewCompExpr(void) { 2779e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlXPathCompExprPtr cur; 2789e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 2799e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard cur = (xmlXPathCompExprPtr) xmlMalloc(sizeof(xmlXPathCompExpr)); 2809e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (cur == NULL) { 2819e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlGenericError(xmlGenericErrorContext, 2829e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard "xmlXPathNewCompExpr : malloc failed\n"); 2839e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard return(NULL); 2849e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } 2859e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard memset(cur, 0, sizeof(xmlXPathCompExpr)); 2869e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard cur->maxStep = 10; 2879e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard cur->nbStep = 0; 2889e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard cur->steps = (xmlXPathStepOp *) xmlMalloc(cur->maxStep * 2899e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard sizeof(xmlXPathStepOp)); 2909e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (cur->steps == NULL) { 2919e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlGenericError(xmlGenericErrorContext, 2929e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard "xmlXPathNewCompExpr : malloc failed\n"); 2939e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlFree(cur); 2949e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard return(NULL); 2959e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } 2969e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard memset(cur->steps, 0, cur->maxStep * sizeof(xmlXPathStepOp)); 2979e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard cur->last = -1; 298f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#ifdef DEBUG_EVAL_COUNTS 299f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard cur->nb = 0; 300f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#endif 3019e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard return(cur); 3029e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard} 3039e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 3049e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard/** 3059e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * xmlXPathFreeCompExpr: 3069e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * @comp: an XPATH comp 3079e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * 3089e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * Free up the memory allocated by @comp 3099e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard */ 3109e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillardvoid 311f06307e2c172284bb41376c396f757bdac9bdd19Daniel VeillardxmlXPathFreeCompExpr(xmlXPathCompExprPtr comp) 312f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard{ 3139e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlXPathStepOpPtr op; 3149e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard int i; 3159e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 3169e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (comp == NULL) 317f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return; 318f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard for (i = 0; i < comp->nbStep; i++) { 319f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard op = &comp->steps[i]; 320f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->value4 != NULL) { 321f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->op == XPATH_OP_VALUE) 322f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathFreeObject(op->value4); 323f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard else 324f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlFree(op->value4); 325f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 326f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->value5 != NULL) 327f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlFree(op->value5); 3289e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } 3299e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (comp->steps != NULL) { 330f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlFree(comp->steps); 3319e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } 332f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#ifdef DEBUG_EVAL_COUNTS 333f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (comp->string != NULL) { 334f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlFree(comp->string); 335f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 336f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#endif 337118aed78f360f51d182770e62b251ef324707aa2Daniel Veillard if (comp->expr != NULL) { 338118aed78f360f51d182770e62b251ef324707aa2Daniel Veillard xmlFree(comp->expr); 339118aed78f360f51d182770e62b251ef324707aa2Daniel Veillard } 340f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 3419e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlFree(comp); 3429e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard} 3439e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 3449e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard/** 3459e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * xmlXPathCompExprAdd: 3469e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * @comp: the compiled expression 3479e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * @ch1: first child index 3489e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * @ch2: second child index 3499e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * @op: an op 3509e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * @value: the first int value 3519e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * @value2: the second int value 3529e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * @value3: the third int value 3539e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * @value4: the first string value 3549e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * @value5: the second string value 3559e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * 3569e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * Add an step to an XPath Compiled Expression 3579e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * 3589e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * Returns -1 in case of failure, the index otherwise 3599e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard */ 36056a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic int 3619e7160d45a18bfa26d708e22ba991f7670d0128bDaniel VeillardxmlXPathCompExprAdd(xmlXPathCompExprPtr comp, int ch1, int ch2, 3629e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlXPathOp op, int value, 3639e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard int value2, int value3, void *value4, void *value5) { 3649e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (comp->nbStep >= comp->maxStep) { 3659e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlXPathStepOp *real; 3669e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 3679e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard comp->maxStep *= 2; 3689e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard real = (xmlXPathStepOp *) xmlRealloc(comp->steps, 3699e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard comp->maxStep * sizeof(xmlXPathStepOp)); 3709e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (real == NULL) { 3719e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard comp->maxStep /= 2; 3729e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlGenericError(xmlGenericErrorContext, 3739e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard "xmlXPathCompExprAdd : realloc failed\n"); 3749e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard return(-1); 3759e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } 3769e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard comp->steps = real; 3779e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } 3789e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard comp->last = comp->nbStep; 3799e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard comp->steps[comp->nbStep].ch1 = ch1; 3809e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard comp->steps[comp->nbStep].ch2 = ch2; 3819e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard comp->steps[comp->nbStep].op = op; 3829e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard comp->steps[comp->nbStep].value = value; 3839e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard comp->steps[comp->nbStep].value2 = value2; 3849e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard comp->steps[comp->nbStep].value3 = value3; 3859e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard comp->steps[comp->nbStep].value4 = value4; 3869e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard comp->steps[comp->nbStep].value5 = value5; 387e39a93d0d3df9907cf3538cd3f1fbbe4106e893dDaniel Veillard comp->steps[comp->nbStep].cache = NULL; 3889e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard return(comp->nbStep++); 3899e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard} 3909e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 391f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard/** 392f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * xmlXPathCompSwap: 393f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * @comp: the compiled expression 394f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * @op: operation index 395f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * 396f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Swaps 2 operations in the compiled expression 397f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 398f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillardstatic void 399f06307e2c172284bb41376c396f757bdac9bdd19Daniel VeillardxmlXPathCompSwap(xmlXPathStepOpPtr op) { 400f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard int tmp; 401f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 402bc6f759ac9b41773e3643ad288b5214732051c98Daniel Veillard#ifndef LIBXML_THREAD_ENABLED 4038146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard /* 4048146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard * Since this manipulates possibly shared variables, this is 4058146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard * disable if one detects that the library is used in a multithreaded 4068146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard * application 4078146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard */ 4088146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard if (xmlXPathDisableOptimizer) 4098146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard return; 4108146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard#endif 4118146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard 412f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard tmp = op->ch1; 413f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard op->ch1 = op->ch2; 414f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard op->ch2 = tmp; 415f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard} 416f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 417d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#define PUSH_FULL_EXPR(op, op1, op2, val, val2, val3, val4, val5) \ 418d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard xmlXPathCompExprAdd(ctxt->comp, (op1), (op2), \ 419d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard (op), (val), (val2), (val3), (val4), (val5)) 4209e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard#define PUSH_LONG_EXPR(op, val, val2, val3, val4, val5) \ 4219e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlXPathCompExprAdd(ctxt->comp, ctxt->comp->last, -1, \ 4229e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard (op), (val), (val2), (val3), (val4), (val5)) 4239e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 4249e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard#define PUSH_LEAVE_EXPR(op, val, val2) \ 4259e7160d45a18bfa26d708e22ba991f7670d0128bDaniel VeillardxmlXPathCompExprAdd(ctxt->comp, -1, -1, (op), (val), (val2), 0 ,NULL ,NULL) 4269e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 4279e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard#define PUSH_UNARY_EXPR(op, ch, val, val2) \ 4289e7160d45a18bfa26d708e22ba991f7670d0128bDaniel VeillardxmlXPathCompExprAdd(ctxt->comp, (ch), -1, (op), (val), (val2), 0 ,NULL ,NULL) 4299e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 4309e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard#define PUSH_BINARY_EXPR(op, ch1, ch2, val, val2) \ 4319e7160d45a18bfa26d708e22ba991f7670d0128bDaniel VeillardxmlXPathCompExprAdd(ctxt->comp, (ch1), (ch2), (op), (val), (val2), 0 ,NULL ,NULL) 4329e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 4339e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard/************************************************************************ 4343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * * 4353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Debugging related functions * 4363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * * 4373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ************************************************************************/ 4383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 4393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define TODO \ 4403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, \ 4413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "Unimplemented block at %s:%d\n", \ 4423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor __FILE__, __LINE__); 4433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 4443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define STRANGE \ 4453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, \ 4463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "Internal error at %s:%d\n", \ 4473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor __FILE__, __LINE__); 4483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 4493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef LIBXML_DEBUG_ENABLED 45056a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic void 45156a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel VeillardxmlXPathDebugDumpNode(FILE *output, xmlNodePtr cur, int depth) { 4523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int i; 4533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor char shift[100]; 4543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 4553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor for (i = 0;((i < depth) && (i < 25));i++) 4563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor shift[2 * i] = shift[2 * i + 1] = ' '; 4573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor shift[2 * i] = shift[2 * i + 1] = 0; 4583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == NULL) { 4593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, shift); 4603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, "Node is NULL !\n"); 4613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return; 4623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 4633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 4643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 4653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((cur->type == XML_DOCUMENT_NODE) || 4663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor (cur->type == XML_HTML_DOCUMENT_NODE)) { 4673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, shift); 4683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, " /\n"); 4693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else if (cur->type == XML_ATTRIBUTE_NODE) 4703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlDebugDumpAttr(output, (xmlAttrPtr)cur, depth); 4713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else 4723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlDebugDumpOneNode(output, cur, depth); 4733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 47456a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic void 47556a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel VeillardxmlXPathDebugDumpNodeList(FILE *output, xmlNodePtr cur, int depth) { 476f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard xmlNodePtr tmp; 477f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard int i; 478f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard char shift[100]; 479f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard 480f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard for (i = 0;((i < depth) && (i < 25));i++) 481f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard shift[2 * i] = shift[2 * i + 1] = ' '; 482f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard shift[2 * i] = shift[2 * i + 1] = 0; 483f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard if (cur == NULL) { 484f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard fprintf(output, shift); 485f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard fprintf(output, "Node is NULL !\n"); 486f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard return; 487f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard 488f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard } 489f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard 490f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard while (cur != NULL) { 491f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard tmp = cur; 492f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard cur = cur->next; 493f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard xmlDebugDumpOneNode(output, tmp, depth); 494f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard } 495f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard} 4963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 49756a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic void 49856a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel VeillardxmlXPathDebugDumpNodeSet(FILE *output, xmlNodeSetPtr cur, int depth) { 4993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int i; 5003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor char shift[100]; 5013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 5023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor for (i = 0;((i < depth) && (i < 25));i++) 5033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor shift[2 * i] = shift[2 * i + 1] = ' '; 5043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor shift[2 * i] = shift[2 * i + 1] = 0; 5053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 5063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == NULL) { 5073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, shift); 5083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, "NodeSet is NULL !\n"); 5093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return; 5103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 5113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 5123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 513911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard if (cur != NULL) { 514911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard fprintf(output, "Set contains %d nodes:\n", cur->nodeNr); 515911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard for (i = 0;i < cur->nodeNr;i++) { 516911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard fprintf(output, shift); 517911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard fprintf(output, "%d", i + 1); 518911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard xmlXPathDebugDumpNode(output, cur->nodeTab[i], depth + 1); 519911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard } 5203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 5213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 5223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 52356a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic void 52456a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel VeillardxmlXPathDebugDumpValueTree(FILE *output, xmlNodeSetPtr cur, int depth) { 525f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard int i; 526f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard char shift[100]; 527f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard 528f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard for (i = 0;((i < depth) && (i < 25));i++) 529f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard shift[2 * i] = shift[2 * i + 1] = ' '; 530f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard shift[2 * i] = shift[2 * i + 1] = 0; 531f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard 532f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard if ((cur == NULL) || (cur->nodeNr == 0) || (cur->nodeTab[0] == NULL)) { 533f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard fprintf(output, shift); 534f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard fprintf(output, "Value Tree is NULL !\n"); 535f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard return; 536f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard 537f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard } 538f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard 539f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard fprintf(output, shift); 540f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard fprintf(output, "%d", i + 1); 541f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard xmlXPathDebugDumpNodeList(output, cur->nodeTab[0]->children, depth + 1); 542f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard} 5433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#if defined(LIBXML_XPTR_ENABLED) 54456a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic void 54556a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel VeillardxmlXPathDebugDumpLocationSet(FILE *output, xmlLocationSetPtr cur, int depth) { 5463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int i; 5473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor char shift[100]; 5483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 5493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor for (i = 0;((i < depth) && (i < 25));i++) 5503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor shift[2 * i] = shift[2 * i + 1] = ' '; 5513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor shift[2 * i] = shift[2 * i + 1] = 0; 5523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 5533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == NULL) { 5543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, shift); 5553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, "LocationSet is NULL !\n"); 5563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return; 5573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 5583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 5593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 5603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor for (i = 0;i < cur->locNr;i++) { 5613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, shift); 5623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, "%d : ", i + 1); 5633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathDebugDumpObject(output, cur->locTab[i], depth + 1); 5643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 5653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 566017b108fcf16dbce05ca7ebd75763f3d888abb5fDaniel Veillard#endif /* LIBXML_XPTR_ENABLED */ 5673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 568afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard/** 569afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathDebugDumpObject: 570afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * @output: the FILE * to dump the output 571afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * @cur: the object to inspect 572afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * @depth: indentation level 573afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * 574afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Dump the content of the object for debugging purposes 575afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard */ 576afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardvoid 577afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathDebugDumpObject(FILE *output, xmlXPathObjectPtr cur, int depth) { 5783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int i; 5793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor char shift[100]; 5803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 5813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor for (i = 0;((i < depth) && (i < 25));i++) 5823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor shift[2 * i] = shift[2 * i + 1] = ' '; 5833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor shift[2 * i] = shift[2 * i + 1] = 0; 5843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 5853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, shift); 5863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 5873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == NULL) { 5883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, "Object is empty (NULL)\n"); 5893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return; 5903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 5913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor switch(cur->type) { 5923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_UNDEFINED: 5933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, "Object is uninitialized\n"); 5943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 5953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_NODESET: 5963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, "Object is a Node Set :\n"); 5973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathDebugDumpNodeSet(output, cur->nodesetval, depth); 5983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 5993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_XSLT_TREE: 6003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, "Object is an XSLT value tree :\n"); 601f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard xmlXPathDebugDumpValueTree(output, cur->nodesetval, depth); 6023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 6033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_BOOLEAN: 6043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, "Object is a Boolean : "); 6053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur->boolval) fprintf(output, "true\n"); 6063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else fprintf(output, "false\n"); 6073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 6083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_NUMBER: 609cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard switch (xmlXPathIsInf(cur->floatval)) { 610357c960e4035ee2fb40d0072bb7bde4533be76f8Daniel Veillard case 1: 6115fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard fprintf(output, "Object is a number : Infinity\n"); 612357c960e4035ee2fb40d0072bb7bde4533be76f8Daniel Veillard break; 613357c960e4035ee2fb40d0072bb7bde4533be76f8Daniel Veillard case -1: 614357c960e4035ee2fb40d0072bb7bde4533be76f8Daniel Veillard fprintf(output, "Object is a number : -Infinity\n"); 615357c960e4035ee2fb40d0072bb7bde4533be76f8Daniel Veillard break; 616357c960e4035ee2fb40d0072bb7bde4533be76f8Daniel Veillard default: 617cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard if (xmlXPathIsNaN(cur->floatval)) { 618357c960e4035ee2fb40d0072bb7bde4533be76f8Daniel Veillard fprintf(output, "Object is a number : NaN\n"); 619d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard } else if (cur->floatval == 0 && xmlXPathGetSign(cur->floatval) != 0) { 620d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard fprintf(output, "Object is a number : 0\n"); 621357c960e4035ee2fb40d0072bb7bde4533be76f8Daniel Veillard } else { 622357c960e4035ee2fb40d0072bb7bde4533be76f8Daniel Veillard fprintf(output, "Object is a number : %0g\n", cur->floatval); 623357c960e4035ee2fb40d0072bb7bde4533be76f8Daniel Veillard } 624357c960e4035ee2fb40d0072bb7bde4533be76f8Daniel Veillard } 6253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 6263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_STRING: 6273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, "Object is a string : "); 6283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlDebugDumpString(output, cur->stringval); 6293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, "\n"); 6303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 6313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_POINT: 6323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, "Object is a point : index %d in node", cur->index); 6333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathDebugDumpNode(output, (xmlNodePtr) cur->user, depth + 1); 6343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, "\n"); 6353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 6363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_RANGE: 6373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((cur->user2 == NULL) || 6383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ((cur->user2 == cur->user) && (cur->index == cur->index2))) { 6393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, "Object is a collapsed range :\n"); 6403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, shift); 6413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur->index >= 0) 6423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, "index %d in ", cur->index); 6433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, "node\n"); 6443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathDebugDumpNode(output, (xmlNodePtr) cur->user, 6453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor depth + 1); 6463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else { 6473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, "Object is a range :\n"); 6483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, shift); 6493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, "From "); 6503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur->index >= 0) 6513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, "index %d in ", cur->index); 6523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, "node\n"); 6533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathDebugDumpNode(output, (xmlNodePtr) cur->user, 6543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor depth + 1); 6553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, shift); 6563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, "To "); 6573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur->index2 >= 0) 6583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, "index %d in ", cur->index2); 6593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, "node\n"); 6603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathDebugDumpNode(output, (xmlNodePtr) cur->user2, 6613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor depth + 1); 6623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, "\n"); 6633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 6643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 6653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_LOCATIONSET: 6663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#if defined(LIBXML_XPTR_ENABLED) 6673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, "Object is a Location Set:\n"); 6683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathDebugDumpLocationSet(output, 6693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor (xmlLocationSetPtr) cur->user, depth); 6703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 6713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 6723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_USERS: 6733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, "Object is user defined\n"); 6743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 6753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 6763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 6779e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 67856a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic void 67956a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel VeillardxmlXPathDebugDumpStepOp(FILE *output, xmlXPathCompExprPtr comp, 6809e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlXPathStepOpPtr op, int depth) { 6819e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard int i; 6829e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard char shift[100]; 6839e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 6849e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard for (i = 0;((i < depth) && (i < 25));i++) 6859e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard shift[2 * i] = shift[2 * i + 1] = ' '; 6869e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard shift[2 * i] = shift[2 * i + 1] = 0; 6879e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 6889e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, shift); 6899e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (op == NULL) { 6909e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "Step is NULL\n"); 6919e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard return; 6929e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } 6939e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard switch (op->op) { 6949e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case XPATH_OP_END: 6959e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "END"); break; 6969e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case XPATH_OP_AND: 6979e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "AND"); break; 6989e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case XPATH_OP_OR: 6999e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "OR"); break; 7009e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case XPATH_OP_EQUAL: 7019e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (op->value) 7029e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "EQUAL ="); 7039e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard else 7049e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "EQUAL !="); 7059e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard break; 7069e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case XPATH_OP_CMP: 7079e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (op->value) 7089e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "CMP <"); 7099e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard else 7109e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "CMP >"); 7119e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (!op->value2) 7129e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "="); 7139e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard break; 7149e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case XPATH_OP_PLUS: 7159e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (op->value == 0) 7169e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "PLUS -"); 7179e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard else if (op->value == 1) 7189e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "PLUS +"); 7199e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard else if (op->value == 2) 7209e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "PLUS unary -"); 7219e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard else if (op->value == 3) 7229e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "PLUS unary - -"); 7239e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard break; 7249e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case XPATH_OP_MULT: 7259e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (op->value == 0) 7269e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "MULT *"); 7279e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard else if (op->value == 1) 7289e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "MULT div"); 7299e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard else 7309e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "MULT mod"); 7319e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard break; 7329e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case XPATH_OP_UNION: 7339e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "UNION"); break; 7349e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case XPATH_OP_ROOT: 7359e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "ROOT"); break; 7369e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case XPATH_OP_NODE: 7379e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "NODE"); break; 7389e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case XPATH_OP_RESET: 7399e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "RESET"); break; 7409e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case XPATH_OP_SORT: 7419e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "SORT"); break; 7429e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case XPATH_OP_COLLECT: { 74378637da0ea1c833dfdfad87a9aa5bea14510d08aWilliam M. Brack xmlXPathAxisVal axis = (xmlXPathAxisVal)op->value; 74478637da0ea1c833dfdfad87a9aa5bea14510d08aWilliam M. Brack xmlXPathTestVal test = (xmlXPathTestVal)op->value2; 74578637da0ea1c833dfdfad87a9aa5bea14510d08aWilliam M. Brack xmlXPathTypeVal type = (xmlXPathTypeVal)op->value3; 7469e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard const xmlChar *prefix = op->value4; 7479e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard const xmlChar *name = op->value5; 7489e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 7499e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "COLLECT "); 7509e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard switch (axis) { 7519e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case AXIS_ANCESTOR: 7529e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, " 'ancestors' "); break; 7539e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case AXIS_ANCESTOR_OR_SELF: 7549e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, " 'ancestors-or-self' "); break; 7559e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case AXIS_ATTRIBUTE: 7569e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, " 'attributes' "); break; 7579e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case AXIS_CHILD: 7589e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, " 'child' "); break; 7599e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case AXIS_DESCENDANT: 7609e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, " 'descendant' "); break; 7619e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case AXIS_DESCENDANT_OR_SELF: 7629e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, " 'descendant-or-self' "); break; 7639e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case AXIS_FOLLOWING: 7649e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, " 'following' "); break; 7659e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case AXIS_FOLLOWING_SIBLING: 7669e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, " 'following-siblings' "); break; 7679e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case AXIS_NAMESPACE: 7689e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, " 'namespace' "); break; 7699e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case AXIS_PARENT: 7709e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, " 'parent' "); break; 7719e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case AXIS_PRECEDING: 7729e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, " 'preceding' "); break; 7739e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case AXIS_PRECEDING_SIBLING: 7749e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, " 'preceding-sibling' "); break; 7759e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case AXIS_SELF: 7769e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, " 'self' "); break; 7779e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } 7789e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard switch (test) { 7799e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case NODE_TEST_NONE: 7809e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "'none' "); break; 7819e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case NODE_TEST_TYPE: 7829e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "'type' "); break; 7839e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case NODE_TEST_PI: 7849e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "'PI' "); break; 7859e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case NODE_TEST_ALL: 7869e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "'all' "); break; 7879e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case NODE_TEST_NS: 7889e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "'namespace' "); break; 7899e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case NODE_TEST_NAME: 7909e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "'name' "); break; 7919e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } 7929e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard switch (type) { 7939e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case NODE_TYPE_NODE: 7949e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "'node' "); break; 7959e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case NODE_TYPE_COMMENT: 7969e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "'comment' "); break; 7979e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case NODE_TYPE_TEXT: 7989e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "'text' "); break; 7999e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case NODE_TYPE_PI: 8009e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "'PI' "); break; 8019e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } 8029e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (prefix != NULL) 8039e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "%s:", prefix); 8049e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (name != NULL) 805580ced8ee28ecd99374da9383897678e4ba6c358Daniel Veillard fprintf(output, "%s", (const char *) name); 8069e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard break; 8079e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 8089e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } 8099e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case XPATH_OP_VALUE: { 8109e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlXPathObjectPtr object = (xmlXPathObjectPtr) op->value4; 8119e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 8129e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "ELEM "); 8139e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlXPathDebugDumpObject(output, object, 0); 8149e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard goto finish; 8159e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } 8169e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case XPATH_OP_VARIABLE: { 8179e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard const xmlChar *prefix = op->value5; 8189e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard const xmlChar *name = op->value4; 8199e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 8209e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (prefix != NULL) 8219e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "VARIABLE %s:%s", prefix, name); 8229e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard else 8239e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "VARIABLE %s", name); 8249e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard break; 8259e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } 8269e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case XPATH_OP_FUNCTION: { 8279e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard int nbargs = op->value; 8289e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard const xmlChar *prefix = op->value5; 8299e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard const xmlChar *name = op->value4; 8309e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 8319e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (prefix != NULL) 8329e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "FUNCTION %s:%s(%d args)", 8339e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard prefix, name, nbargs); 8349e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard else 8359e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "FUNCTION %s(%d args)", name, nbargs); 8369e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard break; 8379e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } 8389e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case XPATH_OP_ARG: fprintf(output, "ARG"); break; 8399e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case XPATH_OP_PREDICATE: fprintf(output, "PREDICATE"); break; 840d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard case XPATH_OP_FILTER: fprintf(output, "FILTER"); break; 841fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard#ifdef LIBXML_XPTR_ENABLED 842fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard case XPATH_OP_RANGETO: fprintf(output, "RANGETO"); break; 843fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard#endif 8449e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard default: 8459e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "UNKNOWN %d\n", op->op); return; 8469e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } 8479e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "\n"); 8489e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillardfinish: 8499e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (op->ch1 >= 0) 8509e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlXPathDebugDumpStepOp(output, comp, &comp->steps[op->ch1], depth + 1); 8519e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (op->ch2 >= 0) 8529e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlXPathDebugDumpStepOp(output, comp, &comp->steps[op->ch2], depth + 1); 8539e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard} 85456a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillard 8555e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard/** 8565e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard * xmlXPathDebugDumpCompExpr: 8575e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard * @output: the FILE * for the output 8585e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard * @comp: the precompiled XPath expression 8595e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard * @depth: the indentation level. 8605e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard * 8615e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard * Dumps the tree of the compiled XPath expression. 8625e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard */ 86356a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardvoid 86456a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel VeillardxmlXPathDebugDumpCompExpr(FILE *output, xmlXPathCompExprPtr comp, 86556a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillard int depth) { 8669e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard int i; 8679e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard char shift[100]; 8689e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 8699e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard for (i = 0;((i < depth) && (i < 25));i++) 8709e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard shift[2 * i] = shift[2 * i + 1] = ' '; 8719e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard shift[2 * i] = shift[2 * i + 1] = 0; 8729e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 8739e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, shift); 8749e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 8759e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (comp == NULL) { 8769e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "Compiled Expression is NULL\n"); 8779e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard return; 8789e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } 8799e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "Compiled Expression : %d elements\n", 8809e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard comp->nbStep); 8819e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard i = comp->last; 8829e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlXPathDebugDumpStepOp(output, comp, &comp->steps[i], depth + 1); 8839e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard} 884017b108fcf16dbce05ca7ebd75763f3d888abb5fDaniel Veillard#endif /* LIBXML_DEBUG_ENABLED */ 8853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 8863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/************************************************************************ 8873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * * 8883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Parser stacks related functions and macros * 8893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * * 8903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ************************************************************************/ 8913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 8925e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard/** 8935e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard * valuePop: 8945e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard * @ctxt: an XPath evaluation context 8955e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard * 8965e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard * Pops the top XPath object from the value stack 8975e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard * 8985e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard * Returns the XPath object just removed 8995e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard */ 9001c732d2e10935529b717864b6fa4296f80edace1Daniel Veillardextern xmlXPathObjectPtr 9011c732d2e10935529b717864b6fa4296f80edace1Daniel VeillardvaluePop(xmlXPathParserContextPtr ctxt) 9021c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard{ 9031c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard xmlXPathObjectPtr ret; 9041c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard 9051c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard if (ctxt->valueNr <= 0) 9061c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard return (0); 9071c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard ctxt->valueNr--; 9081c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard if (ctxt->valueNr > 0) 9091c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard ctxt->value = ctxt->valueTab[ctxt->valueNr - 1]; 9101c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard else 9111c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard ctxt->value = NULL; 9121c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard ret = ctxt->valueTab[ctxt->valueNr]; 9131c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard ctxt->valueTab[ctxt->valueNr] = 0; 9141c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard return (ret); 9151c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard} 9165e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard/** 9175e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard * valuePush: 9185e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard * @ctxt: an XPath evaluation context 9195e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard * @value: the XPath object 9205e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard * 9215e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard * Pushes a new XPath object on top of the value stack 922cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * 923cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * returns the number of items on the value stack 9245e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard */ 9251c732d2e10935529b717864b6fa4296f80edace1Daniel Veillardextern int 9261c732d2e10935529b717864b6fa4296f80edace1Daniel VeillardvaluePush(xmlXPathParserContextPtr ctxt, xmlXPathObjectPtr value) 9271c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard{ 9281c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard if (ctxt->valueNr >= ctxt->valueMax) { 9291c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard ctxt->valueMax *= 2; 9301c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard ctxt->valueTab = 9311c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard (xmlXPathObjectPtr *) xmlRealloc(ctxt->valueTab, 9321c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard ctxt->valueMax * 9331c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard sizeof(ctxt->valueTab[0])); 9341c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard if (ctxt->valueTab == NULL) { 9351c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard xmlGenericError(xmlGenericErrorContext, "realloc failed !\n"); 9361c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard return (0); 9371c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard } 9381c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard } 9391c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard ctxt->valueTab[ctxt->valueNr] = value; 9401c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard ctxt->value = value; 9411c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard return (ctxt->valueNr++); 9421c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard} 9433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 944f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/** 945f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathPopBoolean: 946f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @ctxt: an XPath parser context 947f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 948f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Pops a boolean from the stack, handling conversion if needed. 949f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Check error with #xmlXPathCheckError. 950f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 951f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns the boolean 952f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */ 953f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyerint 954f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathPopBoolean (xmlXPathParserContextPtr ctxt) { 955f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathObjectPtr obj; 956f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer int ret; 957f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 958f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer obj = valuePop(ctxt); 959f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (obj == NULL) { 960f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathSetError(ctxt, XPATH_INVALID_OPERAND); 961f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(0); 962f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer } 963f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer ret = xmlXPathCastToBoolean(obj); 964f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathFreeObject(obj); 965f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(ret); 966f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer} 967f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 968f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/** 969f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathPopNumber: 970f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @ctxt: an XPath parser context 971f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 972f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Pops a number from the stack, handling conversion if needed. 973f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Check error with #xmlXPathCheckError. 974f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 975f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns the number 976f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */ 977f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyerdouble 978f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathPopNumber (xmlXPathParserContextPtr ctxt) { 979f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathObjectPtr obj; 980f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer double ret; 981f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 982f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer obj = valuePop(ctxt); 983f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (obj == NULL) { 984f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathSetError(ctxt, XPATH_INVALID_OPERAND); 985f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(0); 986f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer } 987f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer ret = xmlXPathCastToNumber(obj); 988f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathFreeObject(obj); 989f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(ret); 990f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer} 991f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 992f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/** 993f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathPopString: 994f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @ctxt: an XPath parser context 995f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 996f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Pops a string from the stack, handling conversion if needed. 997f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Check error with #xmlXPathCheckError. 998f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 999f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns the string 1000f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */ 1001f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlChar * 1002f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathPopString (xmlXPathParserContextPtr ctxt) { 1003f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathObjectPtr obj; 1004f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlChar * ret; 1005f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 1006f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer obj = valuePop(ctxt); 1007f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (obj == NULL) { 1008f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathSetError(ctxt, XPATH_INVALID_OPERAND); 1009f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(NULL); 1010f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer } 1011f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer ret = xmlXPathCastToString(obj); 1012f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer /* TODO: needs refactoring somewhere else */ 1013f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (obj->stringval == ret) 1014f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer obj->stringval = NULL; 1015f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathFreeObject(obj); 1016f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(ret); 1017f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer} 1018f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 1019f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/** 1020f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathPopNodeSet: 1021f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @ctxt: an XPath parser context 1022f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 1023f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Pops a node-set from the stack, handling conversion if needed. 1024f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Check error with #xmlXPathCheckError. 1025f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 1026f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns the node-set 1027f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */ 1028f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlNodeSetPtr 1029f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathPopNodeSet (xmlXPathParserContextPtr ctxt) { 1030f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathObjectPtr obj; 1031f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlNodeSetPtr ret; 1032f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 1033f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (ctxt->value == NULL) { 1034f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathSetError(ctxt, XPATH_INVALID_OPERAND); 1035f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(NULL); 1036f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer } 1037f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (!xmlXPathStackIsNodeSet(ctxt)) { 1038f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathSetTypeError(ctxt); 1039f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(NULL); 1040f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer } 1041f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer obj = valuePop(ctxt); 1042f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer ret = obj->nodesetval; 10439deb242b558cbcff45165866e0634a1962404885Daniel Veillard /* to fix memory leak of not clearing obj->user */ 10449deb242b558cbcff45165866e0634a1962404885Daniel Veillard if (obj->boolval && obj->user != NULL) 10459deb242b558cbcff45165866e0634a1962404885Daniel Veillard xmlFreeNodeList((xmlNodePtr) obj->user); 1046f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathFreeNodeSetList(obj); 1047f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(ret); 1048f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer} 1049f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 1050f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/** 1051f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathPopExternal: 1052f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @ctxt: an XPath parser context 1053f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 1054cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * Pops an external object from the stack, handling conversion if needed. 1055f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Check error with #xmlXPathCheckError. 1056f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 1057f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns the object 1058f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */ 1059f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyervoid * 1060f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathPopExternal (xmlXPathParserContextPtr ctxt) { 1061f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathObjectPtr obj; 1062f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer void * ret; 1063f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 1064f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (ctxt->value == NULL) { 1065f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathSetError(ctxt, XPATH_INVALID_OPERAND); 1066f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(NULL); 1067f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer } 1068f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (ctxt->value->type != XPATH_USERS) { 1069f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathSetTypeError(ctxt); 1070f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(NULL); 1071f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer } 1072f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer obj = valuePop(ctxt); 1073f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer ret = obj->user; 1074f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathFreeObject(obj); 1075f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(ret); 1076f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer} 1077f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 10783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/* 10793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Macros for accessing the content. Those should be used only by the parser, 10803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * and not exported. 10813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 10823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Dirty macros, i.e. one need to make assumption on the context to use them 10833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 10843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * CUR_PTR return the current pointer to the xmlChar to be parsed. 10853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * CUR returns the current xmlChar value, i.e. a 8 bit value 10863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * in ISO-Latin or UTF-8. 10873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * This should be used internally by the parser 10883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * only to compare to ASCII values otherwise it would break when 10893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * running with UTF-8 encoding. 10903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * NXT(n) returns the n'th next xmlChar. Same as CUR is should be used only 10913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * to compare on ASCII based substring. 10923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * SKIP(n) Skip n xmlChar, and must also be used only to skip ASCII defined 10933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * strings within the parser. 10943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * CURRENT Returns the current char value, with the full decoding of 10953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * UTF-8 if we are using this mode. It returns an int. 10963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * NEXT Skip to the next character, this does the proper decoding 10973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * in UTF-8 mode. It also pop-up unfinished entities on the fly. 10983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * It returns the pointer to the current xmlChar. 10993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 11003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 11013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define CUR (*ctxt->cur) 11023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define SKIP(val) ctxt->cur += (val) 11033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define NXT(val) ctxt->cur[(val)] 11043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define CUR_PTR ctxt->cur 110561d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard#define CUR_CHAR(l) xmlXPathCurrentChar(ctxt, &l) 110661d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard 110761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard#define COPY_BUF(l,b,i,v) \ 110861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard if (l == 1) b[i++] = (xmlChar) v; \ 110961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard else i += xmlCopyChar(l,&b[i],v) 111061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard 111161d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard#define NEXTL(l) ctxt->cur += l 11123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 11133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define SKIP_BLANKS \ 11143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while (IS_BLANK(*(ctxt->cur))) NEXT 11153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 11163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define CURRENT (*ctxt->cur) 11173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define NEXT ((*ctxt->cur) ? ctxt->cur++: ctxt->cur) 11183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1119e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese 1120e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese#ifndef DBL_DIG 1121e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese#define DBL_DIG 16 1122e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese#endif 1123e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese#ifndef DBL_EPSILON 1124e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese#define DBL_EPSILON 1E-9 1125e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese#endif 1126e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese 1127e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese#define UPPER_DOUBLE 1E9 1128e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese#define LOWER_DOUBLE 1E-5 1129e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese 1130e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese#define INTEGER_DIGITS DBL_DIG 1131e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese#define FRACTION_DIGITS (DBL_DIG + 1) 1132e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese#define EXPONENT_DIGITS (3 + 2) 1133e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese 1134e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese/** 1135e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese * xmlXPathFormatNumber: 1136e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese * @number: number to format 1137e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese * @buffer: output buffer 1138e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese * @buffersize: size of output buffer 1139e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese * 1140e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese * Convert the number into a string representation. 1141e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese */ 1142e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reesestatic void 1143e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn ReesexmlXPathFormatNumber(double number, char buffer[], int buffersize) 1144e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese{ 1145cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard switch (xmlXPathIsInf(number)) { 1146e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese case 1: 11475fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard if (buffersize > (int)sizeof("Infinity")) 114849cc97565fbe2928388a1e437c44429097a504aeAleksey Sanin snprintf(buffer, buffersize, "Infinity"); 1149e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese break; 1150e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese case -1: 1151e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese if (buffersize > (int)sizeof("-Infinity")) 115249cc97565fbe2928388a1e437c44429097a504aeAleksey Sanin snprintf(buffer, buffersize, "-Infinity"); 1153e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese break; 1154e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese default: 1155cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard if (xmlXPathIsNaN(number)) { 1156e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese if (buffersize > (int)sizeof("NaN")) 115749cc97565fbe2928388a1e437c44429097a504aeAleksey Sanin snprintf(buffer, buffersize, "NaN"); 1158d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard } else if (number == 0 && xmlXPathGetSign(number) != 0) { 115949cc97565fbe2928388a1e437c44429097a504aeAleksey Sanin snprintf(buffer, buffersize, "0"); 116028cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard } else if (number == ((int) number)) { 116128cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard char work[30]; 116228cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard char *ptr, *cur; 116328cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard int res, value = (int) number; 116428cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard 116528cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard ptr = &buffer[0]; 116628cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard if (value < 0) { 116728cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard *ptr++ = '-'; 116828cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard value = -value; 116928cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard } 117028cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard if (value == 0) { 117128cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard *ptr++ = '0'; 117228cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard } else { 117328cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard cur = &work[0]; 117428cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard while (value != 0) { 117528cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard res = value % 10; 117628cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard value = value / 10; 117728cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard *cur++ = '0' + res; 117828cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard } 117928cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard cur--; 118028cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard while ((cur >= &work[0]) && (ptr - buffer < buffersize)) { 118128cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard *ptr++ = *cur--; 118228cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard } 118328cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard } 118428cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard if (ptr - buffer < buffersize) { 118528cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard *ptr = 0; 118628cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard } else if (buffersize > 0) { 118728cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard ptr--; 118828cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard *ptr = 0; 118928cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard } 1190e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese } else { 119170a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese /* 3 is sign, decimal point, and terminating zero */ 119270a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese char work[DBL_DIG + EXPONENT_DIGITS + 3]; 119370a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese int integer_place, fraction_place; 119470a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese char *ptr; 119570a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese char *after_fraction; 119670a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese double absolute_value; 119770a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese int size; 119870a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese 119970a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese absolute_value = fabs(number); 120070a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese 120170a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese /* 120270a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese * First choose format - scientific or regular floating point. 120370a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese * In either case, result is in work, and after_fraction points 120470a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese * just past the fractional part. 120570a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese */ 120670a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese if ( ((absolute_value > UPPER_DOUBLE) || 120770a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese (absolute_value < LOWER_DOUBLE)) && 120870a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese (absolute_value != 0.0) ) { 120970a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese /* Use scientific notation */ 121070a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese integer_place = DBL_DIG + EXPONENT_DIGITS + 1; 121170a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese fraction_place = DBL_DIG - 1; 121270a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese snprintf(work, sizeof(work),"%*.*e", 121370a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese integer_place, fraction_place, number); 121470a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese after_fraction = strchr(work + DBL_DIG, 'e'); 1215e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese } 121670a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese else { 121770a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese /* Use regular notation */ 121856f0646e734ffbdd6945d86cc28b69b6569a82fcDaniel Veillard if (absolute_value > 0.0) 121956f0646e734ffbdd6945d86cc28b69b6569a82fcDaniel Veillard integer_place = 1 + (int)log10(absolute_value); 122056f0646e734ffbdd6945d86cc28b69b6569a82fcDaniel Veillard else 1221a3067d19ec3a96fd6e7997753e27a5422a2856f7Daniel Veillard integer_place = 0; 122270a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese fraction_place = (integer_place > 0) 122370a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese ? DBL_DIG - integer_place 122470a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese : DBL_DIG; 122570a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese size = snprintf(work, sizeof(work), "%0.*f", 122670a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese fraction_place, number); 122770a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese after_fraction = work + size; 1228e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese } 1229e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese 123070a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese /* Remove fractional trailing zeroes */ 123170a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese ptr = after_fraction; 123270a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese while (*(--ptr) == '0') 123370a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese ; 123470a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese if (*ptr != '.') 123570a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese ptr++; 12365dd3c9622ab6a8e75870bc5351499155e7963abcDaniel Veillard while ((*ptr++ = *after_fraction++) != 0); 123770a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese 123870a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese /* Finally copy result back to caller */ 123970a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese size = strlen(work) + 1; 124070a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese if (size > buffersize) { 124170a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese work[buffersize - 1] = 0; 124270a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese size = buffersize; 124370a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese } 12445dd3c9622ab6a8e75870bc5351499155e7963abcDaniel Veillard memmove(buffer, work, size); 1245e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese } 1246e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese break; 1247e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese } 1248e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese} 1249e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese 12503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/************************************************************************ 12513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * * 12523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Error handling routines * 12533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * * 12543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ************************************************************************/ 12553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 12563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1257b44025c72b7472971a061b022cfe422adc42715dDaniel Veillardstatic const char *xmlXPathErrorMessages[] = { 12583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "Ok", 12593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "Number encoding", 1260cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard "Unfinished literal", 1261cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard "Start of literal", 12623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "Expected $ for variable reference", 12633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "Undefined variable", 12643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "Invalid predicate", 12653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "Invalid expression", 12663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "Missing closing curly brace", 12673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "Unregistered function", 12683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "Invalid operand", 12693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "Invalid type", 12703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "Invalid number of arguments", 12713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "Invalid context size", 12723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "Invalid context position", 12733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "Memory allocation error", 12743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "Syntax error", 12753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "Resource error", 12763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "Sub resource error", 127761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard "Undefined namespace prefix", 127861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard "Encoding error", 127961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard "Char out of XML range" 12803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}; 12813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 12823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 12835e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard * xmlXPatherror: 12843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 12853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @file: the file name 12863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @line: the line number 12873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @no: the error number 12883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 1289f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Formats an error message. 12903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 12913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 1292dda8f1ba9fb2e731e2dd6aa325ed07add7905ec3Daniel VeillardxmlXPatherror(xmlXPathParserContextPtr ctxt, const char *file ATTRIBUTE_UNUSED, 1293dda8f1ba9fb2e731e2dd6aa325ed07add7905ec3Daniel Veillard int line ATTRIBUTE_UNUSED, int no) { 12943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int n; 12953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor const xmlChar *cur; 12963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor const xmlChar *base; 12973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 12983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur = ctxt->cur; 12993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor base = ctxt->base; 1300118aed78f360f51d182770e62b251ef324707aa2Daniel Veillard if ((cur == NULL) || (base == NULL)) { 1301118aed78f360f51d182770e62b251ef324707aa2Daniel Veillard if ((ctxt->comp != NULL) && (ctxt->comp->expr != NULL)) { 1302118aed78f360f51d182770e62b251ef324707aa2Daniel Veillard xmlGenericError(xmlGenericErrorContext, 1303118aed78f360f51d182770e62b251ef324707aa2Daniel Veillard "XPath error %s in %s\n", xmlXPathErrorMessages[no], 1304118aed78f360f51d182770e62b251ef324707aa2Daniel Veillard ctxt->comp->expr); 1305118aed78f360f51d182770e62b251ef324707aa2Daniel Veillard } else { 1306118aed78f360f51d182770e62b251ef324707aa2Daniel Veillard xmlGenericError(xmlGenericErrorContext, 1307118aed78f360f51d182770e62b251ef324707aa2Daniel Veillard "XPath error %s\n", xmlXPathErrorMessages[no]); 1308118aed78f360f51d182770e62b251ef324707aa2Daniel Veillard } 1309118aed78f360f51d182770e62b251ef324707aa2Daniel Veillard 1310d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard return; 1311118aed78f360f51d182770e62b251ef324707aa2Daniel Veillard } 1312118aed78f360f51d182770e62b251ef324707aa2Daniel Veillard xmlGenericError(xmlGenericErrorContext, 1313118aed78f360f51d182770e62b251ef324707aa2Daniel Veillard "XPath error %s\n", xmlXPathErrorMessages[no]); 1314d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard 13153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while ((cur > base) && ((*cur == '\n') || (*cur == '\r'))) { 13163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur--; 13173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 13183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor n = 0; 13193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while ((n++ < 80) && (cur > base) && (*cur != '\n') && (*cur != '\r')) 13203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur--; 13213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((*cur == '\n') || (*cur == '\r')) cur++; 13223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor base = cur; 13233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor n = 0; 13243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while ((*cur != 0) && (*cur != '\n') && (*cur != '\r') && (n < 79)) { 13253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, "%c", (unsigned char) *cur++); 13263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor n++; 13273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 13283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, "\n"); 13293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur = ctxt->cur; 13303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while ((*cur == '\n') || (*cur == '\r')) 13313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur--; 13323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor n = 0; 13333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while ((cur != base) && (n++ < 80)) { 13343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, " "); 13353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor base++; 13363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 13373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext,"^\n"); 13383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 13393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 13403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 13413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/************************************************************************ 13423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * * 13433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Routines to handle NodeSets * 13443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * * 13453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ************************************************************************/ 13463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 13473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 1348e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard * xmlXPathOrderDocElems: 1349e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard * @doc: an input document 1350e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard * 1351e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard * Call this routine to speed up XPath computation on static documents. 1352e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard * This stamps all the element nodes with the document order 1353e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard * Like for line information, the order is kept in the element->content 1354e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard * field, the value stored is actually - the node number (startting at -1) 1355e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard * to be able to differenciate from line numbers. 1356e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard * 1357e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard * Returns the number of element found in the document or -1 in case 1358e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard * of error. 1359e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard */ 1360e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillardlong 1361e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel VeillardxmlXPathOrderDocElems(xmlDocPtr doc) { 1362e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard long count = 0; 1363e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard xmlNodePtr cur; 1364e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard 1365e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard if (doc == NULL) 1366e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard return(-1); 1367e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard cur = doc->children; 1368e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard while (cur != NULL) { 1369e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard if (cur->type == XML_ELEMENT_NODE) { 1370e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard cur->content = (void *) (-(++count)); 1371e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard if (cur->children != NULL) { 1372e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard cur = cur->children; 1373e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard continue; 1374e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard } 1375e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard } 1376e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard if (cur->next != NULL) { 1377e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard cur = cur->next; 1378e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard continue; 1379e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard } 1380e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard do { 1381e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard cur = cur->parent; 1382e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard if (cur == NULL) 1383e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard break; 1384e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard if (cur == (xmlNodePtr) doc) { 1385e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard cur = NULL; 1386e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard break; 1387e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard } 1388e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard if (cur->next != NULL) { 1389e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard cur = cur->next; 1390e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard break; 1391e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard } 1392e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard } while (cur != NULL); 1393e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard } 1394e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard return(count); 1395e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard} 1396e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard 1397e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard/** 13983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathCmpNodes: 13993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @node1: the first node 14003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @node2: the second node 14013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 14023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Compare two nodes w.r.t document order 14033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 14043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns -2 in case of error 1 if first point < second point, 0 if 14053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * that's the same node, -1 otherwise 14063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 14073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorint 14083473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathCmpNodes(xmlNodePtr node1, xmlNodePtr node2) { 14093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int depth1, depth2; 1410edfd588e95d7c4690b5e85880521a32c20ed4fdeDaniel Veillard int attr1 = 0, attr2 = 0; 14113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlNodePtr cur, root; 14123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 14133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((node1 == NULL) || (node2 == NULL)) 14143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(-2); 14153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 14163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * a couple of optimizations which will avoid computations in most cases 14173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 1418edfd588e95d7c4690b5e85880521a32c20ed4fdeDaniel Veillard if (node1->type == XML_ATTRIBUTE_NODE) { 1419edfd588e95d7c4690b5e85880521a32c20ed4fdeDaniel Veillard attr1 = 1; 1420edfd588e95d7c4690b5e85880521a32c20ed4fdeDaniel Veillard node1 = node1->parent; 1421edfd588e95d7c4690b5e85880521a32c20ed4fdeDaniel Veillard } 1422edfd588e95d7c4690b5e85880521a32c20ed4fdeDaniel Veillard if (node2->type == XML_ATTRIBUTE_NODE) { 1423edfd588e95d7c4690b5e85880521a32c20ed4fdeDaniel Veillard attr2 = 1; 1424edfd588e95d7c4690b5e85880521a32c20ed4fdeDaniel Veillard node2 = node2->parent; 1425edfd588e95d7c4690b5e85880521a32c20ed4fdeDaniel Veillard } 1426edfd588e95d7c4690b5e85880521a32c20ed4fdeDaniel Veillard if (node1 == node2) { 1427edfd588e95d7c4690b5e85880521a32c20ed4fdeDaniel Veillard if (attr1 == attr2) 1428edfd588e95d7c4690b5e85880521a32c20ed4fdeDaniel Veillard return(0); 1429edfd588e95d7c4690b5e85880521a32c20ed4fdeDaniel Veillard if (attr2 == 1) 1430edfd588e95d7c4690b5e85880521a32c20ed4fdeDaniel Veillard return(1); 1431edfd588e95d7c4690b5e85880521a32c20ed4fdeDaniel Veillard return(-1); 1432edfd588e95d7c4690b5e85880521a32c20ed4fdeDaniel Veillard } 1433b33c201978ed1c434877cdc6e2000b7012cc26f9Daniel Veillard if ((node1->type == XML_NAMESPACE_DECL) || 1434b33c201978ed1c434877cdc6e2000b7012cc26f9Daniel Veillard (node2->type == XML_NAMESPACE_DECL)) 1435b33c201978ed1c434877cdc6e2000b7012cc26f9Daniel Veillard return(1); 14363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (node1 == node2->prev) 14373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(1); 14383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (node1 == node2->next) 14393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(-1); 14403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 14413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 1442e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard * Speedup using document order if availble. 14437216cfd6622d947695c67b7b430edef8cc0af967Daniel Veillard */ 14447216cfd6622d947695c67b7b430edef8cc0af967Daniel Veillard if ((node1->type == XML_ELEMENT_NODE) && 14457216cfd6622d947695c67b7b430edef8cc0af967Daniel Veillard (node2->type == XML_ELEMENT_NODE) && 1446e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard (0 > (long) node1->content) && 1447e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard (0 > (long) node2->content) && 1448e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard (node1->doc == node2->doc)) { 1449e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard long l1, l2; 1450e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard 1451e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard l1 = -((long) node1->content); 1452e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard l2 = -((long) node2->content); 14537216cfd6622d947695c67b7b430edef8cc0af967Daniel Veillard if (l1 < l2) 14547216cfd6622d947695c67b7b430edef8cc0af967Daniel Veillard return(1); 14557216cfd6622d947695c67b7b430edef8cc0af967Daniel Veillard if (l1 > l2) 14567216cfd6622d947695c67b7b430edef8cc0af967Daniel Veillard return(-1); 14577216cfd6622d947695c67b7b430edef8cc0af967Daniel Veillard } 1458e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard 14597216cfd6622d947695c67b7b430edef8cc0af967Daniel Veillard /* 14603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * compute depth to root 14613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 14623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor for (depth2 = 0, cur = node2;cur->parent != NULL;cur = cur->parent) { 14633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == node1) 14643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(1); 14653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor depth2++; 14663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 14673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor root = cur; 14683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor for (depth1 = 0, cur = node1;cur->parent != NULL;cur = cur->parent) { 14693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == node2) 14703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(-1); 14713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor depth1++; 14723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 14733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 14743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Distinct document (or distinct entities :-( ) case. 14753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 14763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (root != cur) { 14773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(-2); 14783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 14793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 14803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * get the nearest common ancestor. 14813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 14823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while (depth1 > depth2) { 14833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor depth1--; 14843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor node1 = node1->parent; 14853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 14863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while (depth2 > depth1) { 14873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor depth2--; 14883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor node2 = node2->parent; 14893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 14903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while (node1->parent != node2->parent) { 14913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor node1 = node1->parent; 14923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor node2 = node2->parent; 14933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* should not happen but just in case ... */ 14943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((node1 == NULL) || (node2 == NULL)) 14953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(-2); 14963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 14973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 14983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Find who's first. 14993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 15003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (node1 == node2->next) 15013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(-1); 15023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor for (cur = node1->next;cur != NULL;cur = cur->next) 15033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == node2) 15043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(1); 15053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(-1); /* assume there is no sibling list corruption */ 15063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 15073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 15083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 15093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNodeSetSort: 15103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @set: the node set 15113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 15123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Sort the node set in document order 15133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 15143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 15153473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNodeSetSort(xmlNodeSetPtr set) { 1516e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese int i, j, incr, len; 15173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlNodePtr tmp; 15183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 15193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (set == NULL) 15203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return; 15213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 15223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* Use Shell's sort to sort the node-set */ 15233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor len = set->nodeNr; 15243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor for (incr = len / 2; incr > 0; incr /= 2) { 15253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor for (i = incr; i < len; i++) { 15263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor j = i - incr; 15273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while (j >= 0) { 1528e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese if (xmlXPathCmpNodes(set->nodeTab[j], 1529e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese set->nodeTab[j + incr]) == -1) { 15303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor tmp = set->nodeTab[j]; 15313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor set->nodeTab[j] = set->nodeTab[j + incr]; 15323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor set->nodeTab[j + incr] = tmp; 15333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor j -= incr; 15343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else 15353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 15363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 15373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 15383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 15393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 15403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 15413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define XML_NODESET_DEFAULT 10 15423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 1543044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * xmlXPathNodeSetDupNs: 1544044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * @node: the parent node of the namespace XPath node 1545044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * @ns: the libxml namespace declaration node. 1546044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * 1547044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * Namespace node in libxml don't match the XPath semantic. In a node set 1548044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * the namespace nodes are duplicated and the next pointer is set to the 1549044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * parent node in the XPath semantic. 1550044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * 1551044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * Returns the newly created object. 1552044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard */ 1553044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillardstatic xmlNodePtr 1554044fc6b7476798cbb95277b4905e5111d7c2775dDaniel VeillardxmlXPathNodeSetDupNs(xmlNodePtr node, xmlNsPtr ns) { 1555044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlNsPtr cur; 1556044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard 1557044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if ((ns == NULL) || (ns->type != XML_NAMESPACE_DECL)) 1558044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard return(NULL); 1559044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if ((node == NULL) || (node->type == XML_NAMESPACE_DECL)) 1560044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard return((xmlNodePtr) ns); 1561044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard 1562044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard /* 1563044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * Allocate a new Namespace and fill the fields. 1564044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard */ 1565044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard cur = (xmlNsPtr) xmlMalloc(sizeof(xmlNs)); 1566044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if (cur == NULL) { 1567044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlGenericError(xmlGenericErrorContext, 1568044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard "xmlXPathNodeSetDupNs : malloc failed\n"); 1569044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard return(NULL); 1570044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } 1571044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard memset(cur, 0, sizeof(xmlNs)); 1572044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard cur->type = XML_NAMESPACE_DECL; 1573044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if (ns->href != NULL) 1574044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard cur->href = xmlStrdup(ns->href); 1575044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if (ns->prefix != NULL) 1576044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard cur->prefix = xmlStrdup(ns->prefix); 1577044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard cur->next = (xmlNsPtr) node; 1578044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard return((xmlNodePtr) cur); 1579044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard} 1580044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard 1581044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard/** 1582044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * xmlXPathNodeSetFreeNs: 1583044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * @ns: the XPath namespace node found in a nodeset. 1584044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * 1585044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * Namespace node in libxml don't match the XPath semantic. In a node set 1586044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * the namespace nodes are duplicated and the next pointer is set to the 1587044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * parent node in the XPath semantic. Check if such a node need to be freed 1588044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard */ 1589f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Saninvoid 1590044fc6b7476798cbb95277b4905e5111d7c2775dDaniel VeillardxmlXPathNodeSetFreeNs(xmlNsPtr ns) { 1591044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if ((ns == NULL) || (ns->type != XML_NAMESPACE_DECL)) 1592044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard return; 1593044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard 1594044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if ((ns->next != NULL) && (ns->next->type != XML_NAMESPACE_DECL)) { 1595044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if (ns->href != NULL) 1596044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlFree((xmlChar *)ns->href); 1597044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if (ns->prefix != NULL) 1598044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlFree((xmlChar *)ns->prefix); 1599044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlFree(ns); 1600044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } 1601044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard} 1602044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard 1603044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard/** 16043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNodeSetCreate: 16053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val: an initial xmlNodePtr, or NULL 16063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 16073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Create a new xmlNodeSetPtr of type double and of value @val 16083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 16093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the newly created object. 16103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 16113473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNodeSetPtr 16123473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNodeSetCreate(xmlNodePtr val) { 16133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlNodeSetPtr ret; 16143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 16153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = (xmlNodeSetPtr) xmlMalloc(sizeof(xmlNodeSet)); 16163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ret == NULL) { 16173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 1618cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard "xmlXPathNodeSetCreate: out of memory\n"); 16193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 16203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 16213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor memset(ret, 0 , (size_t) sizeof(xmlNodeSet)); 16223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (val != NULL) { 16233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->nodeTab = (xmlNodePtr *) xmlMalloc(XML_NODESET_DEFAULT * 16243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor sizeof(xmlNodePtr)); 16253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ret->nodeTab == NULL) { 16263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 1627cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard "xmlXPathNodeSetCreate: out of memory\n"); 16283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 16293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 16303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor memset(ret->nodeTab, 0 , 16313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XML_NODESET_DEFAULT * (size_t) sizeof(xmlNodePtr)); 16323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->nodeMax = XML_NODESET_DEFAULT; 1633044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if (val->type == XML_NAMESPACE_DECL) { 1634044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlNsPtr ns = (xmlNsPtr) val; 1635044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard 1636044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard ret->nodeTab[ret->nodeNr++] = 1637044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlXPathNodeSetDupNs((xmlNodePtr) ns->next, ns); 1638044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } else 1639044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard ret->nodeTab[ret->nodeNr++] = val; 16403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 16413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ret); 16423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 16433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 16443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 1645f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathNodeSetContains: 1646f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @cur: the node-set 1647f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @val: the node 1648f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 1649f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * checks whether @cur contains @val 1650f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 1651f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns true (1) if @cur contains @val, false (0) otherwise 1652f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */ 1653f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyerint 1654f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathNodeSetContains (xmlNodeSetPtr cur, xmlNodePtr val) { 1655f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer int i; 1656f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 1657044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if (val->type == XML_NAMESPACE_DECL) { 1658044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard for (i = 0; i < cur->nodeNr; i++) { 1659044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if (cur->nodeTab[i]->type == XML_NAMESPACE_DECL) { 1660044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlNsPtr ns1, ns2; 1661044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard 1662044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard ns1 = (xmlNsPtr) val; 1663044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard ns2 = (xmlNsPtr) cur->nodeTab[i]; 1664044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if (ns1 == ns2) 1665044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard return(1); 1666044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if ((ns1->next != NULL) && (ns2->next == ns1->next) && 1667044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard (xmlStrEqual(ns1->prefix, ns2->prefix))) 1668044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard return(1); 1669044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } 1670044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } 1671044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } else { 1672044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard for (i = 0; i < cur->nodeNr; i++) { 1673044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if (cur->nodeTab[i] == val) 1674044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard return(1); 1675044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } 1676f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer } 1677f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(0); 1678f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer} 1679f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 1680f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/** 1681044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * xmlXPathNodeSetAddNs: 1682044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * @cur: the initial node set 1683044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * @node: the hosting node 1684044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * @ns: a the namespace node 1685044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * 1686044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * add a new namespace node to an existing NodeSet 1687044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard */ 168879376ba94845db7096c3917f4f40baeb450eb0e9Aleksey Saninvoid 1689044fc6b7476798cbb95277b4905e5111d7c2775dDaniel VeillardxmlXPathNodeSetAddNs(xmlNodeSetPtr cur, xmlNodePtr node, xmlNsPtr ns) { 1690044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard int i; 1691044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard 1692044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if ((ns == NULL) || (node == NULL) || (ns->type != XML_NAMESPACE_DECL) || 1693044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard (node->type != XML_ELEMENT_NODE)) 1694044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard return; 1695044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard 1696044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard /* @@ with_ns to check wether namespace nodes should be looked at @@ */ 1697044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard /* 1698044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * check against doublons 1699044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard */ 1700044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard for (i = 0;i < cur->nodeNr;i++) { 1701044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if ((cur->nodeTab[i] != NULL) && 1702044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard (cur->nodeTab[i]->type == XML_NAMESPACE_DECL) && 1703c62a147963b5839fc815267706eaec381f90ca16Daniel Veillard (((xmlNsPtr)cur->nodeTab[i])->next == (xmlNsPtr) node) && 1704044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard (xmlStrEqual(ns->prefix, ((xmlNsPtr)cur->nodeTab[i])->prefix))) 1705044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard return; 1706044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } 1707044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard 1708044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard /* 1709044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * grow the nodeTab if needed 1710044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard */ 1711044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if (cur->nodeMax == 0) { 1712044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard cur->nodeTab = (xmlNodePtr *) xmlMalloc(XML_NODESET_DEFAULT * 1713044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard sizeof(xmlNodePtr)); 1714044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if (cur->nodeTab == NULL) { 1715044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlGenericError(xmlGenericErrorContext, 1716044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard "xmlXPathNodeSetAdd: out of memory\n"); 1717044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard return; 1718044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } 1719044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard memset(cur->nodeTab, 0 , 1720044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard XML_NODESET_DEFAULT * (size_t) sizeof(xmlNodePtr)); 1721044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard cur->nodeMax = XML_NODESET_DEFAULT; 1722044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } else if (cur->nodeNr == cur->nodeMax) { 1723044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlNodePtr *temp; 1724044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard 1725044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard cur->nodeMax *= 2; 1726044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard temp = (xmlNodePtr *) xmlRealloc(cur->nodeTab, cur->nodeMax * 1727044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard sizeof(xmlNodePtr)); 1728044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if (temp == NULL) { 1729044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlGenericError(xmlGenericErrorContext, 1730044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard "xmlXPathNodeSetAdd: out of memory\n"); 1731044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard return; 1732044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } 1733044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard cur->nodeTab = temp; 1734044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } 1735044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard cur->nodeTab[cur->nodeNr++] = xmlXPathNodeSetDupNs(node, ns); 1736044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard} 1737044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard 1738044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard/** 17393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNodeSetAdd: 17403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur: the initial node set 17413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val: a new xmlNodePtr 17423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 1743cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * add a new xmlNodePtr to an existing NodeSet 17443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 17453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 17463473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNodeSetAdd(xmlNodeSetPtr cur, xmlNodePtr val) { 17473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int i; 17483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 17493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (val == NULL) return; 17503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1751ef0b45016373d65700ef6f7d494a200758b2e4c5Daniel Veillard#if 0 1752652d8a949447833405cc0805f4b7ff1179e59ed2Daniel Veillard if ((val->type == XML_ELEMENT_NODE) && (val->name[0] == ' ')) 1753652d8a949447833405cc0805f4b7ff1179e59ed2Daniel Veillard return; /* an XSLT fake node */ 1754ef0b45016373d65700ef6f7d494a200758b2e4c5Daniel Veillard#endif 1755652d8a949447833405cc0805f4b7ff1179e59ed2Daniel Veillard 1756044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard /* @@ with_ns to check wether namespace nodes should be looked at @@ */ 17573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 17583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * check against doublons 17593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 17603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor for (i = 0;i < cur->nodeNr;i++) 17613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur->nodeTab[i] == val) return; 17623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 17633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 17643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * grow the nodeTab if needed 17653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 17663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur->nodeMax == 0) { 17673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur->nodeTab = (xmlNodePtr *) xmlMalloc(XML_NODESET_DEFAULT * 17683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor sizeof(xmlNodePtr)); 17693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur->nodeTab == NULL) { 17703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 17713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "xmlXPathNodeSetAdd: out of memory\n"); 17723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return; 17733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 17743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor memset(cur->nodeTab, 0 , 17753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XML_NODESET_DEFAULT * (size_t) sizeof(xmlNodePtr)); 17763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur->nodeMax = XML_NODESET_DEFAULT; 17773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else if (cur->nodeNr == cur->nodeMax) { 17783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlNodePtr *temp; 17793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 17803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur->nodeMax *= 2; 17813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor temp = (xmlNodePtr *) xmlRealloc(cur->nodeTab, cur->nodeMax * 17823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor sizeof(xmlNodePtr)); 17833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (temp == NULL) { 17843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 17853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "xmlXPathNodeSetAdd: out of memory\n"); 17863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return; 17873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 17883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur->nodeTab = temp; 17893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 1790044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if (val->type == XML_NAMESPACE_DECL) { 1791044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlNsPtr ns = (xmlNsPtr) val; 1792044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard 1793044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard cur->nodeTab[cur->nodeNr++] = 1794044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlXPathNodeSetDupNs((xmlNodePtr) ns->next, ns); 1795044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } else 1796044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard cur->nodeTab[cur->nodeNr++] = val; 17973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 17983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 17993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 18003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNodeSetAddUnique: 18013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur: the initial node set 18023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val: a new xmlNodePtr 18033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 1804cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * add a new xmlNodePtr to an existing NodeSet, optimized version 18053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * when we are sure the node is not already in the set. 18063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 18073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 18083473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNodeSetAddUnique(xmlNodeSetPtr cur, xmlNodePtr val) { 18093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (val == NULL) return; 18103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1811ef0b45016373d65700ef6f7d494a200758b2e4c5Daniel Veillard#if 0 1812652d8a949447833405cc0805f4b7ff1179e59ed2Daniel Veillard if ((val->type == XML_ELEMENT_NODE) && (val->name[0] == ' ')) 1813652d8a949447833405cc0805f4b7ff1179e59ed2Daniel Veillard return; /* an XSLT fake node */ 1814ef0b45016373d65700ef6f7d494a200758b2e4c5Daniel Veillard#endif 1815652d8a949447833405cc0805f4b7ff1179e59ed2Daniel Veillard 1816044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard /* @@ with_ns to check wether namespace nodes should be looked at @@ */ 18173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 18183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * grow the nodeTab if needed 18193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 18203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur->nodeMax == 0) { 18213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur->nodeTab = (xmlNodePtr *) xmlMalloc(XML_NODESET_DEFAULT * 18223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor sizeof(xmlNodePtr)); 18233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur->nodeTab == NULL) { 18243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 18253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "xmlXPathNodeSetAddUnique: out of memory\n"); 18263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return; 18273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 18283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor memset(cur->nodeTab, 0 , 18293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XML_NODESET_DEFAULT * (size_t) sizeof(xmlNodePtr)); 18303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur->nodeMax = XML_NODESET_DEFAULT; 18313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else if (cur->nodeNr == cur->nodeMax) { 18323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlNodePtr *temp; 18333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 18343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur->nodeMax *= 2; 18353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor temp = (xmlNodePtr *) xmlRealloc(cur->nodeTab, cur->nodeMax * 18363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor sizeof(xmlNodePtr)); 18373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (temp == NULL) { 18383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 18393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "xmlXPathNodeSetAddUnique: out of memory\n"); 18403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return; 18413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 18423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur->nodeTab = temp; 18433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 1844044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if (val->type == XML_NAMESPACE_DECL) { 1845044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlNsPtr ns = (xmlNsPtr) val; 1846044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard 1847044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard cur->nodeTab[cur->nodeNr++] = 1848044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlXPathNodeSetDupNs((xmlNodePtr) ns->next, ns); 1849044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } else 1850044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard cur->nodeTab[cur->nodeNr++] = val; 18513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 18523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 18533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 18543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNodeSetMerge: 18553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val1: the first NodeSet or NULL 18563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val2: the second NodeSet 18573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 18583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Merges two nodesets, all nodes from @val2 are added to @val1 18593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * if @val1 is NULL, a new set is created and copied from @val2 18603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 1861cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * Returns @val1 once extended or NULL in case of error. 18623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 18633473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNodeSetPtr 18643473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNodeSetMerge(xmlNodeSetPtr val1, xmlNodeSetPtr val2) { 1865d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard int i, j, initNr, skip; 18663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 18673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (val2 == NULL) return(val1); 18683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (val1 == NULL) { 18693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor val1 = xmlXPathNodeSetCreate(NULL); 18703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 18713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1872044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard /* @@ with_ns to check wether namespace nodes should be looked at @@ */ 18733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor initNr = val1->nodeNr; 18743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 18753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor for (i = 0;i < val2->nodeNr;i++) { 18763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 18773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * check against doublons 18783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 1879d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard skip = 0; 1880d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard for (j = 0; j < initNr; j++) { 1881d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard if (val1->nodeTab[j] == val2->nodeTab[i]) { 1882d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard skip = 1; 1883d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard break; 1884044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } else if ((val1->nodeTab[j]->type == XML_NAMESPACE_DECL) && 1885044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard (val2->nodeTab[i]->type == XML_NAMESPACE_DECL)) { 1886044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlNsPtr ns1, ns2; 1887044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard ns1 = (xmlNsPtr) val1->nodeTab[j]; 1888044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard ns2 = (xmlNsPtr) val2->nodeTab[i]; 1889044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if ((ns1->next == ns2->next) && 1890044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard (xmlStrEqual(ns1->prefix, ns2->prefix))) { 1891044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard skip = 1; 1892044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard break; 1893044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } 1894d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard } 1895d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard } 1896d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard if (skip) 1897d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard continue; 18983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 18993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 19003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * grow the nodeTab if needed 19013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 19023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (val1->nodeMax == 0) { 19033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor val1->nodeTab = (xmlNodePtr *) xmlMalloc(XML_NODESET_DEFAULT * 19043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor sizeof(xmlNodePtr)); 19053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (val1->nodeTab == NULL) { 19063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 19073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "xmlXPathNodeSetMerge: out of memory\n"); 19083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 19093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 19103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor memset(val1->nodeTab, 0 , 19113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XML_NODESET_DEFAULT * (size_t) sizeof(xmlNodePtr)); 19123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor val1->nodeMax = XML_NODESET_DEFAULT; 19133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else if (val1->nodeNr == val1->nodeMax) { 19143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlNodePtr *temp; 19153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 19163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor val1->nodeMax *= 2; 19173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor temp = (xmlNodePtr *) xmlRealloc(val1->nodeTab, val1->nodeMax * 19183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor sizeof(xmlNodePtr)); 19193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (temp == NULL) { 19203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 19213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "xmlXPathNodeSetMerge: out of memory\n"); 19223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 19233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 19243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor val1->nodeTab = temp; 19253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 1926044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if (val2->nodeTab[i]->type == XML_NAMESPACE_DECL) { 1927044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlNsPtr ns = (xmlNsPtr) val2->nodeTab[i]; 1928044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard 1929044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard val1->nodeTab[val1->nodeNr++] = 1930044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlXPathNodeSetDupNs((xmlNodePtr) ns->next, ns); 1931044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } else 1932044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard val1->nodeTab[val1->nodeNr++] = val2->nodeTab[i]; 19333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 19343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 19353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(val1); 19363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 19373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 19383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 193975be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard * xmlXPathNodeSetMergeUnique: 194075be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard * @val1: the first NodeSet or NULL 194175be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard * @val2: the second NodeSet 194275be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard * 194375be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard * Merges two nodesets, all nodes from @val2 are added to @val1 194475be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard * if @val1 is NULL, a new set is created and copied from @val2 194575be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard * 194675be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard * Returns @val1 once extended or NULL in case of error. 194775be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard */ 194875be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillardstatic xmlNodeSetPtr 194975be0130855fe02d238bbbf19a04d3c5eb45f494Daniel VeillardxmlXPathNodeSetMergeUnique(xmlNodeSetPtr val1, xmlNodeSetPtr val2) { 195078637da0ea1c833dfdfad87a9aa5bea14510d08aWilliam M. Brack int i; 195175be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard 195275be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard if (val2 == NULL) return(val1); 195375be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard if (val1 == NULL) { 195475be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard val1 = xmlXPathNodeSetCreate(NULL); 195575be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard } 195675be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard 195775be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard /* @@ with_ns to check wether namespace nodes should be looked at @@ */ 195875be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard 195975be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard for (i = 0;i < val2->nodeNr;i++) { 196075be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard /* 196175be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard * grow the nodeTab if needed 196275be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard */ 196375be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard if (val1->nodeMax == 0) { 196475be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard val1->nodeTab = (xmlNodePtr *) xmlMalloc(XML_NODESET_DEFAULT * 196575be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard sizeof(xmlNodePtr)); 196675be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard if (val1->nodeTab == NULL) { 196775be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard xmlGenericError(xmlGenericErrorContext, 196875be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard "xmlXPathNodeSetMerge: out of memory\n"); 196975be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard return(NULL); 197075be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard } 197175be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard memset(val1->nodeTab, 0 , 197275be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard XML_NODESET_DEFAULT * (size_t) sizeof(xmlNodePtr)); 197375be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard val1->nodeMax = XML_NODESET_DEFAULT; 197475be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard } else if (val1->nodeNr == val1->nodeMax) { 197575be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard xmlNodePtr *temp; 197675be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard 197775be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard val1->nodeMax *= 2; 197875be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard temp = (xmlNodePtr *) xmlRealloc(val1->nodeTab, val1->nodeMax * 197975be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard sizeof(xmlNodePtr)); 198075be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard if (temp == NULL) { 198175be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard xmlGenericError(xmlGenericErrorContext, 198275be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard "xmlXPathNodeSetMerge: out of memory\n"); 198375be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard return(NULL); 198475be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard } 198575be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard val1->nodeTab = temp; 198675be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard } 198775be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard if (val2->nodeTab[i]->type == XML_NAMESPACE_DECL) { 198875be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard xmlNsPtr ns = (xmlNsPtr) val2->nodeTab[i]; 198975be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard 199075be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard val1->nodeTab[val1->nodeNr++] = 199175be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard xmlXPathNodeSetDupNs((xmlNodePtr) ns->next, ns); 199275be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard } else 199375be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard val1->nodeTab[val1->nodeNr++] = val2->nodeTab[i]; 199475be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard } 199575be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard 199675be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard return(val1); 199775be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard} 199875be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard 199975be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard/** 20003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNodeSetDel: 20013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur: the initial node set 20023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val: an xmlNodePtr 20033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 20043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Removes an xmlNodePtr from an existing NodeSet 20053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 20063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 20073473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNodeSetDel(xmlNodeSetPtr cur, xmlNodePtr val) { 20083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int i; 20093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 20103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == NULL) return; 20113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (val == NULL) return; 20123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 20133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 20143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * check against doublons 20153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 20163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor for (i = 0;i < cur->nodeNr;i++) 20173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur->nodeTab[i] == val) break; 20183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 20193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (i >= cur->nodeNr) { 20203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG 20213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 20223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "xmlXPathNodeSetDel: Node %s wasn't found in NodeList\n", 20233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor val->name); 20243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 20253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return; 20263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 2027044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if ((cur->nodeTab[i] != NULL) && 2028044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard (cur->nodeTab[i]->type == XML_NAMESPACE_DECL)) 2029044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlXPathNodeSetFreeNs((xmlNsPtr) cur->nodeTab[i]); 20303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur->nodeNr--; 20313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor for (;i < cur->nodeNr;i++) 20323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur->nodeTab[i] = cur->nodeTab[i + 1]; 20333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur->nodeTab[cur->nodeNr] = NULL; 20343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 20353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 20363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 20373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNodeSetRemove: 20383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur: the initial node set 20393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val: the index to remove 20403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 20413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Removes an entry from an existing NodeSet list. 20423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 20433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 20443473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNodeSetRemove(xmlNodeSetPtr cur, int val) { 20453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == NULL) return; 20463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (val >= cur->nodeNr) return; 2047044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if ((cur->nodeTab[val] != NULL) && 2048044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard (cur->nodeTab[val]->type == XML_NAMESPACE_DECL)) 2049044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlXPathNodeSetFreeNs((xmlNsPtr) cur->nodeTab[val]); 20503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur->nodeNr--; 20513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor for (;val < cur->nodeNr;val++) 20523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur->nodeTab[val] = cur->nodeTab[val + 1]; 20533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur->nodeTab[cur->nodeNr] = NULL; 20543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 20553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 20563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 20573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathFreeNodeSet: 20583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @obj: the xmlNodeSetPtr to free 20593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 20603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Free the NodeSet compound (not the actual nodes !). 20613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 20623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 20633473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathFreeNodeSet(xmlNodeSetPtr obj) { 20643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (obj == NULL) return; 20653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (obj->nodeTab != NULL) { 2066044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard int i; 2067044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard 2068044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard /* @@ with_ns to check wether namespace nodes should be looked at @@ */ 2069044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard for (i = 0;i < obj->nodeNr;i++) 2070044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if ((obj->nodeTab[i] != NULL) && 2071044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard (obj->nodeTab[i]->type == XML_NAMESPACE_DECL)) 2072044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlXPathNodeSetFreeNs((xmlNsPtr) obj->nodeTab[i]); 20733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(obj->nodeTab); 20743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 20753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(obj); 20763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 20773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 20783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 20793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathFreeValueTree: 20803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @obj: the xmlNodeSetPtr to free 20813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 20823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Free the NodeSet compound and the actual tree, this is different 20833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * from xmlXPathFreeNodeSet() 20843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 208556a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic void 20863473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathFreeValueTree(xmlNodeSetPtr obj) { 20873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int i; 20883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 20893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (obj == NULL) return; 20903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 20913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (obj->nodeTab != NULL) { 2092044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard for (i = 0;i < obj->nodeNr;i++) { 2093044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if (obj->nodeTab[i] != NULL) { 2094044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if (obj->nodeTab[i]->type == XML_NAMESPACE_DECL) { 2095044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlXPathNodeSetFreeNs((xmlNsPtr) obj->nodeTab[i]); 2096044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } else { 2097044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlFreeNodeList(obj->nodeTab[i]); 2098044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } 2099044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } 2100044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } 21013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(obj->nodeTab); 21023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 21033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(obj); 21043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 21053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 21063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#if defined(DEBUG) || defined(DEBUG_STEP) 21073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 21083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlGenericErrorContextNodeSet: 21093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @output: a FILE * for the output 21103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @obj: the xmlNodeSetPtr to free 21113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 21123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Quick display of a NodeSet 21133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 21143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 21153473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlGenericErrorContextNodeSet(FILE *output, xmlNodeSetPtr obj) { 21163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int i; 21173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 21183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (output == NULL) output = xmlGenericErrorContext; 21193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (obj == NULL) { 21203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, "NodeSet == NULL !\n"); 21213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return; 21223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 21233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (obj->nodeNr == 0) { 21243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, "NodeSet is empty\n"); 21253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return; 21263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 21273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (obj->nodeTab == NULL) { 21283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, " nodeTab == NULL !\n"); 21293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return; 21303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 21313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor for (i = 0; i < obj->nodeNr; i++) { 21323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (obj->nodeTab[i] == NULL) { 21333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, " NULL !\n"); 21343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return; 21353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 21363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((obj->nodeTab[i]->type == XML_DOCUMENT_NODE) || 21373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor (obj->nodeTab[i]->type == XML_HTML_DOCUMENT_NODE)) 21383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, " /"); 21393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else if (obj->nodeTab[i]->name == NULL) 21403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, " noname!"); 21413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else fprintf(output, " %s", obj->nodeTab[i]->name); 21423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 21433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, "\n"); 21443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 21453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 21463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 21473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 21483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNewNodeSet: 21493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val: the NodePtr value 21503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 21513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Create a new xmlXPathObjectPtr of type NodeSet and initialize 21523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * it with the single Node @val 21533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 21543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the newly created object. 21553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 21563473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathObjectPtr 21573473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNewNodeSet(xmlNodePtr val) { 21583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr ret; 21593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 21603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject)); 21613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ret == NULL) { 21623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 21633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "xmlXPathNewNodeSet: out of memory\n"); 21643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 21653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 21663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor memset(ret, 0 , (size_t) sizeof(xmlXPathObject)); 21673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->type = XPATH_NODESET; 216877851710aba3a0effdc6af67ea4caf212307420cDaniel Veillard ret->boolval = 0; 21693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->nodesetval = xmlXPathNodeSetCreate(val); 2170044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard /* @@ with_ns to check wether namespace nodes should be looked at @@ */ 21713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ret); 21723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 21733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 21743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 21753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNewValueTree: 21763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val: the NodePtr value 21773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 21783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Create a new xmlXPathObjectPtr of type Value Tree (XSLT) and initialize 21793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * it with the tree root @val 21803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 21813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the newly created object. 21823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 21833473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathObjectPtr 21843473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNewValueTree(xmlNodePtr val) { 21853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr ret; 21863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 21873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject)); 21883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ret == NULL) { 21893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 21903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "xmlXPathNewNodeSet: out of memory\n"); 21913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 21923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 21933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor memset(ret, 0 , (size_t) sizeof(xmlXPathObject)); 21943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->type = XPATH_XSLT_TREE; 21950ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard ret->boolval = 1; 21960ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard ret->user = (void *) val; 21973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->nodesetval = xmlXPathNodeSetCreate(val); 21983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ret); 21993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 22003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 22013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 22023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNewNodeSetList: 22033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val: an existing NodeSet 22043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 22053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Create a new xmlXPathObjectPtr of type NodeSet and initialize 22063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * it with the Nodeset @val 22073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 22083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the newly created object. 22093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 22103473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathObjectPtr 2211044fc6b7476798cbb95277b4905e5111d7c2775dDaniel VeillardxmlXPathNewNodeSetList(xmlNodeSetPtr val) 2212044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard{ 22133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr ret; 22143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int i; 22153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 22163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (val == NULL) 2217044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard ret = NULL; 22183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else if (val->nodeTab == NULL) 2219044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard ret = xmlXPathNewNodeSet(NULL); 2220044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard else { 2221044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard ret = xmlXPathNewNodeSet(val->nodeTab[0]); 2222044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard for (i = 1; i < val->nodeNr; ++i) 2223044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlXPathNodeSetAddUnique(ret->nodesetval, val->nodeTab[i]); 2224044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } 22253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 2226044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard return (ret); 22273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 22283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 22293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 22303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathWrapNodeSet: 22313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val: the NodePtr value 22323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 22333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Wrap the Nodeset @val in a new xmlXPathObjectPtr 22343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 22353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the newly created object. 22363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 22373473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathObjectPtr 22383473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathWrapNodeSet(xmlNodeSetPtr val) { 22393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr ret; 22403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 22413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject)); 22423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ret == NULL) { 22433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 22443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "xmlXPathWrapNodeSet: out of memory\n"); 22453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 22463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 22473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor memset(ret, 0 , (size_t) sizeof(xmlXPathObject)); 22483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->type = XPATH_NODESET; 22493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->nodesetval = val; 22503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ret); 22513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 22523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 22533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 22543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathFreeNodeSetList: 22553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @obj: an existing NodeSetList object 22563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 22573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Free up the xmlXPathObjectPtr @obj but don't deallocate the objects in 22583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the list contrary to xmlXPathFreeObject(). 22593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 22603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 22613473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathFreeNodeSetList(xmlXPathObjectPtr obj) { 22623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (obj == NULL) return; 22633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(obj); 22643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 22653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 2266f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/** 2267f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathDifference: 2268f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes1: a node-set 2269f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes2: a node-set 2270f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 2271f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Implements the EXSLT - Sets difference() function: 2272f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * node-set set:difference (node-set, node-set) 2273f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 2274f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns the difference between the two node sets, or nodes1 if 2275f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * nodes2 is empty 2276f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */ 2277f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlNodeSetPtr 2278f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathDifference (xmlNodeSetPtr nodes1, xmlNodeSetPtr nodes2) { 2279f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlNodeSetPtr ret; 2280f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer int i, l1; 2281f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlNodePtr cur; 2282f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 2283f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (xmlXPathNodeSetIsEmpty(nodes2)) 2284f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(nodes1); 2285f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 2286f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer ret = xmlXPathNodeSetCreate(NULL); 2287f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (xmlXPathNodeSetIsEmpty(nodes1)) 2288f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(ret); 2289f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 2290f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer l1 = xmlXPathNodeSetGetLength(nodes1); 2291f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 2292f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer for (i = 0; i < l1; i++) { 2293f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer cur = xmlXPathNodeSetItem(nodes1, i); 2294f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (!xmlXPathNodeSetContains(nodes2, cur)) 2295f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathNodeSetAddUnique(ret, cur); 2296f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer } 2297f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(ret); 2298f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer} 2299f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 2300f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/** 2301f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathIntersection: 2302f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes1: a node-set 2303f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes2: a node-set 2304f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 2305f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Implements the EXSLT - Sets intersection() function: 2306f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * node-set set:intersection (node-set, node-set) 2307f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 2308f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns a node set comprising the nodes that are within both the 2309f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * node sets passed as arguments 2310f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */ 2311f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlNodeSetPtr 2312f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathIntersection (xmlNodeSetPtr nodes1, xmlNodeSetPtr nodes2) { 2313f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlNodeSetPtr ret = xmlXPathNodeSetCreate(NULL); 2314f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer int i, l1; 2315f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlNodePtr cur; 2316f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 2317f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (xmlXPathNodeSetIsEmpty(nodes1)) 2318f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(ret); 2319f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (xmlXPathNodeSetIsEmpty(nodes2)) 2320f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(ret); 2321f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 2322f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer l1 = xmlXPathNodeSetGetLength(nodes1); 2323f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 2324f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer for (i = 0; i < l1; i++) { 2325f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer cur = xmlXPathNodeSetItem(nodes1, i); 2326f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (xmlXPathNodeSetContains(nodes2, cur)) 2327f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathNodeSetAddUnique(ret, cur); 2328f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer } 2329f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(ret); 2330f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer} 2331f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 2332f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/** 2333f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathDistinctSorted: 2334f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes: a node-set, sorted by document order 2335f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 2336f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Implements the EXSLT - Sets distinct() function: 2337f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * node-set set:distinct (node-set) 2338f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 2339f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns a subset of the nodes contained in @nodes, or @nodes if 2340f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * it is empty 2341f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */ 2342f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlNodeSetPtr 2343f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathDistinctSorted (xmlNodeSetPtr nodes) { 2344f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlNodeSetPtr ret; 2345f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlHashTablePtr hash; 2346f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer int i, l; 2347f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlChar * strval; 2348f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlNodePtr cur; 2349f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 2350f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (xmlXPathNodeSetIsEmpty(nodes)) 2351f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(nodes); 2352f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 2353f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer ret = xmlXPathNodeSetCreate(NULL); 2354f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer l = xmlXPathNodeSetGetLength(nodes); 2355f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer hash = xmlHashCreate (l); 2356f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer for (i = 0; i < l; i++) { 2357f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer cur = xmlXPathNodeSetItem(nodes, i); 2358f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer strval = xmlXPathCastNodeToString(cur); 2359f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (xmlHashLookup(hash, strval) == NULL) { 2360f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlHashAddEntry(hash, strval, strval); 2361f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathNodeSetAddUnique(ret, cur); 2362f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer } else { 2363f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlFree(strval); 2364f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer } 2365f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer } 2366f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlHashFree(hash, (xmlHashDeallocator) xmlFree); 2367f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(ret); 2368f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer} 2369f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 2370f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/** 2371f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathDistinct: 2372f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes: a node-set 2373f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 2374f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Implements the EXSLT - Sets distinct() function: 2375f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * node-set set:distinct (node-set) 2376f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes is sorted by document order, then #exslSetsDistinctSorted 2377f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * is called with the sorted node-set 2378f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 2379f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns a subset of the nodes contained in @nodes, or @nodes if 2380f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * it is empty 2381f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */ 2382f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlNodeSetPtr 2383f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathDistinct (xmlNodeSetPtr nodes) { 2384f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (xmlXPathNodeSetIsEmpty(nodes)) 2385f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(nodes); 2386f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 2387f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathNodeSetSort(nodes); 2388f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(xmlXPathDistinctSorted(nodes)); 2389f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer} 2390f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 2391f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/** 2392f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathHasSameNodes: 2393f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes1: a node-set 2394f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes2: a node-set 2395f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 2396f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Implements the EXSLT - Sets has-same-nodes function: 2397f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * boolean set:has-same-node(node-set, node-set) 2398f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 2399f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns true (1) if @nodes1 shares any node with @nodes2, false (0) 2400f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * otherwise 2401f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */ 2402f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyerint 2403f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathHasSameNodes (xmlNodeSetPtr nodes1, xmlNodeSetPtr nodes2) { 2404f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer int i, l; 2405f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlNodePtr cur; 2406f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 2407f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (xmlXPathNodeSetIsEmpty(nodes1) || 2408f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathNodeSetIsEmpty(nodes2)) 2409f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(0); 2410f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 2411f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer l = xmlXPathNodeSetGetLength(nodes1); 2412f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer for (i = 0; i < l; i++) { 2413f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer cur = xmlXPathNodeSetItem(nodes1, i); 2414f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (xmlXPathNodeSetContains(nodes2, cur)) 2415f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(1); 2416f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer } 2417f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(0); 2418f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer} 2419f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 2420f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/** 2421f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathNodeLeadingSorted: 2422f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes: a node-set, sorted by document order 2423f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @node: a node 2424f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 2425f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Implements the EXSLT - Sets leading() function: 2426f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * node-set set:leading (node-set, node-set) 2427f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 2428f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns the nodes in @nodes that precede @node in document order, 2429f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes if @node is NULL or an empty node-set if @nodes 2430f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * doesn't contain @node 2431f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */ 2432f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlNodeSetPtr 2433f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathNodeLeadingSorted (xmlNodeSetPtr nodes, xmlNodePtr node) { 2434f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer int i, l; 2435f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlNodePtr cur; 2436f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlNodeSetPtr ret; 2437f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 2438f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (node == NULL) 2439f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(nodes); 2440f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 2441f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer ret = xmlXPathNodeSetCreate(NULL); 2442f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (xmlXPathNodeSetIsEmpty(nodes) || 2443f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer (!xmlXPathNodeSetContains(nodes, node))) 2444f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(ret); 2445f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 2446f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer l = xmlXPathNodeSetGetLength(nodes); 2447f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer for (i = 0; i < l; i++) { 2448f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer cur = xmlXPathNodeSetItem(nodes, i); 2449f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (cur == node) 2450f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer break; 2451f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathNodeSetAddUnique(ret, cur); 2452f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer } 2453f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(ret); 2454f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer} 2455f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 2456f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/** 2457f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathNodeLeading: 2458f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes: a node-set 2459f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @node: a node 2460f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 2461f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Implements the EXSLT - Sets leading() function: 2462f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * node-set set:leading (node-set, node-set) 2463f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes is sorted by document order, then #exslSetsNodeLeadingSorted 2464f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * is called. 2465f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 2466f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns the nodes in @nodes that precede @node in document order, 2467f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes if @node is NULL or an empty node-set if @nodes 2468f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * doesn't contain @node 2469f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */ 2470f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlNodeSetPtr 2471f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathNodeLeading (xmlNodeSetPtr nodes, xmlNodePtr node) { 2472f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathNodeSetSort(nodes); 2473f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(xmlXPathNodeLeadingSorted(nodes, node)); 2474f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer} 2475f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 2476f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/** 2477f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathLeadingSorted: 2478f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes1: a node-set, sorted by document order 2479f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes2: a node-set, sorted by document order 2480f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 2481f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Implements the EXSLT - Sets leading() function: 2482f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * node-set set:leading (node-set, node-set) 2483f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 2484f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns the nodes in @nodes1 that precede the first node in @nodes2 2485f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * in document order, @nodes1 if @nodes2 is NULL or empty or 2486f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * an empty node-set if @nodes1 doesn't contain @nodes2 2487f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */ 2488f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlNodeSetPtr 2489f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathLeadingSorted (xmlNodeSetPtr nodes1, xmlNodeSetPtr nodes2) { 2490f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (xmlXPathNodeSetIsEmpty(nodes2)) 2491f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(nodes1); 2492f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(xmlXPathNodeLeadingSorted(nodes1, 2493f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathNodeSetItem(nodes2, 1))); 2494f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer} 2495f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 2496f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/** 2497f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathLeading: 2498f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes1: a node-set 2499f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes2: a node-set 2500f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 2501f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Implements the EXSLT - Sets leading() function: 2502f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * node-set set:leading (node-set, node-set) 2503f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes1 and @nodes2 are sorted by document order, then 2504f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * #exslSetsLeadingSorted is called. 2505f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 2506f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns the nodes in @nodes1 that precede the first node in @nodes2 2507f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * in document order, @nodes1 if @nodes2 is NULL or empty or 2508f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * an empty node-set if @nodes1 doesn't contain @nodes2 2509f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */ 2510f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlNodeSetPtr 2511f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathLeading (xmlNodeSetPtr nodes1, xmlNodeSetPtr nodes2) { 2512f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (xmlXPathNodeSetIsEmpty(nodes2)) 2513f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(nodes1); 2514f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (xmlXPathNodeSetIsEmpty(nodes1)) 2515f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(xmlXPathNodeSetCreate(NULL)); 2516f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathNodeSetSort(nodes1); 2517f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathNodeSetSort(nodes2); 2518f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(xmlXPathNodeLeadingSorted(nodes1, 2519f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathNodeSetItem(nodes2, 1))); 2520f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer} 2521f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 2522f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/** 2523f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathNodeTrailingSorted: 2524f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes: a node-set, sorted by document order 2525f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @node: a node 2526f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 2527f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Implements the EXSLT - Sets trailing() function: 2528f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * node-set set:trailing (node-set, node-set) 2529f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 2530f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns the nodes in @nodes that follow @node in document order, 2531f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes if @node is NULL or an empty node-set if @nodes 2532f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * doesn't contain @node 2533f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */ 2534f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlNodeSetPtr 2535f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathNodeTrailingSorted (xmlNodeSetPtr nodes, xmlNodePtr node) { 2536f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer int i, l; 2537f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlNodePtr cur; 2538f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlNodeSetPtr ret; 2539f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 2540f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (node == NULL) 2541f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(nodes); 2542f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 2543f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer ret = xmlXPathNodeSetCreate(NULL); 2544f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (xmlXPathNodeSetIsEmpty(nodes) || 2545f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer (!xmlXPathNodeSetContains(nodes, node))) 2546f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(ret); 2547f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 2548f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer l = xmlXPathNodeSetGetLength(nodes); 2549f186c8259ae985cd56b3e14c1def484ab127fd14Thomas Broyer for (i = l; i > 0; i--) { 2550f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer cur = xmlXPathNodeSetItem(nodes, i); 2551f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (cur == node) 2552f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer break; 2553f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathNodeSetAddUnique(ret, cur); 2554f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer } 2555f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(ret); 2556f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer} 2557f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 2558f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/** 2559f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathNodeTrailing: 2560f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes: a node-set 2561f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @node: a node 2562f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 2563f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Implements the EXSLT - Sets trailing() function: 2564f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * node-set set:trailing (node-set, node-set) 2565f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes is sorted by document order, then #xmlXPathNodeTrailingSorted 2566f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * is called. 2567f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 2568f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns the nodes in @nodes that follow @node in document order, 2569f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes if @node is NULL or an empty node-set if @nodes 2570f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * doesn't contain @node 2571f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */ 2572f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlNodeSetPtr 2573f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathNodeTrailing (xmlNodeSetPtr nodes, xmlNodePtr node) { 2574f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathNodeSetSort(nodes); 2575f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(xmlXPathNodeTrailingSorted(nodes, node)); 2576f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer} 2577f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 2578f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/** 2579f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathTrailingSorted: 2580f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes1: a node-set, sorted by document order 2581f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes2: a node-set, sorted by document order 2582f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 2583f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Implements the EXSLT - Sets trailing() function: 2584f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * node-set set:trailing (node-set, node-set) 2585f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 2586f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns the nodes in @nodes1 that follow the first node in @nodes2 2587f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * in document order, @nodes1 if @nodes2 is NULL or empty or 2588f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * an empty node-set if @nodes1 doesn't contain @nodes2 2589f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */ 2590f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlNodeSetPtr 2591f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathTrailingSorted (xmlNodeSetPtr nodes1, xmlNodeSetPtr nodes2) { 2592f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (xmlXPathNodeSetIsEmpty(nodes2)) 2593f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(nodes1); 2594f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(xmlXPathNodeTrailingSorted(nodes1, 2595f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathNodeSetItem(nodes2, 0))); 2596f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer} 2597f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 2598f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/** 2599f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathTrailing: 2600f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes1: a node-set 2601f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes2: a node-set 2602f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 2603f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Implements the EXSLT - Sets trailing() function: 2604f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * node-set set:trailing (node-set, node-set) 2605f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes1 and @nodes2 are sorted by document order, then 2606f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * #xmlXPathTrailingSorted is called. 2607f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 2608f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns the nodes in @nodes1 that follow the first node in @nodes2 2609f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * in document order, @nodes1 if @nodes2 is NULL or empty or 2610f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * an empty node-set if @nodes1 doesn't contain @nodes2 2611f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */ 2612f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlNodeSetPtr 2613f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathTrailing (xmlNodeSetPtr nodes1, xmlNodeSetPtr nodes2) { 2614f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (xmlXPathNodeSetIsEmpty(nodes2)) 2615f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(nodes1); 2616f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (xmlXPathNodeSetIsEmpty(nodes1)) 2617f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(xmlXPathNodeSetCreate(NULL)); 2618f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathNodeSetSort(nodes1); 2619f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathNodeSetSort(nodes2); 2620f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(xmlXPathNodeTrailingSorted(nodes1, 2621f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathNodeSetItem(nodes2, 0))); 2622f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer} 2623f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 26243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/************************************************************************ 26253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * * 26263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Routines to handle extra functions * 26273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * * 26283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ************************************************************************/ 26293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 26303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 26313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathRegisterFunc: 26323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath context 26333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @name: the function name 26343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @f: the function implementation or NULL 26353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 26363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Register a new function. If @f is NULL it unregisters the function 26373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 26383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns 0 in case of success, -1 in case of error 26393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 26403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorint 26413473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathRegisterFunc(xmlXPathContextPtr ctxt, const xmlChar *name, 26423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFunction f) { 26433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(xmlXPathRegisterFuncNS(ctxt, name, NULL, f)); 26443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 26453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 26463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 26473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathRegisterFuncNS: 26483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath context 26493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @name: the function name 26503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ns_uri: the function namespace URI 26513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @f: the function implementation or NULL 26523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 26533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Register a new function. If @f is NULL it unregisters the function 26543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 26553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns 0 in case of success, -1 in case of error 26563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 26573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorint 26583473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathRegisterFuncNS(xmlXPathContextPtr ctxt, const xmlChar *name, 26593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor const xmlChar *ns_uri, xmlXPathFunction f) { 26603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt == NULL) 26613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(-1); 26623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (name == NULL) 26633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(-1); 26643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 26653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->funcHash == NULL) 26663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ctxt->funcHash = xmlHashCreate(0); 26673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->funcHash == NULL) 26683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(-1); 26693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(xmlHashAddEntry2(ctxt->funcHash, name, ns_uri, (void *) f)); 26703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 26713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 26723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 2673ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer * xmlXPathRegisterFuncLookup: 2674ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer * @ctxt: the XPath context 2675ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer * @f: the lookup function 2676cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * @funcCtxt: the lookup data 2677ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer * 2678cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * Registers an external mechanism to do function lookup. 2679ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer */ 2680ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyervoid 2681ba4ad3263bf7f5625329f115367e0c7018521a16Thomas BroyerxmlXPathRegisterFuncLookup (xmlXPathContextPtr ctxt, 2682ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer xmlXPathFuncLookupFunc f, 2683ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer void *funcCtxt) { 2684ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer if (ctxt == NULL) 2685ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer return; 2686ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer ctxt->funcLookupFunc = (void *) f; 2687ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer ctxt->funcLookupData = funcCtxt; 2688ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer} 2689ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer 2690ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer/** 26913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathFunctionLookup: 26923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath context 26933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @name: the function name 26943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 26953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Search in the Function array of the context for the given 26963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * function. 26973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 26983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the xmlXPathFunction or NULL if not found 26993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 27003473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathFunction 27013473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathFunctionLookup(xmlXPathContextPtr ctxt, const xmlChar *name) { 2702ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer if (ctxt == NULL) 2703ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer return (NULL); 2704ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer 2705ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer if (ctxt->funcLookupFunc != NULL) { 2706ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer xmlXPathFunction ret; 270799e55ebe945f6f4de33e8454f2770e02295a3a00Daniel Veillard xmlXPathFuncLookupFunc f; 2708ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer 270999e55ebe945f6f4de33e8454f2770e02295a3a00Daniel Veillard f = (xmlXPathFuncLookupFunc) ctxt->funcLookupFunc; 2710963d2ae41574066f9b44bcae610dd280c1e57dd8Daniel Veillard ret = f(ctxt->funcLookupData, name, NULL); 2711ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer if (ret != NULL) 2712ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer return(ret); 2713ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer } 27143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(xmlXPathFunctionLookupNS(ctxt, name, NULL)); 27153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 27163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 27173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 27183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathFunctionLookupNS: 27193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath context 27203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @name: the function name 27213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ns_uri: the function namespace URI 27223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 27233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Search in the Function array of the context for the given 27243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * function. 27253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 27263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the xmlXPathFunction or NULL if not found 27273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 27283473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathFunction 27293473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathFunctionLookupNS(xmlXPathContextPtr ctxt, const xmlChar *name, 27303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor const xmlChar *ns_uri) { 27313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt == NULL) 27323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 27333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (name == NULL) 27343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 27353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 2736ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer if (ctxt->funcLookupFunc != NULL) { 2737ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer xmlXPathFunction ret; 273899e55ebe945f6f4de33e8454f2770e02295a3a00Daniel Veillard xmlXPathFuncLookupFunc f; 2739ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer 274099e55ebe945f6f4de33e8454f2770e02295a3a00Daniel Veillard f = (xmlXPathFuncLookupFunc) ctxt->funcLookupFunc; 2741963d2ae41574066f9b44bcae610dd280c1e57dd8Daniel Veillard ret = f(ctxt->funcLookupData, name, ns_uri); 2742ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer if (ret != NULL) 2743ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer return(ret); 2744ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer } 2745ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer 2746ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer if (ctxt->funcHash == NULL) 2747ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer return(NULL); 2748ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer 27493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return((xmlXPathFunction) xmlHashLookup2(ctxt->funcHash, name, ns_uri)); 27503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 27513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 27523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 27533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathRegisteredFuncsCleanup: 27543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath context 27553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 27563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Cleanup the XPath context data associated to registered functions 27573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 27583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 27593473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathRegisteredFuncsCleanup(xmlXPathContextPtr ctxt) { 27603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt == NULL) 27613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return; 27623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 27633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlHashFree(ctxt->funcHash, NULL); 27643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ctxt->funcHash = NULL; 27653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 27663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 27673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/************************************************************************ 27683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * * 27693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Routines to handle Variable * 27703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * * 27713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ************************************************************************/ 27723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 27733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 27743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathRegisterVariable: 27753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath context 27763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @name: the variable name 27773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @value: the variable value or NULL 27783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 27793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Register a new variable value. If @value is NULL it unregisters 27803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the variable 27813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 27823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns 0 in case of success, -1 in case of error 27833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 27843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorint 27853473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathRegisterVariable(xmlXPathContextPtr ctxt, const xmlChar *name, 27863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr value) { 27873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(xmlXPathRegisterVariableNS(ctxt, name, NULL, value)); 27883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 27893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 27903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 27913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathRegisterVariableNS: 27923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath context 27933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @name: the variable name 27943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ns_uri: the variable namespace URI 27953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @value: the variable value or NULL 27963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 27973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Register a new variable value. If @value is NULL it unregisters 27983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the variable 27993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 28003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns 0 in case of success, -1 in case of error 28013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 28023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorint 28033473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathRegisterVariableNS(xmlXPathContextPtr ctxt, const xmlChar *name, 28043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor const xmlChar *ns_uri, 28053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr value) { 28063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt == NULL) 28073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(-1); 28083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (name == NULL) 28093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(-1); 28103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 28113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->varHash == NULL) 28123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ctxt->varHash = xmlHashCreate(0); 28133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->varHash == NULL) 28143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(-1); 28153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(xmlHashUpdateEntry2(ctxt->varHash, name, ns_uri, 28163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor (void *) value, 28173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor (xmlHashDeallocator)xmlXPathFreeObject)); 28183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 28193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 28203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 28213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathRegisterVariableLookup: 28223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath context 28233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @f: the lookup function 28243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @data: the lookup data 28253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 28263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * register an external mechanism to do variable lookup 28273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 28283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 28293473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathRegisterVariableLookup(xmlXPathContextPtr ctxt, 28303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathVariableLookupFunc f, void *data) { 28313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt == NULL) 28323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return; 28333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ctxt->varLookupFunc = (void *) f; 28343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ctxt->varLookupData = data; 28353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 28363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 28373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 28383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathVariableLookup: 28393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath context 28403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @name: the variable name 28413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 28423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Search in the Variable array of the context for the given 28433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * variable value. 28443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 284573c9c049195bf897dbcb6308a1ab9d16b3fe6b2cDaniel Veillard * Returns a copy of the value or NULL if not found 28463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 28473473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathObjectPtr 28483473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathVariableLookup(xmlXPathContextPtr ctxt, const xmlChar *name) { 28493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt == NULL) 28503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 28513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 28523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->varLookupFunc != NULL) { 28533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr ret; 28543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 28553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = ((xmlXPathVariableLookupFunc)ctxt->varLookupFunc) 28563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor (ctxt->varLookupData, name, NULL); 2857556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard return(ret); 28583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 28593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(xmlXPathVariableLookupNS(ctxt, name, NULL)); 28603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 28613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 28623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 28633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathVariableLookupNS: 28643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath context 28653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @name: the variable name 28663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ns_uri: the variable namespace URI 28673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 28683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Search in the Variable array of the context for the given 286973c9c049195bf897dbcb6308a1ab9d16b3fe6b2cDaniel Veillard * variable value. 28703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 287173c9c049195bf897dbcb6308a1ab9d16b3fe6b2cDaniel Veillard * Returns the a copy of the value or NULL if not found 28723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 28733473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathObjectPtr 28743473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathVariableLookupNS(xmlXPathContextPtr ctxt, const xmlChar *name, 28753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor const xmlChar *ns_uri) { 28763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt == NULL) 28773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 28783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 28793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->varLookupFunc != NULL) { 28803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr ret; 28813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 28823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = ((xmlXPathVariableLookupFunc)ctxt->varLookupFunc) 28833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor (ctxt->varLookupData, name, ns_uri); 28843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ret != NULL) return(ret); 28853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 28863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 28873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->varHash == NULL) 28883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 28893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (name == NULL) 28903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 28913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 28928c357d58c2d1dde022b67393a47dcb52100ce129Daniel Veillard return(xmlXPathObjectCopy((xmlXPathObjectPtr) 28938c357d58c2d1dde022b67393a47dcb52100ce129Daniel Veillard xmlHashLookup2(ctxt->varHash, name, ns_uri))); 28943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 28953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 28963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 28973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathRegisteredVariablesCleanup: 28983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath context 28993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 29003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Cleanup the XPath context data associated to registered variables 29013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 29023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 29033473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathRegisteredVariablesCleanup(xmlXPathContextPtr ctxt) { 29043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt == NULL) 29053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return; 29063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 290776d66f416d2d0d5db4a09d212b4e43087e9cdae7Daniel Veillard xmlHashFree(ctxt->varHash, (xmlHashDeallocator)xmlXPathFreeObject); 29083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ctxt->varHash = NULL; 29093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 29103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 29113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 29123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathRegisterNs: 29133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath context 29143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @prefix: the namespace prefix 29153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ns_uri: the namespace name 29163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 29173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Register a new namespace. If @ns_uri is NULL it unregisters 29183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the namespace 29193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 29203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns 0 in case of success, -1 in case of error 29213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 29223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorint 29233473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathRegisterNs(xmlXPathContextPtr ctxt, const xmlChar *prefix, 29243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor const xmlChar *ns_uri) { 29253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt == NULL) 29263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(-1); 29273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (prefix == NULL) 29283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(-1); 29293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 29303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->nsHash == NULL) 29313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ctxt->nsHash = xmlHashCreate(10); 29323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->nsHash == NULL) 29333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(-1); 293442766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard return(xmlHashUpdateEntry(ctxt->nsHash, prefix, (void *) xmlStrdup(ns_uri), 29353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor (xmlHashDeallocator)xmlFree)); 29363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 29373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 29383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 29393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNsLookup: 29403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath context 29413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @prefix: the namespace prefix value 29423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 29433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Search in the namespace declaration array of the context for the given 29443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * namespace name associated to the given prefix 29453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 29463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the value or NULL if not found 29473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 29483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorconst xmlChar * 29493473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNsLookup(xmlXPathContextPtr ctxt, const xmlChar *prefix) { 29503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt == NULL) 29513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 29523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (prefix == NULL) 29533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 29543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 29553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef XML_XML_NAMESPACE 29563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (xmlStrEqual(prefix, (const xmlChar *) "xml")) 29573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(XML_XML_NAMESPACE); 29583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 29593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 2960c8f620ba7f95b3ceb687699e140eeaa33343e41aDaniel Veillard if (ctxt->namespaces != NULL) { 2961c8f620ba7f95b3ceb687699e140eeaa33343e41aDaniel Veillard int i; 2962c8f620ba7f95b3ceb687699e140eeaa33343e41aDaniel Veillard 2963c8f620ba7f95b3ceb687699e140eeaa33343e41aDaniel Veillard for (i = 0;i < ctxt->nsNr;i++) { 2964c8f620ba7f95b3ceb687699e140eeaa33343e41aDaniel Veillard if ((ctxt->namespaces[i] != NULL) && 2965c8f620ba7f95b3ceb687699e140eeaa33343e41aDaniel Veillard (xmlStrEqual(ctxt->namespaces[i]->prefix, prefix))) 2966c8f620ba7f95b3ceb687699e140eeaa33343e41aDaniel Veillard return(ctxt->namespaces[i]->href); 2967c8f620ba7f95b3ceb687699e140eeaa33343e41aDaniel Veillard } 2968c8f620ba7f95b3ceb687699e140eeaa33343e41aDaniel Veillard } 29693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 29703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return((const xmlChar *) xmlHashLookup(ctxt->nsHash, prefix)); 29713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 29723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 29733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 29745e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard * xmlXPathRegisteredNsCleanup: 29753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath context 29763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 29773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Cleanup the XPath context data associated to registered variables 29783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 29793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 29803473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathRegisteredNsCleanup(xmlXPathContextPtr ctxt) { 29813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt == NULL) 29823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return; 29833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 298442766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard xmlHashFree(ctxt->nsHash, (xmlHashDeallocator)xmlFree); 29853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ctxt->nsHash = NULL; 29863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 29873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 29883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/************************************************************************ 29893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * * 29903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Routines to handle Values * 29913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * * 29923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ************************************************************************/ 29933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 29943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/* Allocations are terrible, one need to optimize all this !!! */ 29953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 29963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 29973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNewFloat: 29983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val: the double value 29993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 30003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Create a new xmlXPathObjectPtr of type double and of value @val 30013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 30023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the newly created object. 30033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 30043473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathObjectPtr 30053473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNewFloat(double val) { 30063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr ret; 30073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 30083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject)); 30093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ret == NULL) { 30103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 30113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "xmlXPathNewFloat: out of memory\n"); 30123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 30133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 30143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor memset(ret, 0 , (size_t) sizeof(xmlXPathObject)); 30153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->type = XPATH_NUMBER; 30163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->floatval = val; 30173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ret); 30183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 30193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 30203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 30213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNewBoolean: 30223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val: the boolean value 30233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 30243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Create a new xmlXPathObjectPtr of type boolean and of value @val 30253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 30263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the newly created object. 30273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 30283473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathObjectPtr 30293473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNewBoolean(int val) { 30303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr ret; 30313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 30323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject)); 30333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ret == NULL) { 30343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 30353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "xmlXPathNewBoolean: out of memory\n"); 30363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 30373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 30383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor memset(ret, 0 , (size_t) sizeof(xmlXPathObject)); 30393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->type = XPATH_BOOLEAN; 30403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->boolval = (val != 0); 30413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ret); 30423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 30433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 30443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 30453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNewString: 30463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val: the xmlChar * value 30473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 30483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Create a new xmlXPathObjectPtr of type string and of value @val 30493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 30503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the newly created object. 30513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 30523473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathObjectPtr 30533473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNewString(const xmlChar *val) { 30543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr ret; 30553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 30563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject)); 30573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ret == NULL) { 30583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 30593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "xmlXPathNewString: out of memory\n"); 30603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 30613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 30623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor memset(ret, 0 , (size_t) sizeof(xmlXPathObject)); 30633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->type = XPATH_STRING; 30643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (val != NULL) 30653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->stringval = xmlStrdup(val); 30663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else 30673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->stringval = xmlStrdup((const xmlChar *)""); 30683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ret); 30693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 30703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 30713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 3072ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathWrapString: 3073ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @val: the xmlChar * value 3074ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3075ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Wraps the @val string into an XPath object. 3076ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3077ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns the newly created object. 3078ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */ 3079ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathObjectPtr 3080ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathWrapString (xmlChar *val) { 3081ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlXPathObjectPtr ret; 3082ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 3083ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject)); 3084ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard if (ret == NULL) { 3085ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlGenericError(xmlGenericErrorContext, 3086ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard "xmlXPathWrapString: out of memory\n"); 3087ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(NULL); 3088ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard } 3089ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard memset(ret, 0 , (size_t) sizeof(xmlXPathObject)); 3090ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret->type = XPATH_STRING; 3091ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret->stringval = val; 3092ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(ret); 3093ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard} 3094ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 3095ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/** 30963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNewCString: 30973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val: the char * value 30983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 30993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Create a new xmlXPathObjectPtr of type string and of value @val 31003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 31013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the newly created object. 31023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 31033473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathObjectPtr 31043473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNewCString(const char *val) { 31053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr ret; 31063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 31073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject)); 31083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ret == NULL) { 31093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 31103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "xmlXPathNewCString: out of memory\n"); 31113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 31123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 31133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor memset(ret, 0 , (size_t) sizeof(xmlXPathObject)); 31143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->type = XPATH_STRING; 31153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->stringval = xmlStrdup(BAD_CAST val); 31163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ret); 31173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 31183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 31193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 3120ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathWrapCString: 3121ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @val: the char * value 3122ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3123ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Wraps a string into an XPath object. 3124ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3125ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns the newly created object. 3126ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */ 3127ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathObjectPtr 3128ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathWrapCString (char * val) { 3129ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(xmlXPathWrapString((xmlChar *)(val))); 3130ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard} 3131ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 3132ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/** 3133f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathWrapExternal: 3134f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @val: the user data 3135f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 3136f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Wraps the @val data into an XPath object. 3137f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 3138f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns the newly created object. 3139f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */ 3140f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathObjectPtr 3141f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathWrapExternal (void *val) { 3142f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathObjectPtr ret; 3143f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 3144f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject)); 3145f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (ret == NULL) { 3146f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlGenericError(xmlGenericErrorContext, 3147cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard "xmlXPathWrapExternal: out of memory\n"); 3148f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(NULL); 3149f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer } 3150f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer memset(ret, 0 , (size_t) sizeof(xmlXPathObject)); 3151f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer ret->type = XPATH_USERS; 3152f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer ret->user = val; 3153f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(ret); 3154f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer} 3155f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 3156f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/** 31573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathObjectCopy: 31583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val: the original object 31593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 31603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * allocate a new copy of a given object 31613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 31623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the newly created object. 31633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 31643473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathObjectPtr 31653473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathObjectCopy(xmlXPathObjectPtr val) { 31663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr ret; 31673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 31683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (val == NULL) 31693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 31703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 31713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject)); 31723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ret == NULL) { 31733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 31743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "xmlXPathObjectCopy: out of memory\n"); 31753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 31763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 31773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor memcpy(ret, val , (size_t) sizeof(xmlXPathObject)); 31783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor switch (val->type) { 31793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_BOOLEAN: 31803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_NUMBER: 31813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_POINT: 31823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_RANGE: 31833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 31843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_STRING: 31853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->stringval = xmlStrdup(val->stringval); 31863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 31873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_XSLT_TREE: 31883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((val->nodesetval != NULL) && 31890ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard (val->nodesetval->nodeTab != NULL)) { 31909adc0469d4691e798ea4ad59b84c874cdea8b38dDaniel Veillard xmlNodePtr cur, tmp; 31919adc0469d4691e798ea4ad59b84c874cdea8b38dDaniel Veillard xmlDocPtr top; 3192ef0b45016373d65700ef6f7d494a200758b2e4c5Daniel Veillard 31930ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard ret->boolval = 1; 31949adc0469d4691e798ea4ad59b84c874cdea8b38dDaniel Veillard top = xmlNewDoc(NULL); 31959adc0469d4691e798ea4ad59b84c874cdea8b38dDaniel Veillard top->name = (char *) 31969adc0469d4691e798ea4ad59b84c874cdea8b38dDaniel Veillard xmlStrdup(val->nodesetval->nodeTab[0]->name); 3197ef0b45016373d65700ef6f7d494a200758b2e4c5Daniel Veillard ret->user = top; 3198ef0b45016373d65700ef6f7d494a200758b2e4c5Daniel Veillard if (top != NULL) { 31999adc0469d4691e798ea4ad59b84c874cdea8b38dDaniel Veillard top->doc = top; 3200ef0b45016373d65700ef6f7d494a200758b2e4c5Daniel Veillard cur = val->nodesetval->nodeTab[0]->children; 3201ef0b45016373d65700ef6f7d494a200758b2e4c5Daniel Veillard while (cur != NULL) { 32029adc0469d4691e798ea4ad59b84c874cdea8b38dDaniel Veillard tmp = xmlDocCopyNode(cur, top, 1); 32039adc0469d4691e798ea4ad59b84c874cdea8b38dDaniel Veillard xmlAddChild((xmlNodePtr) top, tmp); 3204ef0b45016373d65700ef6f7d494a200758b2e4c5Daniel Veillard cur = cur->next; 3205ef0b45016373d65700ef6f7d494a200758b2e4c5Daniel Veillard } 3206ef0b45016373d65700ef6f7d494a200758b2e4c5Daniel Veillard } 32079adc0469d4691e798ea4ad59b84c874cdea8b38dDaniel Veillard ret->nodesetval = xmlXPathNodeSetCreate((xmlNodePtr) top); 32080ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard } else 32093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->nodesetval = xmlXPathNodeSetCreate(NULL); 32100ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard /* Deallocate the copied tree value */ 32113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 32123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_NODESET: 32133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->nodesetval = xmlXPathNodeSetMerge(NULL, val->nodesetval); 32140ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard /* Do not deallocate the copied tree value */ 32150ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard ret->boolval = 0; 32163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 32173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_LOCATIONSET: 32183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef LIBXML_XPTR_ENABLED 32193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor { 32203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlLocationSetPtr loc = val->user; 32213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->user = (void *) xmlXPtrLocationSetMerge(NULL, loc); 32223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 32233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 32243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 322547334c09f4373e4cff71334e60a623fee73a525fThomas Broyer case XPATH_USERS: 322647334c09f4373e4cff71334e60a623fee73a525fThomas Broyer ret->user = val->user; 322747334c09f4373e4cff71334e60a623fee73a525fThomas Broyer break; 322847334c09f4373e4cff71334e60a623fee73a525fThomas Broyer case XPATH_UNDEFINED: 32293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 32303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "xmlXPathObjectCopy: unsupported type %d\n", 32313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor val->type); 32323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 32333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 32343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ret); 32353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 32363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 32373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 32383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathFreeObject: 32393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @obj: the object to free 32403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 32413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Free up an xmlXPathObjectPtr object. 32423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 32433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 32443473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathFreeObject(xmlXPathObjectPtr obj) { 32453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (obj == NULL) return; 32460ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard if ((obj->type == XPATH_NODESET) || (obj->type == XPATH_XSLT_TREE)) { 324777851710aba3a0effdc6af67ea4caf212307420cDaniel Veillard if (obj->boolval) { 32480ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard if (obj->user != NULL) { 32490ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard xmlXPathFreeNodeSet(obj->nodesetval); 325038bf6f042507c6051bfa2db5cc9b6666cfc35c2aDaniel Veillard xmlFreeNodeList((xmlNodePtr) obj->user); 32510ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard } else if (obj->nodesetval != NULL) 325277851710aba3a0effdc6af67ea4caf212307420cDaniel Veillard xmlXPathFreeValueTree(obj->nodesetval); 325377851710aba3a0effdc6af67ea4caf212307420cDaniel Veillard } else { 325477851710aba3a0effdc6af67ea4caf212307420cDaniel Veillard if (obj->nodesetval != NULL) 325577851710aba3a0effdc6af67ea4caf212307420cDaniel Veillard xmlXPathFreeNodeSet(obj->nodesetval); 325677851710aba3a0effdc6af67ea4caf212307420cDaniel Veillard } 32573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef LIBXML_XPTR_ENABLED 32583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else if (obj->type == XPATH_LOCATIONSET) { 32593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (obj->user != NULL) 32603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPtrFreeLocationSet(obj->user); 32613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 32623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else if (obj->type == XPATH_STRING) { 32633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (obj->stringval != NULL) 32643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(obj->stringval); 32653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 32663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 32673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(obj); 32683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 32693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 3270ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 3271ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/************************************************************************ 3272ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * * 3273ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Type Casting Routines * 3274ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * * 3275ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ************************************************************************/ 3276ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 3277ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/** 3278ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathCastBooleanToString: 3279ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @val: a boolean 3280ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3281ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts a boolean to its string value. 3282ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3283ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns a newly allocated string. 3284ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */ 3285ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlChar * 3286ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathCastBooleanToString (int val) { 3287ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlChar *ret; 3288ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard if (val) 3289ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = xmlStrdup((const xmlChar *) "true"); 3290ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard else 3291ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = xmlStrdup((const xmlChar *) "false"); 3292ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(ret); 3293ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard} 3294ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 3295ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/** 3296ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathCastNumberToString: 3297ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @val: a number 3298ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3299ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts a number to its string value. 3300ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3301ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns a newly allocated string. 3302ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */ 3303ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlChar * 3304ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathCastNumberToString (double val) { 3305ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlChar *ret; 3306cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard switch (xmlXPathIsInf(val)) { 3307ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case 1: 33085fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard ret = xmlStrdup((const xmlChar *) "Infinity"); 3309ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard break; 3310ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case -1: 3311ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = xmlStrdup((const xmlChar *) "-Infinity"); 3312ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard break; 3313ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard default: 3314cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard if (xmlXPathIsNaN(val)) { 3315ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = xmlStrdup((const xmlChar *) "NaN"); 3316d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard } else if (val == 0 && xmlXPathGetSign(val) != 0) { 3317d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret = xmlStrdup((const xmlChar *) "0"); 3318ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard } else { 3319ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard /* could be improved */ 3320ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard char buf[100]; 3321ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlXPathFormatNumber(val, buf, 100); 3322ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = xmlStrdup((const xmlChar *) buf); 3323ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard } 3324ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard } 3325ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(ret); 3326ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard} 3327ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 3328ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/** 3329ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathCastNodeToString: 3330ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @node: a node 3331ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3332ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts a node to its string value. 3333ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3334ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns a newly allocated string. 3335ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */ 3336ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlChar * 3337ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathCastNodeToString (xmlNodePtr node) { 3338ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(xmlNodeGetContent(node)); 3339ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard} 3340ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 3341ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/** 3342ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathCastNodeSetToString: 3343ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @ns: a node-set 3344ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3345ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts a node-set to its string value. 3346ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3347ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns a newly allocated string. 3348ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */ 3349ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlChar * 3350ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathCastNodeSetToString (xmlNodeSetPtr ns) { 3351ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard if ((ns == NULL) || (ns->nodeNr == 0) || (ns->nodeTab == NULL)) 3352ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(xmlStrdup((const xmlChar *) "")); 3353ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 3354ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlXPathNodeSetSort(ns); 3355ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(xmlXPathCastNodeToString(ns->nodeTab[0])); 3356ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard} 3357ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 3358ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/** 3359ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathCastToString: 3360ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @val: an XPath object 3361ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3362ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts an existing object to its string() equivalent 3363ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3364ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns the string value of the object, NULL in case of error. 3365cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * A new string is allocated only if needed (@val isn't a 3366ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * string object). 3367ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */ 3368ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlChar * 3369ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathCastToString(xmlXPathObjectPtr val) { 3370ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlChar *ret = NULL; 3371ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 3372ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard if (val == NULL) 3373ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(xmlStrdup((const xmlChar *) "")); 3374ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard switch (val->type) { 3375ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_UNDEFINED: 3376ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard#ifdef DEBUG_EXPR 3377ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlGenericError(xmlGenericErrorContext, "String: undefined\n"); 3378ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard#endif 3379ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = xmlStrdup((const xmlChar *) ""); 3380ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard break; 3381ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_NODESET: 33820c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack case XPATH_XSLT_TREE: 3383ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = xmlXPathCastNodeSetToString(val->nodesetval); 3384ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard break; 3385ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_STRING: 33864e2df54bb17645ef0d3f28b9665b2d2dde4b47a3Daniel Veillard return(xmlStrdup(val->stringval)); 3387ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_BOOLEAN: 3388ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = xmlXPathCastBooleanToString(val->boolval); 3389ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard break; 3390ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_NUMBER: { 3391ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = xmlXPathCastNumberToString(val->floatval); 3392ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard break; 3393ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard } 3394ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_USERS: 3395ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_POINT: 3396ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_RANGE: 3397ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_LOCATIONSET: 3398ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard TODO 3399ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = xmlStrdup((const xmlChar *) ""); 3400ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard break; 3401ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard } 3402ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(ret); 3403ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard} 3404ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 3405ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/** 3406ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathConvertString: 3407ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @val: an XPath object 3408ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3409ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts an existing object to its string() equivalent 3410ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3411ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns the new object, the old one is freed (or the operation 3412ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * is done directly on @val) 3413ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */ 3414ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathObjectPtr 3415ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathConvertString(xmlXPathObjectPtr val) { 3416ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlChar *res = NULL; 3417ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 3418ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard if (val == NULL) 3419ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(xmlXPathNewCString("")); 3420ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 3421ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard switch (val->type) { 3422ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_UNDEFINED: 3423ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard#ifdef DEBUG_EXPR 3424ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlGenericError(xmlGenericErrorContext, "STRING: undefined\n"); 3425ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard#endif 3426ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard break; 3427ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_NODESET: 34280c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack case XPATH_XSLT_TREE: 3429ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard res = xmlXPathCastNodeSetToString(val->nodesetval); 3430ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard break; 3431ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_STRING: 3432ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(val); 3433ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_BOOLEAN: 3434ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard res = xmlXPathCastBooleanToString(val->boolval); 3435ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard break; 3436ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_NUMBER: 3437ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard res = xmlXPathCastNumberToString(val->floatval); 3438ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard break; 3439ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_USERS: 3440ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_POINT: 3441ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_RANGE: 3442ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_LOCATIONSET: 3443ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard TODO; 3444ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard break; 3445ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard } 3446ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlXPathFreeObject(val); 3447ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard if (res == NULL) 3448ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(xmlXPathNewCString("")); 3449ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(xmlXPathWrapString(res)); 3450ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard} 3451ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 3452ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/** 3453ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathCastBooleanToNumber: 3454ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @val: a boolean 3455ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3456ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts a boolean to its number value 3457ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3458ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns the number value 3459ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */ 3460ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillarddouble 3461ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathCastBooleanToNumber(int val) { 3462ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard if (val) 3463ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(1.0); 3464ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(0.0); 3465ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard} 3466ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 3467ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/** 3468ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathCastStringToNumber: 3469ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @val: a string 3470ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3471ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts a string to its number value 3472ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3473ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns the number value 3474ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */ 3475ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillarddouble 3476ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathCastStringToNumber(const xmlChar * val) { 3477ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(xmlXPathStringEvalNumber(val)); 3478ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard} 3479ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 3480ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/** 3481ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathCastNodeToNumber: 3482ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @node: a node 3483ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3484ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts a node to its number value 3485ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3486ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns the number value 3487ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */ 3488ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillarddouble 3489ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathCastNodeToNumber (xmlNodePtr node) { 3490ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlChar *strval; 3491ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard double ret; 3492ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 3493ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard if (node == NULL) 3494ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(xmlXPathNAN); 3495ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard strval = xmlXPathCastNodeToString(node); 3496ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard if (strval == NULL) 3497ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(xmlXPathNAN); 3498ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = xmlXPathCastStringToNumber(strval); 3499ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlFree(strval); 3500ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 3501ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(ret); 3502ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard} 3503ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 3504ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/** 3505ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathCastNodeSetToNumber: 3506ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @ns: a node-set 3507ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3508ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts a node-set to its number value 3509ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3510ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns the number value 3511ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */ 3512ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillarddouble 3513ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathCastNodeSetToNumber (xmlNodeSetPtr ns) { 3514ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlChar *str; 3515ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard double ret; 3516ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 3517ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard if (ns == NULL) 3518ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(xmlXPathNAN); 3519ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard str = xmlXPathCastNodeSetToString(ns); 3520ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = xmlXPathCastStringToNumber(str); 3521ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlFree(str); 3522ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(ret); 3523ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard} 3524ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 3525ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/** 3526ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathCastToNumber: 3527ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @val: an XPath object 3528ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3529ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts an XPath object to its number value 3530ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3531ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns the number value 3532ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */ 3533ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillarddouble 3534ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathCastToNumber(xmlXPathObjectPtr val) { 3535ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard double ret = 0.0; 3536ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 3537ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard if (val == NULL) 3538ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(xmlXPathNAN); 3539ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard switch (val->type) { 3540ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_UNDEFINED: 3541ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard#ifdef DEGUB_EXPR 3542ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlGenericError(xmlGenericErrorContext, "NUMBER: undefined\n"); 3543ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard#endif 3544ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = xmlXPathNAN; 3545ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard break; 3546ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_NODESET: 35470c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack case XPATH_XSLT_TREE: 3548ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = xmlXPathCastNodeSetToNumber(val->nodesetval); 3549ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard break; 3550ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_STRING: 3551ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = xmlXPathCastStringToNumber(val->stringval); 3552ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard break; 3553ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_NUMBER: 3554ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = val->floatval; 3555ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard break; 3556ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_BOOLEAN: 3557ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = xmlXPathCastBooleanToNumber(val->boolval); 3558ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard break; 3559ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_USERS: 3560ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_POINT: 3561ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_RANGE: 3562ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_LOCATIONSET: 3563ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard TODO; 3564ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = xmlXPathNAN; 3565ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard break; 3566ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard } 3567ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(ret); 3568ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard} 3569ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 3570ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/** 3571ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathConvertNumber: 3572ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @val: an XPath object 3573ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3574ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts an existing object to its number() equivalent 3575ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3576ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns the new object, the old one is freed (or the operation 3577ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * is done directly on @val) 3578ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */ 3579ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathObjectPtr 3580ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathConvertNumber(xmlXPathObjectPtr val) { 3581ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlXPathObjectPtr ret; 3582ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 3583ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard if (val == NULL) 3584ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(xmlXPathNewFloat(0.0)); 3585ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard if (val->type == XPATH_NUMBER) 3586ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(val); 3587ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = xmlXPathNewFloat(xmlXPathCastToNumber(val)); 3588ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlXPathFreeObject(val); 3589ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(ret); 3590ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard} 3591ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 3592ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/** 3593ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathCastNumberToBoolean: 3594ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @val: a number 3595ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3596ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts a number to its boolean value 3597ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3598ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns the boolean value 3599ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */ 3600ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillardint 3601ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathCastNumberToBoolean (double val) { 3602cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard if (xmlXPathIsNaN(val) || (val == 0.0)) 3603ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(0); 3604ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(1); 3605ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard} 3606ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 3607ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/** 3608ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathCastStringToBoolean: 3609ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @val: a string 3610ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3611ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts a string to its boolean value 3612ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3613ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns the boolean value 3614ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */ 3615ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillardint 3616ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathCastStringToBoolean (const xmlChar *val) { 3617ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard if ((val == NULL) || (xmlStrlen(val) == 0)) 3618ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(0); 3619ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(1); 3620ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard} 3621ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 3622ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/** 3623ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathCastNodeSetToBoolean: 3624ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @ns: a node-set 3625ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3626ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts a node-set to its boolean value 3627ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3628ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns the boolean value 3629ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */ 3630ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillardint 3631ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathCastNodeSetToBoolean (xmlNodeSetPtr ns) { 3632ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard if ((ns == NULL) || (ns->nodeNr == 0)) 3633ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(0); 3634ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(1); 3635ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard} 3636ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 3637ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/** 36385e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard * xmlXPathCastToBoolean: 3639ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @val: an XPath object 3640ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3641ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts an XPath object to its boolean value 3642ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3643ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns the boolean value 3644ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */ 3645ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillardint 3646ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathCastToBoolean (xmlXPathObjectPtr val) { 3647ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard int ret = 0; 3648ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 3649ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard if (val == NULL) 3650ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(0); 3651ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard switch (val->type) { 3652ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_UNDEFINED: 3653ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard#ifdef DEBUG_EXPR 3654ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlGenericError(xmlGenericErrorContext, "BOOLEAN: undefined\n"); 3655ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard#endif 3656ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = 0; 3657ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard break; 3658ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_NODESET: 36590c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack case XPATH_XSLT_TREE: 3660ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = xmlXPathCastNodeSetToBoolean(val->nodesetval); 3661ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard break; 3662ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_STRING: 3663ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = xmlXPathCastStringToBoolean(val->stringval); 3664ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard break; 3665ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_NUMBER: 3666ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = xmlXPathCastNumberToBoolean(val->floatval); 3667ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard break; 3668ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_BOOLEAN: 3669ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = val->boolval; 3670ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard break; 3671ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_USERS: 3672ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_POINT: 3673ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_RANGE: 3674ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_LOCATIONSET: 3675ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard TODO; 3676ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = 0; 3677ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard break; 3678ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard } 3679ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(ret); 3680ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard} 3681ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 3682ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 3683ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/** 3684ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathConvertBoolean: 3685ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @val: an XPath object 3686ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3687ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts an existing object to its boolean() equivalent 3688ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3689ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns the new object, the old one is freed (or the operation 3690ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * is done directly on @val) 3691ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */ 3692ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathObjectPtr 3693ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathConvertBoolean(xmlXPathObjectPtr val) { 3694ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlXPathObjectPtr ret; 3695ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 3696ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard if (val == NULL) 3697ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(xmlXPathNewBoolean(0)); 3698ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard if (val->type == XPATH_BOOLEAN) 3699ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(val); 3700ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = xmlXPathNewBoolean(xmlXPathCastToBoolean(val)); 3701ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlXPathFreeObject(val); 3702ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(ret); 3703ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard} 3704ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 37053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/************************************************************************ 37063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * * 37073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Routines to handle XPath contexts * 37083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * * 37093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ************************************************************************/ 37103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 37113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 37123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNewContext: 37133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @doc: the XML document 37143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 37153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Create a new xmlXPathContext 37163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 3717af43f63aaabf0dc4b4a070773875d0927da3d8a2Daniel Veillard * Returns the xmlXPathContext just allocated. The caller will need to free it. 37183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 37193473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathContextPtr 37203473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNewContext(xmlDocPtr doc) { 37213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathContextPtr ret; 37223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 37233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = (xmlXPathContextPtr) xmlMalloc(sizeof(xmlXPathContext)); 37243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ret == NULL) { 37253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 37263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "xmlXPathNewContext: out of memory\n"); 37273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 37283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 37293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor memset(ret, 0 , (size_t) sizeof(xmlXPathContext)); 37303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->doc = doc; 37313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->node = NULL; 37323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 37333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->varHash = NULL; 37343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 37353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->nb_types = 0; 37363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->max_types = 0; 37373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->types = NULL; 37383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 37393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->funcHash = xmlHashCreate(0); 37403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 37413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->nb_axis = 0; 37423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->max_axis = 0; 37433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->axis = NULL; 37443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 37453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->nsHash = NULL; 37463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->user = NULL; 37473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 37483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->contextSize = -1; 37493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->proximityPosition = -1; 37503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 37513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisterAllFunctions(ret); 37523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 37533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ret); 37543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 37553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 37563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 37573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathFreeContext: 37583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the context to free 37593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 37603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Free up an xmlXPathContext 37613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 37623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 37633473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathFreeContext(xmlXPathContextPtr ctxt) { 37643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisteredNsCleanup(ctxt); 37653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisteredFuncsCleanup(ctxt); 37663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisteredVariablesCleanup(ctxt); 37673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(ctxt); 37683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 37693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 37703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/************************************************************************ 37713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * * 37723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Routines to handle XPath parser contexts * 37733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * * 37743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ************************************************************************/ 37753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 37763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define CHECK_CTXT(ctxt) \ 37773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt == NULL) { \ 37783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, \ 37793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "%s:%d Internal error: ctxt == NULL\n", \ 37803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor __FILE__, __LINE__); \ 37813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } \ 37823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 37833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 37843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define CHECK_CONTEXT(ctxt) \ 37853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt == NULL) { \ 37863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, \ 37873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "%s:%d Internal error: no context\n", \ 37883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor __FILE__, __LINE__); \ 37893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } \ 37903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else if (ctxt->doc == NULL) { \ 37913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, \ 37923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "%s:%d Internal error: no document\n", \ 37933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor __FILE__, __LINE__); \ 37943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } \ 37953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else if (ctxt->doc->children == NULL) { \ 37963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, \ 37973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "%s:%d Internal error: document without root\n", \ 37983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor __FILE__, __LINE__); \ 37993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } \ 38003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 38013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 38023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 38033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNewParserContext: 38043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @str: the XPath expression 38053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath context 38063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 38073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Create a new xmlXPathParserContext 38083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 38093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the xmlXPathParserContext just allocated. 38103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 38113473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathParserContextPtr 38123473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNewParserContext(const xmlChar *str, xmlXPathContextPtr ctxt) { 38133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathParserContextPtr ret; 38143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 38153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = (xmlXPathParserContextPtr) xmlMalloc(sizeof(xmlXPathParserContext)); 38163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ret == NULL) { 38173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 38183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "xmlXPathNewParserContext: out of memory\n"); 38193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 38203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 38213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor memset(ret, 0 , (size_t) sizeof(xmlXPathParserContext)); 38223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->cur = ret->base = str; 38233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->context = ctxt; 38243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 38259e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard ret->comp = xmlXPathNewCompExpr(); 38269e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (ret->comp == NULL) { 38279e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlFree(ret->valueTab); 38289e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlFree(ret); 38299e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard return(NULL); 38309e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } 38319e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 38329e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard return(ret); 38339e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard} 38349e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 38359e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard/** 38369e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * xmlXPathCompParserContext: 38379e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * @comp: the XPath compiled expression 38389e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * @ctxt: the XPath context 38399e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * 38409e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * Create a new xmlXPathParserContext when processing a compiled expression 38419e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * 38429e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * Returns the xmlXPathParserContext just allocated. 38439e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard */ 384456a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic xmlXPathParserContextPtr 38459e7160d45a18bfa26d708e22ba991f7670d0128bDaniel VeillardxmlXPathCompParserContext(xmlXPathCompExprPtr comp, xmlXPathContextPtr ctxt) { 38469e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlXPathParserContextPtr ret; 38479e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 38489e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard ret = (xmlXPathParserContextPtr) xmlMalloc(sizeof(xmlXPathParserContext)); 38499e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (ret == NULL) { 38509e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlGenericError(xmlGenericErrorContext, 3851cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard "xmlXPathCompParserContext: out of memory\n"); 38529e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard return(NULL); 38539e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } 38549e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard memset(ret, 0 , (size_t) sizeof(xmlXPathParserContext)); 38559e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 38563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* Allocate the value stack */ 38573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->valueTab = (xmlXPathObjectPtr *) 38583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlMalloc(10 * sizeof(xmlXPathObjectPtr)); 38599e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (ret->valueTab == NULL) { 38609e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlFree(ret); 38619e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlGenericError(xmlGenericErrorContext, 3862cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard "xmlXPathCompParserContext: out of memory\n"); 38639e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard return(NULL); 38649e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } 38653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->valueNr = 0; 38663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->valueMax = 10; 38673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->value = NULL; 38689e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 3869fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard ret->context = ctxt; 38709e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard ret->comp = comp; 38719e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 38723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ret); 38733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 38743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 38753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 38763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathFreeParserContext: 38773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the context to free 38783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 38793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Free up an xmlXPathParserContext 38803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 38813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 38823473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathFreeParserContext(xmlXPathParserContextPtr ctxt) { 38833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->valueTab != NULL) { 38843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(ctxt->valueTab); 38853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 38869e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (ctxt->comp) 38879e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlXPathFreeCompExpr(ctxt->comp); 38883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(ctxt); 38893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 38903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 38913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/************************************************************************ 38923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * * 38933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The implicit core function library * 38943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * * 38953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ************************************************************************/ 38963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 38973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 389801c13b5be2d249ef66d86585adee87901bb8efa2Daniel Veillard * xmlXPathNodeValHash: 3899f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * @node: a node pointer 3900f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * 3901f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Function computing the beginning of the string value of the node, 3902f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * used to speed up comparisons 3903f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * 3904f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Returns an int usable as a hash 3905f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 3906f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillardstatic unsigned int 3907f06307e2c172284bb41376c396f757bdac9bdd19Daniel VeillardxmlXPathNodeValHash(xmlNodePtr node) { 3908f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard int len = 2; 3909f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard const xmlChar * string = NULL; 3910f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlNodePtr tmp = NULL; 3911f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard unsigned int ret = 0; 3912f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 3913f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (node == NULL) 3914f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return(0); 3915f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 39169adc0469d4691e798ea4ad59b84c874cdea8b38dDaniel Veillard if (node->type == XML_DOCUMENT_NODE) { 39179adc0469d4691e798ea4ad59b84c874cdea8b38dDaniel Veillard tmp = xmlDocGetRootElement((xmlDocPtr) node); 39189adc0469d4691e798ea4ad59b84c874cdea8b38dDaniel Veillard if (tmp == NULL) 39199adc0469d4691e798ea4ad59b84c874cdea8b38dDaniel Veillard node = node->children; 39209adc0469d4691e798ea4ad59b84c874cdea8b38dDaniel Veillard else 39219adc0469d4691e798ea4ad59b84c874cdea8b38dDaniel Veillard node = tmp; 39229adc0469d4691e798ea4ad59b84c874cdea8b38dDaniel Veillard 39239adc0469d4691e798ea4ad59b84c874cdea8b38dDaniel Veillard if (node == NULL) 39249adc0469d4691e798ea4ad59b84c874cdea8b38dDaniel Veillard return(0); 39259adc0469d4691e798ea4ad59b84c874cdea8b38dDaniel Veillard } 3926f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 3927f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard switch (node->type) { 3928f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XML_COMMENT_NODE: 3929f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XML_PI_NODE: 3930f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XML_CDATA_SECTION_NODE: 3931f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XML_TEXT_NODE: 3932f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard string = node->content; 3933f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (string == NULL) 3934f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return(0); 3935f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (string[0] == 0) 3936f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return(0); 3937f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return(((unsigned int) string[0]) + 3938f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (((unsigned int) string[1]) << 8)); 3939f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XML_NAMESPACE_DECL: 3940f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard string = ((xmlNsPtr)node)->href; 3941f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (string == NULL) 3942f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return(0); 3943f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (string[0] == 0) 3944f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return(0); 3945f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return(((unsigned int) string[0]) + 3946f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (((unsigned int) string[1]) << 8)); 3947f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XML_ATTRIBUTE_NODE: 3948f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard tmp = ((xmlAttrPtr) node)->children; 3949f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 3950f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XML_ELEMENT_NODE: 3951f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard tmp = node->children; 3952f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 3953f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard default: 3954f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return(0); 3955f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 3956f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard while (tmp != NULL) { 3957f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard switch (tmp->type) { 3958f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XML_COMMENT_NODE: 3959f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XML_PI_NODE: 3960f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XML_CDATA_SECTION_NODE: 3961f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XML_TEXT_NODE: 3962f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard string = tmp->content; 3963f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 3964f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XML_NAMESPACE_DECL: 3965f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard string = ((xmlNsPtr)tmp)->href; 3966f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 3967f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard default: 3968f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 3969f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 3970f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((string != NULL) && (string[0] != 0)) { 3971f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (string[0] == 0) 3972f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return(0); 3973f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (len == 1) { 3974f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return(ret + (((unsigned int) string[0]) << 8)); 3975f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 3976f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (string[1] == 0) { 3977f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard len = 1; 3978f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ret = (unsigned int) string[0]; 3979f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } else { 3980f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return(((unsigned int) string[0]) + 3981f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (((unsigned int) string[1]) << 8)); 3982f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 3983f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 3984f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* 3985f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Skip to next node 3986f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 3987f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((tmp->children != NULL) && (tmp->type != XML_DTD_NODE)) { 3988f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (tmp->children->type != XML_ENTITY_DECL) { 3989f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard tmp = tmp->children; 3990f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard continue; 3991f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 3992f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 3993f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (tmp == node) 3994f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 3995f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 3996f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (tmp->next != NULL) { 3997f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard tmp = tmp->next; 3998f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard continue; 3999f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 4000f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 4001f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard do { 4002f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard tmp = tmp->parent; 4003f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (tmp == NULL) 4004f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 4005f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (tmp == node) { 4006f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard tmp = NULL; 4007f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 4008f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 4009f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (tmp->next != NULL) { 4010f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard tmp = tmp->next; 4011f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 4012f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 4013f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } while (tmp != NULL); 4014f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 4015f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return(ret); 4016f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard} 4017f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 4018f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard/** 4019f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * xmlXPathStringHash: 4020f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * @string: a string 4021f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * 4022f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Function computing the beginning of the string value of the node, 4023f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * used to speed up comparisons 4024f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * 4025f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Returns an int usable as a hash 4026f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 4027f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillardstatic unsigned int 4028f06307e2c172284bb41376c396f757bdac9bdd19Daniel VeillardxmlXPathStringHash(const xmlChar * string) { 4029f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (string == NULL) 4030f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return((unsigned int) 0); 4031f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (string[0] == 0) 4032f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return(0); 4033f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return(((unsigned int) string[0]) + 4034f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (((unsigned int) string[1]) << 8)); 4035f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard} 4036f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 4037f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard/** 40383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathCompareNodeSetFloat: 40393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 40403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @inf: less than (1) or greater than (0) 40413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @strict: is the comparison strict 40423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @arg: the node set 40433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @f: the value 40443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 40453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the compare operation between a nodeset and a number 40463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ns < @val (1, 1, ... 40473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ns <= @val (1, 0, ... 40483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ns > @val (0, 1, ... 40493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ns >= @val (0, 0, ... 40503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 40513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * If one object to be compared is a node-set and the other is a number, 40523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * then the comparison will be true if and only if there is a node in the 40533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * node-set such that the result of performing the comparison on the number 40543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * to be compared and on the result of converting the string-value of that 40553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * node to a number using the number function is true. 40563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 40573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns 0 or 1 depending on the results of the test. 40583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 405956a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic int 40603473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathCompareNodeSetFloat(xmlXPathParserContextPtr ctxt, int inf, int strict, 40613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr arg, xmlXPathObjectPtr f) { 40623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int i, ret = 0; 40633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlNodeSetPtr ns; 40643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlChar *str2; 40653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 40663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((f == NULL) || (arg == NULL) || 40673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ((arg->type != XPATH_NODESET) && (arg->type != XPATH_XSLT_TREE))) { 40683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(arg); 40693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(f); 40703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(0); 40713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 40723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ns = arg->nodesetval; 4073911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard if (ns != NULL) { 4074911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard for (i = 0;i < ns->nodeNr;i++) { 4075ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard str2 = xmlXPathCastNodeToString(ns->nodeTab[i]); 4076911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard if (str2 != NULL) { 4077911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard valuePush(ctxt, 4078911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard xmlXPathNewString(str2)); 4079911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard xmlFree(str2); 4080911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard xmlXPathNumberFunction(ctxt, 1); 4081911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard valuePush(ctxt, xmlXPathObjectCopy(f)); 4082911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard ret = xmlXPathCompareValues(ctxt, inf, strict); 4083911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard if (ret) 4084911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard break; 4085911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard } 4086911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard } 40873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 40883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(arg); 40893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(f); 40903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ret); 40913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 40923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 40933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 40943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathCompareNodeSetString: 40953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 40963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @inf: less than (1) or greater than (0) 40973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @strict: is the comparison strict 40983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @arg: the node set 40993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @s: the value 41003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 41013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the compare operation between a nodeset and a string 41023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ns < @val (1, 1, ... 41033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ns <= @val (1, 0, ... 41043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ns > @val (0, 1, ... 41053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ns >= @val (0, 0, ... 41063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 41073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * If one object to be compared is a node-set and the other is a string, 41083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * then the comparison will be true if and only if there is a node in 41093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the node-set such that the result of performing the comparison on the 41103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * string-value of the node and the other string is true. 41113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 41123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns 0 or 1 depending on the results of the test. 41133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 411456a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic int 41153473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathCompareNodeSetString(xmlXPathParserContextPtr ctxt, int inf, int strict, 41163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr arg, xmlXPathObjectPtr s) { 41173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int i, ret = 0; 41183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlNodeSetPtr ns; 41193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlChar *str2; 41203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 41213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((s == NULL) || (arg == NULL) || 41223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ((arg->type != XPATH_NODESET) && (arg->type != XPATH_XSLT_TREE))) { 41233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(arg); 41243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(s); 41253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(0); 41263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 41273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ns = arg->nodesetval; 4128911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard if (ns != NULL) { 4129911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard for (i = 0;i < ns->nodeNr;i++) { 4130ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard str2 = xmlXPathCastNodeToString(ns->nodeTab[i]); 4131911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard if (str2 != NULL) { 4132911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard valuePush(ctxt, 4133911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard xmlXPathNewString(str2)); 4134911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard xmlFree(str2); 4135911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard valuePush(ctxt, xmlXPathObjectCopy(s)); 4136911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard ret = xmlXPathCompareValues(ctxt, inf, strict); 4137911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard if (ret) 4138911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard break; 4139911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard } 4140911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard } 41413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 41423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(arg); 41433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(s); 41443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ret); 41453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 41463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 41473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 41483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathCompareNodeSets: 4149ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @inf: less than (1) or greater than (0) 41503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @strict: is the comparison strict 4151cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * @arg1: the first node set object 41523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @arg2: the second node set object 41533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 41543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the compare operation on nodesets: 41553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 41563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * If both objects to be compared are node-sets, then the comparison 41573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * will be true if and only if there is a node in the first node-set 41583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * and a node in the second node-set such that the result of performing 41593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the comparison on the string-values of the two nodes is true. 41603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * .... 41613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * When neither object to be compared is a node-set and the operator 41623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * is <=, <, >= or >, then the objects are compared by converting both 41633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * objects to numbers and comparing the numbers according to IEEE 754. 41643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * .... 41653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The number function converts its argument to a number as follows: 41663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * - a string that consists of optional whitespace followed by an 41673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * optional minus sign followed by a Number followed by whitespace 41683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * is converted to the IEEE 754 number that is nearest (according 41693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * to the IEEE 754 round-to-nearest rule) to the mathematical value 41703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * represented by the string; any other string is converted to NaN 41713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 41723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Conclusion all nodes need to be converted first to their string value 41733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * and then the comparison must be done when possible 41743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 417556a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic int 417656a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel VeillardxmlXPathCompareNodeSets(int inf, int strict, 41773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr arg1, xmlXPathObjectPtr arg2) { 41783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int i, j, init = 0; 41793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor double val1; 41803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor double *values2; 41813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int ret = 0; 41823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlNodeSetPtr ns1; 41833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlNodeSetPtr ns2; 41843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 41853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((arg1 == NULL) || 41864dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard ((arg1->type != XPATH_NODESET) && (arg1->type != XPATH_XSLT_TREE))) { 41874dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard xmlXPathFreeObject(arg2); 41883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(0); 41894dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard } 41903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((arg2 == NULL) || 41914dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard ((arg2->type != XPATH_NODESET) && (arg2->type != XPATH_XSLT_TREE))) { 41924dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard xmlXPathFreeObject(arg1); 41934dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard xmlXPathFreeObject(arg2); 41943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(0); 41954dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard } 41963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 41973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ns1 = arg1->nodesetval; 41983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ns2 = arg2->nodesetval; 41993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 4200d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard if ((ns1 == NULL) || (ns1->nodeNr <= 0)) { 42014dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard xmlXPathFreeObject(arg1); 42024dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard xmlXPathFreeObject(arg2); 42033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(0); 42044dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard } 4205d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard if ((ns2 == NULL) || (ns2->nodeNr <= 0)) { 42064dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard xmlXPathFreeObject(arg1); 42074dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard xmlXPathFreeObject(arg2); 42083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(0); 42094dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard } 42103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 42113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor values2 = (double *) xmlMalloc(ns2->nodeNr * sizeof(double)); 42123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (values2 == NULL) { 42134dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard xmlXPathFreeObject(arg1); 42144dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard xmlXPathFreeObject(arg2); 42153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(0); 42163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 42173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor for (i = 0;i < ns1->nodeNr;i++) { 4218ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard val1 = xmlXPathCastNodeToNumber(ns1->nodeTab[i]); 4219cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard if (xmlXPathIsNaN(val1)) 42203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor continue; 42213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor for (j = 0;j < ns2->nodeNr;j++) { 42223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (init == 0) { 4223ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard values2[j] = xmlXPathCastNodeToNumber(ns2->nodeTab[j]); 42243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 4225cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard if (xmlXPathIsNaN(values2[j])) 42263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor continue; 42273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (inf && strict) 42283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = (val1 < values2[j]); 42293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else if (inf && !strict) 42303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = (val1 <= values2[j]); 42313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else if (!inf && strict) 42323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = (val1 > values2[j]); 42333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else if (!inf && !strict) 42343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = (val1 >= values2[j]); 42353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ret) 42363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 42373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 42383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ret) 42393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 42403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor init = 1; 42413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 42423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(values2); 42434dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard xmlXPathFreeObject(arg1); 42444dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard xmlXPathFreeObject(arg2); 42453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ret); 42463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 42473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 42483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 42493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathCompareNodeSetValue: 42503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 42513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @inf: less than (1) or greater than (0) 42523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @strict: is the comparison strict 42533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @arg: the node set 42543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val: the value 42553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 42563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the compare operation between a nodeset and a value 42573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ns < @val (1, 1, ... 42583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ns <= @val (1, 0, ... 42593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ns > @val (0, 1, ... 42603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ns >= @val (0, 0, ... 42613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 42623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * If one object to be compared is a node-set and the other is a boolean, 42633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * then the comparison will be true if and only if the result of performing 42643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the comparison on the boolean and on the result of converting 42653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the node-set to a boolean using the boolean function is true. 42663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 42673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns 0 or 1 depending on the results of the test. 42683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 426956a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic int 42703473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathCompareNodeSetValue(xmlXPathParserContextPtr ctxt, int inf, int strict, 42713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr arg, xmlXPathObjectPtr val) { 42723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((val == NULL) || (arg == NULL) || 42733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ((arg->type != XPATH_NODESET) && (arg->type != XPATH_XSLT_TREE))) 42743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(0); 42753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 42763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor switch(val->type) { 42773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_NUMBER: 42783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(xmlXPathCompareNodeSetFloat(ctxt, inf, strict, arg, val)); 42793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_NODESET: 42803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_XSLT_TREE: 428156a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillard return(xmlXPathCompareNodeSets(inf, strict, arg, val)); 42823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_STRING: 42833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(xmlXPathCompareNodeSetString(ctxt, inf, strict, arg, val)); 42843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_BOOLEAN: 42853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, arg); 42863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathBooleanFunction(ctxt, 1); 42873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, val); 42883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(xmlXPathCompareValues(ctxt, inf, strict)); 42893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor default: 42903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor TODO 42913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 42923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(0); 42933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 42943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 42953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 429601c13b5be2d249ef66d86585adee87901bb8efa2Daniel Veillard * xmlXPathEqualNodeSetString: 42973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @arg: the nodeset object argument 42983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @str: the string to compare to. 42990c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack * @neq: flag to show whether for '=' (0) or '!=' (1) 43003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 43013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the equal operation on XPath objects content: @arg1 == @arg2 43023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * If one object to be compared is a node-set and the other is a string, 43033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * then the comparison will be true if and only if there is a node in 43043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the node-set such that the result of performing the comparison on the 43053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * string-value of the node and the other string is true. 43063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 43073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns 0 or 1 depending on the results of the test. 43083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 430956a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic int 43100c022ad8234a9228288c651f5e6a9bce7efcd789William M. BrackxmlXPathEqualNodeSetString(xmlXPathObjectPtr arg, const xmlChar * str, int neq) 4311f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard{ 43123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int i; 43133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlNodeSetPtr ns; 43143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlChar *str2; 4315f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard unsigned int hash; 43163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 43173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((str == NULL) || (arg == NULL) || 4318f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ((arg->type != XPATH_NODESET) && (arg->type != XPATH_XSLT_TREE))) 4319f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (0); 43203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ns = arg->nodesetval; 4321f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard hash = xmlXPathStringHash(str); 4322d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard if (ns == NULL) 4323f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (0); 432473c9c049195bf897dbcb6308a1ab9d16b3fe6b2cDaniel Veillard if (ns->nodeNr <= 0) { 432573c9c049195bf897dbcb6308a1ab9d16b3fe6b2cDaniel Veillard if (hash == 0) 43260c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack return(neq ^ 1); 43270c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack return(neq); 432873c9c049195bf897dbcb6308a1ab9d16b3fe6b2cDaniel Veillard } 4329f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard for (i = 0; i < ns->nodeNr; i++) { 4330f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (xmlXPathNodeValHash(ns->nodeTab[i]) == hash) { 4331f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard str2 = xmlNodeGetContent(ns->nodeTab[i]); 4332f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((str2 != NULL) && (xmlStrEqual(str, str2))) { 4333f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlFree(str2); 43340c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack if (neq) 43350c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack continue; 4336f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (1); 43379adc0469d4691e798ea4ad59b84c874cdea8b38dDaniel Veillard } else if ((str2 == NULL) && (xmlStrEqual(str, BAD_CAST ""))) { 43389adc0469d4691e798ea4ad59b84c874cdea8b38dDaniel Veillard if (neq) 43399adc0469d4691e798ea4ad59b84c874cdea8b38dDaniel Veillard continue; 43409adc0469d4691e798ea4ad59b84c874cdea8b38dDaniel Veillard return (1); 43410c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack } else if (neq) { 43420c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack if (str2 != NULL) 43430c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack xmlFree(str2); 43440c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack return (1); 43450c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack } 4346f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (str2 != NULL) 4347f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlFree(str2); 43480c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack } else if (neq) 43490c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack return (1); 43503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 4351f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (0); 43523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 43533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 43543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 435501c13b5be2d249ef66d86585adee87901bb8efa2Daniel Veillard * xmlXPathEqualNodeSetFloat: 43563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @arg: the nodeset object argument 43573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @f: the float to compare to 43580c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack * @neq: flag to show whether to compare '=' (0) or '!=' (1) 43593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 43603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the equal operation on XPath objects content: @arg1 == @arg2 43613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * If one object to be compared is a node-set and the other is a number, 43623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * then the comparison will be true if and only if there is a node in 43633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the node-set such that the result of performing the comparison on the 43643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * number to be compared and on the result of converting the string-value 43653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * of that node to a number using the number function is true. 43663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 43673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns 0 or 1 depending on the results of the test. 43683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 436956a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic int 43700c022ad8234a9228288c651f5e6a9bce7efcd789William M. BrackxmlXPathEqualNodeSetFloat(xmlXPathParserContextPtr ctxt, 43710c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack xmlXPathObjectPtr arg, double f, int neq) { 43720c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack int i, ret=0; 43730c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack xmlNodeSetPtr ns; 43740c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack xmlChar *str2; 43750c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack xmlXPathObjectPtr val; 43760c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack double v; 43773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 43783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((arg == NULL) || 43793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ((arg->type != XPATH_NODESET) && (arg->type != XPATH_XSLT_TREE))) 43803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(0); 43813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 43820c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack ns = arg->nodesetval; 43830c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack if (ns != NULL) { 43840c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack for (i=0;i<ns->nodeNr;i++) { 43850c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack str2 = xmlXPathCastNodeToString(ns->nodeTab[i]); 43860c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack if (str2 != NULL) { 43870c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack valuePush(ctxt, xmlXPathNewString(str2)); 43880c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack xmlFree(str2); 43890c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack xmlXPathNumberFunction(ctxt, 1); 43900c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack val = valuePop(ctxt); 43910c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack v = val->floatval; 43920c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack xmlXPathFreeObject(val); 43930c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack if (!xmlXPathIsNaN(v)) { 43940c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack if ((!neq) && (v==f)) { 43950c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack ret = 1; 43960c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack break; 43970c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack } else if ((neq) && (v!=f)) { 43980c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack ret = 1; 43990c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack break; 44000c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack } 44010c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack } 44020c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack } 44030c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack } 44040c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack } 44050c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack 44060c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack return(ret); 44073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 44083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 44093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 44103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 441101c13b5be2d249ef66d86585adee87901bb8efa2Daniel Veillard * xmlXPathEqualNodeSets: 44123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @arg1: first nodeset object argument 44133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @arg2: second nodeset object argument 44140c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack * @neq: flag to show whether to test '=' (0) or '!=' (1) 44153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 44160c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack * Implement the equal / not equal operation on XPath nodesets: 44170c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack * @arg1 == @arg2 or @arg1 != @arg2 44183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * If both objects to be compared are node-sets, then the comparison 44193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * will be true if and only if there is a node in the first node-set and 44203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * a node in the second node-set such that the result of performing the 44213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * comparison on the string-values of the two nodes is true. 44223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 44233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * (needless to say, this is a costly operation) 44243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 44253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns 0 or 1 depending on the results of the test. 44263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 442756a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic int 44280c022ad8234a9228288c651f5e6a9bce7efcd789William M. BrackxmlXPathEqualNodeSets(xmlXPathObjectPtr arg1, xmlXPathObjectPtr arg2, int neq) { 44293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int i, j; 4430f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard unsigned int *hashs1; 4431f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard unsigned int *hashs2; 44323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlChar **values1; 44333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlChar **values2; 44343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int ret = 0; 44353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlNodeSetPtr ns1; 44363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlNodeSetPtr ns2; 44373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 44383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((arg1 == NULL) || 44393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ((arg1->type != XPATH_NODESET) && (arg1->type != XPATH_XSLT_TREE))) 44403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(0); 44413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((arg2 == NULL) || 44423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ((arg2->type != XPATH_NODESET) && (arg2->type != XPATH_XSLT_TREE))) 44433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(0); 44443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 44453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ns1 = arg1->nodesetval; 44463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ns2 = arg2->nodesetval; 44473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 4448911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard if ((ns1 == NULL) || (ns1->nodeNr <= 0)) 44493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(0); 4450911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard if ((ns2 == NULL) || (ns2->nodeNr <= 0)) 44513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(0); 44523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 44533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 44540c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack * for equal, check if there is a node pertaining to both sets 44553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 44560c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack if (neq == 0) 44570c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack for (i = 0;i < ns1->nodeNr;i++) 44580c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack for (j = 0;j < ns2->nodeNr;j++) 44590c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack if (ns1->nodeTab[i] == ns2->nodeTab[j]) 44600c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack return(1); 44613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 44623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor values1 = (xmlChar **) xmlMalloc(ns1->nodeNr * sizeof(xmlChar *)); 44633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (values1 == NULL) 44643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(0); 4465f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard hashs1 = (unsigned int *) xmlMalloc(ns1->nodeNr * sizeof(unsigned int)); 4466f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (hashs1 == NULL) { 4467f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlFree(values1); 4468f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return(0); 4469f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 44703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor memset(values1, 0, ns1->nodeNr * sizeof(xmlChar *)); 44713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor values2 = (xmlChar **) xmlMalloc(ns2->nodeNr * sizeof(xmlChar *)); 44723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (values2 == NULL) { 4473f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlFree(hashs1); 44743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(values1); 44753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(0); 44763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 4477f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard hashs2 = (unsigned int *) xmlMalloc(ns2->nodeNr * sizeof(unsigned int)); 4478f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (hashs2 == NULL) { 4479f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlFree(hashs1); 4480f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlFree(values1); 4481f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlFree(values2); 4482f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return(0); 4483f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 44843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor memset(values2, 0, ns2->nodeNr * sizeof(xmlChar *)); 44853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor for (i = 0;i < ns1->nodeNr;i++) { 4486f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard hashs1[i] = xmlXPathNodeValHash(ns1->nodeTab[i]); 44873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor for (j = 0;j < ns2->nodeNr;j++) { 44883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (i == 0) 4489f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard hashs2[j] = xmlXPathNodeValHash(ns2->nodeTab[j]); 44900c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack if (hashs1[i] != hashs2[j]) { 44910c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack if (neq) { 44920c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack ret = 1; 44930c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack break; 44940c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack } 44950c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack } 44960c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack else { 4497f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (values1[i] == NULL) 4498f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard values1[i] = xmlNodeGetContent(ns1->nodeTab[i]); 4499f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (values2[j] == NULL) 4500f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard values2[j] = xmlNodeGetContent(ns2->nodeTab[j]); 45010c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack ret = xmlStrEqual(values1[i], values2[j]) ^ neq; 4502f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (ret) 4503f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 4504f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 45053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 45063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ret) 45073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 45083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 45093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor for (i = 0;i < ns1->nodeNr;i++) 45103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (values1[i] != NULL) 45113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(values1[i]); 45123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor for (j = 0;j < ns2->nodeNr;j++) 45133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (values2[j] != NULL) 45143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(values2[j]); 45153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(values1); 45163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(values2); 4517f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlFree(hashs1); 4518f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlFree(hashs2); 45193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ret); 45203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 45213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 45220c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brackstatic int 45230c022ad8234a9228288c651f5e6a9bce7efcd789William M. BrackxmlXPathEqualValuesCommon(xmlXPathParserContextPtr ctxt, 45240c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack xmlXPathObjectPtr arg1, xmlXPathObjectPtr arg2) { 45253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int ret = 0; 45260c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack /* 45270c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack *At this point we are assured neither arg1 nor arg2 45280c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack *is a nodeset, so we can just pick the appropriate routine. 45290c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack */ 45303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor switch (arg1->type) { 45313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_UNDEFINED: 45323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_EXPR 45333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 45343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "Equal: undefined\n"); 45353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 45363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 45373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_BOOLEAN: 45383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor switch (arg2->type) { 45393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_UNDEFINED: 45403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_EXPR 45413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 45423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "Equal: undefined\n"); 45433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 45443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 45453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_BOOLEAN: 45463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_EXPR 45473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 45483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "Equal: %d boolean %d \n", 45493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor arg1->boolval, arg2->boolval); 45503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 45513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = (arg1->boolval == arg2->boolval); 45523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 45533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_NUMBER: 4554ef61d208503e41688f4bf86f6e9023c70e65829bWilliam M. Brack ret = (arg1->boolval == 4555ef61d208503e41688f4bf86f6e9023c70e65829bWilliam M. Brack xmlXPathCastNumberToBoolean(arg2->floatval)); 45563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 45573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_STRING: 45583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((arg2->stringval == NULL) || 45593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor (arg2->stringval[0] == 0)) ret = 0; 45603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else 45613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = 1; 45623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = (arg1->boolval == ret); 45633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 45643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_USERS: 45653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_POINT: 45663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_RANGE: 45673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_LOCATIONSET: 45683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor TODO 45693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 45700c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack case XPATH_NODESET: 45710c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack case XPATH_XSLT_TREE: 45720c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack break; 45733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 45743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 45753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_NUMBER: 45763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor switch (arg2->type) { 45773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_UNDEFINED: 45783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_EXPR 45793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 45803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "Equal: undefined\n"); 45813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 45823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 45833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_BOOLEAN: 4584ef61d208503e41688f4bf86f6e9023c70e65829bWilliam M. Brack ret = (arg2->boolval== 4585ef61d208503e41688f4bf86f6e9023c70e65829bWilliam M. Brack xmlXPathCastNumberToBoolean(arg1->floatval)); 45863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 45873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_STRING: 45883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, arg2); 45893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathNumberFunction(ctxt, 1); 45903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor arg2 = valuePop(ctxt); 45913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* no break on purpose */ 45923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_NUMBER: 4593d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard /* Hand check NaN and Infinity equalities */ 459421458c85e209cd2621ac3eadfee075ae2dc0121dDaniel Veillard if (xmlXPathIsNaN(arg1->floatval) || xmlXPathIsNaN(arg2->floatval)) { 459521458c85e209cd2621ac3eadfee075ae2dc0121dDaniel Veillard ret = 0; 4596d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard } else if (xmlXPathIsInf(arg1->floatval) == 1) { 4597d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard if (xmlXPathIsInf(arg2->floatval) == 1) 4598d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret = 1; 4599d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard else 4600d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret = 0; 4601d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard } else if (xmlXPathIsInf(arg1->floatval) == -1) { 4602d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard if (xmlXPathIsInf(arg2->floatval) == -1) 4603d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret = 1; 4604d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard else 4605d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret = 0; 4606d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard } else if (xmlXPathIsInf(arg2->floatval) == 1) { 4607d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard if (xmlXPathIsInf(arg1->floatval) == 1) 4608d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret = 1; 4609d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard else 4610d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret = 0; 4611d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard } else if (xmlXPathIsInf(arg2->floatval) == -1) { 4612d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard if (xmlXPathIsInf(arg1->floatval) == -1) 4613d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret = 1; 4614d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard else 4615d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret = 0; 461621458c85e209cd2621ac3eadfee075ae2dc0121dDaniel Veillard } else { 461721458c85e209cd2621ac3eadfee075ae2dc0121dDaniel Veillard ret = (arg1->floatval == arg2->floatval); 461821458c85e209cd2621ac3eadfee075ae2dc0121dDaniel Veillard } 46193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 46203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_USERS: 46213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_POINT: 46223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_RANGE: 46233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_LOCATIONSET: 46243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor TODO 46253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 46260c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack case XPATH_NODESET: 46270c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack case XPATH_XSLT_TREE: 46280c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack break; 46293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 46303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 46313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_STRING: 46323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor switch (arg2->type) { 46333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_UNDEFINED: 46343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_EXPR 46353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 46363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "Equal: undefined\n"); 46373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 46383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 46393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_BOOLEAN: 46403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((arg1->stringval == NULL) || 46413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor (arg1->stringval[0] == 0)) ret = 0; 46423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else 46433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = 1; 46443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = (arg2->boolval == ret); 46453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 46463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_STRING: 46473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = xmlStrEqual(arg1->stringval, arg2->stringval); 46483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 46493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_NUMBER: 46503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, arg1); 46513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathNumberFunction(ctxt, 1); 46523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor arg1 = valuePop(ctxt); 4653d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard /* Hand check NaN and Infinity equalities */ 465421458c85e209cd2621ac3eadfee075ae2dc0121dDaniel Veillard if (xmlXPathIsNaN(arg1->floatval) || xmlXPathIsNaN(arg2->floatval)) { 465521458c85e209cd2621ac3eadfee075ae2dc0121dDaniel Veillard ret = 0; 4656d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard } else if (xmlXPathIsInf(arg1->floatval) == 1) { 4657d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard if (xmlXPathIsInf(arg2->floatval) == 1) 4658d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret = 1; 4659d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard else 4660d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret = 0; 4661d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard } else if (xmlXPathIsInf(arg1->floatval) == -1) { 4662d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard if (xmlXPathIsInf(arg2->floatval) == -1) 4663d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret = 1; 4664d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard else 4665d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret = 0; 4666d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard } else if (xmlXPathIsInf(arg2->floatval) == 1) { 4667d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard if (xmlXPathIsInf(arg1->floatval) == 1) 4668d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret = 1; 4669d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard else 4670d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret = 0; 4671d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard } else if (xmlXPathIsInf(arg2->floatval) == -1) { 4672d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard if (xmlXPathIsInf(arg1->floatval) == -1) 4673d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret = 1; 4674d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard else 4675d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret = 0; 467621458c85e209cd2621ac3eadfee075ae2dc0121dDaniel Veillard } else { 467721458c85e209cd2621ac3eadfee075ae2dc0121dDaniel Veillard ret = (arg1->floatval == arg2->floatval); 467821458c85e209cd2621ac3eadfee075ae2dc0121dDaniel Veillard } 46793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 46803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_USERS: 46813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_POINT: 46823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_RANGE: 46833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_LOCATIONSET: 46843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor TODO 46853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 46860c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack case XPATH_NODESET: 46870c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack case XPATH_XSLT_TREE: 46880c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack break; 46893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 46903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 46913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_USERS: 46923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_POINT: 46933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_RANGE: 46943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_LOCATIONSET: 46953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor TODO 46963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 46970c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack case XPATH_NODESET: 46980c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack case XPATH_XSLT_TREE: 46990c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack break; 47003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 47013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(arg1); 47023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(arg2); 47033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ret); 47043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 47053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 47060c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack/** 47070c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack * xmlXPathEqualValues: 47080c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack * @ctxt: the XPath Parser context 47090c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack * 47100c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack * Implement the equal operation on XPath objects content: @arg1 == @arg2 47110c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack * 47120c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack * Returns 0 or 1 depending on the results of the test. 47130c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack */ 47140c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brackint 47150c022ad8234a9228288c651f5e6a9bce7efcd789William M. BrackxmlXPathEqualValues(xmlXPathParserContextPtr ctxt) { 47160c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack xmlXPathObjectPtr arg1, arg2, argtmp; 47170c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack int ret = 0; 47180c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack 47190c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack arg2 = valuePop(ctxt); 47200c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack arg1 = valuePop(ctxt); 47210c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack if ((arg1 == NULL) || (arg2 == NULL)) { 47220c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack if (arg1 != NULL) 47230c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack xmlXPathFreeObject(arg1); 47240c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack else 47250c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack xmlXPathFreeObject(arg2); 47260c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack XP_ERROR0(XPATH_INVALID_OPERAND); 47270c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack } 47280c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack 47290c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack if (arg1 == arg2) { 47300c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack#ifdef DEBUG_EXPR 47310c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack xmlGenericError(xmlGenericErrorContext, 47320c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack "Equal: by pointer\n"); 47330c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack#endif 47340c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack return(1); 47350c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack } 47360c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack 47370c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack /* 47380c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack *If either argument is a nodeset, it's a 'special case' 47390c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack */ 47400c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack if ((arg2->type == XPATH_NODESET) || (arg2->type == XPATH_XSLT_TREE) || 47410c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack (arg1->type == XPATH_NODESET) || (arg1->type == XPATH_XSLT_TREE)) { 47420c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack /* 47430c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack *Hack it to assure arg1 is the nodeset 47440c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack */ 47450c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack if ((arg1->type != XPATH_NODESET) && (arg1->type != XPATH_XSLT_TREE)) { 47460c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack argtmp = arg2; 47470c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack arg2 = arg1; 47480c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack arg1 = argtmp; 47490c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack } 47500c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack switch (arg2->type) { 47510c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack case XPATH_UNDEFINED: 47520c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack#ifdef DEBUG_EXPR 47530c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack xmlGenericError(xmlGenericErrorContext, 47540c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack "Equal: undefined\n"); 47550c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack#endif 47560c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack break; 47570c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack case XPATH_NODESET: 47580c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack case XPATH_XSLT_TREE: 47590c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack ret = xmlXPathEqualNodeSets(arg1, arg2, 0); 47600c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack break; 47610c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack case XPATH_BOOLEAN: 47620c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack if ((arg1->nodesetval == NULL) || 47630c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack (arg1->nodesetval->nodeNr == 0)) ret = 0; 47640c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack else 47650c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack ret = 1; 47660c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack ret = (ret == arg2->boolval); 47670c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack break; 47680c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack case XPATH_NUMBER: 47690c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack ret = xmlXPathEqualNodeSetFloat(ctxt, arg1, arg2->floatval, 0); 47700c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack break; 47710c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack case XPATH_STRING: 47720c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack ret = xmlXPathEqualNodeSetString(arg1, arg2->stringval, 0); 47730c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack break; 47740c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack case XPATH_USERS: 47750c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack case XPATH_POINT: 47760c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack case XPATH_RANGE: 47770c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack case XPATH_LOCATIONSET: 47780c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack TODO 47790c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack break; 47800c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack } 47810c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack xmlXPathFreeObject(arg1); 47820c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack xmlXPathFreeObject(arg2); 47830c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack return(ret); 47840c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack } 47850c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack 47860c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack return (xmlXPathEqualValuesCommon(ctxt, arg1, arg2)); 47870c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack} 47880c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack 47890c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack/** 47900c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack * xmlXPathNotEqualValues: 47910c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack * @ctxt: the XPath Parser context 47920c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack * 47930c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack * Implement the equal operation on XPath objects content: @arg1 == @arg2 47940c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack * 47950c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack * Returns 0 or 1 depending on the results of the test. 47960c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack */ 47970c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brackint 47980c022ad8234a9228288c651f5e6a9bce7efcd789William M. BrackxmlXPathNotEqualValues(xmlXPathParserContextPtr ctxt) { 47990c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack xmlXPathObjectPtr arg1, arg2, argtmp; 48000c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack int ret = 0; 48010c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack 48020c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack arg2 = valuePop(ctxt); 48030c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack arg1 = valuePop(ctxt); 48040c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack if ((arg1 == NULL) || (arg2 == NULL)) { 48050c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack if (arg1 != NULL) 48060c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack xmlXPathFreeObject(arg1); 48070c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack else 48080c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack xmlXPathFreeObject(arg2); 48090c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack XP_ERROR0(XPATH_INVALID_OPERAND); 48100c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack } 48110c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack 48120c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack if (arg1 == arg2) { 48130c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack#ifdef DEBUG_EXPR 48140c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack xmlGenericError(xmlGenericErrorContext, 48150c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack "NotEqual: by pointer\n"); 48160c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack#endif 48170c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack return(0); 48180c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack } 48190c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack 48200c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack /* 48210c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack *If either argument is a nodeset, it's a 'special case' 48220c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack */ 48230c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack if ((arg2->type == XPATH_NODESET) || (arg2->type == XPATH_XSLT_TREE) || 48240c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack (arg1->type == XPATH_NODESET) || (arg1->type == XPATH_XSLT_TREE)) { 48250c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack /* 48260c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack *Hack it to assure arg1 is the nodeset 48270c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack */ 48280c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack if ((arg1->type != XPATH_NODESET) && (arg1->type != XPATH_XSLT_TREE)) { 48290c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack argtmp = arg2; 48300c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack arg2 = arg1; 48310c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack arg1 = argtmp; 48320c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack } 48330c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack switch (arg2->type) { 48340c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack case XPATH_UNDEFINED: 48350c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack#ifdef DEBUG_EXPR 48360c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack xmlGenericError(xmlGenericErrorContext, 48370c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack "NotEqual: undefined\n"); 48380c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack#endif 48390c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack break; 48400c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack case XPATH_NODESET: 48410c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack case XPATH_XSLT_TREE: 48420c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack ret = xmlXPathEqualNodeSets(arg1, arg2, 1); 48430c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack break; 48440c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack case XPATH_BOOLEAN: 48450c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack if ((arg1->nodesetval == NULL) || 48460c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack (arg1->nodesetval->nodeNr == 0)) ret = 0; 48470c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack else 48480c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack ret = 1; 4849ef61d208503e41688f4bf86f6e9023c70e65829bWilliam M. Brack ret = (ret != arg2->boolval); 48500c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack break; 48510c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack case XPATH_NUMBER: 48520c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack ret = xmlXPathEqualNodeSetFloat(ctxt, arg1, arg2->floatval, 1); 48530c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack break; 48540c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack case XPATH_STRING: 48550c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack ret = xmlXPathEqualNodeSetString(arg1, arg2->stringval,1); 48560c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack break; 48570c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack case XPATH_USERS: 48580c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack case XPATH_POINT: 48590c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack case XPATH_RANGE: 48600c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack case XPATH_LOCATIONSET: 48610c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack TODO 48620c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack break; 48630c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack } 48640c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack xmlXPathFreeObject(arg1); 48650c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack xmlXPathFreeObject(arg2); 48660c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack return(ret); 48670c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack } 48680c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack 48690c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack return (!xmlXPathEqualValuesCommon(ctxt, arg1, arg2)); 48700c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack} 48713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 48723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 48733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathCompareValues: 48743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 48753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @inf: less than (1) or greater than (0) 48763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @strict: is the comparison strict 48773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 48783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the compare operation on XPath objects: 48793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @arg1 < @arg2 (1, 1, ... 48803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @arg1 <= @arg2 (1, 0, ... 48813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @arg1 > @arg2 (0, 1, ... 48823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @arg1 >= @arg2 (0, 0, ... 48833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 48843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * When neither object to be compared is a node-set and the operator is 48853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * <=, <, >=, >, then the objects are compared by converted both objects 48863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * to numbers and comparing the numbers according to IEEE 754. The < 48873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * comparison will be true if and only if the first number is less than the 48883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * second number. The <= comparison will be true if and only if the first 48893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * number is less than or equal to the second number. The > comparison 48903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * will be true if and only if the first number is greater than the second 48913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * number. The >= comparison will be true if and only if the first number 48923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * is greater than or equal to the second number. 48933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 4894cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * Returns 1 if the comparison succeeded, 0 if it failed 48953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 48963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorint 48973473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathCompareValues(xmlXPathParserContextPtr ctxt, int inf, int strict) { 4898d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard int ret = 0, arg1i = 0, arg2i = 0; 48993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr arg1, arg2; 49003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 49010c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack arg2 = valuePop(ctxt); 49023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor arg1 = valuePop(ctxt); 49030c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack if ((arg1 == NULL) || (arg2 == NULL)) { 49040c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack if (arg1 != NULL) 49050c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack xmlXPathFreeObject(arg1); 49060c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack else 49070c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack xmlXPathFreeObject(arg2); 49083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XP_ERROR0(XPATH_INVALID_OPERAND); 49093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 49103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 49110c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack if ((arg2->type == XPATH_NODESET) || (arg2->type == XPATH_XSLT_TREE) || 49120c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack (arg1->type == XPATH_NODESET) || (arg1->type == XPATH_XSLT_TREE)) { 49130c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack if (((arg2->type == XPATH_NODESET) || (arg2->type == XPATH_XSLT_TREE)) && 49140c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack ((arg1->type == XPATH_NODESET) || (arg1->type == XPATH_XSLT_TREE))){ 491556a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillard ret = xmlXPathCompareNodeSets(inf, strict, arg1, arg2); 49163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else { 49170c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack if ((arg1->type == XPATH_NODESET) || (arg1->type == XPATH_XSLT_TREE)) { 49184af6b6e801346d1c832cf19b7c3833a831871db2Daniel Veillard ret = xmlXPathCompareNodeSetValue(ctxt, inf, strict, 49194af6b6e801346d1c832cf19b7c3833a831871db2Daniel Veillard arg1, arg2); 49203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else { 49214af6b6e801346d1c832cf19b7c3833a831871db2Daniel Veillard ret = xmlXPathCompareNodeSetValue(ctxt, !inf, strict, 49224af6b6e801346d1c832cf19b7c3833a831871db2Daniel Veillard arg2, arg1); 49233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 49243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 49253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ret); 49263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 49273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 49283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (arg1->type != XPATH_NUMBER) { 49293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, arg1); 49303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathNumberFunction(ctxt, 1); 49313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor arg1 = valuePop(ctxt); 49323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 49333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (arg1->type != XPATH_NUMBER) { 49343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(arg1); 49353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(arg2); 49363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XP_ERROR0(XPATH_INVALID_OPERAND); 49373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 49383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (arg2->type != XPATH_NUMBER) { 49393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, arg2); 49403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathNumberFunction(ctxt, 1); 49413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor arg2 = valuePop(ctxt); 49423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 49433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (arg2->type != XPATH_NUMBER) { 49443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(arg1); 49453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(arg2); 49463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XP_ERROR0(XPATH_INVALID_OPERAND); 49473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 49483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 49493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Add tests for infinity and nan 49503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * => feedback on 3.4 for Inf and NaN 49513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 4952d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard /* Hand check NaN and Infinity comparisons */ 495321458c85e209cd2621ac3eadfee075ae2dc0121dDaniel Veillard if (xmlXPathIsNaN(arg1->floatval) || xmlXPathIsNaN(arg2->floatval)) { 4954d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret=0; 495521458c85e209cd2621ac3eadfee075ae2dc0121dDaniel Veillard } else { 4956d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard arg1i=xmlXPathIsInf(arg1->floatval); 4957d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard arg2i=xmlXPathIsInf(arg2->floatval); 4958d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard if (inf && strict) { 4959d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard if ((arg1i == -1 && arg2i != -1) || 4960d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard (arg2i == 1 && arg1i != 1)) { 4961d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret = 1; 4962d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard } else if (arg1i == 0 && arg2i == 0) { 4963d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret = (arg1->floatval < arg2->floatval); 4964d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard } else { 4965d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret = 0; 4966d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard } 4967d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard } 4968d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard else if (inf && !strict) { 4969d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard if (arg1i == -1 || arg2i == 1) { 4970d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret = 1; 4971d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard } else if (arg1i == 0 && arg2i == 0) { 4972d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret = (arg1->floatval <= arg2->floatval); 4973d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard } else { 4974d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret = 0; 4975d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard } 4976d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard } 4977d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard else if (!inf && strict) { 4978d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard if ((arg1i == 1 && arg2i != 1) || 4979d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard (arg2i == -1 && arg1i != -1)) { 4980d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret = 1; 4981d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard } else if (arg1i == 0 && arg2i == 0) { 4982d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret = (arg1->floatval > arg2->floatval); 4983d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard } else { 4984d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret = 0; 4985d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard } 4986d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard } 4987d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard else if (!inf && !strict) { 4988d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard if (arg1i == 1 || arg2i == -1) { 4989d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret = 1; 4990d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard } else if (arg1i == 0 && arg2i == 0) { 4991d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret = (arg1->floatval >= arg2->floatval); 4992d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard } else { 4993d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret = 0; 4994d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard } 4995d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard } 499621458c85e209cd2621ac3eadfee075ae2dc0121dDaniel Veillard } 49973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(arg1); 49983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(arg2); 49993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ret); 50003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 50013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 50023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 50033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathValueFlipSign: 50043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 50053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 50063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the unary - operation on an XPath object 50073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The numeric operators convert their operands to numbers as if 50083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * by calling the number function. 50093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 50103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 50113473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathValueFlipSign(xmlXPathParserContextPtr ctxt) { 5012ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard CAST_TO_NUMBER; 5013ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard CHECK_TYPE(XPATH_NUMBER); 5014eca82810f0fb81f3e9936d2018347e1e19de513aDaniel Veillard if (xmlXPathIsNaN(ctxt->value->floatval)) 5015eca82810f0fb81f3e9936d2018347e1e19de513aDaniel Veillard ctxt->value->floatval=xmlXPathNAN; 5016eca82810f0fb81f3e9936d2018347e1e19de513aDaniel Veillard else if (xmlXPathIsInf(ctxt->value->floatval) == 1) 5017eca82810f0fb81f3e9936d2018347e1e19de513aDaniel Veillard ctxt->value->floatval=xmlXPathNINF; 5018eca82810f0fb81f3e9936d2018347e1e19de513aDaniel Veillard else if (xmlXPathIsInf(ctxt->value->floatval) == -1) 5019eca82810f0fb81f3e9936d2018347e1e19de513aDaniel Veillard ctxt->value->floatval=xmlXPathPINF; 5020eca82810f0fb81f3e9936d2018347e1e19de513aDaniel Veillard else if (ctxt->value->floatval == 0) { 50215fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard if (xmlXPathGetSign(ctxt->value->floatval) == 0) 50225fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard ctxt->value->floatval = xmlXPathNZERO; 50235fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard else 50245fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard ctxt->value->floatval = 0; 50255fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard } 50265fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard else 50275fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard ctxt->value->floatval = - ctxt->value->floatval; 50283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 50293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 50303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 50313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathAddValues: 50323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 50333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 50343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the add operation on XPath objects: 50353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The numeric operators convert their operands to numbers as if 50363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * by calling the number function. 50373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 50383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 50393473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathAddValues(xmlXPathParserContextPtr ctxt) { 50403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr arg; 50413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor double val; 50423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 5043ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard arg = valuePop(ctxt); 5044ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard if (arg == NULL) 5045ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard XP_ERROR(XPATH_INVALID_OPERAND); 5046ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard val = xmlXPathCastToNumber(arg); 50473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(arg); 50483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 5049ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard CAST_TO_NUMBER; 5050ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard CHECK_TYPE(XPATH_NUMBER); 5051ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ctxt->value->floatval += val; 50523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 50533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 50543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 50553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathSubValues: 50563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 50573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 5058cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * Implement the subtraction operation on XPath objects: 50593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The numeric operators convert their operands to numbers as if 50603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * by calling the number function. 50613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 50623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 50633473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathSubValues(xmlXPathParserContextPtr ctxt) { 50643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr arg; 50653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor double val; 50663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 5067ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard arg = valuePop(ctxt); 5068ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard if (arg == NULL) 5069ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard XP_ERROR(XPATH_INVALID_OPERAND); 5070ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard val = xmlXPathCastToNumber(arg); 50713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(arg); 50723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 5073ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard CAST_TO_NUMBER; 5074ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard CHECK_TYPE(XPATH_NUMBER); 5075ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ctxt->value->floatval -= val; 50763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 50773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 50783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 50793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathMultValues: 50803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 50813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 50823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the multiply operation on XPath objects: 50833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The numeric operators convert their operands to numbers as if 50843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * by calling the number function. 50853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 50863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 50873473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathMultValues(xmlXPathParserContextPtr ctxt) { 50883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr arg; 50893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor double val; 50903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 5091ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard arg = valuePop(ctxt); 5092ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard if (arg == NULL) 5093ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard XP_ERROR(XPATH_INVALID_OPERAND); 5094ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard val = xmlXPathCastToNumber(arg); 50953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(arg); 50963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 5097ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard CAST_TO_NUMBER; 5098ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard CHECK_TYPE(XPATH_NUMBER); 5099ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ctxt->value->floatval *= val; 51003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 51013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 51023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 51033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathDivValues: 51043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 51053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 51063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the div operation on XPath objects @arg1 / @arg2: 51073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The numeric operators convert their operands to numbers as if 51083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * by calling the number function. 51093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 51103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 51113473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathDivValues(xmlXPathParserContextPtr ctxt) { 51123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr arg; 51133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor double val; 51143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 5115ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard arg = valuePop(ctxt); 5116ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard if (arg == NULL) 5117ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard XP_ERROR(XPATH_INVALID_OPERAND); 5118ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard val = xmlXPathCastToNumber(arg); 51193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(arg); 51203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 5121ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard CAST_TO_NUMBER; 5122ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard CHECK_TYPE(XPATH_NUMBER); 5123eca82810f0fb81f3e9936d2018347e1e19de513aDaniel Veillard if (xmlXPathIsNaN(val) || xmlXPathIsNaN(ctxt->value->floatval)) 5124eca82810f0fb81f3e9936d2018347e1e19de513aDaniel Veillard ctxt->value->floatval = xmlXPathNAN; 5125eca82810f0fb81f3e9936d2018347e1e19de513aDaniel Veillard else if (val == 0 && xmlXPathGetSign(val) != 0) { 51265fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard if (ctxt->value->floatval == 0) 51275fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard ctxt->value->floatval = xmlXPathNAN; 51285fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard else if (ctxt->value->floatval > 0) 51295fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard ctxt->value->floatval = xmlXPathNINF; 51305fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard else if (ctxt->value->floatval < 0) 51315fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard ctxt->value->floatval = xmlXPathPINF; 51325fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard } 51335fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard else if (val == 0) { 51345f4b5999b4eeda2ca68e6d9f54a3c534a8474b38Daniel Veillard if (ctxt->value->floatval == 0) 51355f4b5999b4eeda2ca68e6d9f54a3c534a8474b38Daniel Veillard ctxt->value->floatval = xmlXPathNAN; 51365f4b5999b4eeda2ca68e6d9f54a3c534a8474b38Daniel Veillard else if (ctxt->value->floatval > 0) 51375f4b5999b4eeda2ca68e6d9f54a3c534a8474b38Daniel Veillard ctxt->value->floatval = xmlXPathPINF; 51385f4b5999b4eeda2ca68e6d9f54a3c534a8474b38Daniel Veillard else if (ctxt->value->floatval < 0) 51395f4b5999b4eeda2ca68e6d9f54a3c534a8474b38Daniel Veillard ctxt->value->floatval = xmlXPathNINF; 51405f4b5999b4eeda2ca68e6d9f54a3c534a8474b38Daniel Veillard } else 51415f4b5999b4eeda2ca68e6d9f54a3c534a8474b38Daniel Veillard ctxt->value->floatval /= val; 51423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 51433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 51443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 51453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathModValues: 51463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 51473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 51483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the mod operation on XPath objects: @arg1 / @arg2 51493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The numeric operators convert their operands to numbers as if 51503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * by calling the number function. 51513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 51523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 51533473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathModValues(xmlXPathParserContextPtr ctxt) { 51543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr arg; 5155fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard double arg1, arg2; 51563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 5157ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard arg = valuePop(ctxt); 5158ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard if (arg == NULL) 5159ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard XP_ERROR(XPATH_INVALID_OPERAND); 51605fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard arg2 = xmlXPathCastToNumber(arg); 51613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(arg); 51623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 5163ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard CAST_TO_NUMBER; 5164ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard CHECK_TYPE(XPATH_NUMBER); 51655fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard arg1 = ctxt->value->floatval; 5166268fd1bc97f79b43290041cfda2287fb0b0ef2d6Daniel Veillard if (arg2 == 0) 5167268fd1bc97f79b43290041cfda2287fb0b0ef2d6Daniel Veillard ctxt->value->floatval = xmlXPathNAN; 51685fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard else { 5169fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard ctxt->value->floatval = fmod(arg1, arg2); 51705fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard } 51713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 51723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 51733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/************************************************************************ 51743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * * 51753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The traversal functions * 51763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * * 51773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ************************************************************************/ 51783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 51793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/* 51803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * A traversal function enumerates nodes along an axis. 51813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Initially it must be called with NULL, and it indicates 51823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * termination on the axis by returning NULL. 51833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 51843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylortypedef xmlNodePtr (*xmlXPathTraversalFunction) 51853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor (xmlXPathParserContextPtr ctxt, xmlNodePtr cur); 51863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 51873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 51883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNextSelf: 51893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 51903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur: the current node in the traversal 51913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 51923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Traversal function for the "self" direction 51933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The self axis contains just the context node itself 51943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 51953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the next element following that axis 51963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 51973473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNodePtr 51983473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNextSelf(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) { 51993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == NULL) 52003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ctxt->context->node); 52013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 52023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 52033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 52043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 52053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNextChild: 52063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 52073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur: the current node in the traversal 52083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 52093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Traversal function for the "child" direction 52103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The child axis contains the children of the context node in document order. 52113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 52123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the next element following that axis 52133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 52143473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNodePtr 52153473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNextChild(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) { 52163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == NULL) { 52173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->context->node == NULL) return(NULL); 52183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor switch (ctxt->context->node->type) { 52193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ELEMENT_NODE: 52203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_TEXT_NODE: 52213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_CDATA_SECTION_NODE: 52223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ENTITY_REF_NODE: 52233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ENTITY_NODE: 52243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_PI_NODE: 52253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_COMMENT_NODE: 52263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_NOTATION_NODE: 52273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_DTD_NODE: 52283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ctxt->context->node->children); 52293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_DOCUMENT_NODE: 52303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_DOCUMENT_TYPE_NODE: 52313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_DOCUMENT_FRAG_NODE: 52323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_HTML_DOCUMENT_NODE: 5233eae522a0d8aa9f830d2e447f29b504030dbb6bbdDaniel Veillard#ifdef LIBXML_DOCB_ENABLED 5234eae522a0d8aa9f830d2e447f29b504030dbb6bbdDaniel Veillard case XML_DOCB_DOCUMENT_NODE: 52353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 52363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(((xmlDocPtr) ctxt->context->node)->children); 52373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ELEMENT_DECL: 52383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ATTRIBUTE_DECL: 52393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ENTITY_DECL: 52403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ATTRIBUTE_NODE: 52413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_NAMESPACE_DECL: 52423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_XINCLUDE_START: 52433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_XINCLUDE_END: 52443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 52453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 52463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 52473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 52483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((cur->type == XML_DOCUMENT_NODE) || 52493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor (cur->type == XML_HTML_DOCUMENT_NODE)) 52503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 52513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(cur->next); 52523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 52533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 52543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 52553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNextDescendant: 52563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 52573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur: the current node in the traversal 52583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 52593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Traversal function for the "descendant" direction 52603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the descendant axis contains the descendants of the context node in document 52613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * order; a descendant is a child or a child of a child and so on. 52623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 52633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the next element following that axis 52643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 52653473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNodePtr 52663473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNextDescendant(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) { 52673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == NULL) { 52683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->context->node == NULL) 52693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 52703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((ctxt->context->node->type == XML_ATTRIBUTE_NODE) || 52713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor (ctxt->context->node->type == XML_NAMESPACE_DECL)) 52723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 52733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 52743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->context->node == (xmlNodePtr) ctxt->context->doc) 52753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ctxt->context->doc->children); 52763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ctxt->context->node->children); 52773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 52783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 5279567e1b48e8664163894742d5674c24baa4282f9eDaniel Veillard if (cur->children != NULL) { 528068e9e74af85ebbc30781787f247c361bc85adfa0Daniel Veillard /* 528168e9e74af85ebbc30781787f247c361bc85adfa0Daniel Veillard * Do not descend on entities declarations 528268e9e74af85ebbc30781787f247c361bc85adfa0Daniel Veillard */ 528368e9e74af85ebbc30781787f247c361bc85adfa0Daniel Veillard if (cur->children->type != XML_ENTITY_DECL) { 528468e9e74af85ebbc30781787f247c361bc85adfa0Daniel Veillard cur = cur->children; 528568e9e74af85ebbc30781787f247c361bc85adfa0Daniel Veillard /* 528668e9e74af85ebbc30781787f247c361bc85adfa0Daniel Veillard * Skip DTDs 528768e9e74af85ebbc30781787f247c361bc85adfa0Daniel Veillard */ 528868e9e74af85ebbc30781787f247c361bc85adfa0Daniel Veillard if (cur->type != XML_DTD_NODE) 528968e9e74af85ebbc30781787f247c361bc85adfa0Daniel Veillard return(cur); 529068e9e74af85ebbc30781787f247c361bc85adfa0Daniel Veillard } 5291567e1b48e8664163894742d5674c24baa4282f9eDaniel Veillard } 5292567e1b48e8664163894742d5674c24baa4282f9eDaniel Veillard 5293567e1b48e8664163894742d5674c24baa4282f9eDaniel Veillard if (cur == ctxt->context->node) return(NULL); 5294567e1b48e8664163894742d5674c24baa4282f9eDaniel Veillard 529568e9e74af85ebbc30781787f247c361bc85adfa0Daniel Veillard while (cur->next != NULL) { 529668e9e74af85ebbc30781787f247c361bc85adfa0Daniel Veillard cur = cur->next; 529768e9e74af85ebbc30781787f247c361bc85adfa0Daniel Veillard if ((cur->type != XML_ENTITY_DECL) && 529868e9e74af85ebbc30781787f247c361bc85adfa0Daniel Veillard (cur->type != XML_DTD_NODE)) 529968e9e74af85ebbc30781787f247c361bc85adfa0Daniel Veillard return(cur); 530068e9e74af85ebbc30781787f247c361bc85adfa0Daniel Veillard } 53013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 53023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor do { 53033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur = cur->parent; 53043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == NULL) return(NULL); 53053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == ctxt->context->node) return(NULL); 53063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur->next != NULL) { 53073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur = cur->next; 53083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(cur); 53093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 53103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } while (cur != NULL); 53113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(cur); 53123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 53133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 53143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 53153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNextDescendantOrSelf: 53163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 53173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur: the current node in the traversal 53183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 53193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Traversal function for the "descendant-or-self" direction 53203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the descendant-or-self axis contains the context node and the descendants 53213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * of the context node in document order; thus the context node is the first 53223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * node on the axis, and the first child of the context node is the second node 53233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * on the axis 53243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 53253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the next element following that axis 53263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 53273473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNodePtr 53283473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNextDescendantOrSelf(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) { 53293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == NULL) { 53303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->context->node == NULL) 53313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 53323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((ctxt->context->node->type == XML_ATTRIBUTE_NODE) || 53333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor (ctxt->context->node->type == XML_NAMESPACE_DECL)) 53343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 53353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ctxt->context->node); 53363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 53373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 53383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(xmlXPathNextDescendant(ctxt, cur)); 53393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 53403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 53413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 53423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNextParent: 53433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 53443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur: the current node in the traversal 53453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 53463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Traversal function for the "parent" direction 53473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The parent axis contains the parent of the context node, if there is one. 53483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 53493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the next element following that axis 53503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 53513473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNodePtr 53523473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNextParent(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) { 53533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 53543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the parent of an attribute or namespace node is the element 53553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * to which the attribute or namespace node is attached 53563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Namespace handling !!! 53573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 53583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == NULL) { 53593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->context->node == NULL) return(NULL); 53603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor switch (ctxt->context->node->type) { 53613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ELEMENT_NODE: 53623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_TEXT_NODE: 53633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_CDATA_SECTION_NODE: 53643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ENTITY_REF_NODE: 53653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ENTITY_NODE: 53663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_PI_NODE: 53673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_COMMENT_NODE: 53683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_NOTATION_NODE: 53693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_DTD_NODE: 53703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ELEMENT_DECL: 53713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ATTRIBUTE_DECL: 53723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_XINCLUDE_START: 53733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_XINCLUDE_END: 53743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ENTITY_DECL: 53753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->context->node->parent == NULL) 53763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return((xmlNodePtr) ctxt->context->doc); 53778e7e1c00ce5cc3ce959833b888c50ed9fd9d5aaeDaniel Veillard if ((ctxt->context->node->parent->type == XML_ELEMENT_NODE) && 5378652d8a949447833405cc0805f4b7ff1179e59ed2Daniel Veillard ((ctxt->context->node->parent->name[0] == ' ') || 5379652d8a949447833405cc0805f4b7ff1179e59ed2Daniel Veillard (xmlStrEqual(ctxt->context->node->parent->name, 5380652d8a949447833405cc0805f4b7ff1179e59ed2Daniel Veillard BAD_CAST "fake node libxslt")))) 53818e7e1c00ce5cc3ce959833b888c50ed9fd9d5aaeDaniel Veillard return(NULL); 53823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ctxt->context->node->parent); 53833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ATTRIBUTE_NODE: { 53843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlAttrPtr att = (xmlAttrPtr) ctxt->context->node; 53853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 53863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(att->parent); 53873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 53883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_DOCUMENT_NODE: 53893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_DOCUMENT_TYPE_NODE: 53903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_DOCUMENT_FRAG_NODE: 53913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_HTML_DOCUMENT_NODE: 5392eae522a0d8aa9f830d2e447f29b504030dbb6bbdDaniel Veillard#ifdef LIBXML_DOCB_ENABLED 5393eae522a0d8aa9f830d2e447f29b504030dbb6bbdDaniel Veillard case XML_DOCB_DOCUMENT_NODE: 53943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 53953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 5396044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard case XML_NAMESPACE_DECL: { 5397044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlNsPtr ns = (xmlNsPtr) ctxt->context->node; 5398044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard 5399044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if ((ns->next != NULL) && 5400044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard (ns->next->type != XML_NAMESPACE_DECL)) 5401044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard return((xmlNodePtr) ns->next); 54023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 5403044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } 54043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 54053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 54063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 54073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 54083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 54093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 54103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNextAncestor: 54113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 54123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur: the current node in the traversal 54133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 54143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Traversal function for the "ancestor" direction 54153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the ancestor axis contains the ancestors of the context node; the ancestors 54163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * of the context node consist of the parent of context node and the parent's 54173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * parent and so on; the nodes are ordered in reverse document order; thus the 54183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * parent is the first node on the axis, and the parent's parent is the second 54193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * node on the axis 54203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 54213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the next element following that axis 54223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 54233473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNodePtr 54243473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNextAncestor(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) { 54253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 54263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the parent of an attribute or namespace node is the element 54273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * to which the attribute or namespace node is attached 54283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * !!!!!!!!!!!!! 54293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 54303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == NULL) { 54313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->context->node == NULL) return(NULL); 54323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor switch (ctxt->context->node->type) { 54333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ELEMENT_NODE: 54343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_TEXT_NODE: 54353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_CDATA_SECTION_NODE: 54363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ENTITY_REF_NODE: 54373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ENTITY_NODE: 54383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_PI_NODE: 54393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_COMMENT_NODE: 54403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_DTD_NODE: 54413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ELEMENT_DECL: 54423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ATTRIBUTE_DECL: 54433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ENTITY_DECL: 54443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_NOTATION_NODE: 54453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_XINCLUDE_START: 54463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_XINCLUDE_END: 54473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->context->node->parent == NULL) 54483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return((xmlNodePtr) ctxt->context->doc); 54498e7e1c00ce5cc3ce959833b888c50ed9fd9d5aaeDaniel Veillard if ((ctxt->context->node->parent->type == XML_ELEMENT_NODE) && 5450652d8a949447833405cc0805f4b7ff1179e59ed2Daniel Veillard ((ctxt->context->node->parent->name[0] == ' ') || 5451652d8a949447833405cc0805f4b7ff1179e59ed2Daniel Veillard (xmlStrEqual(ctxt->context->node->parent->name, 5452652d8a949447833405cc0805f4b7ff1179e59ed2Daniel Veillard BAD_CAST "fake node libxslt")))) 54538e7e1c00ce5cc3ce959833b888c50ed9fd9d5aaeDaniel Veillard return(NULL); 54543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ctxt->context->node->parent); 54553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ATTRIBUTE_NODE: { 545656a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillard xmlAttrPtr tmp = (xmlAttrPtr) ctxt->context->node; 54573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 545856a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillard return(tmp->parent); 54593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 54603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_DOCUMENT_NODE: 54613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_DOCUMENT_TYPE_NODE: 54623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_DOCUMENT_FRAG_NODE: 54633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_HTML_DOCUMENT_NODE: 5464eae522a0d8aa9f830d2e447f29b504030dbb6bbdDaniel Veillard#ifdef LIBXML_DOCB_ENABLED 5465eae522a0d8aa9f830d2e447f29b504030dbb6bbdDaniel Veillard case XML_DOCB_DOCUMENT_NODE: 54663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 54673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 5468044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard case XML_NAMESPACE_DECL: { 5469044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlNsPtr ns = (xmlNsPtr) ctxt->context->node; 5470044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard 5471044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if ((ns->next != NULL) && 5472044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard (ns->next->type != XML_NAMESPACE_DECL)) 5473044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard return((xmlNodePtr) ns->next); 5474044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard /* Bad, how did that namespace ended-up there ? */ 54753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 5476044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } 54773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 54783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 54793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 54803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == ctxt->context->doc->children) 54813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return((xmlNodePtr) ctxt->context->doc); 54823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == (xmlNodePtr) ctxt->context->doc) 54833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 54843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor switch (cur->type) { 54853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ELEMENT_NODE: 54863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_TEXT_NODE: 54873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_CDATA_SECTION_NODE: 54883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ENTITY_REF_NODE: 54893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ENTITY_NODE: 54903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_PI_NODE: 54913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_COMMENT_NODE: 54923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_NOTATION_NODE: 54933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_DTD_NODE: 54943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ELEMENT_DECL: 54953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ATTRIBUTE_DECL: 54963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ENTITY_DECL: 54973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_XINCLUDE_START: 54983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_XINCLUDE_END: 54998e7e1c00ce5cc3ce959833b888c50ed9fd9d5aaeDaniel Veillard if (cur->parent == NULL) 55008e7e1c00ce5cc3ce959833b888c50ed9fd9d5aaeDaniel Veillard return(NULL); 55018e7e1c00ce5cc3ce959833b888c50ed9fd9d5aaeDaniel Veillard if ((cur->parent->type == XML_ELEMENT_NODE) && 5502652d8a949447833405cc0805f4b7ff1179e59ed2Daniel Veillard ((cur->parent->name[0] == ' ') || 5503652d8a949447833405cc0805f4b7ff1179e59ed2Daniel Veillard (xmlStrEqual(cur->parent->name, 5504652d8a949447833405cc0805f4b7ff1179e59ed2Daniel Veillard BAD_CAST "fake node libxslt")))) 55058e7e1c00ce5cc3ce959833b888c50ed9fd9d5aaeDaniel Veillard return(NULL); 55063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(cur->parent); 55073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ATTRIBUTE_NODE: { 55083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlAttrPtr att = (xmlAttrPtr) ctxt->context->node; 55093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 55103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(att->parent); 55113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 5512dffd5c8dbc7b9052db7ae69dce419a96e22acc68Aleksey Sanin case XML_NAMESPACE_DECL: { 5513dffd5c8dbc7b9052db7ae69dce419a96e22acc68Aleksey Sanin xmlNsPtr ns = (xmlNsPtr) ctxt->context->node; 5514dffd5c8dbc7b9052db7ae69dce419a96e22acc68Aleksey Sanin 5515dffd5c8dbc7b9052db7ae69dce419a96e22acc68Aleksey Sanin if ((ns->next != NULL) && 5516dffd5c8dbc7b9052db7ae69dce419a96e22acc68Aleksey Sanin (ns->next->type != XML_NAMESPACE_DECL)) 5517dffd5c8dbc7b9052db7ae69dce419a96e22acc68Aleksey Sanin return((xmlNodePtr) ns->next); 5518dffd5c8dbc7b9052db7ae69dce419a96e22acc68Aleksey Sanin /* Bad, how did that namespace ended-up there ? */ 5519dffd5c8dbc7b9052db7ae69dce419a96e22acc68Aleksey Sanin return(NULL); 5520dffd5c8dbc7b9052db7ae69dce419a96e22acc68Aleksey Sanin } 55213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_DOCUMENT_NODE: 55223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_DOCUMENT_TYPE_NODE: 55233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_DOCUMENT_FRAG_NODE: 55243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_HTML_DOCUMENT_NODE: 5525eae522a0d8aa9f830d2e447f29b504030dbb6bbdDaniel Veillard#ifdef LIBXML_DOCB_ENABLED 5526eae522a0d8aa9f830d2e447f29b504030dbb6bbdDaniel Veillard case XML_DOCB_DOCUMENT_NODE: 55273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 55283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 55293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 55303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 55313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 55323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 55333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 55343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNextAncestorOrSelf: 55353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 55363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur: the current node in the traversal 55373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 55383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Traversal function for the "ancestor-or-self" direction 55393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * he ancestor-or-self axis contains the context node and ancestors of 55403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the context node in reverse document order; thus the context node is 55413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the first node on the axis, and the context node's parent the second; 55423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * parent here is defined the same as with the parent axis. 55433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 55443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the next element following that axis 55453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 55463473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNodePtr 55473473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNextAncestorOrSelf(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) { 55483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == NULL) 55493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ctxt->context->node); 55503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(xmlXPathNextAncestor(ctxt, cur)); 55513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 55523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 55533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 55543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNextFollowingSibling: 55553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 55563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur: the current node in the traversal 55573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 55583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Traversal function for the "following-sibling" direction 55593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The following-sibling axis contains the following siblings of the context 55603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * node in document order. 55613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 55623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the next element following that axis 55633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 55643473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNodePtr 55653473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNextFollowingSibling(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) { 55663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((ctxt->context->node->type == XML_ATTRIBUTE_NODE) || 55673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor (ctxt->context->node->type == XML_NAMESPACE_DECL)) 55683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 55693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == (xmlNodePtr) ctxt->context->doc) 55703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 55713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == NULL) 55723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ctxt->context->node->next); 55733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(cur->next); 55743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 55753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 55763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 55773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNextPrecedingSibling: 55783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 55793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur: the current node in the traversal 55803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 55813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Traversal function for the "preceding-sibling" direction 55823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The preceding-sibling axis contains the preceding siblings of the context 55833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * node in reverse document order; the first preceding sibling is first on the 55843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * axis; the sibling preceding that node is the second on the axis and so on. 55853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 55863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the next element following that axis 55873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 55883473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNodePtr 55893473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNextPrecedingSibling(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) { 55903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((ctxt->context->node->type == XML_ATTRIBUTE_NODE) || 55913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor (ctxt->context->node->type == XML_NAMESPACE_DECL)) 55923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 55933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == (xmlNodePtr) ctxt->context->doc) 55943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 55953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == NULL) 55963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ctxt->context->node->prev); 5597f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((cur->prev != NULL) && (cur->prev->type == XML_DTD_NODE)) { 5598f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard cur = cur->prev; 5599f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (cur == NULL) 5600f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return(ctxt->context->node->prev); 5601f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 56023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(cur->prev); 56033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 56043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 56053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 56063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNextFollowing: 56073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 56083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur: the current node in the traversal 56093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 56103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Traversal function for the "following" direction 56113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The following axis contains all nodes in the same document as the context 56123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * node that are after the context node in document order, excluding any 56133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * descendants and excluding attribute nodes and namespace nodes; the nodes 56143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * are ordered in document order 56153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 56163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the next element following that axis 56173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 56183473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNodePtr 56193473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNextFollowing(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) { 56203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur != NULL && cur->children != NULL) 56213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return cur->children ; 56223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == NULL) cur = ctxt->context->node; 56233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == NULL) return(NULL) ; /* ERROR */ 56243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur->next != NULL) return(cur->next) ; 56253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor do { 56263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur = cur->parent; 56273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == NULL) return(NULL); 56283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == (xmlNodePtr) ctxt->context->doc) return(NULL); 56293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur->next != NULL) return(cur->next); 56303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } while (cur != NULL); 56313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(cur); 56323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 56333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 56343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/* 56353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathIsAncestor: 56363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ancestor: the ancestor node 56373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @node: the current node 56383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 56393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Check that @ancestor is a @node's ancestor 56403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 56413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * returns 1 if @ancestor is a @node's ancestor, 0 otherwise. 56423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 56433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorstatic int 56443473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathIsAncestor(xmlNodePtr ancestor, xmlNodePtr node) { 56453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((ancestor == NULL) || (node == NULL)) return(0); 56463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* nodes need to be in the same document */ 56473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ancestor->doc != node->doc) return(0); 56483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* avoid searching if ancestor or node is the root node */ 56493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ancestor == (xmlNodePtr) node->doc) return(1); 56503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (node == (xmlNodePtr) ancestor->doc) return(0); 56513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while (node->parent != NULL) { 56523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (node->parent == ancestor) 56533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(1); 56543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor node = node->parent; 56553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 56563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(0); 56573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 56583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 56593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 56603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNextPreceding: 56613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 56623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur: the current node in the traversal 56633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 56643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Traversal function for the "preceding" direction 56653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the preceding axis contains all nodes in the same document as the context 56663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * node that are before the context node in document order, excluding any 56673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * ancestors and excluding attribute nodes and namespace nodes; the nodes are 56683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * ordered in reverse document order 56693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 56703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the next element following that axis 56713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 56723473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNodePtr 5673f06307e2c172284bb41376c396f757bdac9bdd19Daniel VeillardxmlXPathNextPreceding(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) 5674f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard{ 5675f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (cur == NULL) 5676f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard cur = ctxt->context->node; 56773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == NULL) 5678f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (NULL); 5679f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((cur->prev != NULL) && (cur->prev->type == XML_DTD_NODE)) 5680f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard cur = cur->prev; 56813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor do { 56823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur->prev != NULL) { 5683f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard for (cur = cur->prev; cur->last != NULL; cur = cur->last) ; 5684f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (cur); 56853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 56863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 56873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur = cur->parent; 5688f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (cur == NULL) 5689f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (NULL); 5690f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (cur == ctxt->context->doc->children) 5691f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (NULL); 56923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } while (xmlXPathIsAncestor(cur, ctxt->context->node)); 5693f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (cur); 5694f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard} 5695f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 5696f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard/** 5697f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * xmlXPathNextPrecedingInternal: 5698f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * @ctxt: the XPath Parser context 5699f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * @cur: the current node in the traversal 5700f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * 5701f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Traversal function for the "preceding" direction 5702f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * the preceding axis contains all nodes in the same document as the context 5703f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * node that are before the context node in document order, excluding any 5704f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * ancestors and excluding attribute nodes and namespace nodes; the nodes are 5705f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * ordered in reverse document order 5706f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * This is a faster implementation but internal only since it requires a 5707f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * state kept in the parser context: ctxt->ancestor. 5708f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * 5709f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Returns the next element following that axis 5710f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 5711f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillardstatic xmlNodePtr 5712f06307e2c172284bb41376c396f757bdac9bdd19Daniel VeillardxmlXPathNextPrecedingInternal(xmlXPathParserContextPtr ctxt, 5713f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlNodePtr cur) 5714f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard{ 5715f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (cur == NULL) { 5716f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard cur = ctxt->context->node; 5717f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (cur == NULL) 5718f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (NULL); 5719f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->ancestor = cur->parent; 5720f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 5721f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((cur->prev != NULL) && (cur->prev->type == XML_DTD_NODE)) 5722f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard cur = cur->prev; 5723f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard while (cur->prev == NULL) { 5724f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard cur = cur->parent; 5725f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (cur == NULL) 5726f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (NULL); 5727f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (cur == ctxt->context->doc->children) 5728f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (NULL); 5729f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (cur != ctxt->ancestor) 5730f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (cur); 5731f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->ancestor = cur->parent; 5732f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 5733f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard cur = cur->prev; 5734f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard while (cur->last != NULL) 5735f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard cur = cur->last; 5736f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (cur); 57373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 57383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 57393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 57403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNextNamespace: 57413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 57423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur: the current attribute in the traversal 57433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 57443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Traversal function for the "namespace" direction 57453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the namespace axis contains the namespace nodes of the context node; 57463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the order of nodes on this axis is implementation-defined; the axis will 57473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * be empty unless the context node is an element 57483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 574920ee8c03107e5d5724765da513d595fdaf290dceDaniel Veillard * We keep the XML namespace node at the end of the list. 575020ee8c03107e5d5724765da513d595fdaf290dceDaniel Veillard * 57513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the next element following that axis 57523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 57533473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNodePtr 57543473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNextNamespace(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) { 57553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->context->node->type != XML_ELEMENT_NODE) return(NULL); 5756fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard if (ctxt->context->tmpNsList == NULL && cur != (xmlNodePtr) xmlXPathXMLNamespace) { 57577d7e37919fc6c7f257769c867122d885d2aae26fDaniel Veillard if (ctxt->context->tmpNsList != NULL) 57587d7e37919fc6c7f257769c867122d885d2aae26fDaniel Veillard xmlFree(ctxt->context->tmpNsList); 57597d7e37919fc6c7f257769c867122d885d2aae26fDaniel Veillard ctxt->context->tmpNsList = 57603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGetNsList(ctxt->context->doc, ctxt->context->node); 57617d7e37919fc6c7f257769c867122d885d2aae26fDaniel Veillard ctxt->context->tmpNsNr = 0; 5762fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard if (ctxt->context->tmpNsList != NULL) { 5763fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard while (ctxt->context->tmpNsList[ctxt->context->tmpNsNr] != NULL) { 5764fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard ctxt->context->tmpNsNr++; 5765fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard } 5766fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard } 5767fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard return((xmlNodePtr) xmlXPathXMLNamespace); 57687d7e37919fc6c7f257769c867122d885d2aae26fDaniel Veillard } 5769fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard if (ctxt->context->tmpNsNr > 0) { 5770fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard return (xmlNodePtr)ctxt->context->tmpNsList[--ctxt->context->tmpNsNr]; 5771fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard } else { 5772fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard if (ctxt->context->tmpNsList != NULL) 5773fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard xmlFree(ctxt->context->tmpNsList); 57747d7e37919fc6c7f257769c867122d885d2aae26fDaniel Veillard ctxt->context->tmpNsList = NULL; 5775fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard return(NULL); 57763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 57773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 57783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 57793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 57803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNextAttribute: 57813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 57823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur: the current attribute in the traversal 57833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 57843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Traversal function for the "attribute" direction 57853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * TODO: support DTD inherited default attributes 57863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 57873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the next element following that axis 57883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 57893473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNodePtr 57903473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNextAttribute(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) { 5791e470df7fdd3505c6232d6498f3b8834ebfce522dDaniel Veillard if (ctxt->context->node == NULL) 5792e470df7fdd3505c6232d6498f3b8834ebfce522dDaniel Veillard return(NULL); 5793e470df7fdd3505c6232d6498f3b8834ebfce522dDaniel Veillard if (ctxt->context->node->type != XML_ELEMENT_NODE) 5794e470df7fdd3505c6232d6498f3b8834ebfce522dDaniel Veillard return(NULL); 57953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == NULL) { 57963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->context->node == (xmlNodePtr) ctxt->context->doc) 57973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 57983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return((xmlNodePtr)ctxt->context->node->properties); 57993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 58003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return((xmlNodePtr)cur->next); 58013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 58023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 58033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/************************************************************************ 58043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * * 58053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * NodeTest Functions * 58063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * * 58073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ************************************************************************/ 58083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 58093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define IS_FUNCTION 200 58103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 5811d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard 5812d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard/************************************************************************ 5813d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * * 5814d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * Implicit tree core function library * 5815d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * * 5816d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard ************************************************************************/ 5817d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard 58183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 5819d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * xmlXPathRoot: 58203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 58213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 5822d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * Initialize the context to the root of the document 58233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 5824d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillardvoid 5825d8df6c0e8c883e1d618388d266015dda36731440Daniel VeillardxmlXPathRoot(xmlXPathParserContextPtr ctxt) { 5826d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard ctxt->context->node = (xmlNodePtr) ctxt->context->doc; 5827d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard valuePush(ctxt, xmlXPathNewNodeSet(ctxt->context->node)); 5828d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard} 58293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 5830d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard/************************************************************************ 5831d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * * 5832d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * The explicit core function library * 5833d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard *http://www.w3.org/Style/XSL/Group/1999/07/xpath-19990705.html#corelib * 5834d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * * 5835d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard ************************************************************************/ 58363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 5837d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard 5838d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard/** 5839d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * xmlXPathLastFunction: 5840d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * @ctxt: the XPath Parser context 5841d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * @nargs: the number of arguments 5842d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * 5843d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * Implement the last() XPath function 5844d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * number last() 5845d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * The last function returns the number of nodes in the context node list. 5846d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard */ 5847d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillardvoid 5848d8df6c0e8c883e1d618388d266015dda36731440Daniel VeillardxmlXPathLastFunction(xmlXPathParserContextPtr ctxt, int nargs) { 5849d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard CHECK_ARITY(0); 5850d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard if (ctxt->context->contextSize >= 0) { 5851d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard valuePush(ctxt, xmlXPathNewFloat((double) ctxt->context->contextSize)); 5852d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_EXPR 5853d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard xmlGenericError(xmlGenericErrorContext, 5854d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard "last() : %d\n", ctxt->context->contextSize); 58553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 5856d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard } else { 5857d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard XP_ERROR(XPATH_INVALID_CTXT_SIZE); 58583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 5859d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard} 58603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 5861d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard/** 5862d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * xmlXPathPositionFunction: 5863d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * @ctxt: the XPath Parser context 5864d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * @nargs: the number of arguments 5865d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * 5866d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * Implement the position() XPath function 5867d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * number position() 5868d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * The position function returns the position of the context node in the 5869cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * context node list. The first position is 1, and so the last position 5870d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * will be equal to last(). 5871d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard */ 5872d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillardvoid 5873d8df6c0e8c883e1d618388d266015dda36731440Daniel VeillardxmlXPathPositionFunction(xmlXPathParserContextPtr ctxt, int nargs) { 5874d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard CHECK_ARITY(0); 5875d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard if (ctxt->context->proximityPosition >= 0) { 5876d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard valuePush(ctxt, 5877d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard xmlXPathNewFloat((double) ctxt->context->proximityPosition)); 5878d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_EXPR 5879d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard xmlGenericError(xmlGenericErrorContext, "position() : %d\n", 5880d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard ctxt->context->proximityPosition); 58813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 5882d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard } else { 5883d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard XP_ERROR(XPATH_INVALID_CTXT_POSITION); 5884d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard } 5885d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard} 58863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 58873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 58883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathCountFunction: 58893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 58903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs: the number of arguments 58913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 58923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the count() XPath function 58933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * number count(node-set) 58943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 58953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 58963473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathCountFunction(xmlXPathParserContextPtr ctxt, int nargs) { 58973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr cur; 58983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 58993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ARITY(1); 59003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((ctxt->value == NULL) || 59013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ((ctxt->value->type != XPATH_NODESET) && 59023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor (ctxt->value->type != XPATH_XSLT_TREE))) 59033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XP_ERROR(XPATH_INVALID_TYPE); 59043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur = valuePop(ctxt); 59053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 5906911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard if ((cur == NULL) || (cur->nodesetval == NULL)) 5907911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard valuePush(ctxt, xmlXPathNewFloat((double) 0)); 59080c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack else if ((cur->type == XPATH_NODESET) || (cur->type == XPATH_XSLT_TREE)) { 5909911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard valuePush(ctxt, xmlXPathNewFloat((double) cur->nodesetval->nodeNr)); 5910fe70332f7f29f146a364c73450729a8b3274daeeDaniel Veillard } else { 5911fe70332f7f29f146a364c73450729a8b3274daeeDaniel Veillard if ((cur->nodesetval->nodeNr != 1) || 5912fe70332f7f29f146a364c73450729a8b3274daeeDaniel Veillard (cur->nodesetval->nodeTab == NULL)) { 5913fe70332f7f29f146a364c73450729a8b3274daeeDaniel Veillard valuePush(ctxt, xmlXPathNewFloat((double) 0)); 5914fe70332f7f29f146a364c73450729a8b3274daeeDaniel Veillard } else { 5915fe70332f7f29f146a364c73450729a8b3274daeeDaniel Veillard xmlNodePtr tmp; 5916fe70332f7f29f146a364c73450729a8b3274daeeDaniel Veillard int i = 0; 5917fe70332f7f29f146a364c73450729a8b3274daeeDaniel Veillard 5918fe70332f7f29f146a364c73450729a8b3274daeeDaniel Veillard tmp = cur->nodesetval->nodeTab[0]; 5919fe70332f7f29f146a364c73450729a8b3274daeeDaniel Veillard if (tmp != NULL) { 5920fe70332f7f29f146a364c73450729a8b3274daeeDaniel Veillard tmp = tmp->children; 5921fe70332f7f29f146a364c73450729a8b3274daeeDaniel Veillard while (tmp != NULL) { 5922fe70332f7f29f146a364c73450729a8b3274daeeDaniel Veillard tmp = tmp->next; 5923fe70332f7f29f146a364c73450729a8b3274daeeDaniel Veillard i++; 5924fe70332f7f29f146a364c73450729a8b3274daeeDaniel Veillard } 5925fe70332f7f29f146a364c73450729a8b3274daeeDaniel Veillard } 5926fe70332f7f29f146a364c73450729a8b3274daeeDaniel Veillard valuePush(ctxt, xmlXPathNewFloat((double) i)); 5927fe70332f7f29f146a364c73450729a8b3274daeeDaniel Veillard } 5928fe70332f7f29f146a364c73450729a8b3274daeeDaniel Veillard } 59293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(cur); 59303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 59313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 59323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 5933ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathGetElementsByIds: 5934ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @doc: the document 5935ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @ids: a whitespace separated list of IDs 5936ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 5937ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Selects elements by their unique ID. 5938ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 5939ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns a node-set of selected elements. 5940ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */ 5941ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillardstatic xmlNodeSetPtr 5942ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathGetElementsByIds (xmlDocPtr doc, const xmlChar *ids) { 5943ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlNodeSetPtr ret; 5944ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard const xmlChar *cur = ids; 5945ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlChar *ID; 5946ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlAttrPtr attr; 5947ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlNodePtr elem = NULL; 5948ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 59497a985a18c2fee0aa9b490792dd990b75506e3740Daniel Veillard if (ids == NULL) return(NULL); 59507a985a18c2fee0aa9b490792dd990b75506e3740Daniel Veillard 5951ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = xmlXPathNodeSetCreate(NULL); 5952ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 5953ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard while (IS_BLANK(*cur)) cur++; 5954ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard while (*cur != 0) { 5955e209b330558d170da195acb3a7618b0048d22c9eDaniel Veillard while ((!IS_BLANK(*cur)) && (*cur != 0)) 5956e209b330558d170da195acb3a7618b0048d22c9eDaniel Veillard cur++; 5957ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 5958ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ID = xmlStrndup(ids, cur - ids); 5959e209b330558d170da195acb3a7618b0048d22c9eDaniel Veillard if (ID != NULL) { 5960e209b330558d170da195acb3a7618b0048d22c9eDaniel Veillard if (xmlValidateNCName(ID, 1) == 0) { 5961e209b330558d170da195acb3a7618b0048d22c9eDaniel Veillard attr = xmlGetID(doc, ID); 5962e209b330558d170da195acb3a7618b0048d22c9eDaniel Veillard if (attr != NULL) { 5963e209b330558d170da195acb3a7618b0048d22c9eDaniel Veillard if (attr->type == XML_ATTRIBUTE_NODE) 5964e209b330558d170da195acb3a7618b0048d22c9eDaniel Veillard elem = attr->parent; 5965e209b330558d170da195acb3a7618b0048d22c9eDaniel Veillard else if (attr->type == XML_ELEMENT_NODE) 5966e209b330558d170da195acb3a7618b0048d22c9eDaniel Veillard elem = (xmlNodePtr) attr; 5967e209b330558d170da195acb3a7618b0048d22c9eDaniel Veillard else 5968e209b330558d170da195acb3a7618b0048d22c9eDaniel Veillard elem = NULL; 5969e209b330558d170da195acb3a7618b0048d22c9eDaniel Veillard if (elem != NULL) 5970e209b330558d170da195acb3a7618b0048d22c9eDaniel Veillard xmlXPathNodeSetAdd(ret, elem); 5971e209b330558d170da195acb3a7618b0048d22c9eDaniel Veillard } 5972e209b330558d170da195acb3a7618b0048d22c9eDaniel Veillard } 5973ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlFree(ID); 5974e209b330558d170da195acb3a7618b0048d22c9eDaniel Veillard } 5975ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 5976ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard while (IS_BLANK(*cur)) cur++; 5977ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ids = cur; 5978ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard } 5979ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(ret); 5980ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard} 5981ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 5982ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/** 59833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathIdFunction: 59843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 59853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs: the number of arguments 59863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 59873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the id() XPath function 59883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * node-set id(object) 59893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The id function selects elements by their unique ID 59903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * (see [5.2.1 Unique IDs]). When the argument to id is of type node-set, 59913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * then the result is the union of the result of applying id to the 59923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * string value of each of the nodes in the argument node-set. When the 59933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * argument to id is of any other type, the argument is converted to a 59943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * string as if by a call to the string function; the string is split 59953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * into a whitespace-separated list of tokens (whitespace is any sequence 59963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * of characters matching the production S); the result is a node-set 59973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * containing the elements in the same document as the context node that 59983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * have a unique ID equal to any of the tokens in the list. 59993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 60003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 60013473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathIdFunction(xmlXPathParserContextPtr ctxt, int nargs) { 6002ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlChar *tokens; 6003ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlNodeSetPtr ret; 6004ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlXPathObjectPtr obj; 60053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 60063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ARITY(1); 60073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor obj = valuePop(ctxt); 60083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (obj == NULL) XP_ERROR(XPATH_INVALID_OPERAND); 60090c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack if ((obj->type == XPATH_NODESET) || (obj->type == XPATH_XSLT_TREE)) { 6010ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlNodeSetPtr ns; 60113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int i; 60123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 6013ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = xmlXPathNodeSetCreate(NULL); 60143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 6015911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard if (obj->nodesetval != NULL) { 6016911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard for (i = 0; i < obj->nodesetval->nodeNr; i++) { 6017ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard tokens = 6018ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlXPathCastNodeToString(obj->nodesetval->nodeTab[i]); 6019ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ns = xmlXPathGetElementsByIds(ctxt->context->doc, tokens); 6020ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = xmlXPathNodeSetMerge(ret, ns); 6021ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlXPathFreeNodeSet(ns); 6022ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard if (tokens != NULL) 6023ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlFree(tokens); 6024911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard } 60253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 60263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 60273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(obj); 6028ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard valuePush(ctxt, xmlXPathWrapNodeSet(ret)); 60293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return; 60303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 6031ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard obj = xmlXPathConvertString(obj); 60323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 6033ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = xmlXPathGetElementsByIds(ctxt->context->doc, obj->stringval); 6034ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard valuePush(ctxt, xmlXPathWrapNodeSet(ret)); 60353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 60363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(obj); 60373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return; 60383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 60393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 60403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 60413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathLocalNameFunction: 60423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 60433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs: the number of arguments 60443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 60453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the local-name() XPath function 60463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * string local-name(node-set?) 60473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The local-name function returns a string containing the local part 60483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * of the name of the node in the argument node-set that is first in 60493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * document order. If the node-set is empty or the first node has no 60503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * name, an empty string is returned. If the argument is omitted it 60513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * defaults to the context node. 60523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 60533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 60543473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathLocalNameFunction(xmlXPathParserContextPtr ctxt, int nargs) { 60553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr cur; 60563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 60573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (nargs == 0) { 60583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, xmlXPathNewNodeSet(ctxt->context->node)); 60593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor nargs = 1; 60603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 60613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 60623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ARITY(1); 60633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((ctxt->value == NULL) || 60643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ((ctxt->value->type != XPATH_NODESET) && 60653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor (ctxt->value->type != XPATH_XSLT_TREE))) 60663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XP_ERROR(XPATH_INVALID_TYPE); 60673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur = valuePop(ctxt); 60683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 6069911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard if ((cur->nodesetval == NULL) || (cur->nodesetval->nodeNr == 0)) { 60703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, xmlXPathNewCString("")); 60713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else { 60723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int i = 0; /* Should be first in document order !!!!! */ 60733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor switch (cur->nodesetval->nodeTab[i]->type) { 60743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ELEMENT_NODE: 60753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ATTRIBUTE_NODE: 60763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_PI_NODE: 6077652d8a949447833405cc0805f4b7ff1179e59ed2Daniel Veillard if (cur->nodesetval->nodeTab[i]->name[0] == ' ') 6078652d8a949447833405cc0805f4b7ff1179e59ed2Daniel Veillard valuePush(ctxt, xmlXPathNewCString("")); 6079652d8a949447833405cc0805f4b7ff1179e59ed2Daniel Veillard else 6080652d8a949447833405cc0805f4b7ff1179e59ed2Daniel Veillard valuePush(ctxt, 60813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathNewString(cur->nodesetval->nodeTab[i]->name)); 60823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 60833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_NAMESPACE_DECL: 60843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, xmlXPathNewString( 60853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ((xmlNsPtr)cur->nodesetval->nodeTab[i])->prefix)); 60863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 60873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor default: 60883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, xmlXPathNewCString("")); 60893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 60903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 60913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(cur); 60923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 60933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 60943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 60953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNamespaceURIFunction: 60963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 60973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs: the number of arguments 60983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 60993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the namespace-uri() XPath function 61003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * string namespace-uri(node-set?) 61013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The namespace-uri function returns a string containing the 61023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * namespace URI of the expanded name of the node in the argument 61033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * node-set that is first in document order. If the node-set is empty, 61043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the first node has no name, or the expanded name has no namespace 61053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * URI, an empty string is returned. If the argument is omitted it 61063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * defaults to the context node. 61073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 61083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 61093473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNamespaceURIFunction(xmlXPathParserContextPtr ctxt, int nargs) { 61103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr cur; 61113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 61123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (nargs == 0) { 61133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, xmlXPathNewNodeSet(ctxt->context->node)); 61143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor nargs = 1; 61153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 61163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ARITY(1); 61173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((ctxt->value == NULL) || 61183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ((ctxt->value->type != XPATH_NODESET) && 61193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor (ctxt->value->type != XPATH_XSLT_TREE))) 61203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XP_ERROR(XPATH_INVALID_TYPE); 61213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur = valuePop(ctxt); 61223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 6123911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard if ((cur->nodesetval == NULL) || (cur->nodesetval->nodeNr == 0)) { 61243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, xmlXPathNewCString("")); 61253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else { 61263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int i = 0; /* Should be first in document order !!!!! */ 61273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor switch (cur->nodesetval->nodeTab[i]->type) { 61283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ELEMENT_NODE: 61293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ATTRIBUTE_NODE: 61303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur->nodesetval->nodeTab[i]->ns == NULL) 61313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, xmlXPathNewCString("")); 61323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else 61333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, xmlXPathNewString( 61343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur->nodesetval->nodeTab[i]->ns->href)); 61353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 61363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor default: 61373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, xmlXPathNewCString("")); 61383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 61393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 61403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(cur); 61413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 61423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 61433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 61443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNameFunction: 61453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 61463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs: the number of arguments 61473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 61483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the name() XPath function 61493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * string name(node-set?) 61503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The name function returns a string containing a QName representing 6151cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * the name of the node in the argument node-set that is first in document 61523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * order. The QName must represent the name with respect to the namespace 61533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * declarations in effect on the node whose name is being represented. 61543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Typically, this will be the form in which the name occurred in the XML 61553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * source. This need not be the case if there are namespace declarations 61563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * in effect on the node that associate multiple prefixes with the same 61573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * namespace. However, an implementation may include information about 61583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the original prefix in its representation of nodes; in this case, an 61593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * implementation can ensure that the returned string is always the same 61603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * as the QName used in the XML source. If the argument it omitted it 61613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * defaults to the context node. 61623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Libxml keep the original prefix so the "real qualified name" used is 61633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * returned. 61643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 616556a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic void 61660438375d2e6be47d0179826271081ae64df94f8bDaniel VeillardxmlXPathNameFunction(xmlXPathParserContextPtr ctxt, int nargs) 61670438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard{ 61683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr cur; 61693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 61703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (nargs == 0) { 61710438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard valuePush(ctxt, xmlXPathNewNodeSet(ctxt->context->node)); 61720438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard nargs = 1; 61733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 61743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 61753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ARITY(1); 61760438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard if ((ctxt->value == NULL) || 61770438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard ((ctxt->value->type != XPATH_NODESET) && 61780438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard (ctxt->value->type != XPATH_XSLT_TREE))) 61790438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard XP_ERROR(XPATH_INVALID_TYPE); 61803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur = valuePop(ctxt); 61813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 6182911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard if ((cur->nodesetval == NULL) || (cur->nodesetval->nodeNr == 0)) { 61830438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard valuePush(ctxt, xmlXPathNewCString("")); 61843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else { 61850438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard int i = 0; /* Should be first in document order !!!!! */ 61863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 61870438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard switch (cur->nodesetval->nodeTab[i]->type) { 61880438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard case XML_ELEMENT_NODE: 61890438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard case XML_ATTRIBUTE_NODE: 6190652d8a949447833405cc0805f4b7ff1179e59ed2Daniel Veillard if (cur->nodesetval->nodeTab[i]->name[0] == ' ') 6191652d8a949447833405cc0805f4b7ff1179e59ed2Daniel Veillard valuePush(ctxt, xmlXPathNewCString("")); 6192652d8a949447833405cc0805f4b7ff1179e59ed2Daniel Veillard else if ((cur->nodesetval->nodeTab[i]->ns == NULL) || 6193652d8a949447833405cc0805f4b7ff1179e59ed2Daniel Veillard (cur->nodesetval->nodeTab[i]->ns->prefix == NULL)) { 61940438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard valuePush(ctxt, 6195c00cda8c065beba24706c9e8719f08e9de420274Daniel Veillard xmlXPathNewString(cur->nodesetval->nodeTab[i]->name)); 61960438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard 6197652d8a949447833405cc0805f4b7ff1179e59ed2Daniel Veillard } else { 6198c00cda8c065beba24706c9e8719f08e9de420274Daniel Veillard xmlChar *fullname; 6199c00cda8c065beba24706c9e8719f08e9de420274Daniel Veillard 6200c00cda8c065beba24706c9e8719f08e9de420274Daniel Veillard fullname = xmlBuildQName(cur->nodesetval->nodeTab[i]->name, 6201c00cda8c065beba24706c9e8719f08e9de420274Daniel Veillard cur->nodesetval->nodeTab[i]->ns->prefix, 6202c00cda8c065beba24706c9e8719f08e9de420274Daniel Veillard NULL, 0); 6203c00cda8c065beba24706c9e8719f08e9de420274Daniel Veillard if (fullname == cur->nodesetval->nodeTab[i]->name) 6204c00cda8c065beba24706c9e8719f08e9de420274Daniel Veillard fullname = xmlStrdup(cur->nodesetval->nodeTab[i]->name); 6205c00cda8c065beba24706c9e8719f08e9de420274Daniel Veillard if (fullname == NULL) { 6206c00cda8c065beba24706c9e8719f08e9de420274Daniel Veillard XP_ERROR(XPATH_MEMORY_ERROR); 6207c00cda8c065beba24706c9e8719f08e9de420274Daniel Veillard } 6208c00cda8c065beba24706c9e8719f08e9de420274Daniel Veillard valuePush(ctxt, xmlXPathWrapString(fullname)); 62090438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard } 62100438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard break; 62110438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard default: 62120438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard valuePush(ctxt, 62130438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard xmlXPathNewNodeSet(cur->nodesetval->nodeTab[i])); 62140438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard xmlXPathLocalNameFunction(ctxt, 1); 62150438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard } 62163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 62173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(cur); 62183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 62193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 6220fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard 6221fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard/** 62223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathStringFunction: 62233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 62243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs: the number of arguments 62253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 62263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the string() XPath function 62273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * string string(object?) 62283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * he string function converts an object to a string as follows: 62293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * - A node-set is converted to a string by returning the value of 62303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the node in the node-set that is first in document order. 62313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * If the node-set is empty, an empty string is returned. 62323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * - A number is converted to a string as follows 62333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * + NaN is converted to the string NaN 62343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * + positive zero is converted to the string 0 62353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * + negative zero is converted to the string 0 62363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * + positive infinity is converted to the string Infinity 62373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * + negative infinity is converted to the string -Infinity 62383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * + if the number is an integer, the number is represented in 62393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * decimal form as a Number with no decimal point and no leading 62403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * zeros, preceded by a minus sign (-) if the number is negative 62413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * + otherwise, the number is represented in decimal form as a 62423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Number including a decimal point with at least one digit 62433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * before the decimal point and at least one digit after the 62443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * decimal point, preceded by a minus sign (-) if the number 62453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * is negative; there must be no leading zeros before the decimal 6246cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * point apart possibly from the one required digit immediately 62473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * before the decimal point; beyond the one required digit 62483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * after the decimal point there must be as many, but only as 62493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * many, more digits as are needed to uniquely distinguish the 62503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * number from all other IEEE 754 numeric values. 62513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * - The boolean false value is converted to the string false. 62523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The boolean true value is converted to the string true. 62533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 62543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * If the argument is omitted, it defaults to a node-set with the 62553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * context node as its only member. 62563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 62573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 62583473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathStringFunction(xmlXPathParserContextPtr ctxt, int nargs) { 62593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr cur; 62603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 62613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (nargs == 0) { 6262ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard valuePush(ctxt, 6263ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlXPathWrapString( 6264ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlXPathCastNodeToString(ctxt->context->node))); 6265ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return; 62663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 62673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 62683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ARITY(1); 62693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur = valuePop(ctxt); 62703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == NULL) XP_ERROR(XPATH_INVALID_OPERAND); 6271fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard cur = xmlXPathConvertString(cur); 6272fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard valuePush(ctxt, cur); 62733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 62743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 62753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 62763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathStringLengthFunction: 62773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 62783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs: the number of arguments 62793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 62803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the string-length() XPath function 62813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * number string-length(string?) 62823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The string-length returns the number of characters in the string 62833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * (see [3.6 Strings]). If the argument is omitted, it defaults to 62843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the context node converted to a string, in other words the value 62853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * of the context node. 62863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 62873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 62883473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathStringLengthFunction(xmlXPathParserContextPtr ctxt, int nargs) { 62893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr cur; 62903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 62913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (nargs == 0) { 62923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->context->node == NULL) { 62933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, xmlXPathNewFloat(0)); 62943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else { 62953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlChar *content; 62963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 6297ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard content = xmlXPathCastNodeToString(ctxt->context->node); 6298e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard valuePush(ctxt, xmlXPathNewFloat(xmlUTF8Strlen(content))); 62993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(content); 63003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 63013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return; 63023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 63033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ARITY(1); 63043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CAST_TO_STRING; 63053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_TYPE(XPATH_STRING); 63063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur = valuePop(ctxt); 6307e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard valuePush(ctxt, xmlXPathNewFloat(xmlUTF8Strlen(cur->stringval))); 63083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(cur); 63093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 63103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 63113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 63123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathConcatFunction: 63133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 63143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs: the number of arguments 63153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 63163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the concat() XPath function 63173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * string concat(string, string, string*) 63183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The concat function returns the concatenation of its arguments. 63193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 63203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 63213473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathConcatFunction(xmlXPathParserContextPtr ctxt, int nargs) { 63223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr cur, newobj; 63233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlChar *tmp; 63243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 63253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (nargs < 2) { 63263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ARITY(2); 63273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 63283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 63293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CAST_TO_STRING; 63303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur = valuePop(ctxt); 63313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((cur == NULL) || (cur->type != XPATH_STRING)) { 63323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(cur); 63333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return; 63343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 63353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor nargs--; 63363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 63373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while (nargs > 0) { 63383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CAST_TO_STRING; 63393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor newobj = valuePop(ctxt); 63403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((newobj == NULL) || (newobj->type != XPATH_STRING)) { 63413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(newobj); 63423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(cur); 63433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XP_ERROR(XPATH_INVALID_TYPE); 63443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 63453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor tmp = xmlStrcat(newobj->stringval, cur->stringval); 63463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor newobj->stringval = cur->stringval; 63473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur->stringval = tmp; 63483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 63493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(newobj); 63503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor nargs--; 63513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 63523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, cur); 63533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 63543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 63553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 63563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathContainsFunction: 63573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 63583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs: the number of arguments 63593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 63603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the contains() XPath function 63613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * boolean contains(string, string) 63623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The contains function returns true if the first argument string 63633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * contains the second argument string, and otherwise returns false. 63643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 63653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 63663473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathContainsFunction(xmlXPathParserContextPtr ctxt, int nargs) { 63673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr hay, needle; 63683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 63693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ARITY(2); 63703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CAST_TO_STRING; 63713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_TYPE(XPATH_STRING); 63723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor needle = valuePop(ctxt); 63733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CAST_TO_STRING; 63743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor hay = valuePop(ctxt); 63753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((hay == NULL) || (hay->type != XPATH_STRING)) { 63763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(hay); 63773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(needle); 63783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XP_ERROR(XPATH_INVALID_TYPE); 63793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 63803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (xmlStrstr(hay->stringval, needle->stringval)) 63813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, xmlXPathNewBoolean(1)); 63823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else 63833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, xmlXPathNewBoolean(0)); 63843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(hay); 63853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(needle); 63863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 63873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 63883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 63893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathStartsWithFunction: 63903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 63913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs: the number of arguments 63923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 63933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the starts-with() XPath function 63943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * boolean starts-with(string, string) 63953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The starts-with function returns true if the first argument string 63963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * starts with the second argument string, and otherwise returns false. 63973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 63983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 63993473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathStartsWithFunction(xmlXPathParserContextPtr ctxt, int nargs) { 64003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr hay, needle; 64013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int n; 64023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 64033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ARITY(2); 64043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CAST_TO_STRING; 64053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_TYPE(XPATH_STRING); 64063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor needle = valuePop(ctxt); 64073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CAST_TO_STRING; 64083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor hay = valuePop(ctxt); 64093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((hay == NULL) || (hay->type != XPATH_STRING)) { 64103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(hay); 64113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(needle); 64123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XP_ERROR(XPATH_INVALID_TYPE); 64133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 64143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor n = xmlStrlen(needle->stringval); 64153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (xmlStrncmp(hay->stringval, needle->stringval, n)) 64163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, xmlXPathNewBoolean(0)); 64173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else 64183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, xmlXPathNewBoolean(1)); 64193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(hay); 64203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(needle); 64213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 64223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 64233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 64243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathSubstringFunction: 64253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 64263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs: the number of arguments 64273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 64283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the substring() XPath function 64293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * string substring(string, number, number?) 64303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The substring function returns the substring of the first argument 64313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * starting at the position specified in the second argument with 64323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * length specified in the third argument. For example, 64333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * substring("12345",2,3) returns "234". If the third argument is not 64343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * specified, it returns the substring starting at the position specified 64353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * in the second argument and continuing to the end of the string. For 64363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * example, substring("12345",2) returns "2345". More precisely, each 64373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * character in the string (see [3.6 Strings]) is considered to have a 64383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * numeric position: the position of the first character is 1, the position 64393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * of the second character is 2 and so on. The returned substring contains 64403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * those characters for which the position of the character is greater than 64413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * or equal to the second argument and, if the third argument is specified, 64423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * less than the sum of the second and third arguments; the comparisons 64433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * and addition used for the above follow the standard IEEE 754 rules. Thus: 64443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * - substring("12345", 1.5, 2.6) returns "234" 64453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * - substring("12345", 0, 3) returns "12" 64463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * - substring("12345", 0 div 0, 3) returns "" 64473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * - substring("12345", 1, 0 div 0) returns "" 64483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * - substring("12345", -42, 1 div 0) returns "12345" 64493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * - substring("12345", -1 div 0, 1 div 0) returns "" 64503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 64513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 64523473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathSubstringFunction(xmlXPathParserContextPtr ctxt, int nargs) { 64533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr str, start, len; 645497ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard double le=0, in; 645597ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard int i, l, m; 64563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlChar *ret; 64573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 64583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (nargs < 2) { 64593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ARITY(2); 64603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 64613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (nargs > 3) { 64623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ARITY(3); 64633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 646497ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard /* 646597ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard * take care of possible last (position) argument 646697ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard */ 64673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (nargs == 3) { 64683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CAST_TO_NUMBER; 64693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_TYPE(XPATH_NUMBER); 64703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor len = valuePop(ctxt); 64713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor le = len->floatval; 64723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(len); 64733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 647497ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard 64753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CAST_TO_NUMBER; 64763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_TYPE(XPATH_NUMBER); 64773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor start = valuePop(ctxt); 64783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor in = start->floatval; 64793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(start); 64803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CAST_TO_STRING; 64813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_TYPE(XPATH_STRING); 64823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor str = valuePop(ctxt); 648397ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard m = xmlUTF8Strlen((const unsigned char *)str->stringval); 648497ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard 648597ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard /* 648697ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard * If last pos not present, calculate last position 648797ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard */ 64889e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard if (nargs != 3) { 64899e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard le = (double)m; 64909e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard if (in < 1.0) 64919e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard in = 1.0; 64929e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard } 649397ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard 64940eafdef9881c396ce4c014359d8f497cc088cfabDaniel Veillard /* Need to check for the special cases where either 64950eafdef9881c396ce4c014359d8f497cc088cfabDaniel Veillard * the index is NaN, the length is NaN, or both 64960eafdef9881c396ce4c014359d8f497cc088cfabDaniel Veillard * arguments are infinity (relying on Inf + -Inf = NaN) 649797ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard */ 64989e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard if (!xmlXPathIsNaN(in + le) && !xmlXPathIsInf(in)) { 64990eafdef9881c396ce4c014359d8f497cc088cfabDaniel Veillard /* 65009e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard * To meet the requirements of the spec, the arguments 65019e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard * must be converted to integer format before 65029e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard * initial index calculations are done 65030eafdef9881c396ce4c014359d8f497cc088cfabDaniel Veillard * 65049e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard * First we go to integer form, rounding up 65059e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard * and checking for special cases 65060eafdef9881c396ce4c014359d8f497cc088cfabDaniel Veillard */ 65070eafdef9881c396ce4c014359d8f497cc088cfabDaniel Veillard i = (int) in; 65089e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard if (((double)i)+0.5 <= in) i++; 65099e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard 65109e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard if (xmlXPathIsInf(le) == 1) { 65119e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard l = m; 65129e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard if (i < 1) 65139e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard i = 1; 65149e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard } 65159e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard else if (xmlXPathIsInf(le) == -1 || le < 0.0) 65169e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard l = 0; 65179e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard else { 65189e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard l = (int) le; 65199e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard if (((double)l)+0.5 <= le) l++; 65209e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard } 65210eafdef9881c396ce4c014359d8f497cc088cfabDaniel Veillard 65229e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard /* Now we normalize inidices */ 65239e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard i -= 1; 65249e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard l += i; 65259e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard if (i < 0) 65269e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard i = 0; 65279e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard if (l > m) 65289e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard l = m; 65293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 65300eafdef9881c396ce4c014359d8f497cc088cfabDaniel Veillard /* number of chars to copy */ 65310eafdef9881c396ce4c014359d8f497cc088cfabDaniel Veillard l -= i; 65323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 65330eafdef9881c396ce4c014359d8f497cc088cfabDaniel Veillard ret = xmlUTF8Strsub(str->stringval, i, l); 65340eafdef9881c396ce4c014359d8f497cc088cfabDaniel Veillard } 65350eafdef9881c396ce4c014359d8f497cc088cfabDaniel Veillard else { 65360eafdef9881c396ce4c014359d8f497cc088cfabDaniel Veillard ret = NULL; 65370eafdef9881c396ce4c014359d8f497cc088cfabDaniel Veillard } 65383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 65393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ret == NULL) 65403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, xmlXPathNewCString("")); 65413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else { 65423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, xmlXPathNewString(ret)); 65433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(ret); 65443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 654597ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard 65463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(str); 65473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 65483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 65493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 65503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathSubstringBeforeFunction: 65513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 65523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs: the number of arguments 65533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 65543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the substring-before() XPath function 65553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * string substring-before(string, string) 65563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The substring-before function returns the substring of the first 65573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * argument string that precedes the first occurrence of the second 65583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * argument string in the first argument string, or the empty string 65593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * if the first argument string does not contain the second argument 65603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * string. For example, substring-before("1999/04/01","/") returns 1999. 65613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 65623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 65633473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathSubstringBeforeFunction(xmlXPathParserContextPtr ctxt, int nargs) { 65643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr str; 65653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr find; 65663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlBufferPtr target; 65673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor const xmlChar *point; 65683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int offset; 65693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 65703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ARITY(2); 65713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CAST_TO_STRING; 65723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor find = valuePop(ctxt); 65733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CAST_TO_STRING; 65743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor str = valuePop(ctxt); 65753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 65763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor target = xmlBufferCreate(); 65773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (target) { 65783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor point = xmlStrstr(str->stringval, find->stringval); 65793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (point) { 65803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor offset = (int)(point - str->stringval); 65813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlBufferAdd(target, str->stringval, offset); 65823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 65833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, xmlXPathNewString(xmlBufferContent(target))); 65843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlBufferFree(target); 65853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 65863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 65873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(str); 65883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(find); 65893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 65903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 65913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 65923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathSubstringAfterFunction: 65933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 65943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs: the number of arguments 65953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 65963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the substring-after() XPath function 65973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * string substring-after(string, string) 65983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The substring-after function returns the substring of the first 65993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * argument string that follows the first occurrence of the second 66003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * argument string in the first argument string, or the empty stringi 66013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * if the first argument string does not contain the second argument 66023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * string. For example, substring-after("1999/04/01","/") returns 04/01, 66033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * and substring-after("1999/04/01","19") returns 99/04/01. 66043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 66053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 66063473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathSubstringAfterFunction(xmlXPathParserContextPtr ctxt, int nargs) { 66073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr str; 66083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr find; 66093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlBufferPtr target; 66103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor const xmlChar *point; 66113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int offset; 66123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 66133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ARITY(2); 66143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CAST_TO_STRING; 66153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor find = valuePop(ctxt); 66163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CAST_TO_STRING; 66173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor str = valuePop(ctxt); 66183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 66193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor target = xmlBufferCreate(); 66203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (target) { 66213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor point = xmlStrstr(str->stringval, find->stringval); 66223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (point) { 66233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor offset = (int)(point - str->stringval) + xmlStrlen(find->stringval); 66243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlBufferAdd(target, &str->stringval[offset], 66253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlStrlen(str->stringval) - offset); 66263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 66273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, xmlXPathNewString(xmlBufferContent(target))); 66283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlBufferFree(target); 66293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 66303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 66313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(str); 66323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(find); 66333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 66343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 66353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 66363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNormalizeFunction: 66373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 66383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs: the number of arguments 66393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 66403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the normalize-space() XPath function 66413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * string normalize-space(string?) 66423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The normalize-space function returns the argument string with white 66433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * space normalized by stripping leading and trailing whitespace 66443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * and replacing sequences of whitespace characters by a single 66453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * space. Whitespace characters are the same allowed by the S production 66463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * in XML. If the argument is omitted, it defaults to the context 66473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * node converted to a string, in other words the value of the context node. 66483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 66493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 66503473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNormalizeFunction(xmlXPathParserContextPtr ctxt, int nargs) { 66513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr obj = NULL; 66523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlChar *source = NULL; 66533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlBufferPtr target; 66543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlChar blank; 66553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 66563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (nargs == 0) { 66573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* Use current context node */ 6658ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard valuePush(ctxt, 6659ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlXPathWrapString( 6660ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlXPathCastNodeToString(ctxt->context->node))); 66613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor nargs = 1; 66623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 66633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 66643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ARITY(1); 66653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CAST_TO_STRING; 66663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_TYPE(XPATH_STRING); 66673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor obj = valuePop(ctxt); 66683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor source = obj->stringval; 66693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 66703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor target = xmlBufferCreate(); 66713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (target && source) { 66723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 66733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* Skip leading whitespaces */ 66743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while (IS_BLANK(*source)) 66753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor source++; 66763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 66773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* Collapse intermediate whitespaces, and skip trailing whitespaces */ 66783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor blank = 0; 66793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while (*source) { 66803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (IS_BLANK(*source)) { 668197ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard blank = 0x20; 66823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else { 66833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (blank) { 66843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlBufferAdd(target, &blank, 1); 66853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor blank = 0; 66863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 66873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlBufferAdd(target, source, 1); 66883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 66893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor source++; 66903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 66913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 66923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, xmlXPathNewString(xmlBufferContent(target))); 66933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlBufferFree(target); 66943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 66953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(obj); 66963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 66973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 66983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 66993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathTranslateFunction: 67003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 67013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs: the number of arguments 67023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 67033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the translate() XPath function 67043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * string translate(string, string, string) 67053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The translate function returns the first argument string with 67063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * occurrences of characters in the second argument string replaced 67073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * by the character at the corresponding position in the third argument 67083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * string. For example, translate("bar","abc","ABC") returns the string 67093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * BAr. If there is a character in the second argument string with no 67103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * character at a corresponding position in the third argument string 67113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * (because the second argument string is longer than the third argument 67123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * string), then occurrences of that character in the first argument 67133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * string are removed. For example, translate("--aaa--","abc-","ABC") 67143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * returns "AAA". If a character occurs more than once in second 67153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * argument string, then the first occurrence determines the replacement 67163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * character. If the third argument string is longer than the second 67173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * argument string, then excess characters are ignored. 67183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 67193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 67203473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathTranslateFunction(xmlXPathParserContextPtr ctxt, int nargs) { 6721e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard xmlXPathObjectPtr str; 6722e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard xmlXPathObjectPtr from; 6723e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard xmlXPathObjectPtr to; 6724e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard xmlBufferPtr target; 672597ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard int offset, max; 6726e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard xmlChar ch; 672797ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard xmlChar *point; 672897ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard xmlChar *cptr; 67293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 6730e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard CHECK_ARITY(3); 67313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 6732e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard CAST_TO_STRING; 6733e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard to = valuePop(ctxt); 6734e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard CAST_TO_STRING; 6735e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard from = valuePop(ctxt); 6736e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard CAST_TO_STRING; 6737e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard str = valuePop(ctxt); 67383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 6739e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard target = xmlBufferCreate(); 6740e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard if (target) { 674197ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard max = xmlUTF8Strlen(to->stringval); 674297ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard for (cptr = str->stringval; (ch=*cptr); ) { 674397ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard offset = xmlUTF8Strloc(from->stringval, cptr); 674497ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard if (offset >= 0) { 674597ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard if (offset < max) { 674697ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard point = xmlUTF8Strpos(to->stringval, offset); 674797ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard if (point) 674897ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard xmlBufferAdd(target, point, xmlUTF8Strsize(point, 1)); 674997ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard } 675097ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard } else 675197ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard xmlBufferAdd(target, cptr, xmlUTF8Strsize(cptr, 1)); 675297ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard 675397ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard /* Step to next character in input */ 675497ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard cptr++; 675597ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard if ( ch & 0x80 ) { 675697ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard /* if not simple ascii, verify proper format */ 675797ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard if ( (ch & 0xc0) != 0xc0 ) { 675897ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard xmlGenericError(xmlGenericErrorContext, 675997ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard "xmlXPathTranslateFunction: Invalid UTF8 string\n"); 676097ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard break; 676197ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard } 676297ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard /* then skip over remaining bytes for this char */ 676397ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard while ( (ch <<= 1) & 0x80 ) 676497ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard if ( (*cptr++ & 0xc0) != 0x80 ) { 676597ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard xmlGenericError(xmlGenericErrorContext, 676697ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard "xmlXPathTranslateFunction: Invalid UTF8 string\n"); 676797ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard break; 676897ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard } 676997ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard if (ch & 0x80) /* must have had error encountered */ 677097ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard break; 677197ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard } 6772e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard } 67733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 6774e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard valuePush(ctxt, xmlXPathNewString(xmlBufferContent(target))); 6775e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard xmlBufferFree(target); 6776e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard xmlXPathFreeObject(str); 6777e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard xmlXPathFreeObject(from); 6778e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard xmlXPathFreeObject(to); 67793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 67803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 67813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 6782fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * xmlXPathBooleanFunction: 6783fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * @ctxt: the XPath Parser context 6784fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * @nargs: the number of arguments 6785fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * 6786fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * Implement the boolean() XPath function 6787fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * boolean boolean(object) 6788fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * he boolean function converts its argument to a boolean as follows: 6789fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * - a number is true if and only if it is neither positive or 6790fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * negative zero nor NaN 6791fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * - a node-set is true if and only if it is non-empty 6792fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * - a string is true if and only if its length is non-zero 6793fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard */ 6794fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillardvoid 6795fbf8a2d0c8145b713099df63d174154a8442e60dDaniel VeillardxmlXPathBooleanFunction(xmlXPathParserContextPtr ctxt, int nargs) { 6796fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard xmlXPathObjectPtr cur; 6797fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard 6798fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard CHECK_ARITY(1); 6799fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard cur = valuePop(ctxt); 6800fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard if (cur == NULL) XP_ERROR(XPATH_INVALID_OPERAND); 6801fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard cur = xmlXPathConvertBoolean(cur); 6802fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard valuePush(ctxt, cur); 68033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 68043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 68053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 68063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNotFunction: 68073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 68083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs: the number of arguments 68093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 68103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the not() XPath function 68113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * boolean not(boolean) 68123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The not function returns true if its argument is false, 68133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * and false otherwise. 68143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 68153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 68163473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNotFunction(xmlXPathParserContextPtr ctxt, int nargs) { 68173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ARITY(1); 68183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CAST_TO_BOOLEAN; 68193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_TYPE(XPATH_BOOLEAN); 68203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ctxt->value->boolval = ! ctxt->value->boolval; 68213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 68223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 68233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 68243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathTrueFunction: 68253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 68263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs: the number of arguments 68273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 68283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the true() XPath function 68293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * boolean true() 68303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 68313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 68323473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathTrueFunction(xmlXPathParserContextPtr ctxt, int nargs) { 68333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ARITY(0); 68343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, xmlXPathNewBoolean(1)); 68353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 68363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 68373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 68383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathFalseFunction: 68393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 68403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs: the number of arguments 68413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 68423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the false() XPath function 68433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * boolean false() 68443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 68453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 68463473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathFalseFunction(xmlXPathParserContextPtr ctxt, int nargs) { 68473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ARITY(0); 68483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, xmlXPathNewBoolean(0)); 68493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 68503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 68513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 68523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathLangFunction: 68533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 68543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs: the number of arguments 68553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 68563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the lang() XPath function 68573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * boolean lang(string) 68583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The lang function returns true or false depending on whether the 68593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * language of the context node as specified by xml:lang attributes 68603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * is the same as or is a sublanguage of the language specified by 68613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the argument string. The language of the context node is determined 68623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * by the value of the xml:lang attribute on the context node, or, if 68633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the context node has no xml:lang attribute, by the value of the 68643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xml:lang attribute on the nearest ancestor of the context node that 68653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * has an xml:lang attribute. If there is no such attribute, then lang 68663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * returns false. If there is such an attribute, then lang returns 68673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * true if the attribute value is equal to the argument ignoring case, 68683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * or if there is some suffix starting with - such that the attribute 68693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * value is equal to the argument ignoring that suffix of the attribute 68703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * value and ignoring case. 68713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 68723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 68733473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathLangFunction(xmlXPathParserContextPtr ctxt, int nargs) { 68743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr val; 68753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor const xmlChar *theLang; 68763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor const xmlChar *lang; 68773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int ret = 0; 68783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int i; 68793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 68803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ARITY(1); 68813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CAST_TO_STRING; 68823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_TYPE(XPATH_STRING); 68833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor val = valuePop(ctxt); 68843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor lang = val->stringval; 68853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor theLang = xmlNodeGetLang(ctxt->context->node); 68863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((theLang != NULL) && (lang != NULL)) { 68873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor for (i = 0;lang[i] != 0;i++) 68883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (toupper(lang[i]) != toupper(theLang[i])) 68893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor goto not_equal; 68903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = 1; 68913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 68923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylornot_equal: 68933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(val); 68943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, xmlXPathNewBoolean(ret)); 68953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 68963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 68973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 68983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNumberFunction: 68993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 69003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs: the number of arguments 69013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 69023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the number() XPath function 69033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * number number(object?) 69043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 69053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 69063473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNumberFunction(xmlXPathParserContextPtr ctxt, int nargs) { 69073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr cur; 69083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor double res; 69093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 69103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (nargs == 0) { 69113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->context->node == NULL) { 69123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, xmlXPathNewFloat(0.0)); 69133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else { 69143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlChar* content = xmlNodeGetContent(ctxt->context->node); 69153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 69163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor res = xmlXPathStringEvalNumber(content); 69173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, xmlXPathNewFloat(res)); 69183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(content); 69193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 69203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return; 69213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 69223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 69233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ARITY(1); 69243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur = valuePop(ctxt); 6925fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard cur = xmlXPathConvertNumber(cur); 6926fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard valuePush(ctxt, cur); 69273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 69283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 69293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 69303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathSumFunction: 69313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 69323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs: the number of arguments 69333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 69343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the sum() XPath function 69353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * number sum(node-set) 69363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The sum function returns the sum of the values of the nodes in 69373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the argument node-set. 69383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 69393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 69403473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathSumFunction(xmlXPathParserContextPtr ctxt, int nargs) { 69413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr cur; 69423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int i; 6943ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard double res = 0.0; 69443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 69453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ARITY(1); 69463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((ctxt->value == NULL) || 69473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ((ctxt->value->type != XPATH_NODESET) && 69483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor (ctxt->value->type != XPATH_XSLT_TREE))) 69493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XP_ERROR(XPATH_INVALID_TYPE); 69503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur = valuePop(ctxt); 69513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 6952d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard if ((cur->nodesetval == NULL) || (cur->nodesetval->nodeNr == 0)) { 69533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, xmlXPathNewFloat(0.0)); 69543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else { 6955ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard for (i = 0; i < cur->nodesetval->nodeNr; i++) { 6956ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard res += xmlXPathCastNodeToNumber(cur->nodesetval->nodeTab[i]); 69573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 6958ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard valuePush(ctxt, xmlXPathNewFloat(res)); 69593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 69603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(cur); 69613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 69623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 69633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 69643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathFloorFunction: 69653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 69663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs: the number of arguments 69673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 69683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the floor() XPath function 69693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * number floor(number) 69703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The floor function returns the largest (closest to positive infinity) 69713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * number that is not greater than the argument and that is an integer. 69723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 69733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 69743473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathFloorFunction(xmlXPathParserContextPtr ctxt, int nargs) { 697556cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard double f; 697656cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard 69773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ARITY(1); 69783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CAST_TO_NUMBER; 69793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_TYPE(XPATH_NUMBER); 698056cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard 698156cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard f = (double)((int) ctxt->value->floatval); 698256cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard if (f != ctxt->value->floatval) { 698356cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard if (ctxt->value->floatval > 0) 698456cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard ctxt->value->floatval = f; 698556cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard else 698656cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard ctxt->value->floatval = f - 1; 698756cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard } 69883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 69893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 69903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 69913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathCeilingFunction: 69923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 69933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs: the number of arguments 69943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 69953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the ceiling() XPath function 69963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * number ceiling(number) 69973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The ceiling function returns the smallest (closest to negative infinity) 69983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * number that is not less than the argument and that is an integer. 69993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 70003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 70013473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathCeilingFunction(xmlXPathParserContextPtr ctxt, int nargs) { 70023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor double f; 70033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 70043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ARITY(1); 70053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CAST_TO_NUMBER; 70063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_TYPE(XPATH_NUMBER); 70073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 70083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#if 0 70093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ctxt->value->floatval = ceil(ctxt->value->floatval); 70103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#else 70113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor f = (double)((int) ctxt->value->floatval); 701256cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard if (f != ctxt->value->floatval) { 701356cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard if (ctxt->value->floatval > 0) 701456cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard ctxt->value->floatval = f + 1; 70155fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard else { 70165fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard if (ctxt->value->floatval < 0 && f == 0) 70175fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard ctxt->value->floatval = xmlXPathNZERO; 70185fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard else 70195fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard ctxt->value->floatval = f; 70205fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard } 70215fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard 702256cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard } 70233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 70243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 70253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 70263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 70273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathRoundFunction: 70283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 70293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs: the number of arguments 70303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 70313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the round() XPath function 70323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * number round(number) 70333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The round function returns the number that is closest to the 70343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * argument and that is an integer. If there are two such numbers, 70353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * then the one that is even is returned. 70363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 70373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 70383473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathRoundFunction(xmlXPathParserContextPtr ctxt, int nargs) { 70393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor double f; 70403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 70413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ARITY(1); 70423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CAST_TO_NUMBER; 70433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_TYPE(XPATH_NUMBER); 70443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 7045cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard if ((xmlXPathIsNaN(ctxt->value->floatval)) || 7046cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard (xmlXPathIsInf(ctxt->value->floatval) == 1) || 7047cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard (xmlXPathIsInf(ctxt->value->floatval) == -1) || 70483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor (ctxt->value->floatval == 0.0)) 70493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return; 70503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 70513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor f = (double)((int) ctxt->value->floatval); 705256cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard if (ctxt->value->floatval < 0) { 705356cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard if (ctxt->value->floatval < f - 0.5) 705456cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard ctxt->value->floatval = f - 1; 705556cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard else 705656cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard ctxt->value->floatval = f; 70575fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard if (ctxt->value->floatval == 0) 70585fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard ctxt->value->floatval = xmlXPathNZERO; 705956cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard } else { 706056cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard if (ctxt->value->floatval < f + 0.5) 706156cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard ctxt->value->floatval = f; 706256cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard else 706356cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard ctxt->value->floatval = f + 1; 706456cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard } 70653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 70663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 70673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/************************************************************************ 70683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * * 70693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The Parser * 70703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * * 70713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ************************************************************************/ 70723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 70733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/* 70743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * a couple of forward declarations since we use a recursive call based 70753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * implementation. 70763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 7077afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void xmlXPathCompileExpr(xmlXPathParserContextPtr ctxt); 7078d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillardstatic void xmlXPathCompPredicate(xmlXPathParserContextPtr ctxt, int filter); 7079afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void xmlXPathCompLocationPath(xmlXPathParserContextPtr ctxt); 7080afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void xmlXPathCompRelativeLocationPath(xmlXPathParserContextPtr ctxt); 70812156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillardstatic xmlChar * xmlXPathParseNameComplex(xmlXPathParserContextPtr ctxt, 70822156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard int qualified); 70833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 70843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 708561d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard * xmlXPathCurrentChar: 708661d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard * @ctxt: the XPath parser context 708761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard * @cur: pointer to the beginning of the char 708861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard * @len: pointer to the length of the char read 708961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard * 7090cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * The current char value, if using UTF-8 this may actually span multiple 709161d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard * bytes in the input buffer. 709261d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard * 709360087f30f3b4cf21de48f39181736e7d71e7a661Daniel Veillard * Returns the current char value and its length 709461d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard */ 709561d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard 709661d80a2822b2678dee885ac2850295cc96277c63Daniel Veillardstatic int 709761d80a2822b2678dee885ac2850295cc96277c63Daniel VeillardxmlXPathCurrentChar(xmlXPathParserContextPtr ctxt, int *len) { 709861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard unsigned char c; 709961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard unsigned int val; 710061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard const xmlChar *cur; 710161d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard 710261d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard if (ctxt == NULL) 710361d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard return(0); 710461d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard cur = ctxt->cur; 710561d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard 710661d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard /* 710761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard * We are supposed to handle UTF8, check it's valid 710861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard * From rfc2044: encoding of the Unicode values on UTF-8: 710961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard * 711061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard * UCS-4 range (hex.) UTF-8 octet sequence (binary) 711161d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard * 0000 0000-0000 007F 0xxxxxxx 711261d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard * 0000 0080-0000 07FF 110xxxxx 10xxxxxx 711361d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard * 0000 0800-0000 FFFF 1110xxxx 10xxxxxx 10xxxxxx 711461d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard * 711561d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard * Check for the 0x110000 limit too 711661d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard */ 711761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard c = *cur; 711861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard if (c & 0x80) { 711961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard if ((cur[1] & 0xc0) != 0x80) 712061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard goto encoding_error; 712161d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard if ((c & 0xe0) == 0xe0) { 712261d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard 712361d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard if ((cur[2] & 0xc0) != 0x80) 712461d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard goto encoding_error; 712561d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard if ((c & 0xf0) == 0xf0) { 712661d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard if (((c & 0xf8) != 0xf0) || 712761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard ((cur[3] & 0xc0) != 0x80)) 712861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard goto encoding_error; 712961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard /* 4-byte code */ 713061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard *len = 4; 713161d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard val = (cur[0] & 0x7) << 18; 713261d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard val |= (cur[1] & 0x3f) << 12; 713361d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard val |= (cur[2] & 0x3f) << 6; 713461d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard val |= cur[3] & 0x3f; 713561d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard } else { 713661d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard /* 3-byte code */ 713761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard *len = 3; 713861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard val = (cur[0] & 0xf) << 12; 713961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard val |= (cur[1] & 0x3f) << 6; 714061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard val |= cur[2] & 0x3f; 714161d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard } 714261d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard } else { 714361d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard /* 2-byte code */ 714461d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard *len = 2; 714561d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard val = (cur[0] & 0x1f) << 6; 714661d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard val |= cur[1] & 0x3f; 714761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard } 714861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard if (!IS_CHAR(val)) { 714961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard XP_ERROR0(XPATH_INVALID_CHAR_ERROR); 715061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard } 715161d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard return(val); 715261d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard } else { 715361d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard /* 1-byte code */ 715461d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard *len = 1; 715561d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard return((int) *cur); 715661d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard } 715761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillardencoding_error: 715861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard /* 715961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard * If we detect an UTF8 error that probably mean that the 716061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard * input encoding didn't get properly advertized in the 716161d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard * declaration header. Report the error and switch the encoding 716261d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard * to ISO-Latin-1 (if you don't like this policy, just declare the 716361d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard * encoding !) 716461d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard */ 716542596ad20cdf1925dd79ea801cbe598b6e7b7aecDaniel Veillard *len = 0; 716661d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard XP_ERROR0(XPATH_ENCODING_ERROR); 716761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard} 716861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard 716961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard/** 71703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathParseNCName: 71713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 71723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 71733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * parse an XML namespace non qualified name. 71743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 71753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [NS 3] NCName ::= (Letter | '_') (NCNameChar)* 71763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 71773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [NS 4] NCNameChar ::= Letter | Digit | '.' | '-' | '_' | 71783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * CombiningChar | Extender 71793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 71803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the namespace name or NULL 71813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 71823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 71833473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlChar * 71843473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathParseNCName(xmlXPathParserContextPtr ctxt) { 71852156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard const xmlChar *in; 71862156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard xmlChar *ret; 71872156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard int count = 0; 71883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 71892156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard /* 71902156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard * Accelerator for simple ASCII names 71912156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard */ 71922156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard in = ctxt->cur; 71932156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard if (((*in >= 0x61) && (*in <= 0x7A)) || 71942156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard ((*in >= 0x41) && (*in <= 0x5A)) || 71952156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard (*in == '_')) { 71962156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard in++; 71972156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard while (((*in >= 0x61) && (*in <= 0x7A)) || 71982156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard ((*in >= 0x41) && (*in <= 0x5A)) || 71992156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard ((*in >= 0x30) && (*in <= 0x39)) || 72009a89a8ab80bc021deec9da7d79bda20995c4e78dDaniel Veillard (*in == '_') || (*in == '.') || 72019a89a8ab80bc021deec9da7d79bda20995c4e78dDaniel Veillard (*in == '-')) 72022156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard in++; 72032156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard if ((*in == ' ') || (*in == '>') || (*in == '/') || 72042156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard (*in == '[') || (*in == ']') || (*in == ':') || 72052156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard (*in == '@') || (*in == '*')) { 72062156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard count = in - ctxt->cur; 72072156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard if (count == 0) 72082156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard return(NULL); 72092156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard ret = xmlStrndup(ctxt->cur, count); 72102156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard ctxt->cur = in; 72112156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard return(ret); 72122156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard } 72132156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard } 72142156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard return(xmlXPathParseNameComplex(ctxt, 0)); 72153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 72163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 72172156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard 72183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 72193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathParseQName: 72203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 72213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @prefix: a xmlChar ** 72223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 72233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * parse an XML qualified name 72243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 72253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [NS 5] QName ::= (Prefix ':')? LocalPart 72263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 72273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [NS 6] Prefix ::= NCName 72283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 72293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [NS 7] LocalPart ::= NCName 72303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 72313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the function returns the local part, and prefix is updated 72323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * to get the Prefix if any. 72333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 72343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 723556a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic xmlChar * 72363473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathParseQName(xmlXPathParserContextPtr ctxt, xmlChar **prefix) { 72373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlChar *ret = NULL; 72383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 72393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *prefix = NULL; 72403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = xmlXPathParseNCName(ctxt); 72413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (CUR == ':') { 72423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *prefix = ret; 72433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 72443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = xmlXPathParseNCName(ctxt); 72453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 72463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ret); 72473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 72483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 72493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 72503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathParseName: 72513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 72523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 72533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * parse an XML name 72543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 72553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [4] NameChar ::= Letter | Digit | '.' | '-' | '_' | ':' | 72563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * CombiningChar | Extender 72573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 72583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [5] Name ::= (Letter | '_' | ':') (NameChar)* 72593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 72603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the namespace name or NULL 72613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 72623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 72633473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlChar * 72643473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathParseName(xmlXPathParserContextPtr ctxt) { 726561d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard const xmlChar *in; 726661d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard xmlChar *ret; 726761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard int count = 0; 72683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 726961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard /* 727061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard * Accelerator for simple ASCII names 727161d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard */ 727261d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard in = ctxt->cur; 727361d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard if (((*in >= 0x61) && (*in <= 0x7A)) || 727461d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard ((*in >= 0x41) && (*in <= 0x5A)) || 727561d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard (*in == '_') || (*in == ':')) { 727661d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard in++; 727761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard while (((*in >= 0x61) && (*in <= 0x7A)) || 727861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard ((*in >= 0x41) && (*in <= 0x5A)) || 727961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard ((*in >= 0x30) && (*in <= 0x39)) || 728076d66f416d2d0d5db4a09d212b4e43087e9cdae7Daniel Veillard (*in == '_') || (*in == '-') || 728176d66f416d2d0d5db4a09d212b4e43087e9cdae7Daniel Veillard (*in == ':') || (*in == '.')) 728261d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard in++; 728376d66f416d2d0d5db4a09d212b4e43087e9cdae7Daniel Veillard if ((*in > 0) && (*in < 0x80)) { 728461d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard count = in - ctxt->cur; 728561d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard ret = xmlStrndup(ctxt->cur, count); 728661d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard ctxt->cur = in; 728761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard return(ret); 728861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard } 728961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard } 72902156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard return(xmlXPathParseNameComplex(ctxt, 1)); 729161d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard} 72923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 729361d80a2822b2678dee885ac2850295cc96277c63Daniel Veillardstatic xmlChar * 72942156a56bcbf5d83fb3d694123be01beebf84d273Daniel VeillardxmlXPathParseNameComplex(xmlXPathParserContextPtr ctxt, int qualified) { 729561d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard xmlChar buf[XML_MAX_NAMELEN + 5]; 729661d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard int len = 0, l; 729761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard int c; 72983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 729961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard /* 730061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard * Handler for more complex cases 730161d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard */ 730261d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard c = CUR_CHAR(l); 730361d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard if ((c == ' ') || (c == '>') || (c == '/') || /* accelerators */ 73042156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard (c == '[') || (c == ']') || (c == '@') || /* accelerators */ 73052156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard (c == '*') || /* accelerators */ 730661d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard (!IS_LETTER(c) && (c != '_') && 73072156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard ((qualified) && (c != ':')))) { 730861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard return(NULL); 730961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard } 73103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 731161d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard while ((c != ' ') && (c != '>') && (c != '/') && /* test bigname.xml */ 731261d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard ((IS_LETTER(c)) || (IS_DIGIT(c)) || 731361d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard (c == '.') || (c == '-') || 73142156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard (c == '_') || ((qualified) && (c == ':')) || 731561d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard (IS_COMBINING(c)) || 731661d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard (IS_EXTENDER(c)))) { 731761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard COPY_BUF(l,buf,len,c); 731861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard NEXTL(l); 731961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard c = CUR_CHAR(l); 732061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard if (len >= XML_MAX_NAMELEN) { 732161d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard /* 732261d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard * Okay someone managed to make a huge name, so he's ready to pay 732361d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard * for the processing speed. 732461d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard */ 732561d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard xmlChar *buffer; 732661d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard int max = len * 2; 732761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard 73283c908dca479ed50dca24b8593bca90e40dbde6b8Daniel Veillard buffer = (xmlChar *) xmlMallocAtomic(max * sizeof(xmlChar)); 732961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard if (buffer == NULL) { 733061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard XP_ERROR0(XPATH_MEMORY_ERROR); 733161d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard } 733261d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard memcpy(buffer, buf, len); 733361d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard while ((IS_LETTER(c)) || (IS_DIGIT(c)) || /* test bigname.xml */ 733461d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard (c == '.') || (c == '-') || 73352156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard (c == '_') || ((qualified) && (c == ':')) || 733661d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard (IS_COMBINING(c)) || 733761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard (IS_EXTENDER(c))) { 733861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard if (len + 10 > max) { 733961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard max *= 2; 734061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard buffer = (xmlChar *) xmlRealloc(buffer, 734161d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard max * sizeof(xmlChar)); 734261d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard if (buffer == NULL) { 734361d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard XP_ERROR0(XPATH_MEMORY_ERROR); 734461d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard } 734561d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard } 734661d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard COPY_BUF(l,buffer,len,c); 734761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard NEXTL(l); 734861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard c = CUR_CHAR(l); 734961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard } 735061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard buffer[len] = 0; 735161d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard return(buffer); 735261d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard } 735361d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard } 73542156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard if (len == 0) 73552156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard return(NULL); 735661d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard return(xmlStrndup(buf, len)); 735761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard} 73583cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard 73593cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard#define MAX_FRAC 20 73603cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard 73613cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillardstatic double my_pow10[MAX_FRAC] = { 73623cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard 1.0, 10.0, 100.0, 1000.0, 10000.0, 73633cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard 100000.0, 1000000.0, 10000000.0, 100000000.0, 1000000000.0, 73643cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard 10000000000.0, 100000000000.0, 1000000000000.0, 10000000000000.0, 73653cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard 100000000000000.0, 73663cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard 1000000000000000.0, 10000000000000000.0, 100000000000000000.0, 73673cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard 1000000000000000000.0, 10000000000000000000.0 73683cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard}; 73693cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard 73703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 73713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathStringEvalNumber: 73723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @str: A string to scan 73733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 737470a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese * [30a] Float ::= Number ('e' Digits?)? 737570a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese * 73763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [30] Number ::= Digits ('.' Digits?)? 73773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | '.' Digits 73783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [31] Digits ::= [0-9]+ 73793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 7380afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile a Number in the string 73813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * In complement of the Number expression, this function also handles 73823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * negative values : '-' Number. 73833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 73843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the double value. 73853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 73863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylordouble 73873473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathStringEvalNumber(const xmlChar *str) { 73883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor const xmlChar *cur = str; 73897b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard double ret; 7390b06c61455f86758511aa050a06ff1bbd33f8c3c3Daniel Veillard int ok = 0; 73913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int isneg = 0; 739270a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese int exponent = 0; 739370a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese int is_exponent_negative = 0; 7394b06c61455f86758511aa050a06ff1bbd33f8c3c3Daniel Veillard#ifdef __GNUC__ 7395b06c61455f86758511aa050a06ff1bbd33f8c3c3Daniel Veillard unsigned long tmp = 0; 73967b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard double temp; 7397b06c61455f86758511aa050a06ff1bbd33f8c3c3Daniel Veillard#endif 7398eca82810f0fb81f3e9936d2018347e1e19de513aDaniel Veillard if (cur == NULL) return(0); 73993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while (IS_BLANK(*cur)) cur++; 74003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((*cur != '.') && ((*cur < '0') || (*cur > '9')) && (*cur != '-')) { 74013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(xmlXPathNAN); 74023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 74033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (*cur == '-') { 74043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor isneg = 1; 74053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur++; 74063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 7407b06c61455f86758511aa050a06ff1bbd33f8c3c3Daniel Veillard 7408b06c61455f86758511aa050a06ff1bbd33f8c3c3Daniel Veillard#ifdef __GNUC__ 7409d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard /* 74107b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard * tmp/temp is a workaround against a gcc compiler bug 74117b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard * http://veillard.com/gcc.bug 7412d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard */ 74137b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard ret = 0; 74143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while ((*cur >= '0') && (*cur <= '9')) { 74157b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard ret = ret * 10; 74167b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard tmp = (*cur - '0'); 74173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ok = 1; 74183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur++; 74197b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard temp = (double) tmp; 74207b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard ret = ret + temp; 74213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 7422b06c61455f86758511aa050a06ff1bbd33f8c3c3Daniel Veillard#else 74237b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard ret = 0; 7424b06c61455f86758511aa050a06ff1bbd33f8c3c3Daniel Veillard while ((*cur >= '0') && (*cur <= '9')) { 7425b06c61455f86758511aa050a06ff1bbd33f8c3c3Daniel Veillard ret = ret * 10 + (*cur - '0'); 7426b06c61455f86758511aa050a06ff1bbd33f8c3c3Daniel Veillard ok = 1; 7427b06c61455f86758511aa050a06ff1bbd33f8c3c3Daniel Veillard cur++; 7428b06c61455f86758511aa050a06ff1bbd33f8c3c3Daniel Veillard } 7429b06c61455f86758511aa050a06ff1bbd33f8c3c3Daniel Veillard#endif 7430d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard 74313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (*cur == '.') { 74323cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard int v, frac = 0; 74333cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard double fraction = 0; 74343cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard 74353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur++; 74363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (((*cur < '0') || (*cur > '9')) && (!ok)) { 74373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(xmlXPathNAN); 74383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 74393cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard while (((*cur >= '0') && (*cur <= '9')) && (frac < MAX_FRAC)) { 74403cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard v = (*cur - '0'); 74413cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard fraction = fraction * 10 + v; 74423cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard frac = frac + 1; 74433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur++; 74443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 74453cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard fraction /= my_pow10[frac]; 74463cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard ret = ret + fraction; 74473cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard while ((*cur >= '0') && (*cur <= '9')) 74483cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard cur++; 74493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 745070a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese if ((*cur == 'e') || (*cur == 'E')) { 745170a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese cur++; 745270a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese if (*cur == '-') { 745370a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese is_exponent_negative = 1; 745470a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese cur++; 745570a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese } 745670a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese while ((*cur >= '0') && (*cur <= '9')) { 745770a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese exponent = exponent * 10 + (*cur - '0'); 745870a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese cur++; 745970a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese } 746070a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese } 74613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while (IS_BLANK(*cur)) cur++; 74623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (*cur != 0) return(xmlXPathNAN); 74633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (isneg) ret = -ret; 746470a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese if (is_exponent_negative) exponent = -exponent; 746570a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese ret *= pow(10.0, (double)exponent); 74663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ret); 74673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 74683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 74693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 7470afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompNumber: 74713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 74723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 74733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [30] Number ::= Digits ('.' Digits?)? 74743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | '.' Digits 74753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [31] Digits ::= [0-9]+ 74763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 7477afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile a Number, then push it on the stack 74783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 74793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 7480afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void 7481d79bcd1b36412a7996ace1900ab613e38a609b60Daniel VeillardxmlXPathCompNumber(xmlXPathParserContextPtr ctxt) 7482d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard{ 74833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor double ret = 0.0; 74843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor double mult = 1; 74857b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard int ok = 0; 748670a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese int exponent = 0; 748770a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese int is_exponent_negative = 0; 74887b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard#ifdef __GNUC__ 74897b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard unsigned long tmp = 0; 74907b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard double temp; 74917b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard#endif 74923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 74933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ERROR; 74943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((CUR != '.') && ((CUR < '0') || (CUR > '9'))) { 74953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XP_ERROR(XPATH_NUMBER_ERROR); 74963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 74977b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard#ifdef __GNUC__ 7498d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard /* 74997b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard * tmp/temp is a workaround against a gcc compiler bug 75007b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard * http://veillard.com/gcc.bug 7501d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard */ 75027b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard ret = 0; 75033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while ((CUR >= '0') && (CUR <= '9')) { 75047b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard ret = ret * 10; 75057b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard tmp = (CUR - '0'); 7506d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard ok = 1; 7507d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard NEXT; 75087b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard temp = (double) tmp; 75097b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard ret = ret + temp; 75103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 75117b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard#else 75127b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard ret = 0; 75137b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard while ((CUR >= '0') && (CUR <= '9')) { 75147b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard ret = ret * 10 + (CUR - '0'); 75157b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard ok = 1; 75167b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard NEXT; 75177b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard } 75187b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard#endif 75193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (CUR == '.') { 75203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 7521d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard if (((CUR < '0') || (CUR > '9')) && (!ok)) { 7522d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard XP_ERROR(XPATH_NUMBER_ERROR); 7523d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard } 7524d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard while ((CUR >= '0') && (CUR <= '9')) { 7525d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard mult /= 10; 7526d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard ret = ret + (CUR - '0') * mult; 7527d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard NEXT; 7528d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard } 75293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 753070a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese if ((CUR == 'e') || (CUR == 'E')) { 7531d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard NEXT; 7532d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard if (CUR == '-') { 7533d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard is_exponent_negative = 1; 7534d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard NEXT; 7535d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard } 7536d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard while ((CUR >= '0') && (CUR <= '9')) { 7537d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard exponent = exponent * 10 + (CUR - '0'); 7538d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard NEXT; 7539d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard } 7540d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard if (is_exponent_negative) 7541d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard exponent = -exponent; 7542d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard ret *= pow(10.0, (double) exponent); 754370a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese } 75449e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard PUSH_LONG_EXPR(XPATH_OP_VALUE, XPATH_NUMBER, 0, 0, 7545d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard xmlXPathNewFloat(ret), NULL); 75463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 75473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 75483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 7549fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * xmlXPathParseLiteral: 7550fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * @ctxt: the XPath Parser context 7551fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * 7552fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * Parse a Literal 7553fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * 7554fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * [29] Literal ::= '"' [^"]* '"' 7555fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * | "'" [^']* "'" 7556fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * 7557fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * Returns the value found or NULL in case of error 7558fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard */ 7559fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillardstatic xmlChar * 7560fbf8a2d0c8145b713099df63d174154a8442e60dDaniel VeillardxmlXPathParseLiteral(xmlXPathParserContextPtr ctxt) { 7561fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard const xmlChar *q; 7562fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard xmlChar *ret = NULL; 7563fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard 7564fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard if (CUR == '"') { 7565fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard NEXT; 7566fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard q = CUR_PTR; 756734ba38793669da505d735e76794253b23dec447cDaniel Veillard while ((IS_CHAR((unsigned int) CUR)) && (CUR != '"')) 7568fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard NEXT; 756934ba38793669da505d735e76794253b23dec447cDaniel Veillard if (!IS_CHAR((unsigned int) CUR)) { 7570fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard XP_ERROR0(XPATH_UNFINISHED_LITERAL_ERROR); 7571fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard } else { 7572fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard ret = xmlStrndup(q, CUR_PTR - q); 7573fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard NEXT; 7574fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard } 7575fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard } else if (CUR == '\'') { 7576fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard NEXT; 7577fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard q = CUR_PTR; 757834ba38793669da505d735e76794253b23dec447cDaniel Veillard while ((IS_CHAR((unsigned int) CUR)) && (CUR != '\'')) 7579fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard NEXT; 758034ba38793669da505d735e76794253b23dec447cDaniel Veillard if (!IS_CHAR((unsigned int) CUR)) { 7581fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard XP_ERROR0(XPATH_UNFINISHED_LITERAL_ERROR); 7582fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard } else { 7583fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard ret = xmlStrndup(q, CUR_PTR - q); 7584fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard NEXT; 7585fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard } 7586fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard } else { 7587fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard XP_ERROR0(XPATH_START_LITERAL_ERROR); 7588fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard } 7589fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard return(ret); 7590fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard} 7591fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard 7592fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard/** 7593afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompLiteral: 75943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 75953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 75963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Parse a Literal and push it on the stack. 75973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 75983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [29] Literal ::= '"' [^"]* '"' 75993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | "'" [^']* "'" 76003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 7601afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * TODO: xmlXPathCompLiteral memory allocation could be improved. 76023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 7603afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void 7604afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompLiteral(xmlXPathParserContextPtr ctxt) { 76053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor const xmlChar *q; 76063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlChar *ret = NULL; 76073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 76083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (CUR == '"') { 76093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 76103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor q = CUR_PTR; 761134ba38793669da505d735e76794253b23dec447cDaniel Veillard while ((IS_CHAR((unsigned int) CUR)) && (CUR != '"')) 76123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 761334ba38793669da505d735e76794253b23dec447cDaniel Veillard if (!IS_CHAR((unsigned int) CUR)) { 76143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XP_ERROR(XPATH_UNFINISHED_LITERAL_ERROR); 76153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else { 76163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = xmlStrndup(q, CUR_PTR - q); 76173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 76183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 76193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else if (CUR == '\'') { 76203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 76213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor q = CUR_PTR; 762234ba38793669da505d735e76794253b23dec447cDaniel Veillard while ((IS_CHAR((unsigned int) CUR)) && (CUR != '\'')) 76233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 762434ba38793669da505d735e76794253b23dec447cDaniel Veillard if (!IS_CHAR((unsigned int) CUR)) { 76253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XP_ERROR(XPATH_UNFINISHED_LITERAL_ERROR); 76263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else { 76273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = xmlStrndup(q, CUR_PTR - q); 76283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 76293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 76303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else { 76313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XP_ERROR(XPATH_START_LITERAL_ERROR); 76323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 76333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ret == NULL) return; 76349e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard PUSH_LONG_EXPR(XPATH_OP_VALUE, XPATH_STRING, 0, 0, 76359e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlXPathNewString(ret), NULL); 76363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(ret); 76373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 76383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 76393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 7640afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompVariableReference: 76413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 76423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 76433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Parse a VariableReference, evaluate it and push it on the stack. 76443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 76453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The variable bindings consist of a mapping from variable names 76463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * to variable values. The value of a variable is an object, which 76473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * of any of the types that are possible for the value of an expression, 76483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * and may also be of additional types not specified here. 76493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 76503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Early evaluation is possible since: 76513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The variable bindings [...] used to evaluate a subexpression are 76523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * always the same as those used to evaluate the containing expression. 76533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 76543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [36] VariableReference ::= '$' QName 76553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 7656afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void 7657afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompVariableReference(xmlXPathParserContextPtr ctxt) { 76583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlChar *name; 76593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlChar *prefix; 76603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 76613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 76623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (CUR != '$') { 76633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XP_ERROR(XPATH_VARIABLE_REF_ERROR); 76643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 76653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 76663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor name = xmlXPathParseQName(ctxt, &prefix); 76673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (name == NULL) { 76683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XP_ERROR(XPATH_VARIABLE_REF_ERROR); 76693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 7670fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard ctxt->comp->last = -1; 76719e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard PUSH_LONG_EXPR(XPATH_OP_VARIABLE, 0, 0, 0, 76729e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard name, prefix); 76733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 76743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 76753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 76763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 76773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathIsNodeType: 76783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @name: a name string 76793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 76803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Is the name given a NodeType one. 76813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 76823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [38] NodeType ::= 'comment' 76833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | 'text' 76843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | 'processing-instruction' 76853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | 'node' 76863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 76873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns 1 if true 0 otherwise 76883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 76893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorint 76903473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathIsNodeType(const xmlChar *name) { 76913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (name == NULL) 76923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(0); 76933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 76941971ee2698cb84c7699c96d3302f00e20d42c0d3Daniel Veillard if (xmlStrEqual(name, BAD_CAST "node")) 76953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(1); 76963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (xmlStrEqual(name, BAD_CAST "text")) 76973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(1); 76981971ee2698cb84c7699c96d3302f00e20d42c0d3Daniel Veillard if (xmlStrEqual(name, BAD_CAST "comment")) 76993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(1); 77001971ee2698cb84c7699c96d3302f00e20d42c0d3Daniel Veillard if (xmlStrEqual(name, BAD_CAST "processing-instruction")) 77013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(1); 77023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(0); 77033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 77043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 77053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 7706afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompFunctionCall: 77073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 77083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 77093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [16] FunctionCall ::= FunctionName '(' ( Argument ( ',' Argument)*)? ')' 77103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [17] Argument ::= Expr 77113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 7712afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile a function call, the evaluation of all arguments are 77133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * pushed on the stack 77143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 7715afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void 7716afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompFunctionCall(xmlXPathParserContextPtr ctxt) { 77173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlChar *name; 77183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlChar *prefix; 77193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int nbargs = 0; 77203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 77213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor name = xmlXPathParseQName(ctxt, &prefix); 77223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (name == NULL) { 77233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XP_ERROR(XPATH_EXPR_ERROR); 77243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 77253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 77263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_EXPR 77273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (prefix == NULL) 77283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, "Calling function %s\n", 77293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor name); 77303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else 77313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, "Calling function %s:%s\n", 77323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor prefix, name); 77333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 77343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 77353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (CUR != '(') { 77363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XP_ERROR(XPATH_EXPR_ERROR); 77373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 77383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 77393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 77403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 77419e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard ctxt->comp->last = -1; 774271f9d7310c1f8c587f518ec685b1448160df7336Daniel Veillard if (CUR != ')') { 774371f9d7310c1f8c587f518ec685b1448160df7336Daniel Veillard while (CUR != 0) { 774471f9d7310c1f8c587f518ec685b1448160df7336Daniel Veillard int op1 = ctxt->comp->last; 774571f9d7310c1f8c587f518ec685b1448160df7336Daniel Veillard ctxt->comp->last = -1; 774671f9d7310c1f8c587f518ec685b1448160df7336Daniel Veillard xmlXPathCompileExpr(ctxt); 774771f9d7310c1f8c587f518ec685b1448160df7336Daniel Veillard CHECK_ERROR; 774871f9d7310c1f8c587f518ec685b1448160df7336Daniel Veillard PUSH_BINARY_EXPR(XPATH_OP_ARG, op1, ctxt->comp->last, 0, 0); 774971f9d7310c1f8c587f518ec685b1448160df7336Daniel Veillard nbargs++; 775071f9d7310c1f8c587f518ec685b1448160df7336Daniel Veillard if (CUR == ')') break; 775171f9d7310c1f8c587f518ec685b1448160df7336Daniel Veillard if (CUR != ',') { 775271f9d7310c1f8c587f518ec685b1448160df7336Daniel Veillard XP_ERROR(XPATH_EXPR_ERROR); 775371f9d7310c1f8c587f518ec685b1448160df7336Daniel Veillard } 775471f9d7310c1f8c587f518ec685b1448160df7336Daniel Veillard NEXT; 775571f9d7310c1f8c587f518ec685b1448160df7336Daniel Veillard SKIP_BLANKS; 77563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 77573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 77589e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard PUSH_LONG_EXPR(XPATH_OP_FUNCTION, nbargs, 0, 0, 77599e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard name, prefix); 77603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 77613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 77623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 77633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 77643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 7765afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompPrimaryExpr: 77663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 77673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 77683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [15] PrimaryExpr ::= VariableReference 77693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | '(' Expr ')' 77703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | Literal 77713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | Number 77723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | FunctionCall 77733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 7774afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile a primary expression. 77753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 7776afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void 7777afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompPrimaryExpr(xmlXPathParserContextPtr ctxt) { 77783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 7779afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard if (CUR == '$') xmlXPathCompVariableReference(ctxt); 77803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else if (CUR == '(') { 77813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 77823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 7783afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompileExpr(ctxt); 778450fe8b1732048003f47b32b009507fe6cdecd39fAleksey Sanin CHECK_ERROR; 77853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (CUR != ')') { 77863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XP_ERROR(XPATH_EXPR_ERROR); 77873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 77883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 77893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 779001917aa1cb20fb33e6fa2b1e0ca2125051e491e0Daniel Veillard } else if (IS_DIGIT(CUR) || (CUR == '.' && IS_DIGIT(NXT(1)))) { 7791afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompNumber(ctxt); 77923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else if ((CUR == '\'') || (CUR == '"')) { 7793afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompLiteral(ctxt); 77943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else { 7795afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompFunctionCall(ctxt); 77963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 77973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 77983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 77993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 78003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 7801afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompFilterExpr: 78023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 78033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 78043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [20] FilterExpr ::= PrimaryExpr 78053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | FilterExpr Predicate 78063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 7807afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile a filter expression. 78083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Square brackets are used to filter expressions in the same way that 78093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * they are used in location paths. It is an error if the expression to 78103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * be filtered does not evaluate to a node-set. The context node list 78113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * used for evaluating the expression in square brackets is the node-set 78123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * to be filtered listed in document order. 78133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 78143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 7815afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void 7816afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompFilterExpr(xmlXPathParserContextPtr ctxt) { 7817afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompPrimaryExpr(ctxt); 78183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ERROR; 78193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 78203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 78213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while (CUR == '[') { 7822d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard xmlXPathCompPredicate(ctxt, 1); 78233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 78243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 78253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 78263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 78273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 78283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 78293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 78303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathScanName: 78313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 78323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 78333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Trickery: parse an XML name but without consuming the input flow 78343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Needed to avoid insanity in the parser state. 78353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 78363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [4] NameChar ::= Letter | Digit | '.' | '-' | '_' | ':' | 78373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * CombiningChar | Extender 78383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 78393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [5] Name ::= (Letter | '_' | ':') (NameChar)* 78403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 78413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [6] Names ::= Name (S Name)* 78423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 78433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the Name parsed or NULL 78443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 78453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 784656a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic xmlChar * 78473473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathScanName(xmlXPathParserContextPtr ctxt) { 78483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlChar buf[XML_MAX_NAMELEN]; 78493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int len = 0; 78503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 78513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 78523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (!IS_LETTER(CUR) && (CUR != '_') && 78533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor (CUR != ':')) { 78543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 78553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 78563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 78573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while ((IS_LETTER(NXT(len))) || (IS_DIGIT(NXT(len))) || 78583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor (NXT(len) == '.') || (NXT(len) == '-') || 78593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor (NXT(len) == '_') || (NXT(len) == ':') || 78603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor (IS_COMBINING(NXT(len))) || 78613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor (IS_EXTENDER(NXT(len)))) { 78623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor buf[len] = NXT(len); 78633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor len++; 78643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (len >= XML_MAX_NAMELEN) { 78653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 78663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "xmlScanName: reached XML_MAX_NAMELEN limit\n"); 78673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while ((IS_LETTER(NXT(len))) || (IS_DIGIT(NXT(len))) || 78683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor (NXT(len) == '.') || (NXT(len) == '-') || 78693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor (NXT(len) == '_') || (NXT(len) == ':') || 78703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor (IS_COMBINING(NXT(len))) || 78713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor (IS_EXTENDER(NXT(len)))) 78723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor len++; 78733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 78743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 78753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 78763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(xmlStrndup(buf, len)); 78773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 78783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 78793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 7880afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompPathExpr: 78813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 78823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 78833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [19] PathExpr ::= LocationPath 78843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | FilterExpr 78853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | FilterExpr '/' RelativeLocationPath 78863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | FilterExpr '//' RelativeLocationPath 78873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 7888afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile a path expression. 78893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The / operator and // operators combine an arbitrary expression 78903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * and a relative location path. It is an error if the expression 78913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * does not evaluate to a node-set. 78923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The / operator does composition in the same way as when / is 78933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * used in a location path. As in location paths, // is short for 78943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * /descendant-or-self::node()/. 78953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 78963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 7897afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void 7898afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompPathExpr(xmlXPathParserContextPtr ctxt) { 78993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int lc = 1; /* Should we branch to LocationPath ? */ 79003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlChar *name = NULL; /* we may have to preparse a name to find out */ 79013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 79023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 79033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((CUR == '$') || (CUR == '(') || (IS_DIGIT(CUR)) || 790401917aa1cb20fb33e6fa2b1e0ca2125051e491e0Daniel Veillard (CUR == '\'') || (CUR == '"') || (CUR == '.' && IS_DIGIT(NXT(1)))) { 79053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor lc = 0; 79063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else if (CUR == '*') { 79073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* relative or absolute location path */ 79083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor lc = 1; 79093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else if (CUR == '/') { 79103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* relative or absolute location path */ 79113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor lc = 1; 79123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else if (CUR == '@') { 79133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* relative abbreviated attribute location path */ 79143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor lc = 1; 79153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else if (CUR == '.') { 79163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* relative abbreviated attribute location path */ 79173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor lc = 1; 79183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else { 79193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 79203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Problem is finding if we have a name here whether it's: 79213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * - a nodetype 79223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * - a function call in which case it's followed by '(' 79233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * - an axis in which case it's followed by ':' 79243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * - a element name 79253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * We do an a priori analysis here rather than having to 79263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * maintain parsed token content through the recursive function 79273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * calls. This looks uglier but makes the code quite easier to 79283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * read/write/debug. 79293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 79303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 79313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor name = xmlXPathScanName(ctxt); 79323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((name != NULL) && (xmlStrstr(name, (xmlChar *) "::") != NULL)) { 79333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_STEP 79343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 79353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "PathExpr: Axis\n"); 79363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 79373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor lc = 1; 79383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(name); 79393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else if (name != NULL) { 79403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int len =xmlStrlen(name); 79413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 79423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 79433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while (NXT(len) != 0) { 79443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (NXT(len) == '/') { 79453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* element name */ 79463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_STEP 79473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 79483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "PathExpr: AbbrRelLocation\n"); 79493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 79503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor lc = 1; 79513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 79523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else if (IS_BLANK(NXT(len))) { 795378637da0ea1c833dfdfad87a9aa5bea14510d08aWilliam M. Brack /* ignore blanks */ 795478637da0ea1c833dfdfad87a9aa5bea14510d08aWilliam M. Brack ; 79553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else if (NXT(len) == ':') { 79563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_STEP 79573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 79583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "PathExpr: AbbrRelLocation\n"); 79593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 79603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor lc = 1; 79613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 79623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else if ((NXT(len) == '(')) { 79633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* Note Type or Function */ 79643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (xmlXPathIsNodeType(name)) { 79653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_STEP 79663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 79673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "PathExpr: Type search\n"); 79683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 79693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor lc = 1; 79703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else { 79713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_STEP 79723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 79733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "PathExpr: function call\n"); 79743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 79753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor lc = 0; 79763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 79773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 79783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else if ((NXT(len) == '[')) { 79793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* element name */ 79803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_STEP 79813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 79823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "PathExpr: AbbrRelLocation\n"); 79833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 79843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor lc = 1; 79853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 79863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else if ((NXT(len) == '<') || (NXT(len) == '>') || 79873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor (NXT(len) == '=')) { 79883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor lc = 1; 79893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 79903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else { 79913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor lc = 1; 79923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 79933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 79943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor len++; 79953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 79963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (NXT(len) == 0) { 79973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_STEP 79983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 79993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "PathExpr: AbbrRelLocation\n"); 80003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 80013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* element name */ 80023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor lc = 1; 80033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 80043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(name); 80053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else { 80063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* make sure all cases are covered explicitely */ 80073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XP_ERROR(XPATH_EXPR_ERROR); 80083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 80093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 80103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 80113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (lc) { 80129e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (CUR == '/') { 80139e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard PUSH_LEAVE_EXPR(XPATH_OP_ROOT, 0, 0); 80149e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } else { 80159e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard PUSH_LEAVE_EXPR(XPATH_OP_NODE, 0, 0); 80163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 8017afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompLocationPath(ctxt); 80183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else { 8019afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompFilterExpr(ctxt); 80203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ERROR; 80213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((CUR == '/') && (NXT(1) == '/')) { 80223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP(2); 80233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 80249e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 80259e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard PUSH_LONG_EXPR(XPATH_OP_COLLECT, AXIS_DESCENDANT_OR_SELF, 80269e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard NODE_TEST_TYPE, NODE_TYPE_NODE, NULL, NULL); 80279e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard PUSH_UNARY_EXPR(XPATH_OP_RESET, ctxt->comp->last, 1, 0); 80289e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 8029afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompRelativeLocationPath(ctxt); 80303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else if (CUR == '/') { 8031afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompRelativeLocationPath(ctxt); 80323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 80333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 80343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 80353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 80363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 80373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 8038afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompUnionExpr: 80393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 80403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 80413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [18] UnionExpr ::= PathExpr 80423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | UnionExpr '|' PathExpr 80433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 8044afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile an union expression. 80453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 80463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 8047afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void 8048afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompUnionExpr(xmlXPathParserContextPtr ctxt) { 8049afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompPathExpr(ctxt); 80503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ERROR; 80513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 80523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while (CUR == '|') { 80539e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard int op1 = ctxt->comp->last; 80549e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard PUSH_LEAVE_EXPR(XPATH_OP_NODE, 0, 0); 80553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 80563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 80573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 8058afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompPathExpr(ctxt); 80593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 80609e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard PUSH_BINARY_EXPR(XPATH_OP_UNION, op1, ctxt->comp->last, 0, 0); 80619e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 80623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 80633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 80643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 80653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 80663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 8067afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompUnaryExpr: 80683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 80693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 80703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [27] UnaryExpr ::= UnionExpr 80713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | '-' UnaryExpr 80723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 8073afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile an unary expression. 80743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 80753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 8076afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void 8077afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompUnaryExpr(xmlXPathParserContextPtr ctxt) { 80783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int minus = 0; 80799e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard int found = 0; 80803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 80813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 808268d7b67ada0941ad7e1d02602f48de4015a67af3Daniel Veillard while (CUR == '-') { 808368d7b67ada0941ad7e1d02602f48de4015a67af3Daniel Veillard minus = 1 - minus; 80849e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard found = 1; 80853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 80863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 80873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 80889e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 8089afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompUnionExpr(ctxt); 80903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ERROR; 80919e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (found) { 80929e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (minus) 80939e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard PUSH_UNARY_EXPR(XPATH_OP_PLUS, ctxt->comp->last, 2, 0); 80949e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard else 80959e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard PUSH_UNARY_EXPR(XPATH_OP_PLUS, ctxt->comp->last, 3, 0); 80963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 80973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 80983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 80993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 8100afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompMultiplicativeExpr: 81013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 81023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 81033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [26] MultiplicativeExpr ::= UnaryExpr 81043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | MultiplicativeExpr MultiplyOperator UnaryExpr 81053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | MultiplicativeExpr 'div' UnaryExpr 81063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | MultiplicativeExpr 'mod' UnaryExpr 81073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [34] MultiplyOperator ::= '*' 81083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 8109afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile an Additive expression. 81103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 81113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 8112afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void 8113afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompMultiplicativeExpr(xmlXPathParserContextPtr ctxt) { 8114afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompUnaryExpr(ctxt); 81153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ERROR; 81163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 81173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while ((CUR == '*') || 81183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ((CUR == 'd') && (NXT(1) == 'i') && (NXT(2) == 'v')) || 81193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ((CUR == 'm') && (NXT(1) == 'o') && (NXT(2) == 'd'))) { 81203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int op = -1; 81219e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard int op1 = ctxt->comp->last; 81223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 81233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (CUR == '*') { 81243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor op = 0; 81253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 81263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else if (CUR == 'd') { 81273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor op = 1; 81283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP(3); 81293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else if (CUR == 'm') { 81303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor op = 2; 81313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP(3); 81323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 81333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 8134afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompUnaryExpr(ctxt); 81353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ERROR; 81369e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard PUSH_BINARY_EXPR(XPATH_OP_MULT, op1, ctxt->comp->last, op, 0); 81373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 81383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 81393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 81403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 81413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 8142afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompAdditiveExpr: 81433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 81443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 81453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [25] AdditiveExpr ::= MultiplicativeExpr 81463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | AdditiveExpr '+' MultiplicativeExpr 81473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | AdditiveExpr '-' MultiplicativeExpr 81483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 8149afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile an Additive expression. 81503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 81513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 8152afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void 8153afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompAdditiveExpr(xmlXPathParserContextPtr ctxt) { 81549e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 8155afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompMultiplicativeExpr(ctxt); 81563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ERROR; 81573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 81583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while ((CUR == '+') || (CUR == '-')) { 81593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int plus; 81609e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard int op1 = ctxt->comp->last; 81613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 81623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (CUR == '+') plus = 1; 81633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else plus = 0; 81643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 81653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 8166afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompMultiplicativeExpr(ctxt); 81673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ERROR; 81689e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard PUSH_BINARY_EXPR(XPATH_OP_PLUS, op1, ctxt->comp->last, plus, 0); 81693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 81703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 81713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 81723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 81733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 8174afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompRelationalExpr: 81753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 81763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 81773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [24] RelationalExpr ::= AdditiveExpr 81783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | RelationalExpr '<' AdditiveExpr 81793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | RelationalExpr '>' AdditiveExpr 81803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | RelationalExpr '<=' AdditiveExpr 81813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | RelationalExpr '>=' AdditiveExpr 81823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 81833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * A <= B > C is allowed ? Answer from James, yes with 81843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * (AdditiveExpr <= AdditiveExpr) > AdditiveExpr 81853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * which is basically what got implemented. 81863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 8187afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile a Relational expression, then push the result 81883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * on the stack 81893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 81903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 8191afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void 8192afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompRelationalExpr(xmlXPathParserContextPtr ctxt) { 8193afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompAdditiveExpr(ctxt); 81943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ERROR; 81953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 81963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while ((CUR == '<') || 81973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor (CUR == '>') || 81983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ((CUR == '<') && (NXT(1) == '=')) || 81993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ((CUR == '>') && (NXT(1) == '='))) { 82009e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard int inf, strict; 82019e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard int op1 = ctxt->comp->last; 82023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 82033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (CUR == '<') inf = 1; 82043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else inf = 0; 82053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (NXT(1) == '=') strict = 0; 82063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else strict = 1; 82073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 82083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (!strict) NEXT; 82093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 8210afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompAdditiveExpr(ctxt); 82113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ERROR; 82129e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard PUSH_BINARY_EXPR(XPATH_OP_CMP, op1, ctxt->comp->last, inf, strict); 82133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 82143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 82153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 82163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 82173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 8218afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompEqualityExpr: 82193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 82203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 82213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [23] EqualityExpr ::= RelationalExpr 82223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | EqualityExpr '=' RelationalExpr 82233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | EqualityExpr '!=' RelationalExpr 82243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 82253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * A != B != C is allowed ? Answer from James, yes with 82263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * (RelationalExpr = RelationalExpr) = RelationalExpr 82273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * (RelationalExpr != RelationalExpr) != RelationalExpr 82283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * which is basically what got implemented. 82293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 8230afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile an Equality expression. 82313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 82323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 8233afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void 8234afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompEqualityExpr(xmlXPathParserContextPtr ctxt) { 8235afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompRelationalExpr(ctxt); 82363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ERROR; 82373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 82383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while ((CUR == '=') || ((CUR == '!') && (NXT(1) == '='))) { 82399e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard int eq; 82409e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard int op1 = ctxt->comp->last; 82413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 82423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (CUR == '=') eq = 1; 82433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else eq = 0; 82443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 82453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (!eq) NEXT; 82463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 8247afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompRelationalExpr(ctxt); 82483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ERROR; 82499e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard PUSH_BINARY_EXPR(XPATH_OP_EQUAL, op1, ctxt->comp->last, eq, 0); 82503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 82513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 82523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 82533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 82543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 8255afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompAndExpr: 82563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 82573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 82583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [22] AndExpr ::= EqualityExpr 82593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | AndExpr 'and' EqualityExpr 82603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 8261afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile an AND expression. 82623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 82633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 8264afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void 8265afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompAndExpr(xmlXPathParserContextPtr ctxt) { 8266afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompEqualityExpr(ctxt); 82673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ERROR; 82683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 82693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while ((CUR == 'a') && (NXT(1) == 'n') && (NXT(2) == 'd')) { 82709e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard int op1 = ctxt->comp->last; 82713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP(3); 82723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 8273afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompEqualityExpr(ctxt); 82743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ERROR; 82759e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard PUSH_BINARY_EXPR(XPATH_OP_AND, op1, ctxt->comp->last, 0, 0); 82763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 82773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 82783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 82793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 82803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 8281591b4be0fe1986b5e71d54c5c063493987ef4285Daniel Veillard * xmlXPathCompileExpr: 82823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 82833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 82843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [14] Expr ::= OrExpr 82853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [21] OrExpr ::= AndExpr 82863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | OrExpr 'or' AndExpr 82873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 8288afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Parse and compile an expression 82893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 8290afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void 8291afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompileExpr(xmlXPathParserContextPtr ctxt) { 8292afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompAndExpr(ctxt); 82933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ERROR; 82943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 82953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while ((CUR == 'o') && (NXT(1) == 'r')) { 82969e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard int op1 = ctxt->comp->last; 82973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP(2); 82983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 8299afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompAndExpr(ctxt); 83003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ERROR; 83019e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard PUSH_BINARY_EXPR(XPATH_OP_OR, op1, ctxt->comp->last, 0, 0); 83029e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard op1 = ctxt->comp->nbStep; 83033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 83043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 83059e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (ctxt->comp->steps[ctxt->comp->last].op != XPATH_OP_VALUE) { 83069e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard /* more ops could be optimized too */ 83079e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard PUSH_UNARY_EXPR(XPATH_OP_SORT, ctxt->comp->last , 0, 0); 83089e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } 83093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 83103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 83113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 8312afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompPredicate: 83133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 8314d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * @filter: act as a filter 83153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 83163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [8] Predicate ::= '[' PredicateExpr ']' 83173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [9] PredicateExpr ::= Expr 83183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 8319afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile a predicate expression 83209e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard */ 8321afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void 8322d8df6c0e8c883e1d618388d266015dda36731440Daniel VeillardxmlXPathCompPredicate(xmlXPathParserContextPtr ctxt, int filter) { 83239e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard int op1 = ctxt->comp->last; 83249e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 83259e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard SKIP_BLANKS; 83269e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (CUR != '[') { 83279e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard XP_ERROR(XPATH_INVALID_PREDICATE_ERROR); 83289e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } 83299e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard NEXT; 83309e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard SKIP_BLANKS; 83319e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 83329e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard ctxt->comp->last = -1; 8333afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompileExpr(ctxt); 83349e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard CHECK_ERROR; 83359e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 83369e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (CUR != ']') { 83379e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard XP_ERROR(XPATH_INVALID_PREDICATE_ERROR); 83389e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } 83399e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 8340d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard if (filter) 8341d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard PUSH_BINARY_EXPR(XPATH_OP_FILTER, op1, ctxt->comp->last, 0, 0); 8342d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard else 8343d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard PUSH_BINARY_EXPR(XPATH_OP_PREDICATE, op1, ctxt->comp->last, 0, 0); 83449e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 83459e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard NEXT; 83469e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard SKIP_BLANKS; 83479e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard} 83489e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 83499e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard/** 8350afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompNodeTest: 83513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 83523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @test: pointer to a xmlXPathTestVal 83533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @type: pointer to a xmlXPathTypeVal 83543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @prefix: placeholder for a possible name prefix 83553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 83563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [7] NodeTest ::= NameTest 83573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | NodeType '(' ')' 83583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | 'processing-instruction' '(' Literal ')' 83593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 83603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [37] NameTest ::= '*' 83613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | NCName ':' '*' 83623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | QName 83633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [38] NodeType ::= 'comment' 83643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | 'text' 83653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | 'processing-instruction' 83663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | 'node' 83673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 83683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the name found and update @test, @type and @prefix appropriately 83693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 837056a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic xmlChar * 8371afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompNodeTest(xmlXPathParserContextPtr ctxt, xmlXPathTestVal *test, 8372afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathTypeVal *type, const xmlChar **prefix, 8373afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlChar *name) { 83743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int blanks; 83753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 83763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((test == NULL) || (type == NULL) || (prefix == NULL)) { 83773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor STRANGE; 83783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 83793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 838078637da0ea1c833dfdfad87a9aa5bea14510d08aWilliam M. Brack *type = (xmlXPathTypeVal) 0; 838178637da0ea1c833dfdfad87a9aa5bea14510d08aWilliam M. Brack *test = (xmlXPathTestVal) 0; 83823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *prefix = NULL; 83833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 83843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 83853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((name == NULL) && (CUR == '*')) { 83863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 83873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * All elements 83883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 83893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 83903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *test = NODE_TEST_ALL; 83913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 83923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 83933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 83943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (name == NULL) 83953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor name = xmlXPathParseNCName(ctxt); 83963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (name == NULL) { 83973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XP_ERROR0(XPATH_EXPR_ERROR); 83983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 83993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 84003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor blanks = IS_BLANK(CUR); 84013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 84023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (CUR == '(') { 84033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 84043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 84053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * NodeType or PI search 84063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 84073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (xmlStrEqual(name, BAD_CAST "comment")) 84083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *type = NODE_TYPE_COMMENT; 84093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else if (xmlStrEqual(name, BAD_CAST "node")) 84103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *type = NODE_TYPE_NODE; 84113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else if (xmlStrEqual(name, BAD_CAST "processing-instruction")) 84123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *type = NODE_TYPE_PI; 84133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else if (xmlStrEqual(name, BAD_CAST "text")) 84143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *type = NODE_TYPE_TEXT; 84153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else { 84163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (name != NULL) 84173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(name); 84183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XP_ERROR0(XPATH_EXPR_ERROR); 84193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 84203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 84213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *test = NODE_TEST_TYPE; 84223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 84233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 84243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (*type == NODE_TYPE_PI) { 84253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 84263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Specific case: search a PI by name. 84273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 84283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (name != NULL) 84293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(name); 843082e4971dc2f470c9b6f19cf8b15ff32781067167Daniel Veillard name = NULL; 843182e4971dc2f470c9b6f19cf8b15ff32781067167Daniel Veillard if (CUR != ')') { 843282e4971dc2f470c9b6f19cf8b15ff32781067167Daniel Veillard name = xmlXPathParseLiteral(ctxt); 843382e4971dc2f470c9b6f19cf8b15ff32781067167Daniel Veillard CHECK_ERROR 0; 8434ed23b7dc73f6c1146701ece20ed3f03d68366516Daniel Veillard *test = NODE_TEST_PI; 843582e4971dc2f470c9b6f19cf8b15ff32781067167Daniel Veillard SKIP_BLANKS; 843682e4971dc2f470c9b6f19cf8b15ff32781067167Daniel Veillard } 84373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 84383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (CUR != ')') { 84393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (name != NULL) 84403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(name); 84413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XP_ERROR0(XPATH_UNCLOSED_ERROR); 84423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 84433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 84443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(name); 84453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 84463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *test = NODE_TEST_NAME; 84473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((!blanks) && (CUR == ':')) { 84483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 84493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 84503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 8451fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * Since currently the parser context don't have a 8452fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * namespace list associated: 8453fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * The namespace name for this prefix can be computed 8454fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * only at evaluation time. The compilation is done 8455fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * outside of any context. 84563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 8457fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard#if 0 84583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *prefix = xmlXPathNsLookup(ctxt->context, name); 84593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (name != NULL) 84603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(name); 84613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (*prefix == NULL) { 84623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XP_ERROR0(XPATH_UNDEF_PREFIX_ERROR); 84633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 8464fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard#else 8465fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard *prefix = name; 8466fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard#endif 84673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 84683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (CUR == '*') { 84693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 84703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * All elements 84713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 84723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 84733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *test = NODE_TEST_ALL; 84743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 84753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 84763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 84773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor name = xmlXPathParseNCName(ctxt); 84783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (name == NULL) { 84793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XP_ERROR0(XPATH_EXPR_ERROR); 84803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 84813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 84823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(name); 84833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 84843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 84853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 84863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathIsAxisName: 84873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @name: a preparsed name token 84883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 84893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [6] AxisName ::= 'ancestor' 84903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | 'ancestor-or-self' 84913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | 'attribute' 84923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | 'child' 84933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | 'descendant' 84943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | 'descendant-or-self' 84953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | 'following' 84963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | 'following-sibling' 84973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | 'namespace' 84983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | 'parent' 84993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | 'preceding' 85003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | 'preceding-sibling' 85013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | 'self' 85023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 85033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the axis or 0 85043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 850556a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic xmlXPathAxisVal 85063473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathIsAxisName(const xmlChar *name) { 850778637da0ea1c833dfdfad87a9aa5bea14510d08aWilliam M. Brack xmlXPathAxisVal ret = (xmlXPathAxisVal) 0; 85083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor switch (name[0]) { 85093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case 'a': 85103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (xmlStrEqual(name, BAD_CAST "ancestor")) 85113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = AXIS_ANCESTOR; 85123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (xmlStrEqual(name, BAD_CAST "ancestor-or-self")) 85133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = AXIS_ANCESTOR_OR_SELF; 85143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (xmlStrEqual(name, BAD_CAST "attribute")) 85153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = AXIS_ATTRIBUTE; 85163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 85173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case 'c': 85183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (xmlStrEqual(name, BAD_CAST "child")) 85193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = AXIS_CHILD; 85203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 85213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case 'd': 85223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (xmlStrEqual(name, BAD_CAST "descendant")) 85233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = AXIS_DESCENDANT; 85243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (xmlStrEqual(name, BAD_CAST "descendant-or-self")) 85253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = AXIS_DESCENDANT_OR_SELF; 85263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 85273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case 'f': 85283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (xmlStrEqual(name, BAD_CAST "following")) 85293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = AXIS_FOLLOWING; 85303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (xmlStrEqual(name, BAD_CAST "following-sibling")) 85313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = AXIS_FOLLOWING_SIBLING; 85323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 85333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case 'n': 85343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (xmlStrEqual(name, BAD_CAST "namespace")) 85353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = AXIS_NAMESPACE; 85363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 85373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case 'p': 85383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (xmlStrEqual(name, BAD_CAST "parent")) 85393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = AXIS_PARENT; 85403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (xmlStrEqual(name, BAD_CAST "preceding")) 85413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = AXIS_PRECEDING; 85423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (xmlStrEqual(name, BAD_CAST "preceding-sibling")) 85433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = AXIS_PRECEDING_SIBLING; 85443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 85453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case 's': 85463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (xmlStrEqual(name, BAD_CAST "self")) 85473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = AXIS_SELF; 85483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 85493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 85503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ret); 85513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 85523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 85533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 8554afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompStep: 85553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 85563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 85573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [4] Step ::= AxisSpecifier NodeTest Predicate* 85583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | AbbreviatedStep 85593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 85603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [12] AbbreviatedStep ::= '.' | '..' 85613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 85623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [5] AxisSpecifier ::= AxisName '::' 85633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | AbbreviatedAxisSpecifier 85643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 85653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [13] AbbreviatedAxisSpecifier ::= '@'? 85663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 85673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Modified for XPtr range support as: 85683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 85693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [4xptr] Step ::= AxisSpecifier NodeTest Predicate* 85703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | AbbreviatedStep 85713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | 'range-to' '(' Expr ')' Predicate* 85723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 8573afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile one step in a Location Path 85743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * A location step of . is short for self::node(). This is 85753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * particularly useful in conjunction with //. For example, the 85763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * location path .//para is short for 85773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * self::node()/descendant-or-self::node()/child::para 85783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * and so will select all para descendant elements of the context 85793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * node. 85803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Similarly, a location step of .. is short for parent::node(). 85813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * For example, ../title is short for parent::node()/child::title 85823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * and so will select the title children of the parent of the context 85833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * node. 85843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 8585afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void 8586afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompStep(xmlXPathParserContextPtr ctxt) { 8587fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard#ifdef LIBXML_XPTR_ENABLED 8588fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard int rangeto = 0; 8589fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard int op2 = -1; 8590fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard#endif 8591fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard 85923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 85933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((CUR == '.') && (NXT(1) == '.')) { 85943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP(2); 85953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 85969e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard PUSH_LONG_EXPR(XPATH_OP_COLLECT, AXIS_PARENT, 85979e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard NODE_TEST_TYPE, NODE_TYPE_NODE, NULL, NULL); 85983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else if (CUR == '.') { 85993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 86003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 86013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else { 86023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlChar *name = NULL; 86033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor const xmlChar *prefix = NULL; 86043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathTestVal test; 860578637da0ea1c833dfdfad87a9aa5bea14510d08aWilliam M. Brack xmlXPathAxisVal axis = (xmlXPathAxisVal) 0; 86063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathTypeVal type; 8607d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard int op1; 86083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 86093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 86103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The modification needed for XPointer change to the production 86113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 86123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef LIBXML_XPTR_ENABLED 8613fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard if (ctxt->xptr) { 86143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor name = xmlXPathParseNCName(ctxt); 86153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((name != NULL) && (xmlStrEqual(name, BAD_CAST "range-to"))) { 8616fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard op2 = ctxt->comp->last; 86173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(name); 86183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 86193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (CUR != '(') { 86203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XP_ERROR(XPATH_EXPR_ERROR); 86213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 86223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 86233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 86243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 8625afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompileExpr(ctxt); 8626fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard /* PUSH_BINARY_EXPR(XPATH_OP_RANGETO, op2, ctxt->comp->last, 0, 0); */ 86273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ERROR; 86283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 86293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 86303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (CUR != ')') { 86313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XP_ERROR(XPATH_EXPR_ERROR); 86323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 86333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 8634fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard rangeto = 1; 86353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor goto eval_predicates; 86363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 86373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 86383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 86392156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard if (CUR == '*') { 86402156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard axis = AXIS_CHILD; 86412156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard } else { 86422156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard if (name == NULL) 86432156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard name = xmlXPathParseNCName(ctxt); 86442156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard if (name != NULL) { 86452156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard axis = xmlXPathIsAxisName(name); 86462156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard if (axis != 0) { 86472156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard SKIP_BLANKS; 86482156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard if ((CUR == ':') && (NXT(1) == ':')) { 86492156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard SKIP(2); 86502156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard xmlFree(name); 86512156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard name = NULL; 86522156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard } else { 86532156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard /* an element name can conflict with an axis one :-\ */ 86542156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard axis = AXIS_CHILD; 86552156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard } 86563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else { 86573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor axis = AXIS_CHILD; 86583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 86592156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard } else if (CUR == '@') { 86602156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard NEXT; 86612156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard axis = AXIS_ATTRIBUTE; 86623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else { 86632156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard axis = AXIS_CHILD; 86643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 86653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 86663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 86673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ERROR; 86683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 8669afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard name = xmlXPathCompNodeTest(ctxt, &test, &type, &prefix, name); 86703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (test == 0) 86713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return; 86723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 86733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_STEP 86743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 86753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "Basis : computing new set\n"); 86763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 86779e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 86783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_STEP 86793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, "Basis : "); 8680fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard if (ctxt->value == NULL) 8681fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard xmlGenericError(xmlGenericErrorContext, "no value\n"); 8682fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard else if (ctxt->value->nodesetval == NULL) 8683fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard xmlGenericError(xmlGenericErrorContext, "Empty\n"); 8684fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard else 8685fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard xmlGenericErrorContextNodeSet(stdout, ctxt->value->nodesetval); 86863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 86873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 86883473f88a7abdf4e585e267288fb77e898c580d2bOwen Tayloreval_predicates: 8689d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard op1 = ctxt->comp->last; 8690d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard ctxt->comp->last = -1; 8691d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard 86923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 86933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while (CUR == '[') { 8694d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard xmlXPathCompPredicate(ctxt, 0); 86953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 8696d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard 8697fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard#ifdef LIBXML_XPTR_ENABLED 8698fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard if (rangeto) { 8699fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard PUSH_BINARY_EXPR(XPATH_OP_RANGETO, op2, op1, 0, 0); 8700fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard } else 8701fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard#endif 8702fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard PUSH_FULL_EXPR(XPATH_OP_COLLECT, op1, ctxt->comp->last, axis, 8703fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard test, type, (void *)prefix, (void *)name); 8704d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard 87053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 87063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_STEP 87073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, "Step : "); 8708fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard if (ctxt->value == NULL) 8709fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard xmlGenericError(xmlGenericErrorContext, "no value\n"); 8710fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard else if (ctxt->value->nodesetval == NULL) 8711fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard xmlGenericError(xmlGenericErrorContext, "Empty\n"); 8712fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard else 8713fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard xmlGenericErrorContextNodeSet(xmlGenericErrorContext, 8714fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard ctxt->value->nodesetval); 87153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 87163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 87173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 87183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 8719afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompRelativeLocationPath: 87203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 87213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 87223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [3] RelativeLocationPath ::= Step 87233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | RelativeLocationPath '/' Step 87243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | AbbreviatedRelativeLocationPath 87253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [11] AbbreviatedRelativeLocationPath ::= RelativeLocationPath '//' Step 87263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 8727afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile a relative location path. 87283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 8729afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void 8730afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompRelativeLocationPath 87313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor(xmlXPathParserContextPtr ctxt) { 87323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 87333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((CUR == '/') && (NXT(1) == '/')) { 87343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP(2); 87353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 87369e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard PUSH_LONG_EXPR(XPATH_OP_COLLECT, AXIS_DESCENDANT_OR_SELF, 87379e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard NODE_TEST_TYPE, NODE_TYPE_NODE, NULL, NULL); 87383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else if (CUR == '/') { 87393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 87403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 87413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 8742afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompStep(ctxt); 87433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 87443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while (CUR == '/') { 87453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((CUR == '/') && (NXT(1) == '/')) { 87463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP(2); 87473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 87489e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard PUSH_LONG_EXPR(XPATH_OP_COLLECT, AXIS_DESCENDANT_OR_SELF, 87493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NODE_TEST_TYPE, NODE_TYPE_NODE, NULL, NULL); 8750afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompStep(ctxt); 87513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else if (CUR == '/') { 87523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 87533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 8754afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompStep(ctxt); 87553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 87563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 87573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 87583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 87593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 87603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 8761afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompLocationPath: 87623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 87633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 87643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [1] LocationPath ::= RelativeLocationPath 87653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | AbsoluteLocationPath 87663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [2] AbsoluteLocationPath ::= '/' RelativeLocationPath? 87673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | AbbreviatedAbsoluteLocationPath 87683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [10] AbbreviatedAbsoluteLocationPath ::= 87693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * '//' RelativeLocationPath 87703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 8771afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile a location path 8772afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * 87733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * // is short for /descendant-or-self::node()/. For example, 87743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * //para is short for /descendant-or-self::node()/child::para and 87753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * so will select any para element in the document (even a para element 87763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * that is a document element will be selected by //para since the 87773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * document element node is a child of the root node); div//para is 87783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * short for div/descendant-or-self::node()/child::para and so will 87793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * select all para descendants of div children. 87803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 8781afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void 8782afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompLocationPath(xmlXPathParserContextPtr ctxt) { 87833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 87843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (CUR != '/') { 8785afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompRelativeLocationPath(ctxt); 87863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else { 87873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while (CUR == '/') { 87883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((CUR == '/') && (NXT(1) == '/')) { 87893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP(2); 87903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 87919e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard PUSH_LONG_EXPR(XPATH_OP_COLLECT, AXIS_DESCENDANT_OR_SELF, 87929e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard NODE_TEST_TYPE, NODE_TYPE_NODE, NULL, NULL); 8793afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompRelativeLocationPath(ctxt); 87943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else if (CUR == '/') { 87953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 8796608ad0791b3b35072c8021ea4f66cf9d700394b9Daniel Veillard SKIP_BLANKS; 8797608ad0791b3b35072c8021ea4f66cf9d700394b9Daniel Veillard if ((CUR != 0 ) && 8798608ad0791b3b35072c8021ea4f66cf9d700394b9Daniel Veillard ((IS_LETTER(CUR)) || (CUR == '_') || (CUR == '.') || 8799608ad0791b3b35072c8021ea4f66cf9d700394b9Daniel Veillard (CUR == '@') || (CUR == '*'))) 8800afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompRelativeLocationPath(ctxt); 88013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 88023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 88033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 88043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 88053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 88069e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard/************************************************************************ 88079e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * * 88089e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * XPath precompiled expression evaluation * 88099e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * * 88109e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard ************************************************************************/ 88119e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 8812f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillardstatic int 8813d8df6c0e8c883e1d618388d266015dda36731440Daniel VeillardxmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op); 8814d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard 88159e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard/** 8816d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * xmlXPathNodeCollectAndTest: 8817d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * @ctxt: the XPath Parser context 8818d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * @op: the XPath precompiled step operation 8819f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * @first: pointer to the first element in document order 8820f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * @last: pointer to the last element in document order 88219e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * 8822d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * This is the function implementing a step: based on the current list 8823d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * of nodes, it builds up a new list, looking at all nodes under that 8824d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * axis and selecting them it also do the predicate filtering 8825d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * 8826d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * Pushes the new NodeSet resulting from the search. 8827f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * 8828f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Returns the number of node traversed 88299e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard */ 8830f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillardstatic int 8831d8df6c0e8c883e1d618388d266015dda36731440Daniel VeillardxmlXPathNodeCollectAndTest(xmlXPathParserContextPtr ctxt, 8832f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathStepOpPtr op, 8833f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlNodePtr * first, xmlNodePtr * last) 8834f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard{ 883578637da0ea1c833dfdfad87a9aa5bea14510d08aWilliam M. Brack xmlXPathAxisVal axis = (xmlXPathAxisVal) op->value; 883678637da0ea1c833dfdfad87a9aa5bea14510d08aWilliam M. Brack xmlXPathTestVal test = (xmlXPathTestVal) op->value2; 883778637da0ea1c833dfdfad87a9aa5bea14510d08aWilliam M. Brack xmlXPathTypeVal type = (xmlXPathTypeVal) op->value3; 8838d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard const xmlChar *prefix = op->value4; 8839d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard const xmlChar *name = op->value5; 8840e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard const xmlChar *URI = NULL; 88419e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 8842d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP 8843f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard int n = 0; 8844d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif 8845f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard int i, t = 0; 8846d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard xmlNodeSetPtr ret, list; 8847d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard xmlXPathTraversalFunction next = NULL; 8848f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard void (*addNode) (xmlNodeSetPtr, xmlNodePtr); 884975be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard xmlNodeSetPtr (*mergeNodeSet) (xmlNodeSetPtr, xmlNodeSetPtr); 8850d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard xmlNodePtr cur = NULL; 8851d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard xmlXPathObjectPtr obj; 8852d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard xmlNodeSetPtr nodelist; 8853d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard xmlNodePtr tmp; 8854d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard 8855f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard CHECK_TYPE0(XPATH_NODESET); 8856d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard obj = valuePop(ctxt); 8857d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard addNode = xmlXPathNodeSetAdd; 885875be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard mergeNodeSet = xmlXPathNodeSetMerge; 8859e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard if (prefix != NULL) { 8860f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard URI = xmlXPathNsLookup(ctxt->context, prefix); 8861f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (URI == NULL) 8862f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard XP_ERROR0(XPATH_UNDEF_PREFIX_ERROR); 8863e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard } 8864d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP 8865f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, "new step : "); 8866d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif 8867d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard switch (axis) { 8868d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard case AXIS_ANCESTOR: 8869d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP 8870f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, "axis 'ancestors' "); 8871d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif 8872f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard first = NULL; 8873f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard next = xmlXPathNextAncestor; 8874f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 8875d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard case AXIS_ANCESTOR_OR_SELF: 8876d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP 8877f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, 8878f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard "axis 'ancestors-or-self' "); 8879d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif 8880f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard first = NULL; 8881f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard next = xmlXPathNextAncestorOrSelf; 8882f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 8883d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard case AXIS_ATTRIBUTE: 8884d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP 8885f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, "axis 'attributes' "); 8886d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif 8887f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard first = NULL; 8888f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard last = NULL; 8889f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard next = xmlXPathNextAttribute; 889075be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard mergeNodeSet = xmlXPathNodeSetMergeUnique; 8891f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 8892d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard case AXIS_CHILD: 8893d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP 8894f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, "axis 'child' "); 8895d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif 8896f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard last = NULL; 8897f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard next = xmlXPathNextChild; 889875be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard mergeNodeSet = xmlXPathNodeSetMergeUnique; 8899f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 8900d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard case AXIS_DESCENDANT: 8901d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP 8902f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, "axis 'descendant' "); 8903d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif 8904f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard last = NULL; 8905f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard next = xmlXPathNextDescendant; 8906f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 8907d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard case AXIS_DESCENDANT_OR_SELF: 8908d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP 8909f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, 8910f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard "axis 'descendant-or-self' "); 8911d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif 8912f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard last = NULL; 8913f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard next = xmlXPathNextDescendantOrSelf; 8914f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 8915d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard case AXIS_FOLLOWING: 8916d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP 8917f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, "axis 'following' "); 8918d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif 8919f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard last = NULL; 8920f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard next = xmlXPathNextFollowing; 8921f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 8922d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard case AXIS_FOLLOWING_SIBLING: 8923d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP 8924f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, 8925f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard "axis 'following-siblings' "); 8926d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif 8927f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard last = NULL; 8928f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard next = xmlXPathNextFollowingSibling; 8929f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 8930d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard case AXIS_NAMESPACE: 8931d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP 8932f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, "axis 'namespace' "); 8933d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif 8934f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard first = NULL; 8935f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard last = NULL; 8936f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard next = (xmlXPathTraversalFunction) xmlXPathNextNamespace; 893775be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard mergeNodeSet = xmlXPathNodeSetMergeUnique; 8938f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 8939d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard case AXIS_PARENT: 8940d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP 8941f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, "axis 'parent' "); 8942d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif 8943f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard first = NULL; 8944f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard next = xmlXPathNextParent; 8945f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 8946d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard case AXIS_PRECEDING: 8947d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP 8948f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, "axis 'preceding' "); 8949d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif 8950f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard first = NULL; 8951f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard next = xmlXPathNextPrecedingInternal; 8952f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 8953d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard case AXIS_PRECEDING_SIBLING: 8954d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP 8955f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, 8956f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard "axis 'preceding-sibling' "); 8957d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif 8958f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard first = NULL; 8959f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard next = xmlXPathNextPrecedingSibling; 8960f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 8961d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard case AXIS_SELF: 8962d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP 8963f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, "axis 'self' "); 8964d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif 8965f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard first = NULL; 8966f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard last = NULL; 8967f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard next = xmlXPathNextSelf; 896875be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard mergeNodeSet = xmlXPathNodeSetMergeUnique; 8969f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 8970d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard } 8971d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard if (next == NULL) 8972f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return(0); 8973d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard 8974d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard nodelist = obj->nodesetval; 8975d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard if (nodelist == NULL) { 8976f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathFreeObject(obj); 8977f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard valuePush(ctxt, xmlXPathWrapNodeSet(NULL)); 8978f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return(0); 8979d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard } 8980d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard addNode = xmlXPathNodeSetAddUnique; 8981d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard ret = NULL; 8982d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP 8983d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard xmlGenericError(xmlGenericErrorContext, 8984f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard " context contains %d nodes\n", nodelist->nodeNr); 8985d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard switch (test) { 8986f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case NODE_TEST_NONE: 8987f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, 8988f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard " searching for none !!!\n"); 8989f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 8990f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case NODE_TEST_TYPE: 8991f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, 8992f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard " searching for type %d\n", type); 8993f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 8994f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case NODE_TEST_PI: 8995f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, 8996f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard " searching for PI !!!\n"); 8997f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 8998f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case NODE_TEST_ALL: 8999f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, 9000f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard " searching for *\n"); 9001f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9002f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case NODE_TEST_NS: 9003f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, 9004f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard " searching for namespace %s\n", 9005f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard prefix); 9006f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9007f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case NODE_TEST_NAME: 9008f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, 9009f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard " searching for name %s\n", name); 9010f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (prefix != NULL) 9011f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, 9012f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard " with namespace %s\n", prefix); 9013f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9014d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard } 9015d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard xmlGenericError(xmlGenericErrorContext, "Testing : "); 9016d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif 9017d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard /* 9018d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * 2.3 Node Tests 9019d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * - For the attribute axis, the principal node type is attribute. 9020d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * - For the namespace axis, the principal node type is namespace. 9021d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * - For other axes, the principal node type is element. 9022d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * 9023d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * A node test * is true for any node of the 9024cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * principal node type. For example, child::* will 9025d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * select all element children of the context node 9026d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard */ 9027d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard tmp = ctxt->context->node; 9028f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard for (i = 0; i < nodelist->nodeNr; i++) { 9029d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard ctxt->context->node = nodelist->nodeTab[i]; 9030d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard 9031f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard cur = NULL; 9032f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard list = xmlXPathNodeSetCreate(NULL); 9033f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard do { 9034f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard cur = next(ctxt, cur); 9035f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (cur == NULL) 9036f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9037f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((first != NULL) && (*first == cur)) 9038f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9039f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (((t % 256) == 0) && 9040f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (first != NULL) && (*first != NULL) && 9041f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (xmlXPathCmpNodes(*first, cur) >= 0)) 9042f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9043f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((last != NULL) && (*last == cur)) 9044f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9045f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (((t % 256) == 0) && 9046f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (last != NULL) && (*last != NULL) && 9047f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (xmlXPathCmpNodes(cur, *last) >= 0)) 9048f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9049d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard t++; 9050f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#ifdef DEBUG_STEP 9051d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard xmlGenericError(xmlGenericErrorContext, " %s", cur->name); 9052d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif 9053f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard switch (test) { 9054d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard case NODE_TEST_NONE: 9055f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->node = tmp; 9056f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard STRANGE return(t); 9057d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard case NODE_TEST_TYPE: 9058f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((cur->type == type) || 9059f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ((type == NODE_TYPE_NODE) && 9060f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ((cur->type == XML_DOCUMENT_NODE) || 9061f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (cur->type == XML_HTML_DOCUMENT_NODE) || 9062f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (cur->type == XML_ELEMENT_NODE) || 9063f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin (cur->type == XML_NAMESPACE_DECL) || 9064f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin (cur->type == XML_ATTRIBUTE_NODE) || 9065f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (cur->type == XML_PI_NODE) || 9066f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (cur->type == XML_COMMENT_NODE) || 9067f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (cur->type == XML_CDATA_SECTION_NODE) || 90687583a59b5a0792599a181f77aaf0a39749fada27Daniel Veillard (cur->type == XML_TEXT_NODE))) || 90697583a59b5a0792599a181f77aaf0a39749fada27Daniel Veillard ((type == NODE_TYPE_TEXT) && 90707583a59b5a0792599a181f77aaf0a39749fada27Daniel Veillard (cur->type == XML_CDATA_SECTION_NODE))) { 9071d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP 9072d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard n++; 9073d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif 9074f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard addNode(list, cur); 9075f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9076f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9077d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard case NODE_TEST_PI: 9078f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (cur->type == XML_PI_NODE) { 9079f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((name != NULL) && 9080f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (!xmlStrEqual(name, cur->name))) 9081f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9082d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP 9083f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard n++; 9084d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif 9085f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard addNode(list, cur); 9086f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9087f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9088d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard case NODE_TEST_ALL: 9089f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (axis == AXIS_ATTRIBUTE) { 9090f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (cur->type == XML_ATTRIBUTE_NODE) { 9091d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP 9092f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard n++; 9093d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif 9094f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard addNode(list, cur); 9095f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9096f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } else if (axis == AXIS_NAMESPACE) { 9097f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (cur->type == XML_NAMESPACE_DECL) { 9098d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP 9099f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard n++; 9100d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif 9101044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlXPathNodeSetAddNs(list, ctxt->context->node, 9102044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard (xmlNsPtr) cur); 9103f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9104f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } else { 9105f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (cur->type == XML_ELEMENT_NODE) { 9106f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (prefix == NULL) { 9107d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP 9108f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard n++; 9109d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif 9110f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard addNode(list, cur); 9111f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } else if ((cur->ns != NULL) && 9112f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (xmlStrEqual(URI, cur->ns->href))) { 9113d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP 9114f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard n++; 9115d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif 9116f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard addNode(list, cur); 9117f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9118f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9119f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9120f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9121f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case NODE_TEST_NS:{ 9122f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard TODO; 9123f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9124f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9125d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard case NODE_TEST_NAME: 9126f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard switch (cur->type) { 9127f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XML_ELEMENT_NODE: 9128f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (xmlStrEqual(name, cur->name)) { 9129f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (prefix == NULL) { 9130f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (cur->ns == NULL) { 9131d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP 9132f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard n++; 9133d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif 9134f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard addNode(list, cur); 9135f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9136f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } else { 9137f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((cur->ns != NULL) && 9138f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (xmlStrEqual(URI, 9139f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard cur->ns->href))) { 9140d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP 9141f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard n++; 9142d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif 9143f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard addNode(list, cur); 9144f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9145f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9146f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9147f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9148f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XML_ATTRIBUTE_NODE:{ 9149f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlAttrPtr attr = (xmlAttrPtr) cur; 9150f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 9151f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (xmlStrEqual(name, attr->name)) { 9152f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (prefix == NULL) { 9153f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((attr->ns == NULL) || 9154f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (attr->ns->prefix == NULL)) { 9155d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP 9156f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard n++; 9157d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif 9158f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard addNode(list, 9159f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (xmlNodePtr) attr); 9160f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9161f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } else { 9162f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((attr->ns != NULL) && 9163f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (xmlStrEqual(URI, 9164f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard attr->ns-> 9165f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard href))) { 9166d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP 9167f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard n++; 9168d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif 9169f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard addNode(list, 9170f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (xmlNodePtr) attr); 9171f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9172f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9173f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9174f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9175f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9176f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XML_NAMESPACE_DECL: 9177f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (cur->type == XML_NAMESPACE_DECL) { 9178f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlNsPtr ns = (xmlNsPtr) cur; 9179f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 9180f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((ns->prefix != NULL) && (name != NULL) 9181f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard && (xmlStrEqual(ns->prefix, name))) { 91828b8d2254fa1604efd37b3ba92eaeb2e40b2909a8Daniel Veillard#ifdef DEBUG_STEP 9183f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard n++; 91848b8d2254fa1604efd37b3ba92eaeb2e40b2909a8Daniel Veillard#endif 9185044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlXPathNodeSetAddNs(list, 9186044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard ctxt->context->node, (xmlNsPtr) cur); 9187f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9188f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9189f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9190f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard default: 9191f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9192f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9193f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9194f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9195f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9196f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } while (cur != NULL); 9197f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 9198f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* 9199f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * If there is some predicate filtering do it now 9200f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 92016fbcf42aa301dca50737c65fb738752328ca3a4cDaniel Veillard if ((op->ch2 != -1) && (list != NULL) && (list->nodeNr > 0)) { 9202f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathObjectPtr obj2; 9203f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 9204f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard valuePush(ctxt, xmlXPathWrapNodeSet(list)); 9205f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathCompOpEval(ctxt, &ctxt->comp->steps[op->ch2]); 9206f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard CHECK_TYPE0(XPATH_NODESET); 9207f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard obj2 = valuePop(ctxt); 9208f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard list = obj2->nodesetval; 9209f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard obj2->nodesetval = NULL; 9210f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathFreeObject(obj2); 9211f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9212f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (ret == NULL) { 9213f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ret = list; 9214f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } else { 921575be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard ret = mergeNodeSet(ret, list); 9216f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathFreeNodeSet(list); 9217f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9218d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard } 9219d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard ctxt->context->node = tmp; 9220d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP 9221d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard xmlGenericError(xmlGenericErrorContext, 9222f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard "\nExamined %d nodes, found %d nodes at that step\n", 9223f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard t, n); 9224d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif 9225d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard valuePush(ctxt, xmlXPathWrapNodeSet(ret)); 92260ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard if ((obj->boolval) && (obj->user != NULL)) { 92270ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard ctxt->value->boolval = 1; 92280ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard ctxt->value->user = obj->user; 92290ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard obj->user = NULL; 92300ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard obj->boolval = 0; 92310ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard } 92320ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard xmlXPathFreeObject(obj); 9233f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return(t); 9234d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard} 9235d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard 9236d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard/** 9237f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * xmlXPathNodeCollectAndTestNth: 9238f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * @ctxt: the XPath Parser context 9239f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * @op: the XPath precompiled step operation 9240f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * @indx: the index to collect 9241f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * @first: pointer to the first element in document order 9242f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * @last: pointer to the last element in document order 9243f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * 9244f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * This is the function implementing a step: based on the current list 9245f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * of nodes, it builds up a new list, looking at all nodes under that 9246f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * axis and selecting them it also do the predicate filtering 9247f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * 9248f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Pushes the new NodeSet resulting from the search. 9249f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Returns the number of node traversed 9250f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 9251f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillardstatic int 9252f06307e2c172284bb41376c396f757bdac9bdd19Daniel VeillardxmlXPathNodeCollectAndTestNth(xmlXPathParserContextPtr ctxt, 9253f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathStepOpPtr op, int indx, 9254f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlNodePtr * first, xmlNodePtr * last) 9255f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard{ 925678637da0ea1c833dfdfad87a9aa5bea14510d08aWilliam M. Brack xmlXPathAxisVal axis = (xmlXPathAxisVal) op->value; 925778637da0ea1c833dfdfad87a9aa5bea14510d08aWilliam M. Brack xmlXPathTestVal test = (xmlXPathTestVal) op->value2; 925878637da0ea1c833dfdfad87a9aa5bea14510d08aWilliam M. Brack xmlXPathTypeVal type = (xmlXPathTypeVal) op->value3; 9259f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard const xmlChar *prefix = op->value4; 9260f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard const xmlChar *name = op->value5; 9261f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard const xmlChar *URI = NULL; 9262f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard int n = 0, t = 0; 9263f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 9264f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard int i; 9265f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlNodeSetPtr list; 9266f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathTraversalFunction next = NULL; 9267f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard void (*addNode) (xmlNodeSetPtr, xmlNodePtr); 9268f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlNodePtr cur = NULL; 9269f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathObjectPtr obj; 9270f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlNodeSetPtr nodelist; 9271f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlNodePtr tmp; 9272f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 9273f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard CHECK_TYPE0(XPATH_NODESET); 9274f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard obj = valuePop(ctxt); 9275f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard addNode = xmlXPathNodeSetAdd; 9276f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (prefix != NULL) { 9277f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard URI = xmlXPathNsLookup(ctxt->context, prefix); 9278f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (URI == NULL) 9279f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard XP_ERROR0(XPATH_UNDEF_PREFIX_ERROR); 9280f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9281f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#ifdef DEBUG_STEP_NTH 9282f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, "new step : "); 9283f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (first != NULL) { 9284f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (*first != NULL) 9285f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, "first = %s ", 9286f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (*first)->name); 9287f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard else 9288f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, "first = NULL "); 9289f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9290f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (last != NULL) { 9291f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (*last != NULL) 9292f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, "last = %s ", 9293f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (*last)->name); 9294f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard else 9295f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, "last = NULL "); 9296f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9297f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#endif 9298f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard switch (axis) { 9299f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case AXIS_ANCESTOR: 9300f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#ifdef DEBUG_STEP_NTH 9301f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, "axis 'ancestors' "); 9302f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#endif 9303f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard first = NULL; 9304f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard next = xmlXPathNextAncestor; 9305f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9306f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case AXIS_ANCESTOR_OR_SELF: 9307f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#ifdef DEBUG_STEP_NTH 9308f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, 9309f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard "axis 'ancestors-or-self' "); 9310f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#endif 9311f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard first = NULL; 9312f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard next = xmlXPathNextAncestorOrSelf; 9313f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9314f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case AXIS_ATTRIBUTE: 9315f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#ifdef DEBUG_STEP_NTH 9316f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, "axis 'attributes' "); 9317f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#endif 9318f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard first = NULL; 9319f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard last = NULL; 9320f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard next = xmlXPathNextAttribute; 9321f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9322f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case AXIS_CHILD: 9323f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#ifdef DEBUG_STEP_NTH 9324f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, "axis 'child' "); 9325f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#endif 9326f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard last = NULL; 9327f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard next = xmlXPathNextChild; 9328f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9329f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case AXIS_DESCENDANT: 9330f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#ifdef DEBUG_STEP_NTH 9331f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, "axis 'descendant' "); 9332f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#endif 9333f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard last = NULL; 9334f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard next = xmlXPathNextDescendant; 9335f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9336f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case AXIS_DESCENDANT_OR_SELF: 9337f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#ifdef DEBUG_STEP_NTH 9338f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, 9339f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard "axis 'descendant-or-self' "); 9340f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#endif 9341f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard last = NULL; 9342f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard next = xmlXPathNextDescendantOrSelf; 9343f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9344f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case AXIS_FOLLOWING: 9345f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#ifdef DEBUG_STEP_NTH 9346f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, "axis 'following' "); 9347f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#endif 9348f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard last = NULL; 9349f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard next = xmlXPathNextFollowing; 9350f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9351f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case AXIS_FOLLOWING_SIBLING: 9352f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#ifdef DEBUG_STEP_NTH 9353f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, 9354f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard "axis 'following-siblings' "); 9355f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#endif 9356f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard last = NULL; 9357f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard next = xmlXPathNextFollowingSibling; 9358f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9359f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case AXIS_NAMESPACE: 9360f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#ifdef DEBUG_STEP_NTH 9361f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, "axis 'namespace' "); 9362f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#endif 9363f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard last = NULL; 9364f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard first = NULL; 9365f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard next = (xmlXPathTraversalFunction) xmlXPathNextNamespace; 9366f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9367f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case AXIS_PARENT: 9368f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#ifdef DEBUG_STEP_NTH 9369f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, "axis 'parent' "); 9370f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#endif 9371f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard first = NULL; 9372f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard next = xmlXPathNextParent; 9373f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9374f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case AXIS_PRECEDING: 9375f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#ifdef DEBUG_STEP_NTH 9376f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, "axis 'preceding' "); 9377f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#endif 9378f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard first = NULL; 9379f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard next = xmlXPathNextPrecedingInternal; 9380f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9381f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case AXIS_PRECEDING_SIBLING: 9382f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#ifdef DEBUG_STEP_NTH 9383f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, 9384f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard "axis 'preceding-sibling' "); 9385f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#endif 9386f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard first = NULL; 9387f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard next = xmlXPathNextPrecedingSibling; 9388f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9389f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case AXIS_SELF: 9390f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#ifdef DEBUG_STEP_NTH 9391f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, "axis 'self' "); 9392f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#endif 9393f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard first = NULL; 9394f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard last = NULL; 9395f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard next = xmlXPathNextSelf; 9396f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9397f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9398f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (next == NULL) 9399f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return(0); 9400f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 9401f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard nodelist = obj->nodesetval; 9402f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (nodelist == NULL) { 9403f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathFreeObject(obj); 9404f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard valuePush(ctxt, xmlXPathWrapNodeSet(NULL)); 9405f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return(0); 9406f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9407f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard addNode = xmlXPathNodeSetAddUnique; 9408f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#ifdef DEBUG_STEP_NTH 9409f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, 9410f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard " context contains %d nodes\n", nodelist->nodeNr); 9411f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard switch (test) { 9412f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case NODE_TEST_NONE: 9413f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, 9414f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard " searching for none !!!\n"); 9415f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9416f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case NODE_TEST_TYPE: 9417f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, 9418f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard " searching for type %d\n", type); 9419f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9420f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case NODE_TEST_PI: 9421f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, 9422f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard " searching for PI !!!\n"); 9423f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9424f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case NODE_TEST_ALL: 9425f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, 9426f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard " searching for *\n"); 9427f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9428f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case NODE_TEST_NS: 9429f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, 9430f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard " searching for namespace %s\n", 9431f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard prefix); 9432f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9433f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case NODE_TEST_NAME: 9434f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, 9435f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard " searching for name %s\n", name); 9436f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (prefix != NULL) 9437f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, 9438f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard " with namespace %s\n", prefix); 9439f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9440f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9441f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, "Testing : "); 9442f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#endif 9443f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* 9444f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * 2.3 Node Tests 9445f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * - For the attribute axis, the principal node type is attribute. 9446f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * - For the namespace axis, the principal node type is namespace. 9447f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * - For other axes, the principal node type is element. 9448f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * 9449f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * A node test * is true for any node of the 9450cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * principal node type. For example, child::* will 9451f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * select all element children of the context node 9452f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 9453f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard tmp = ctxt->context->node; 9454f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard list = xmlXPathNodeSetCreate(NULL); 9455f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard for (i = 0; i < nodelist->nodeNr; i++) { 9456f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->node = nodelist->nodeTab[i]; 9457f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 9458f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard cur = NULL; 9459f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard n = 0; 9460f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard do { 9461f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard cur = next(ctxt, cur); 9462f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (cur == NULL) 9463f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9464f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((first != NULL) && (*first == cur)) 9465f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9466f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (((t % 256) == 0) && 9467f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (first != NULL) && (*first != NULL) && 9468f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (xmlXPathCmpNodes(*first, cur) >= 0)) 9469f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9470f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((last != NULL) && (*last == cur)) 9471f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9472f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (((t % 256) == 0) && 9473f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (last != NULL) && (*last != NULL) && 9474f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (xmlXPathCmpNodes(cur, *last) >= 0)) 9475f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9476f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard t++; 9477f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard switch (test) { 9478f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case NODE_TEST_NONE: 9479f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->node = tmp; 9480f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard STRANGE return(0); 9481f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case NODE_TEST_TYPE: 9482f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((cur->type == type) || 9483f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ((type == NODE_TYPE_NODE) && 9484f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ((cur->type == XML_DOCUMENT_NODE) || 9485f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (cur->type == XML_HTML_DOCUMENT_NODE) || 9486f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (cur->type == XML_ELEMENT_NODE) || 9487f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (cur->type == XML_PI_NODE) || 9488f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (cur->type == XML_COMMENT_NODE) || 9489f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (cur->type == XML_CDATA_SECTION_NODE) || 94908606bbbc0a04293afd7541033d6a83c4943a6f02Daniel Veillard (cur->type == XML_TEXT_NODE))) || 94918606bbbc0a04293afd7541033d6a83c4943a6f02Daniel Veillard ((type == NODE_TYPE_TEXT) && 94928606bbbc0a04293afd7541033d6a83c4943a6f02Daniel Veillard (cur->type == XML_CDATA_SECTION_NODE))) { 9493f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard n++; 9494f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (n == indx) 9495f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard addNode(list, cur); 9496f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9497f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9498f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case NODE_TEST_PI: 9499f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (cur->type == XML_PI_NODE) { 9500f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((name != NULL) && 9501f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (!xmlStrEqual(name, cur->name))) 9502f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9503f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard n++; 9504f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (n == indx) 9505f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard addNode(list, cur); 9506f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9507f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9508f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case NODE_TEST_ALL: 9509f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (axis == AXIS_ATTRIBUTE) { 9510f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (cur->type == XML_ATTRIBUTE_NODE) { 9511f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard n++; 9512f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (n == indx) 9513f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard addNode(list, cur); 9514f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9515f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } else if (axis == AXIS_NAMESPACE) { 9516f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (cur->type == XML_NAMESPACE_DECL) { 9517f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard n++; 9518f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (n == indx) 9519044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlXPathNodeSetAddNs(list, ctxt->context->node, 9520044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard (xmlNsPtr) cur); 9521f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9522f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } else { 9523f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (cur->type == XML_ELEMENT_NODE) { 9524f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (prefix == NULL) { 9525f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard n++; 9526f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (n == indx) 9527f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard addNode(list, cur); 9528f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } else if ((cur->ns != NULL) && 9529f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (xmlStrEqual(URI, cur->ns->href))) { 9530f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard n++; 9531f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (n == indx) 9532f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard addNode(list, cur); 9533f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9534f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9535f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9536f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9537f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case NODE_TEST_NS:{ 9538f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard TODO; 9539f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9540f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9541f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case NODE_TEST_NAME: 9542f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard switch (cur->type) { 9543f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XML_ELEMENT_NODE: 9544f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (xmlStrEqual(name, cur->name)) { 9545f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (prefix == NULL) { 9546f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (cur->ns == NULL) { 9547f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard n++; 9548f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (n == indx) 9549f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard addNode(list, cur); 9550f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9551f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } else { 9552f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((cur->ns != NULL) && 9553f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (xmlStrEqual(URI, 9554f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard cur->ns->href))) { 9555f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard n++; 9556f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (n == indx) 9557f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard addNode(list, cur); 9558f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9559f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9560f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9561f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9562f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XML_ATTRIBUTE_NODE:{ 9563f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlAttrPtr attr = (xmlAttrPtr) cur; 9564f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 9565f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (xmlStrEqual(name, attr->name)) { 9566f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (prefix == NULL) { 9567f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((attr->ns == NULL) || 9568f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (attr->ns->prefix == NULL)) { 9569f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard n++; 9570f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (n == indx) 9571f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard addNode(list, cur); 9572f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9573f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } else { 9574f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((attr->ns != NULL) && 9575f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (xmlStrEqual(URI, 9576f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard attr->ns-> 9577f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard href))) { 9578f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard n++; 9579f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (n == indx) 9580f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard addNode(list, cur); 9581f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9582f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9583f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9584f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9585f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9586f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XML_NAMESPACE_DECL: 9587f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (cur->type == XML_NAMESPACE_DECL) { 9588f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlNsPtr ns = (xmlNsPtr) cur; 9589f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 9590f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((ns->prefix != NULL) && (name != NULL) 9591f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard && (xmlStrEqual(ns->prefix, name))) { 9592f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard n++; 9593f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (n == indx) 9594044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlXPathNodeSetAddNs(list, 9595044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard ctxt->context->node, (xmlNsPtr) cur); 9596f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9597f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9598f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9599f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard default: 9600f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9601f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9602f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9603f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9604f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9605f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } while (n < indx); 9606f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9607f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->node = tmp; 9608f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#ifdef DEBUG_STEP_NTH 9609f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, 9610f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard "\nExamined %d nodes, found %d nodes at that step\n", 9611f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard t, list->nodeNr); 9612f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#endif 9613f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard valuePush(ctxt, xmlXPathWrapNodeSet(list)); 96140ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard if ((obj->boolval) && (obj->user != NULL)) { 96150ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard ctxt->value->boolval = 1; 96160ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard ctxt->value->user = obj->user; 96170ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard obj->user = NULL; 96180ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard obj->boolval = 0; 96190ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard } 96200ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard xmlXPathFreeObject(obj); 9621f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return(t); 9622f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard} 9623f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 9624f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard/** 9625f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * xmlXPathCompOpEvalFirst: 9626d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * @ctxt: the XPath parser context with the compiled expression 9627d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * @op: an XPath compiled operation 9628f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * @first: the first elem found so far 9629d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * 9630f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Evaluate the Precompiled XPath operation searching only the first 9631f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * element in document order 9632f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * 9633f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Returns the number of examined objects. 9634d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard */ 9635f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillardstatic int 9636f06307e2c172284bb41376c396f757bdac9bdd19Daniel VeillardxmlXPathCompOpEvalFirst(xmlXPathParserContextPtr ctxt, 9637f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathStepOpPtr op, xmlNodePtr * first) 9638f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard{ 9639f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard int total = 0, cur; 9640d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard xmlXPathCompExprPtr comp; 9641d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard xmlXPathObjectPtr arg1, arg2; 9642d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard 9643556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 9644d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard comp = ctxt->comp; 9645d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard switch (op->op) { 9646f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_END: 9647f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (0); 9648f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_UNION: 9649f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total = 9650f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathCompOpEvalFirst(ctxt, &comp->steps[op->ch1], 9651f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard first); 9652556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 9653f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((ctxt->value != NULL) 9654f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard && (ctxt->value->type == XPATH_NODESET) 9655f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard && (ctxt->value->nodesetval != NULL) 9656f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard && (ctxt->value->nodesetval->nodeNr >= 1)) { 9657f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* 9658f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * limit tree traversing to first node in the result 9659f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 9660f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathNodeSetSort(ctxt->value->nodesetval); 9661f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard *first = ctxt->value->nodesetval->nodeTab[0]; 9662f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9663f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard cur = 9664f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathCompOpEvalFirst(ctxt, &comp->steps[op->ch2], 9665f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard first); 9666556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 9667f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard CHECK_TYPE0(XPATH_NODESET); 9668f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard arg2 = valuePop(ctxt); 9669f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 9670f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard CHECK_TYPE0(XPATH_NODESET); 9671f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard arg1 = valuePop(ctxt); 9672f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 9673f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard arg1->nodesetval = xmlXPathNodeSetMerge(arg1->nodesetval, 9674f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard arg2->nodesetval); 9675f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard valuePush(ctxt, arg1); 9676f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathFreeObject(arg2); 9677f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* optimizer */ 9678f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (total > cur) 9679f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathCompSwap(op); 9680f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total + cur); 9681f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_ROOT: 9682f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathRoot(ctxt); 9683f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (0); 9684f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_NODE: 9685f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch1 != -1) 9686f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]); 9687556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 9688f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch2 != -1) 9689f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]); 9690556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 9691f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard valuePush(ctxt, xmlXPathNewNodeSet(ctxt->context->node)); 9692f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 9693f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_RESET: 9694f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch1 != -1) 9695f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]); 9696556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 9697f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch2 != -1) 9698f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]); 9699556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 9700f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->node = NULL; 9701f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 9702f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_COLLECT:{ 9703f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch1 == -1) 9704f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 9705f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 9706f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total = xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]); 9707556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 9708f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 9709f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* 9710f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Optimization for [n] selection where n is a number 9711f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 9712f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((op->ch2 != -1) && 9713f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (comp->steps[op->ch2].op == XPATH_OP_PREDICATE) && 9714f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (comp->steps[op->ch2].ch1 == -1) && 9715f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (comp->steps[op->ch2].ch2 != -1) && 9716f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (comp->steps[comp->steps[op->ch2].ch2].op == 9717f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard XPATH_OP_VALUE)) { 9718f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathObjectPtr val; 9719f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 9720f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard val = comp->steps[comp->steps[op->ch2].ch2].value4; 9721f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((val != NULL) && (val->type == XPATH_NUMBER)) { 9722f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard int indx = (int) val->floatval; 9723f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 9724f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (val->floatval == (float) indx) { 9725f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathNodeCollectAndTestNth(ctxt, op, indx, 9726f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard first, NULL); 9727f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 9728f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9729f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9730f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9731f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathNodeCollectAndTest(ctxt, op, first, NULL); 9732f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 9733f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9734f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_VALUE: 9735f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard valuePush(ctxt, 9736f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathObjectCopy((xmlXPathObjectPtr) op->value4)); 9737f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (0); 9738f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_SORT: 9739f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch1 != -1) 9740f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += 9741f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathCompOpEvalFirst(ctxt, &comp->steps[op->ch1], 9742f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard first); 9743556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 9744f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((ctxt->value != NULL) 9745f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard && (ctxt->value->type == XPATH_NODESET) 9746f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard && (ctxt->value->nodesetval != NULL)) 9747f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathNodeSetSort(ctxt->value->nodesetval); 9748f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 9749f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard default: 9750f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (xmlXPathCompOpEval(ctxt, op)); 9751f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9752f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard} 975342596ad20cdf1925dd79ea801cbe598b6e7b7aecDaniel Veillard 9754f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard/** 9755f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * xmlXPathCompOpEvalLast: 9756f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * @ctxt: the XPath parser context with the compiled expression 9757f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * @op: an XPath compiled operation 9758f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * @last: the last elem found so far 9759f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * 9760f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Evaluate the Precompiled XPath operation searching only the last 9761f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * element in document order 9762f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * 9763f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Returns the number of node traversed 9764f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 9765f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillardstatic int 9766f06307e2c172284bb41376c396f757bdac9bdd19Daniel VeillardxmlXPathCompOpEvalLast(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op, 9767f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlNodePtr * last) 9768f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard{ 9769f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard int total = 0, cur; 9770f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathCompExprPtr comp; 9771f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathObjectPtr arg1, arg2; 97729e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 9773556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 9774f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard comp = ctxt->comp; 9775f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard switch (op->op) { 9776f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_END: 9777f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (0); 9778f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_UNION: 9779f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total = 9780f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathCompOpEvalLast(ctxt, &comp->steps[op->ch1], last); 9781556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 9782f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((ctxt->value != NULL) 9783f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard && (ctxt->value->type == XPATH_NODESET) 9784f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard && (ctxt->value->nodesetval != NULL) 9785f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard && (ctxt->value->nodesetval->nodeNr >= 1)) { 9786f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* 9787f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * limit tree traversing to first node in the result 9788f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 9789f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathNodeSetSort(ctxt->value->nodesetval); 9790f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard *last = 9791f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->value->nodesetval->nodeTab[ctxt->value-> 9792f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard nodesetval->nodeNr - 9793f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 1]; 9794f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9795f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard cur = 9796f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathCompOpEvalLast(ctxt, &comp->steps[op->ch2], last); 9797556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 9798f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((ctxt->value != NULL) 9799f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard && (ctxt->value->type == XPATH_NODESET) 9800f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard && (ctxt->value->nodesetval != NULL) 9801f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard && (ctxt->value->nodesetval->nodeNr >= 1)) { 9802f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9803f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard CHECK_TYPE0(XPATH_NODESET); 9804f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard arg2 = valuePop(ctxt); 9805f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 9806f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard CHECK_TYPE0(XPATH_NODESET); 9807f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard arg1 = valuePop(ctxt); 9808f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 9809f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard arg1->nodesetval = xmlXPathNodeSetMerge(arg1->nodesetval, 9810f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard arg2->nodesetval); 9811f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard valuePush(ctxt, arg1); 9812f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathFreeObject(arg2); 9813f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* optimizer */ 9814f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (total > cur) 9815f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathCompSwap(op); 9816f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total + cur); 9817f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_ROOT: 9818f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathRoot(ctxt); 9819f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (0); 9820f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_NODE: 9821f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch1 != -1) 9822f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]); 9823556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 9824f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch2 != -1) 9825f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]); 9826556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 9827f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard valuePush(ctxt, xmlXPathNewNodeSet(ctxt->context->node)); 9828f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 9829f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_RESET: 9830f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch1 != -1) 9831f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]); 9832556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 9833f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch2 != -1) 9834f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]); 9835556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 9836f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->node = NULL; 9837f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 9838f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_COLLECT:{ 9839f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch1 == -1) 9840f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (0); 9841f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 9842f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]); 9843556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 9844f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 9845f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* 9846f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Optimization for [n] selection where n is a number 9847f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 9848f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((op->ch2 != -1) && 9849f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (comp->steps[op->ch2].op == XPATH_OP_PREDICATE) && 9850f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (comp->steps[op->ch2].ch1 == -1) && 9851f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (comp->steps[op->ch2].ch2 != -1) && 9852f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (comp->steps[comp->steps[op->ch2].ch2].op == 9853f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard XPATH_OP_VALUE)) { 9854f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathObjectPtr val; 9855f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 9856f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard val = comp->steps[comp->steps[op->ch2].ch2].value4; 9857f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((val != NULL) && (val->type == XPATH_NUMBER)) { 9858f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard int indx = (int) val->floatval; 9859f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 9860f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (val->floatval == (float) indx) { 9861f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += 9862f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathNodeCollectAndTestNth(ctxt, op, 9863f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard indx, NULL, 9864f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard last); 9865f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 9866f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9867f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9868f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9869f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathNodeCollectAndTest(ctxt, op, NULL, last); 9870f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 9871f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9872f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_VALUE: 9873f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard valuePush(ctxt, 9874f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathObjectCopy((xmlXPathObjectPtr) op->value4)); 9875f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (0); 9876f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_SORT: 9877f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch1 != -1) 9878f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += 9879f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathCompOpEvalLast(ctxt, &comp->steps[op->ch1], 9880f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard last); 9881556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 9882f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((ctxt->value != NULL) 9883f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard && (ctxt->value->type == XPATH_NODESET) 9884f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard && (ctxt->value->nodesetval != NULL)) 9885f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathNodeSetSort(ctxt->value->nodesetval); 9886f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 9887f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard default: 9888f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (xmlXPathCompOpEval(ctxt, op)); 9889f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9890f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard} 98919e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 9892f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard/** 9893f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * xmlXPathCompOpEval: 9894f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * @ctxt: the XPath parser context with the compiled expression 9895f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * @op: an XPath compiled operation 9896f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * 9897f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Evaluate the Precompiled XPath operation 9898f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Returns the number of node traversed 9899f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 9900f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillardstatic int 9901f06307e2c172284bb41376c396f757bdac9bdd19Daniel VeillardxmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op) 9902f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard{ 9903f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard int total = 0; 9904f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard int equal, ret; 9905f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathCompExprPtr comp; 9906f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathObjectPtr arg1, arg2; 99077089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard xmlNodePtr bak; 99087089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard xmlDocPtr bakd; 99096000af549b49464a3b1947fc582998a1c9ff7c79William M. Brack int pp; 9910692092b5886073a8cd1c97bb7d57579e4a9cfc3fWilliam M. Brack int cs; 99119e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 9912556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 9913f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard comp = ctxt->comp; 9914f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard switch (op->op) { 9915f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_END: 9916f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (0); 9917f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_AND: 99187089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard bakd = ctxt->context->doc; 99197089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard bak = ctxt->context->node; 99206000af549b49464a3b1947fc582998a1c9ff7c79William M. Brack pp = ctxt->context->proximityPosition; 9921692092b5886073a8cd1c97bb7d57579e4a9cfc3fWilliam M. Brack cs = ctxt->context->contextSize; 9922f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]); 9923556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 9924f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathBooleanFunction(ctxt, 1); 9925f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((ctxt->value == NULL) || (ctxt->value->boolval == 0)) 9926f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 9927f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard arg2 = valuePop(ctxt); 99287089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard ctxt->context->doc = bakd; 99297089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard ctxt->context->node = bak; 99306000af549b49464a3b1947fc582998a1c9ff7c79William M. Brack ctxt->context->proximityPosition = pp; 9931692092b5886073a8cd1c97bb7d57579e4a9cfc3fWilliam M. Brack ctxt->context->contextSize = cs; 9932f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]); 9933556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard if (ctxt->error) { 9934556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard xmlXPathFreeObject(arg2); 9935556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard return(0); 9936556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard } 9937f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathBooleanFunction(ctxt, 1); 9938f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard arg1 = valuePop(ctxt); 9939f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard arg1->boolval &= arg2->boolval; 9940f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard valuePush(ctxt, arg1); 9941f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathFreeObject(arg2); 9942f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 9943f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_OR: 99447089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard bakd = ctxt->context->doc; 99457089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard bak = ctxt->context->node; 99466000af549b49464a3b1947fc582998a1c9ff7c79William M. Brack pp = ctxt->context->proximityPosition; 9947692092b5886073a8cd1c97bb7d57579e4a9cfc3fWilliam M. Brack cs = ctxt->context->contextSize; 9948f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]); 9949556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 9950f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathBooleanFunction(ctxt, 1); 9951f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((ctxt->value == NULL) || (ctxt->value->boolval == 1)) 9952f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 9953f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard arg2 = valuePop(ctxt); 99547089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard ctxt->context->doc = bakd; 99557089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard ctxt->context->node = bak; 99566000af549b49464a3b1947fc582998a1c9ff7c79William M. Brack ctxt->context->proximityPosition = pp; 9957692092b5886073a8cd1c97bb7d57579e4a9cfc3fWilliam M. Brack ctxt->context->contextSize = cs; 9958f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]); 9959556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard if (ctxt->error) { 9960556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard xmlXPathFreeObject(arg2); 9961556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard return(0); 9962556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard } 9963f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathBooleanFunction(ctxt, 1); 9964f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard arg1 = valuePop(ctxt); 9965f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard arg1->boolval |= arg2->boolval; 9966f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard valuePush(ctxt, arg1); 9967f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathFreeObject(arg2); 9968f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 9969f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_EQUAL: 99707089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard bakd = ctxt->context->doc; 99717089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard bak = ctxt->context->node; 99726000af549b49464a3b1947fc582998a1c9ff7c79William M. Brack pp = ctxt->context->proximityPosition; 9973692092b5886073a8cd1c97bb7d57579e4a9cfc3fWilliam M. Brack cs = ctxt->context->contextSize; 9974f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]); 9975556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 99767089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard ctxt->context->doc = bakd; 99777089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard ctxt->context->node = bak; 99786000af549b49464a3b1947fc582998a1c9ff7c79William M. Brack ctxt->context->proximityPosition = pp; 9979692092b5886073a8cd1c97bb7d57579e4a9cfc3fWilliam M. Brack ctxt->context->contextSize = cs; 9980f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]); 9981556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 99820c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack if (op->value) 99830c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack equal = xmlXPathEqualValues(ctxt); 99840c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack else 99850c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack equal = xmlXPathNotEqualValues(ctxt); 99860c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack valuePush(ctxt, xmlXPathNewBoolean(equal)); 9987f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 9988f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_CMP: 99897089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard bakd = ctxt->context->doc; 99907089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard bak = ctxt->context->node; 99916000af549b49464a3b1947fc582998a1c9ff7c79William M. Brack pp = ctxt->context->proximityPosition; 9992692092b5886073a8cd1c97bb7d57579e4a9cfc3fWilliam M. Brack cs = ctxt->context->contextSize; 9993f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]); 9994556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 99957089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard ctxt->context->doc = bakd; 99967089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard ctxt->context->node = bak; 99976000af549b49464a3b1947fc582998a1c9ff7c79William M. Brack ctxt->context->proximityPosition = pp; 9998692092b5886073a8cd1c97bb7d57579e4a9cfc3fWilliam M. Brack ctxt->context->contextSize = cs; 9999f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]); 10000556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 10001f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ret = xmlXPathCompareValues(ctxt, op->value, op->value2); 10002f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard valuePush(ctxt, xmlXPathNewBoolean(ret)); 10003f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 10004f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_PLUS: 100057089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard bakd = ctxt->context->doc; 100067089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard bak = ctxt->context->node; 100076000af549b49464a3b1947fc582998a1c9ff7c79William M. Brack pp = ctxt->context->proximityPosition; 10008692092b5886073a8cd1c97bb7d57579e4a9cfc3fWilliam M. Brack cs = ctxt->context->contextSize; 10009f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]); 10010556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 100117089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard if (op->ch2 != -1) { 100127089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard ctxt->context->doc = bakd; 100137089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard ctxt->context->node = bak; 100146000af549b49464a3b1947fc582998a1c9ff7c79William M. Brack ctxt->context->proximityPosition = pp; 10015692092b5886073a8cd1c97bb7d57579e4a9cfc3fWilliam M. Brack ctxt->context->contextSize = cs; 10016f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]); 100177089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard } 10018556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 10019f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->value == 0) 10020f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathSubValues(ctxt); 10021f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard else if (op->value == 1) 10022f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathAddValues(ctxt); 10023f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard else if (op->value == 2) 10024f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathValueFlipSign(ctxt); 10025f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard else if (op->value == 3) { 10026f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard CAST_TO_NUMBER; 10027f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard CHECK_TYPE0(XPATH_NUMBER); 10028f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10029f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 10030f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_MULT: 100317089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard bakd = ctxt->context->doc; 100327089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard bak = ctxt->context->node; 100336000af549b49464a3b1947fc582998a1c9ff7c79William M. Brack pp = ctxt->context->proximityPosition; 10034692092b5886073a8cd1c97bb7d57579e4a9cfc3fWilliam M. Brack cs = ctxt->context->contextSize; 10035f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]); 10036556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 100377089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard ctxt->context->doc = bakd; 100387089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard ctxt->context->node = bak; 100396000af549b49464a3b1947fc582998a1c9ff7c79William M. Brack ctxt->context->proximityPosition = pp; 10040692092b5886073a8cd1c97bb7d57579e4a9cfc3fWilliam M. Brack ctxt->context->contextSize = cs; 10041f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]); 10042556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 10043f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->value == 0) 10044f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathMultValues(ctxt); 10045f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard else if (op->value == 1) 10046f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathDivValues(ctxt); 10047f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard else if (op->value == 2) 10048f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathModValues(ctxt); 10049f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 10050f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_UNION: 100517089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard bakd = ctxt->context->doc; 100527089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard bak = ctxt->context->node; 100536000af549b49464a3b1947fc582998a1c9ff7c79William M. Brack pp = ctxt->context->proximityPosition; 10054692092b5886073a8cd1c97bb7d57579e4a9cfc3fWilliam M. Brack cs = ctxt->context->contextSize; 10055f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]); 10056556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 100577089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard ctxt->context->doc = bakd; 100587089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard ctxt->context->node = bak; 100596000af549b49464a3b1947fc582998a1c9ff7c79William M. Brack ctxt->context->proximityPosition = pp; 10060692092b5886073a8cd1c97bb7d57579e4a9cfc3fWilliam M. Brack ctxt->context->contextSize = cs; 10061f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]); 10062556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 10063f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard CHECK_TYPE0(XPATH_NODESET); 10064f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard arg2 = valuePop(ctxt); 10065f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10066f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard CHECK_TYPE0(XPATH_NODESET); 10067f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard arg1 = valuePop(ctxt); 10068f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10069f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard arg1->nodesetval = xmlXPathNodeSetMerge(arg1->nodesetval, 10070f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard arg2->nodesetval); 10071f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard valuePush(ctxt, arg1); 10072f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathFreeObject(arg2); 10073f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 10074f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_ROOT: 10075f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathRoot(ctxt); 10076f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 10077f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_NODE: 10078f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch1 != -1) 10079f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]); 10080556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 10081f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch2 != -1) 10082f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]); 10083556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 10084f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard valuePush(ctxt, xmlXPathNewNodeSet(ctxt->context->node)); 10085f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 10086f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_RESET: 10087f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch1 != -1) 10088f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]); 10089556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 10090f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch2 != -1) 10091f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]); 10092556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 10093f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->node = NULL; 10094f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 10095f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_COLLECT:{ 10096f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch1 == -1) 10097f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 10098f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10099f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]); 10100556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 10101f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10102f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* 10103f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Optimization for [n] selection where n is a number 10104f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 10105f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((op->ch2 != -1) && 10106f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (comp->steps[op->ch2].op == XPATH_OP_PREDICATE) && 10107f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (comp->steps[op->ch2].ch1 == -1) && 10108f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (comp->steps[op->ch2].ch2 != -1) && 10109f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (comp->steps[comp->steps[op->ch2].ch2].op == 10110f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard XPATH_OP_VALUE)) { 10111f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathObjectPtr val; 10112f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10113f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard val = comp->steps[comp->steps[op->ch2].ch2].value4; 10114f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((val != NULL) && (val->type == XPATH_NUMBER)) { 10115f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard int indx = (int) val->floatval; 10116f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10117f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (val->floatval == (float) indx) { 10118f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += 10119f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathNodeCollectAndTestNth(ctxt, op, 10120f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard indx, NULL, 10121f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard NULL); 10122f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 10123f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10124f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10125f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10126f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathNodeCollectAndTest(ctxt, op, NULL, NULL); 10127f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 10128f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10129f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_VALUE: 10130f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard valuePush(ctxt, 10131f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathObjectCopy((xmlXPathObjectPtr) op->value4)); 10132f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 10133f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_VARIABLE:{ 10134556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard xmlXPathObjectPtr val; 10135556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard 10136f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch1 != -1) 10137f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += 10138f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]); 10139556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard if (op->value5 == NULL) { 10140556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard val = xmlXPathVariableLookup(ctxt->context, op->value4); 10141556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard if (val == NULL) { 10142556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard ctxt->error = XPATH_UNDEF_VARIABLE_ERROR; 10143556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard return(0); 10144556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard } 10145556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard valuePush(ctxt, val); 10146556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard } else { 10147f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard const xmlChar *URI; 10148f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10149f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard URI = xmlXPathNsLookup(ctxt->context, op->value5); 10150f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (URI == NULL) { 10151f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, 10152cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard "xmlXPathCompOpEval: variable %s bound to undefined prefix %s\n", 10153f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard op->value4, op->value5); 10154f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 10155f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10156556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard val = xmlXPathVariableLookupNS(ctxt->context, 10157556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard op->value4, URI); 10158556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard if (val == NULL) { 10159556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard ctxt->error = XPATH_UNDEF_VARIABLE_ERROR; 10160556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard return(0); 10161556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard } 10162556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard valuePush(ctxt, val); 10163f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10164f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 10165f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10166f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_FUNCTION:{ 10167f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathFunction func; 10168f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard const xmlChar *oldFunc, *oldFuncURI; 10169556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard int i; 10170f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10171f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch1 != -1) 10172f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += 10173f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]); 10174556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard if (ctxt->valueNr < op->value) { 10175556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, 10176cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard "xmlXPathCompOpEval: parameter error\n"); 10177556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard ctxt->error = XPATH_INVALID_OPERAND; 10178556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard return (total); 10179556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard } 10180556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard for (i = 0; i < op->value; i++) 10181556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard if (ctxt->valueTab[(ctxt->valueNr - 1) - i] == NULL) { 10182556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, 10183cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard "xmlXPathCompOpEval: parameter error\n"); 10184556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard ctxt->error = XPATH_INVALID_OPERAND; 10185556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard return (total); 10186556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard } 10187f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->cache != NULL) 10188f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard func = (xmlXPathFunction) op->cache; 10189f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard else { 10190f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard const xmlChar *URI = NULL; 10191f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10192f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->value5 == NULL) 10193f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard func = 10194f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathFunctionLookup(ctxt->context, 10195f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard op->value4); 10196f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard else { 10197f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard URI = xmlXPathNsLookup(ctxt->context, op->value5); 10198f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (URI == NULL) { 10199f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, 10200cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard "xmlXPathCompOpEval: function %s bound to undefined prefix %s\n", 10201f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard op->value4, op->value5); 10202f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 10203f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10204f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard func = xmlXPathFunctionLookupNS(ctxt->context, 10205f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard op->value4, URI); 10206f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10207f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (func == NULL) { 10208f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, 10209cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard "xmlXPathCompOpEval: function %s not found\n", 10210f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard op->value4); 10211f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard XP_ERROR0(XPATH_UNKNOWN_FUNC_ERROR); 10212f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10213f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard op->cache = (void *) func; 10214f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard op->cacheURI = (void *) URI; 10215f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10216f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard oldFunc = ctxt->context->function; 10217f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard oldFuncURI = ctxt->context->functionURI; 10218f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->function = op->value4; 10219f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->functionURI = op->cacheURI; 10220f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard func(ctxt, op->value); 10221f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->function = oldFunc; 10222f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->functionURI = oldFuncURI; 10223f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 10224f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10225f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_ARG: 10226088bf1163080cbbb72ba9d4a52ab08cc7c8ff6c7Daniel Veillard bakd = ctxt->context->doc; 10227088bf1163080cbbb72ba9d4a52ab08cc7c8ff6c7Daniel Veillard bak = ctxt->context->node; 10228f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch1 != -1) 10229f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]); 10230088bf1163080cbbb72ba9d4a52ab08cc7c8ff6c7Daniel Veillard ctxt->context->doc = bakd; 10231088bf1163080cbbb72ba9d4a52ab08cc7c8ff6c7Daniel Veillard ctxt->context->node = bak; 10232556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 10233f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch2 != -1) 10234f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]); 10235088bf1163080cbbb72ba9d4a52ab08cc7c8ff6c7Daniel Veillard ctxt->context->doc = bakd; 10236088bf1163080cbbb72ba9d4a52ab08cc7c8ff6c7Daniel Veillard ctxt->context->node = bak; 10237556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 10238f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 10239f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_PREDICATE: 10240f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_FILTER:{ 10241f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathObjectPtr res; 10242f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathObjectPtr obj, tmp; 10243f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlNodeSetPtr newset = NULL; 10244f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlNodeSetPtr oldset; 10245f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlNodePtr oldnode; 10246f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard int i; 10247f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10248f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* 10249f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Optimization for ()[1] selection i.e. the first elem 10250f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 10251f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((op->ch1 != -1) && (op->ch2 != -1) && 10252f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (comp->steps[op->ch1].op == XPATH_OP_SORT) && 10253f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (comp->steps[op->ch2].op == XPATH_OP_VALUE)) { 10254f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathObjectPtr val; 10255f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10256f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard val = comp->steps[op->ch2].value4; 10257f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((val != NULL) && (val->type == XPATH_NUMBER) && 10258f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (val->floatval == 1.0)) { 10259f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlNodePtr first = NULL; 10260f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10261f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += 10262f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathCompOpEvalFirst(ctxt, 10263f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard &comp->steps[op->ch1], 10264f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard &first); 10265556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 10266f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* 10267f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * The nodeset should be in document order, 10268f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Keep only the first value 10269f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 10270f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((ctxt->value != NULL) && 10271f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (ctxt->value->type == XPATH_NODESET) && 10272f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (ctxt->value->nodesetval != NULL) && 10273f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (ctxt->value->nodesetval->nodeNr > 1)) 10274f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->value->nodesetval->nodeNr = 1; 10275f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 10276f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10277f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10278f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* 10279f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Optimization for ()[last()] selection i.e. the last elem 10280f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 10281f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((op->ch1 != -1) && (op->ch2 != -1) && 10282f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (comp->steps[op->ch1].op == XPATH_OP_SORT) && 10283f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (comp->steps[op->ch2].op == XPATH_OP_SORT)) { 10284f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard int f = comp->steps[op->ch2].ch1; 10285f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10286f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((f != -1) && 10287f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (comp->steps[f].op == XPATH_OP_FUNCTION) && 10288f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (comp->steps[f].value5 == NULL) && 10289f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (comp->steps[f].value == 0) && 10290f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (comp->steps[f].value4 != NULL) && 10291f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (xmlStrEqual 10292f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (comp->steps[f].value4, BAD_CAST "last"))) { 10293f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlNodePtr last = NULL; 10294f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10295f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += 10296f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathCompOpEvalLast(ctxt, 10297f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard &comp->steps[op->ch1], 10298f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard &last); 10299556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 10300f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* 10301f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * The nodeset should be in document order, 10302f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Keep only the last value 10303f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 10304f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((ctxt->value != NULL) && 10305f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (ctxt->value->type == XPATH_NODESET) && 10306f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (ctxt->value->nodesetval != NULL) && 10307f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (ctxt->value->nodesetval->nodeTab != NULL) && 10308f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (ctxt->value->nodesetval->nodeNr > 1)) { 10309f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->value->nodesetval->nodeTab[0] = 10310f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->value->nodesetval->nodeTab[ctxt-> 10311f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard value-> 10312f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard nodesetval-> 10313f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard nodeNr - 10314f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 1]; 10315f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->value->nodesetval->nodeNr = 1; 10316f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10317f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 10318f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10319f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10320f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10321f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch1 != -1) 10322f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += 10323f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]); 10324556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 10325f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch2 == -1) 10326f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 10327f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (ctxt->value == NULL) 10328f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 10329f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10330f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard oldnode = ctxt->context->node; 103319e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 10332f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#ifdef LIBXML_XPTR_ENABLED 10333f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* 10334f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Hum are we filtering the result of an XPointer expression 10335f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 10336f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (ctxt->value->type == XPATH_LOCATIONSET) { 10337f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlLocationSetPtr newlocset = NULL; 10338f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlLocationSetPtr oldlocset; 10339f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10340f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* 10341f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Extract the old locset, and then evaluate the result of the 10342f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * expression for all the element in the locset. use it to grow 10343f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * up a new locset. 10344f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 10345f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard CHECK_TYPE0(XPATH_LOCATIONSET); 10346f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard obj = valuePop(ctxt); 10347f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard oldlocset = obj->user; 10348f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->node = NULL; 10349f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10350f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((oldlocset == NULL) || (oldlocset->locNr == 0)) { 10351f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->contextSize = 0; 10352f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->proximityPosition = 0; 10353f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch2 != -1) 10354f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += 10355f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathCompOpEval(ctxt, 10356f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard &comp->steps[op->ch2]); 10357f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard res = valuePop(ctxt); 10358f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (res != NULL) 10359f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathFreeObject(res); 10360f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard valuePush(ctxt, obj); 10361f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard CHECK_ERROR0; 10362f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 10363f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10364f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard newlocset = xmlXPtrLocationSetCreate(NULL); 10365f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10366f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard for (i = 0; i < oldlocset->locNr; i++) { 10367f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* 10368f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Run the evaluation with a node list made of a 10369f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * single item in the nodelocset. 10370f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 10371f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->node = oldlocset->locTab[i]->user; 10372f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard tmp = xmlXPathNewNodeSet(ctxt->context->node); 10373f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard valuePush(ctxt, tmp); 10374f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->contextSize = oldlocset->locNr; 10375f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->proximityPosition = i + 1; 10376f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10377f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch2 != -1) 10378f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += 10379f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathCompOpEval(ctxt, 10380f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard &comp->steps[op->ch2]); 10381f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard CHECK_ERROR0; 10382f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10383f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* 10384f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * The result of the evaluation need to be tested to 10385f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * decided whether the filter succeeded or not 10386f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 10387f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard res = valuePop(ctxt); 10388f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (xmlXPathEvaluatePredicateResult(ctxt, res)) { 10389f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPtrLocationSetAdd(newlocset, 10390f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathObjectCopy 10391f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (oldlocset->locTab[i])); 10392f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10393f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10394f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* 10395f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Cleanup 10396f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 10397f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (res != NULL) 10398f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathFreeObject(res); 10399f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (ctxt->value == tmp) { 10400f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard res = valuePop(ctxt); 10401f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathFreeObject(res); 10402f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10403f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10404f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->node = NULL; 10405f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10406f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10407f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* 10408f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * The result is used as the new evaluation locset. 10409f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 10410f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathFreeObject(obj); 10411f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->node = NULL; 10412f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->contextSize = -1; 10413f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->proximityPosition = -1; 10414f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard valuePush(ctxt, xmlXPtrWrapLocationSet(newlocset)); 10415f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->node = oldnode; 10416f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 10417f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 104189e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard#endif /* LIBXML_XPTR_ENABLED */ 104199e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 10420f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* 10421f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Extract the old set, and then evaluate the result of the 10422f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * expression for all the element in the set. use it to grow 10423f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * up a new set. 10424f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 10425f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard CHECK_TYPE0(XPATH_NODESET); 10426f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard obj = valuePop(ctxt); 10427f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard oldset = obj->nodesetval; 10428f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10429f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard oldnode = ctxt->context->node; 10430f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->node = NULL; 10431f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10432f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((oldset == NULL) || (oldset->nodeNr == 0)) { 10433f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->contextSize = 0; 10434f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->proximityPosition = 0; 10435f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch2 != -1) 10436f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += 10437f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathCompOpEval(ctxt, 10438f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard &comp->steps[op->ch2]); 10439556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 10440f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard res = valuePop(ctxt); 10441f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (res != NULL) 10442f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathFreeObject(res); 10443f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard valuePush(ctxt, obj); 10444f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->node = oldnode; 10445f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard CHECK_ERROR0; 10446f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } else { 10447f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* 10448f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Initialize the new set. 10449f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 10450f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard newset = xmlXPathNodeSetCreate(NULL); 10451f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10452f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard for (i = 0; i < oldset->nodeNr; i++) { 10453f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* 10454f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Run the evaluation with a node list made of 10455f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * a single item in the nodeset. 10456f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 10457f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->node = oldset->nodeTab[i]; 10458f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard tmp = xmlXPathNewNodeSet(ctxt->context->node); 10459f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard valuePush(ctxt, tmp); 10460f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->contextSize = oldset->nodeNr; 10461f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->proximityPosition = i + 1; 10462f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10463f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch2 != -1) 10464f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += 10465f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathCompOpEval(ctxt, 10466f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard &comp->steps[op->ch2]); 10467f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard CHECK_ERROR0; 10468f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10469f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* 10470f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * The result of the evaluation need to be tested to 10471f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * decided whether the filter succeeded or not 10472f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 10473f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard res = valuePop(ctxt); 10474f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (xmlXPathEvaluatePredicateResult(ctxt, res)) { 10475f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathNodeSetAdd(newset, oldset->nodeTab[i]); 10476f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10477f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10478f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* 10479f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Cleanup 10480f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 10481f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (res != NULL) 10482f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathFreeObject(res); 10483f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (ctxt->value == tmp) { 10484f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard res = valuePop(ctxt); 10485f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathFreeObject(res); 10486f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10487f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10488f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->node = NULL; 10489f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10490f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10491f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* 10492f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * The result is used as the new evaluation set. 10493f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 10494f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathFreeObject(obj); 10495f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->node = NULL; 10496f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->contextSize = -1; 10497f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->proximityPosition = -1; 10498f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard valuePush(ctxt, xmlXPathWrapNodeSet(newset)); 10499f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10500f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->node = oldnode; 10501f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 10502f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10503f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_SORT: 10504f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch1 != -1) 10505f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]); 10506556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 10507f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((ctxt->value != NULL) && 10508f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (ctxt->value->type == XPATH_NODESET) && 10509f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (ctxt->value->nodesetval != NULL)) 10510f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathNodeSetSort(ctxt->value->nodesetval); 10511f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 105129e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard#ifdef LIBXML_XPTR_ENABLED 10513f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_RANGETO:{ 10514f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathObjectPtr range; 10515f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathObjectPtr res, obj; 10516f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathObjectPtr tmp; 10517f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlLocationSetPtr newset = NULL; 10518f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlNodeSetPtr oldset; 10519f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard int i; 10520f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10521f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch1 != -1) 10522f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += 10523f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]); 10524f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch2 == -1) 10525f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 10526f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10527f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard CHECK_TYPE0(XPATH_NODESET); 10528f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard obj = valuePop(ctxt); 10529f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard oldset = obj->nodesetval; 10530f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->node = NULL; 10531f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10532f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard newset = xmlXPtrLocationSetCreate(NULL); 10533f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10534f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (oldset != NULL) { 10535f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard for (i = 0; i < oldset->nodeNr; i++) { 10536f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* 10537f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Run the evaluation with a node list made of a single item 10538f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * in the nodeset. 10539f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 10540f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->node = oldset->nodeTab[i]; 10541f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard tmp = xmlXPathNewNodeSet(ctxt->context->node); 10542f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard valuePush(ctxt, tmp); 10543f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10544f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch2 != -1) 10545f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += 10546f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathCompOpEval(ctxt, 10547f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard &comp->steps[op->ch2]); 10548f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard CHECK_ERROR0; 10549f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10550f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* 10551f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * The result of the evaluation need to be tested to 10552f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * decided whether the filter succeeded or not 10553f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 10554f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard res = valuePop(ctxt); 10555f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard range = 10556f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPtrNewRangeNodeObject(oldset->nodeTab[i], 10557f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard res); 10558f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (range != NULL) { 10559f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPtrLocationSetAdd(newset, range); 10560f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10561f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10562f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* 10563f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Cleanup 10564f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 10565f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (res != NULL) 10566f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathFreeObject(res); 10567f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (ctxt->value == tmp) { 10568f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard res = valuePop(ctxt); 10569f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathFreeObject(res); 10570f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10571f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10572f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->node = NULL; 10573f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10574f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10575f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10576f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* 10577f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * The result is used as the new evaluation set. 10578f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 10579f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathFreeObject(obj); 10580f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->node = NULL; 10581f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->contextSize = -1; 10582f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->proximityPosition = -1; 10583f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard valuePush(ctxt, xmlXPtrWrapLocationSet(newset)); 10584f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 10585f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 105869e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard#endif /* LIBXML_XPTR_ENABLED */ 105879e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } 105889e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlGenericError(xmlGenericErrorContext, 10589f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard "XPath: unknown precompiled operation %d\n", op->op); 10590f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 105919e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard} 105929e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 105939e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard/** 105949e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * xmlXPathRunEval: 105959e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * @ctxt: the XPath parser context with the compiled expression 105969e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * 105979e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * Evaluate the Precompiled XPath expression in the given context. 105989e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard */ 10599fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillardstatic void 106009e7160d45a18bfa26d708e22ba991f7670d0128bDaniel VeillardxmlXPathRunEval(xmlXPathParserContextPtr ctxt) { 106019e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlXPathCompExprPtr comp; 106029e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 106039e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if ((ctxt == NULL) || (ctxt->comp == NULL)) 106049e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard return; 106059e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 106069e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (ctxt->valueTab == NULL) { 106079e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard /* Allocate the value stack */ 106089e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard ctxt->valueTab = (xmlXPathObjectPtr *) 106099e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlMalloc(10 * sizeof(xmlXPathObjectPtr)); 106109e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (ctxt->valueTab == NULL) { 106119e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlFree(ctxt); 106129e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } 106139e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard ctxt->valueNr = 0; 106149e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard ctxt->valueMax = 10; 106159e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard ctxt->value = NULL; 106169e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } 106179e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard comp = ctxt->comp; 1061829b6f76c5326616aed5dcff9cb55145137863e97Aleksey Sanin if(comp->last < 0) { 1061929b6f76c5326616aed5dcff9cb55145137863e97Aleksey Sanin xmlGenericError(xmlGenericErrorContext, 1062029b6f76c5326616aed5dcff9cb55145137863e97Aleksey Sanin "xmlXPathRunEval: last is less than zero\n"); 1062129b6f76c5326616aed5dcff9cb55145137863e97Aleksey Sanin return; 1062229b6f76c5326616aed5dcff9cb55145137863e97Aleksey Sanin } 106239e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlXPathCompOpEval(ctxt, &comp->steps[comp->last]); 106249e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard} 106259e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 10626afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard/************************************************************************ 10627afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * * 10628afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Public interfaces * 10629afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * * 10630afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard ************************************************************************/ 10631afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard 10632afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard/** 10633fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * xmlXPathEvalPredicate: 10634fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * @ctxt: the XPath context 10635fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * @res: the Predicate Expression evaluation result 10636fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * 10637fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * Evaluate a predicate result for the current node. 10638fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * A PredicateExpr is evaluated by evaluating the Expr and converting 10639fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * the result to a boolean. If the result is a number, the result will 10640fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * be converted to true if the number is equal to the position of the 10641fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * context node in the context node list (as returned by the position 10642fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * function) and will be converted to false otherwise; if the result 10643fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * is not a number, then the result will be converted as if by a call 10644fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * to the boolean function. 10645fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * 10646cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * Returns 1 if predicate is true, 0 otherwise 10647fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard */ 10648fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillardint 10649fbf8a2d0c8145b713099df63d174154a8442e60dDaniel VeillardxmlXPathEvalPredicate(xmlXPathContextPtr ctxt, xmlXPathObjectPtr res) { 10650fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard if (res == NULL) return(0); 10651fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard switch (res->type) { 10652fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard case XPATH_BOOLEAN: 10653fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard return(res->boolval); 10654fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard case XPATH_NUMBER: 10655fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard return(res->floatval == ctxt->proximityPosition); 10656fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard case XPATH_NODESET: 10657fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard case XPATH_XSLT_TREE: 10658d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard if (res->nodesetval == NULL) 10659d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard return(0); 10660fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard return(res->nodesetval->nodeNr != 0); 10661fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard case XPATH_STRING: 10662fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard return((res->stringval != NULL) && 10663fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard (xmlStrlen(res->stringval) != 0)); 10664fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard default: 10665fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard STRANGE 10666fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard } 10667fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard return(0); 10668fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard} 10669fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard 10670fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard/** 10671afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathEvaluatePredicateResult: 10672afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * @ctxt: the XPath Parser context 10673afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * @res: the Predicate Expression evaluation result 10674afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * 10675afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Evaluate a predicate result for the current node. 10676afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * A PredicateExpr is evaluated by evaluating the Expr and converting 10677afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * the result to a boolean. If the result is a number, the result will 10678afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * be converted to true if the number is equal to the position of the 10679afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * context node in the context node list (as returned by the position 10680afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * function) and will be converted to false otherwise; if the result 10681afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * is not a number, then the result will be converted as if by a call 10682afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * to the boolean function. 10683afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * 10684cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * Returns 1 if predicate is true, 0 otherwise 10685afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard */ 10686afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardint 10687afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathEvaluatePredicateResult(xmlXPathParserContextPtr ctxt, 10688afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathObjectPtr res) { 10689afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard if (res == NULL) return(0); 10690afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard switch (res->type) { 10691afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard case XPATH_BOOLEAN: 10692afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard return(res->boolval); 10693afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard case XPATH_NUMBER: 10694afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard return(res->floatval == ctxt->context->proximityPosition); 10695afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard case XPATH_NODESET: 10696afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard case XPATH_XSLT_TREE: 1069773639a73c5a51c3739595f54c338bb531c1319c2Daniel Veillard if (res->nodesetval == NULL) 10698911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard return(0); 10699afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard return(res->nodesetval->nodeNr != 0); 10700afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard case XPATH_STRING: 10701afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard return((res->stringval != NULL) && 10702afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard (xmlStrlen(res->stringval) != 0)); 10703afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard default: 10704afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard STRANGE 10705afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard } 10706afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard return(0); 10707afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard} 10708afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard 10709afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard/** 10710afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompile: 10711afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * @str: the XPath expression 10712afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * 10713afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile an XPath expression 10714afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * 10715591b4be0fe1986b5e71d54c5c063493987ef4285Daniel Veillard * Returns the xmlXPathCompExprPtr resulting from the compilation or NULL. 10716afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * the caller has to free the object. 10717afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard */ 10718afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompExprPtr 10719afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompile(const xmlChar *str) { 10720afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathParserContextPtr ctxt; 10721afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompExprPtr comp; 10722afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard 10723afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathInit(); 10724afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard 10725afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard ctxt = xmlXPathNewParserContext(str, NULL); 10726afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompileExpr(ctxt); 1072750fe8b1732048003f47b32b009507fe6cdecd39fAleksey Sanin 1072840af649f9b5b32f97879f10432c56bb5ef60c958Daniel Veillard if (*ctxt->cur != 0) { 1072950fe8b1732048003f47b32b009507fe6cdecd39fAleksey Sanin /* 1073050fe8b1732048003f47b32b009507fe6cdecd39fAleksey Sanin * aleksey: in some cases this line prints *second* error message 1073150fe8b1732048003f47b32b009507fe6cdecd39fAleksey Sanin * (see bug #78858) and probably this should be fixed. 1073250fe8b1732048003f47b32b009507fe6cdecd39fAleksey Sanin * However, we are not sure that all error messages are printed 1073350fe8b1732048003f47b32b009507fe6cdecd39fAleksey Sanin * out in other places. It's not critical so we leave it as-is for now 1073450fe8b1732048003f47b32b009507fe6cdecd39fAleksey Sanin */ 1073540af649f9b5b32f97879f10432c56bb5ef60c958Daniel Veillard xmlXPatherror(ctxt, __FILE__, __LINE__, XPATH_EXPR_ERROR); 1073640af649f9b5b32f97879f10432c56bb5ef60c958Daniel Veillard comp = NULL; 1073740af649f9b5b32f97879f10432c56bb5ef60c958Daniel Veillard } else { 1073840af649f9b5b32f97879f10432c56bb5ef60c958Daniel Veillard comp = ctxt->comp; 1073940af649f9b5b32f97879f10432c56bb5ef60c958Daniel Veillard ctxt->comp = NULL; 1074040af649f9b5b32f97879f10432c56bb5ef60c958Daniel Veillard } 10741afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathFreeParserContext(ctxt); 10742f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (comp != NULL) { 10743ceb09b956efa2cf1ec41c1887394396e5a6030f2Daniel Veillard comp->expr = xmlStrdup(str); 10744ceb09b956efa2cf1ec41c1887394396e5a6030f2Daniel Veillard#ifdef DEBUG_EVAL_COUNTS 10745f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard comp->string = xmlStrdup(str); 10746f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard comp->nb = 0; 10747f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#endif 10748ceb09b956efa2cf1ec41c1887394396e5a6030f2Daniel Veillard } 10749afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard return(comp); 10750afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard} 10751afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard 107529e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard/** 107539e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * xmlXPathCompiledEval: 107549e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * @comp: the compiled XPath expression 107559e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * @ctx: the XPath context 107569e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * 107579e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * Evaluate the Precompiled XPath expression in the given context. 107589e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * 10759cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * Returns the xmlXPathObjectPtr resulting from the evaluation or NULL. 107609e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * the caller has to free the object. 107619e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard */ 107629e7160d45a18bfa26d708e22ba991f7670d0128bDaniel VeillardxmlXPathObjectPtr 107639e7160d45a18bfa26d708e22ba991f7670d0128bDaniel VeillardxmlXPathCompiledEval(xmlXPathCompExprPtr comp, xmlXPathContextPtr ctx) { 107649e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlXPathParserContextPtr ctxt; 107659e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlXPathObjectPtr res, tmp, init = NULL; 107669e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard int stack = 0; 107678146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard#ifndef LIBXML_THREAD_ENABLED 107688146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard static int reentance = 0; 107698146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard#endif 107709e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 107719e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if ((comp == NULL) || (ctx == NULL)) 107729e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard return(NULL); 107739e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlXPathInit(); 107749e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 107759e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard CHECK_CONTEXT(ctx) 107769e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 107778146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard#ifndef LIBXML_THREAD_ENABLED 107788146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard reentance++; 107798146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard if (reentance > 1) 107808146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard xmlXPathDisableOptimizer = 1; 107818146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard#endif 107828146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard 10783f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#ifdef DEBUG_EVAL_COUNTS 10784f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard comp->nb++; 10785f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((comp->string != NULL) && (comp->nb > 100)) { 10786f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard fprintf(stderr, "100 x %s\n", comp->string); 10787f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard comp->nb = 0; 10788f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10789f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#endif 107909e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard ctxt = xmlXPathCompParserContext(comp, ctx); 107919e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlXPathRunEval(ctxt); 107929e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 107939e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (ctxt->value == NULL) { 107949e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlGenericError(xmlGenericErrorContext, 10795cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard "xmlXPathCompiledEval: evaluation failed\n"); 107969e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard res = NULL; 107979e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } else { 107989e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard res = valuePop(ctxt); 107999e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } 108009e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 10801f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 108029e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard do { 108039e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard tmp = valuePop(ctxt); 108049e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (tmp != NULL) { 108059e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (tmp != init) 108069e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard stack++; 108079e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlXPathFreeObject(tmp); 108089e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } 108099e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } while (tmp != NULL); 108109e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if ((stack != 0) && (res != NULL)) { 108119e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlGenericError(xmlGenericErrorContext, 10812cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard "xmlXPathCompiledEval: %d object left on the stack\n", 108139e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard stack); 108149e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } 108159e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (ctxt->error != XPATH_EXPRESSION_OK) { 108169e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlXPathFreeObject(res); 108179e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard res = NULL; 108189e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } 108199e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 108209e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 10821afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard ctxt->comp = NULL; 108229e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlXPathFreeParserContext(ctxt); 108238146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard#ifndef LIBXML_THREAD_ENABLED 108248146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard reentance--; 108258146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard#endif 108269e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard return(res); 108279e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard} 108289e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 10829afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard/** 10830afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathEvalExpr: 10831afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * @ctxt: the XPath Parser context 10832afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * 10833afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Parse and evaluate an XPath expression in the given context, 10834afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * then push the result on the context stack 10835afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard */ 10836afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardvoid 10837afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathEvalExpr(xmlXPathParserContextPtr ctxt) { 10838afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompileExpr(ctxt); 1083950fe8b1732048003f47b32b009507fe6cdecd39fAleksey Sanin CHECK_ERROR; 10840afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathRunEval(ctxt); 10841afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard} 108429e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 108433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 108443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathEval: 108453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @str: the XPath expression 108463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctx: the XPath context 108473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 108483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Evaluate the XPath Location Path in the given context. 108493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 10850cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * Returns the xmlXPathObjectPtr resulting from the evaluation or NULL. 108513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the caller has to free the object. 108523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 108533473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathObjectPtr 108543473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathEval(const xmlChar *str, xmlXPathContextPtr ctx) { 108553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathParserContextPtr ctxt; 108563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr res, tmp, init = NULL; 108573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int stack = 0; 108583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 108593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathInit(); 108603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 108613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_CONTEXT(ctx) 108623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 108633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ctxt = xmlXPathNewParserContext(str, ctx); 108643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathEvalExpr(ctxt); 108653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 108663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->value == NULL) { 108673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 108683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "xmlXPathEval: evaluation failed\n"); 108693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor res = NULL; 108703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else if (*ctxt->cur != 0) { 108713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPatherror(ctxt, __FILE__, __LINE__, XPATH_EXPR_ERROR); 108723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor res = NULL; 108733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else { 108743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor res = valuePop(ctxt); 108753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 108763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 108773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor do { 108783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor tmp = valuePop(ctxt); 108793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (tmp != NULL) { 108803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (tmp != init) 108813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor stack++; 108823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(tmp); 108833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 108843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } while (tmp != NULL); 108853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((stack != 0) && (res != NULL)) { 108863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 108873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "xmlXPathEval: %d object left on the stack\n", 108883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor stack); 108893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 108903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->error != XPATH_EXPRESSION_OK) { 108913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(res); 108923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor res = NULL; 108933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 108949e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 108953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeParserContext(ctxt); 108963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(res); 108973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 108983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 108993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 109003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathEvalExpression: 109013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @str: the XPath expression 109023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath context 109033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 109043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Evaluate the XPath expression in the given context. 109053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 109063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the xmlXPathObjectPtr resulting from the evaluation or NULL. 109073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the caller has to free the object. 109083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 109093473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathObjectPtr 109103473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathEvalExpression(const xmlChar *str, xmlXPathContextPtr ctxt) { 109113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathParserContextPtr pctxt; 109123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr res, tmp; 109133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int stack = 0; 109143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 109153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathInit(); 109163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 109173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_CONTEXT(ctxt) 109183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 109193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor pctxt = xmlXPathNewParserContext(str, ctxt); 109203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathEvalExpr(pctxt); 109213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 109223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (*pctxt->cur != 0) { 109233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPatherror(pctxt, __FILE__, __LINE__, XPATH_EXPR_ERROR); 109243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor res = NULL; 109253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else { 109263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor res = valuePop(pctxt); 109273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 109283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor do { 109293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor tmp = valuePop(pctxt); 109303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (tmp != NULL) { 109313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(tmp); 109323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor stack++; 109333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 109343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } while (tmp != NULL); 109353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((stack != 0) && (res != NULL)) { 109363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 109373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "xmlXPathEvalExpression: %d object left on the stack\n", 109383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor stack); 109393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 109403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeParserContext(pctxt); 109413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(res); 109423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 109433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1094442766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard/************************************************************************ 1094542766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * * 1094642766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * Extra functions not pertaining to the XPath spec * 1094742766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * * 1094842766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard ************************************************************************/ 1094942766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard/** 1095042766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * xmlXPathEscapeUriFunction: 1095142766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * @ctxt: the XPath Parser context 1095242766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * @nargs: the number of arguments 1095342766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * 1095442766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * Implement the escape-uri() XPath function 1095542766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * string escape-uri(string $str, bool $escape-reserved) 1095642766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * 1095742766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * This function applies the URI escaping rules defined in section 2 of [RFC 1095842766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * 2396] to the string supplied as $uri-part, which typically represents all 1095942766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * or part of a URI. The effect of the function is to replace any special 1096042766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * character in the string by an escape sequence of the form %xx%yy..., 1096142766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * where xxyy... is the hexadecimal representation of the octets used to 1096242766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * represent the character in UTF-8. 1096342766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * 1096442766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * The set of characters that are escaped depends on the setting of the 1096542766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * boolean argument $escape-reserved. 1096642766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * 1096742766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * If $escape-reserved is true, all characters are escaped other than lower 1096842766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * case letters a-z, upper case letters A-Z, digits 0-9, and the characters 1096942766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * referred to in [RFC 2396] as "marks": specifically, "-" | "_" | "." | "!" 1097042766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * | "~" | "*" | "'" | "(" | ")". The "%" character itself is escaped only 1097142766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * if it is not followed by two hexadecimal digits (that is, 0-9, a-f, and 1097242766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * A-F). 1097342766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * 1097442766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * If $escape-reserved is false, the behavior differs in that characters 1097542766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * referred to in [RFC 2396] as reserved characters are not escaped. These 1097642766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * characters are ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" | "$" | ",". 1097742766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * 1097842766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * [RFC 2396] does not define whether escaped URIs should use lower case or 1097942766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * upper case for hexadecimal digits. To ensure that escaped URIs can be 1098042766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * compared using string comparison functions, this function must always use 1098142766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * the upper-case letters A-F. 1098242766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * 1098342766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * Generally, $escape-reserved should be set to true when escaping a string 1098442766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * that is to form a single part of a URI, and to false when escaping an 1098542766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * entire URI or URI reference. 1098642766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * 1098742766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * In the case of non-ascii characters, the string is encoded according to 1098842766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * utf-8 and then converted according to RFC 2396. 1098942766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * 1099042766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * Examples 1099142766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * xf:escape-uri ("gopher://spinaltap.micro.umn.edu/00/Weather/California/Los%20Angeles#ocean"), true()) 1099242766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * returns "gopher%3A%2F%2Fspinaltap.micro.umn.edu%2F00%2FWeather%2FCalifornia%2FLos%20Angeles%23ocean" 1099342766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * xf:escape-uri ("gopher://spinaltap.micro.umn.edu/00/Weather/California/Los%20Angeles#ocean"), false()) 1099442766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * returns "gopher://spinaltap.micro.umn.edu/00/Weather/California/Los%20Angeles%23ocean" 1099542766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * 1099642766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard */ 10997118aed78f360f51d182770e62b251ef324707aa2Daniel Veillardstatic void 1099842766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel VeillardxmlXPathEscapeUriFunction(xmlXPathParserContextPtr ctxt, int nargs) { 1099942766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard xmlXPathObjectPtr str; 1100042766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard int escape_reserved; 1100142766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard xmlBufferPtr target; 1100242766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard xmlChar *cptr; 1100342766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard xmlChar escape[4]; 1100442766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard 1100542766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard CHECK_ARITY(2); 1100642766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard 1100742766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard escape_reserved = xmlXPathPopBoolean(ctxt); 1100842766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard 1100942766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard CAST_TO_STRING; 1101042766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard str = valuePop(ctxt); 1101142766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard 1101242766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard target = xmlBufferCreate(); 1101342766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard 1101442766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard escape[0] = '%'; 1101542766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard escape[3] = 0; 1101642766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard 1101742766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard if (target) { 1101842766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard for (cptr = str->stringval; *cptr; cptr++) { 1101942766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard if ((*cptr >= 'A' && *cptr <= 'Z') || 1102042766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard (*cptr >= 'a' && *cptr <= 'z') || 1102142766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard (*cptr >= '0' && *cptr <= '9') || 1102242766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard *cptr == '-' || *cptr == '_' || *cptr == '.' || 1102342766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard *cptr == '!' || *cptr == '~' || *cptr == '*' || 1102442766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard *cptr == '\''|| *cptr == '(' || *cptr == ')' || 1102542766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard (*cptr == '%' && 1102642766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard ((cptr[1] >= 'A' && cptr[1] <= 'F') || 1102742766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard (cptr[1] >= 'a' && cptr[1] <= 'f') || 1102842766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard (cptr[1] >= '0' && cptr[1] <= '9')) && 1102942766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard ((cptr[2] >= 'A' && cptr[2] <= 'F') || 1103042766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard (cptr[2] >= 'a' && cptr[2] <= 'f') || 1103142766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard (cptr[2] >= '0' && cptr[2] <= '9'))) || 1103242766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard (!escape_reserved && 1103342766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard (*cptr == ';' || *cptr == '/' || *cptr == '?' || 1103442766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard *cptr == ':' || *cptr == '@' || *cptr == '&' || 1103542766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard *cptr == '=' || *cptr == '+' || *cptr == '$' || 1103642766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard *cptr == ','))) { 1103742766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard xmlBufferAdd(target, cptr, 1); 1103842766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard } else { 1103942766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard if ((*cptr >> 4) < 10) 1104042766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard escape[1] = '0' + (*cptr >> 4); 1104142766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard else 1104242766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard escape[1] = 'A' - 10 + (*cptr >> 4); 1104342766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard if ((*cptr & 0xF) < 10) 1104442766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard escape[2] = '0' + (*cptr & 0xF); 1104542766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard else 1104642766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard escape[2] = 'A' - 10 + (*cptr & 0xF); 1104742766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard 1104842766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard xmlBufferAdd(target, &escape[0], 3); 1104942766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard } 1105042766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard } 1105142766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard } 1105242766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard valuePush(ctxt, xmlXPathNewString(xmlBufferContent(target))); 1105342766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard xmlBufferFree(target); 1105442766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard xmlXPathFreeObject(str); 1105542766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard} 1105642766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard 110573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 110583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathRegisterAllFunctions: 110593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath context 110603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 110613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Registers all default XPath functions in this context 110623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 110633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 110643473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathRegisterAllFunctions(xmlXPathContextPtr ctxt) 110653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor{ 110663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisterFunc(ctxt, (const xmlChar *)"boolean", 110673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathBooleanFunction); 110683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisterFunc(ctxt, (const xmlChar *)"ceiling", 110693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathCeilingFunction); 110703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisterFunc(ctxt, (const xmlChar *)"count", 110713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathCountFunction); 110723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisterFunc(ctxt, (const xmlChar *)"concat", 110733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathConcatFunction); 110743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisterFunc(ctxt, (const xmlChar *)"contains", 110753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathContainsFunction); 110763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisterFunc(ctxt, (const xmlChar *)"id", 110773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathIdFunction); 110783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisterFunc(ctxt, (const xmlChar *)"false", 110793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFalseFunction); 110803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisterFunc(ctxt, (const xmlChar *)"floor", 110813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFloorFunction); 110823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisterFunc(ctxt, (const xmlChar *)"last", 110833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathLastFunction); 110843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisterFunc(ctxt, (const xmlChar *)"lang", 110853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathLangFunction); 110863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisterFunc(ctxt, (const xmlChar *)"local-name", 110873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathLocalNameFunction); 110883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisterFunc(ctxt, (const xmlChar *)"not", 110893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathNotFunction); 110903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisterFunc(ctxt, (const xmlChar *)"name", 110913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathNameFunction); 110923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisterFunc(ctxt, (const xmlChar *)"namespace-uri", 110933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathNamespaceURIFunction); 110943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisterFunc(ctxt, (const xmlChar *)"normalize-space", 110953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathNormalizeFunction); 110963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisterFunc(ctxt, (const xmlChar *)"number", 110973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathNumberFunction); 110983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisterFunc(ctxt, (const xmlChar *)"position", 110993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathPositionFunction); 111003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisterFunc(ctxt, (const xmlChar *)"round", 111013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRoundFunction); 111023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisterFunc(ctxt, (const xmlChar *)"string", 111033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathStringFunction); 111043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisterFunc(ctxt, (const xmlChar *)"string-length", 111053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathStringLengthFunction); 111063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisterFunc(ctxt, (const xmlChar *)"starts-with", 111073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathStartsWithFunction); 111083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisterFunc(ctxt, (const xmlChar *)"substring", 111093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathSubstringFunction); 111103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisterFunc(ctxt, (const xmlChar *)"substring-before", 111113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathSubstringBeforeFunction); 111123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisterFunc(ctxt, (const xmlChar *)"substring-after", 111133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathSubstringAfterFunction); 111143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisterFunc(ctxt, (const xmlChar *)"sum", 111153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathSumFunction); 111163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisterFunc(ctxt, (const xmlChar *)"true", 111173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathTrueFunction); 111183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisterFunc(ctxt, (const xmlChar *)"translate", 111193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathTranslateFunction); 1112042766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard 1112142766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard xmlXPathRegisterFuncNS(ctxt, (const xmlChar *)"escape-uri", 1112242766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard (const xmlChar *)"http://www.w3.org/2002/08/xquery-functions", 1112342766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard xmlXPathEscapeUriFunction); 111243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 111253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 111263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif /* LIBXML_XPATH_ENABLED */ 11127