xpath.c revision 692092b5886073a8cd1c97bb7d57579e4a9cfc3f
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 * 14 Nov 2000 ht - truncated declaration of xmlXPathEvalRelativeLocationPath 163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * for VMS 173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1934ce8bece2f22cc99d25221b77315cd008f4866bDaniel Veillard#define IN_LIBXML 2070a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese#include "libxml.h" 213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef LIBXML_XPATH_ENABLED 223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include <string.h> 243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef HAVE_SYS_TYPES_H 263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include <sys/types.h> 273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef HAVE_MATH_H 293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include <math.h> 303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef HAVE_FLOAT_H 323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include <float.h> 333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef HAVE_CTYPE_H 353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include <ctype.h> 363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 375792e16f0562d206e1ef4e611f7b43ec53c92149Daniel Veillard#ifdef HAVE_SIGNAL_H 38b45c43be206b8c824558269731128c6a64599a54Daniel Veillard#include <signal.h> 39b45c43be206b8c824558269731128c6a64599a54Daniel Veillard#endif 403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include <libxml/xmlmemory.h> 423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include <libxml/tree.h> 433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include <libxml/valid.h> 443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include <libxml/xpath.h> 453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include <libxml/xpathInternals.h> 463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include <libxml/parserInternals.h> 473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include <libxml/hash.h> 483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef LIBXML_XPTR_ENABLED 493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include <libxml/xpointer.h> 503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef LIBXML_DEBUG_ENABLED 523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include <libxml/debugXML.h> 533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include <libxml/xmlerror.h> 558146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard#include <libxml/threads.h> 563c01b1d81b696fe8624b6d7e26ec0ebffcc7c06bDaniel Veillard#include <libxml/globals.h> 573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/* #define DEBUG */ 593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/* #define DEBUG_STEP */ 60f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard/* #define DEBUG_STEP_NTH */ 613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/* #define DEBUG_EXPR */ 62f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard/* #define DEBUG_EVAL_COUNTS */ 633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 645792e16f0562d206e1ef4e611f7b43ec53c92149Daniel Veillarddouble xmlXPathDivideBy(double f, double fzero); 653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 6620ee8c03107e5d5724765da513d595fdaf290dceDaniel Veillardstatic xmlNs xmlXPathXMLNamespaceStruct = { 6720ee8c03107e5d5724765da513d595fdaf290dceDaniel Veillard NULL, 6820ee8c03107e5d5724765da513d595fdaf290dceDaniel Veillard XML_NAMESPACE_DECL, 6920ee8c03107e5d5724765da513d595fdaf290dceDaniel Veillard XML_XML_NAMESPACE, 7020ee8c03107e5d5724765da513d595fdaf290dceDaniel Veillard BAD_CAST "xml" 7120ee8c03107e5d5724765da513d595fdaf290dceDaniel Veillard}; 7220ee8c03107e5d5724765da513d595fdaf290dceDaniel Veillardstatic xmlNsPtr xmlXPathXMLNamespace = &xmlXPathXMLNamespaceStruct; 73da423da207ec877ed93a7b165c5ef6d6785e8940Daniel Veillard#ifndef LIBXML_THREAD_ENABLED 748146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard/* 758146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard * Optimizer is disabled only when threaded apps are detected while 768146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard * the library ain't compiled for thread safety. 778146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard */ 788146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillardstatic int xmlXPathDisableOptimizer = 0; 798146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard#endif 8020ee8c03107e5d5724765da513d595fdaf290dceDaniel Veillard 819e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard/************************************************************************ 829e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * * 839e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * Floating point stuff * 849e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * * 859e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard ************************************************************************/ 869e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 87c0631a608f62902eca453096f0b2fc5b449b0b0aDaniel Veillard#ifndef TRIO_REPLACE_STDIO 88cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard#define TRIO_PUBLIC static 89c0631a608f62902eca453096f0b2fc5b449b0b0aDaniel Veillard#endif 90cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard#include "trionan.c" 91cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard 923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/* 933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The lack of portability of this section of the libc is annoying ! 943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylordouble xmlXPathNAN = 0; 963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylordouble xmlXPathPINF = 1; 973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylordouble xmlXPathNINF = -1; 985fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillarddouble xmlXPathNZERO = 0; 9920ee8c03107e5d5724765da513d595fdaf290dceDaniel Veillardstatic int xmlXPathInitialized = 0; 1003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 1023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathInit: 1033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 1043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Initialize the XPath environment 1053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 1063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 1073473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathInit(void) { 10820ee8c03107e5d5724765da513d595fdaf290dceDaniel Veillard if (xmlXPathInitialized) return; 1093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 110450296070e14629141738fbb34b9a0ad13af1f02Bjorn Reese xmlXPathPINF = trio_pinf(); 111450296070e14629141738fbb34b9a0ad13af1f02Bjorn Reese xmlXPathNINF = trio_ninf(); 112450296070e14629141738fbb34b9a0ad13af1f02Bjorn Reese xmlXPathNAN = trio_nan(); 1135fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard xmlXPathNZERO = trio_nzero(); 1143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 11520ee8c03107e5d5724765da513d595fdaf290dceDaniel Veillard xmlXPathInitialized = 1; 1163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 1173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 118cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard/** 119cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * xmlXPathIsNaN: 120cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * @val: a double value 121cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * 122cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * Provides a portable isnan() function to detect whether a double 123cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * is a NotaNumber. Based on trio code 124cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * http://sourceforge.net/projects/ctrio/ 125cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * 126cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * Returns 1 if the value is a NaN, 0 otherwise 127cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard */ 128cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillardint 129cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel VeillardxmlXPathIsNaN(double val) { 130cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard return(trio_isnan(val)); 131cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard} 132cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard 133cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard/** 134cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * xmlXPathIsInf: 135cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * @val: a double value 136cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * 137cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * Provides a portable isinf() function to detect whether a double 138cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * is a +Infinite or -Infinite. Based on trio code 139cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * http://sourceforge.net/projects/ctrio/ 140cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * 141cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * Returns 1 vi the value is +Infinite, -1 if -Infinite, 0 otherwise 142cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard */ 143cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillardint 144cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel VeillardxmlXPathIsInf(double val) { 145cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard return(trio_isinf(val)); 146cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard} 147cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard 1485fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard/** 1495fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard * xmlXPathGetSign: 1505fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard * @val: a double value 1515fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard * 1525fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard * Provides a portable function to detect the sign of a double 1535fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard * Modified from trio code 1545fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard * http://sourceforge.net/projects/ctrio/ 1555fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard * 1565fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard * Returns 1 if the value is Negative, 0 if positive 1575fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard */ 15821458c85e209cd2621ac3eadfee075ae2dc0121dDaniel Veillardstatic int 1595fc1f0893af6ffe76453ac16817204a866bdeab2Daniel VeillardxmlXPathGetSign(double val) { 16021458c85e209cd2621ac3eadfee075ae2dc0121dDaniel Veillard return(trio_signbit(val)); 1615fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard} 1625fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard 1635fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard 1643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/************************************************************************ 1659e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * * 1669e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * Parser Types * 1679e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * * 1689e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard ************************************************************************/ 1699e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 1709e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard/* 1719e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * Types are private: 1729e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard */ 1739e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 1749e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillardtypedef enum { 1759e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard XPATH_OP_END=0, 1769e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard XPATH_OP_AND, 1779e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard XPATH_OP_OR, 1789e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard XPATH_OP_EQUAL, 1799e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard XPATH_OP_CMP, 1809e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard XPATH_OP_PLUS, 1819e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard XPATH_OP_MULT, 1829e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard XPATH_OP_UNION, 1839e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard XPATH_OP_ROOT, 1849e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard XPATH_OP_NODE, 1859e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard XPATH_OP_RESET, 1869e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard XPATH_OP_COLLECT, 1879e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard XPATH_OP_VALUE, 1889e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard XPATH_OP_VARIABLE, 1899e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard XPATH_OP_FUNCTION, 1909e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard XPATH_OP_ARG, 1919e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard XPATH_OP_PREDICATE, 192d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard XPATH_OP_FILTER, 1939e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard XPATH_OP_SORT 1949e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard#ifdef LIBXML_XPTR_ENABLED 1959e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard ,XPATH_OP_RANGETO 1969e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard#endif 1979e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard} xmlXPathOp; 1989e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 1999e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillardtypedef enum { 2009e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard AXIS_ANCESTOR = 1, 2019e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard AXIS_ANCESTOR_OR_SELF, 2029e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard AXIS_ATTRIBUTE, 2039e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard AXIS_CHILD, 2049e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard AXIS_DESCENDANT, 2059e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard AXIS_DESCENDANT_OR_SELF, 2069e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard AXIS_FOLLOWING, 2079e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard AXIS_FOLLOWING_SIBLING, 2089e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard AXIS_NAMESPACE, 2099e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard AXIS_PARENT, 2109e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard AXIS_PRECEDING, 2119e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard AXIS_PRECEDING_SIBLING, 2129e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard AXIS_SELF 2139e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard} xmlXPathAxisVal; 2149e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 2159e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillardtypedef enum { 2169e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard NODE_TEST_NONE = 0, 2179e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard NODE_TEST_TYPE = 1, 2189e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard NODE_TEST_PI = 2, 2199e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard NODE_TEST_ALL = 3, 2209e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard NODE_TEST_NS = 4, 2219e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard NODE_TEST_NAME = 5 2229e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard} xmlXPathTestVal; 2239e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 2249e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillardtypedef enum { 2259e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard NODE_TYPE_NODE = 0, 2269e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard NODE_TYPE_COMMENT = XML_COMMENT_NODE, 2279e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard NODE_TYPE_TEXT = XML_TEXT_NODE, 2289e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard NODE_TYPE_PI = XML_PI_NODE 2299e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard} xmlXPathTypeVal; 2309e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 2319e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 2329e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillardtypedef struct _xmlXPathStepOp xmlXPathStepOp; 2339e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillardtypedef xmlXPathStepOp *xmlXPathStepOpPtr; 2349e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillardstruct _xmlXPathStepOp { 2359e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlXPathOp op; 2369e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard int ch1; 2379e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard int ch2; 2389e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard int value; 2399e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard int value2; 2409e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard int value3; 2419e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard void *value4; 2429e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard void *value5; 243e39a93d0d3df9907cf3538cd3f1fbbe4106e893dDaniel Veillard void *cache; 24442596ad20cdf1925dd79ea801cbe598b6e7b7aecDaniel Veillard void *cacheURI; 2459e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard}; 2469e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 2479e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillardstruct _xmlXPathCompExpr { 2489e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard int nbStep; 2499e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard int maxStep; 2509e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlXPathStepOp *steps; /* ops for computation */ 2519e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard int last; 252f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#ifdef DEBUG_EVAL_COUNTS 253f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard int nb; 254f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlChar *string; 255f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#endif 2569e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard}; 2579e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 2589e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard/************************************************************************ 2599e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * * 2609e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * Parser Type functions * 2619e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * * 2629e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard ************************************************************************/ 2639e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 2649e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard/** 2659e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * xmlXPathNewCompExpr: 2669e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * 2679e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * Create a new Xpath component 2689e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * 2699e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * Returns the newly allocated xmlXPathCompExprPtr or NULL in case of error 2709e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard */ 27156a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic xmlXPathCompExprPtr 2729e7160d45a18bfa26d708e22ba991f7670d0128bDaniel VeillardxmlXPathNewCompExpr(void) { 2739e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlXPathCompExprPtr cur; 2749e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 2759e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard cur = (xmlXPathCompExprPtr) xmlMalloc(sizeof(xmlXPathCompExpr)); 2769e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (cur == NULL) { 2779e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlGenericError(xmlGenericErrorContext, 2789e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard "xmlXPathNewCompExpr : malloc failed\n"); 2799e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard return(NULL); 2809e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } 2819e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard memset(cur, 0, sizeof(xmlXPathCompExpr)); 2829e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard cur->maxStep = 10; 2839e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard cur->nbStep = 0; 2849e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard cur->steps = (xmlXPathStepOp *) xmlMalloc(cur->maxStep * 2859e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard sizeof(xmlXPathStepOp)); 2869e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (cur->steps == NULL) { 2879e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlGenericError(xmlGenericErrorContext, 2889e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard "xmlXPathNewCompExpr : malloc failed\n"); 2899e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlFree(cur); 2909e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard return(NULL); 2919e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } 2929e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard memset(cur->steps, 0, cur->maxStep * sizeof(xmlXPathStepOp)); 2939e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard cur->last = -1; 294f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#ifdef DEBUG_EVAL_COUNTS 295f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard cur->nb = 0; 296f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#endif 2979e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard return(cur); 2989e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard} 2999e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 3009e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard/** 3019e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * xmlXPathFreeCompExpr: 3029e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * @comp: an XPATH comp 3039e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * 3049e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * Free up the memory allocated by @comp 3059e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard */ 3069e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillardvoid 307f06307e2c172284bb41376c396f757bdac9bdd19Daniel VeillardxmlXPathFreeCompExpr(xmlXPathCompExprPtr comp) 308f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard{ 3099e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlXPathStepOpPtr op; 3109e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard int i; 3119e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 3129e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (comp == NULL) 313f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return; 314f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard for (i = 0; i < comp->nbStep; i++) { 315f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard op = &comp->steps[i]; 316f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->value4 != NULL) { 317f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->op == XPATH_OP_VALUE) 318f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathFreeObject(op->value4); 319f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard else 320f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlFree(op->value4); 321f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 322f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->value5 != NULL) 323f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlFree(op->value5); 3249e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } 3259e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (comp->steps != NULL) { 326f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlFree(comp->steps); 3279e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } 328f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#ifdef DEBUG_EVAL_COUNTS 329f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (comp->string != NULL) { 330f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlFree(comp->string); 331f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 332f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#endif 333f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 3349e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlFree(comp); 3359e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard} 3369e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 3379e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard/** 3389e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * xmlXPathCompExprAdd: 3399e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * @comp: the compiled expression 3409e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * @ch1: first child index 3419e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * @ch2: second child index 3429e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * @op: an op 3439e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * @value: the first int value 3449e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * @value2: the second int value 3459e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * @value3: the third int value 3469e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * @value4: the first string value 3479e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * @value5: the second string value 3489e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * 3499e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * Add an step to an XPath Compiled Expression 3509e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * 3519e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * Returns -1 in case of failure, the index otherwise 3529e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard */ 35356a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic int 3549e7160d45a18bfa26d708e22ba991f7670d0128bDaniel VeillardxmlXPathCompExprAdd(xmlXPathCompExprPtr comp, int ch1, int ch2, 3559e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlXPathOp op, int value, 3569e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard int value2, int value3, void *value4, void *value5) { 3579e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (comp->nbStep >= comp->maxStep) { 3589e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlXPathStepOp *real; 3599e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 3609e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard comp->maxStep *= 2; 3619e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard real = (xmlXPathStepOp *) xmlRealloc(comp->steps, 3629e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard comp->maxStep * sizeof(xmlXPathStepOp)); 3639e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (real == NULL) { 3649e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard comp->maxStep /= 2; 3659e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlGenericError(xmlGenericErrorContext, 3669e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard "xmlXPathCompExprAdd : realloc failed\n"); 3679e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard return(-1); 3689e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } 3699e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard comp->steps = real; 3709e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } 3719e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard comp->last = comp->nbStep; 3729e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard comp->steps[comp->nbStep].ch1 = ch1; 3739e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard comp->steps[comp->nbStep].ch2 = ch2; 3749e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard comp->steps[comp->nbStep].op = op; 3759e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard comp->steps[comp->nbStep].value = value; 3769e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard comp->steps[comp->nbStep].value2 = value2; 3779e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard comp->steps[comp->nbStep].value3 = value3; 3789e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard comp->steps[comp->nbStep].value4 = value4; 3799e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard comp->steps[comp->nbStep].value5 = value5; 380e39a93d0d3df9907cf3538cd3f1fbbe4106e893dDaniel Veillard comp->steps[comp->nbStep].cache = NULL; 3819e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard return(comp->nbStep++); 3829e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard} 3839e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 384f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard/** 385f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * xmlXPathCompSwap: 386f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * @comp: the compiled expression 387f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * @op: operation index 388f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * 389f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Swaps 2 operations in the compiled expression 390f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 391f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillardstatic void 392f06307e2c172284bb41376c396f757bdac9bdd19Daniel VeillardxmlXPathCompSwap(xmlXPathStepOpPtr op) { 393f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard int tmp; 394f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 395bc6f759ac9b41773e3643ad288b5214732051c98Daniel Veillard#ifndef LIBXML_THREAD_ENABLED 3968146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard /* 3978146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard * Since this manipulates possibly shared variables, this is 3988146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard * disable if one detects that the library is used in a multithreaded 3998146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard * application 4008146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard */ 4018146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard if (xmlXPathDisableOptimizer) 4028146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard return; 4038146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard#endif 4048146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard 405f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard tmp = op->ch1; 406f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard op->ch1 = op->ch2; 407f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard op->ch2 = tmp; 408f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard} 409f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 410d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#define PUSH_FULL_EXPR(op, op1, op2, val, val2, val3, val4, val5) \ 411d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard xmlXPathCompExprAdd(ctxt->comp, (op1), (op2), \ 412d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard (op), (val), (val2), (val3), (val4), (val5)) 4139e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard#define PUSH_LONG_EXPR(op, val, val2, val3, val4, val5) \ 4149e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlXPathCompExprAdd(ctxt->comp, ctxt->comp->last, -1, \ 4159e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard (op), (val), (val2), (val3), (val4), (val5)) 4169e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 4179e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard#define PUSH_LEAVE_EXPR(op, val, val2) \ 4189e7160d45a18bfa26d708e22ba991f7670d0128bDaniel VeillardxmlXPathCompExprAdd(ctxt->comp, -1, -1, (op), (val), (val2), 0 ,NULL ,NULL) 4199e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 4209e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard#define PUSH_UNARY_EXPR(op, ch, val, val2) \ 4219e7160d45a18bfa26d708e22ba991f7670d0128bDaniel VeillardxmlXPathCompExprAdd(ctxt->comp, (ch), -1, (op), (val), (val2), 0 ,NULL ,NULL) 4229e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 4239e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard#define PUSH_BINARY_EXPR(op, ch1, ch2, val, val2) \ 4249e7160d45a18bfa26d708e22ba991f7670d0128bDaniel VeillardxmlXPathCompExprAdd(ctxt->comp, (ch1), (ch2), (op), (val), (val2), 0 ,NULL ,NULL) 4259e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 4269e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard/************************************************************************ 4273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * * 4283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Debugging related functions * 4293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * * 4303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ************************************************************************/ 4313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 4323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define TODO \ 4333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, \ 4343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "Unimplemented block at %s:%d\n", \ 4353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor __FILE__, __LINE__); 4363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 4373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define STRANGE \ 4383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, \ 4393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "Internal error at %s:%d\n", \ 4403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor __FILE__, __LINE__); 4413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 4423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef LIBXML_DEBUG_ENABLED 44356a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic void 44456a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel VeillardxmlXPathDebugDumpNode(FILE *output, xmlNodePtr cur, int depth) { 4453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int i; 4463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor char shift[100]; 4473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 4483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor for (i = 0;((i < depth) && (i < 25));i++) 4493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor shift[2 * i] = shift[2 * i + 1] = ' '; 4503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor shift[2 * i] = shift[2 * i + 1] = 0; 4513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == NULL) { 4523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, shift); 4533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, "Node is NULL !\n"); 4543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return; 4553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 4563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 4573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 4583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((cur->type == XML_DOCUMENT_NODE) || 4593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor (cur->type == XML_HTML_DOCUMENT_NODE)) { 4603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, shift); 4613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, " /\n"); 4623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else if (cur->type == XML_ATTRIBUTE_NODE) 4633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlDebugDumpAttr(output, (xmlAttrPtr)cur, depth); 4643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else 4653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlDebugDumpOneNode(output, cur, depth); 4663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 46756a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic void 46856a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel VeillardxmlXPathDebugDumpNodeList(FILE *output, xmlNodePtr cur, int depth) { 469f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard xmlNodePtr tmp; 470f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard int i; 471f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard char shift[100]; 472f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard 473f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard for (i = 0;((i < depth) && (i < 25));i++) 474f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard shift[2 * i] = shift[2 * i + 1] = ' '; 475f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard shift[2 * i] = shift[2 * i + 1] = 0; 476f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard if (cur == NULL) { 477f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard fprintf(output, shift); 478f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard fprintf(output, "Node is NULL !\n"); 479f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard return; 480f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard 481f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard } 482f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard 483f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard while (cur != NULL) { 484f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard tmp = cur; 485f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard cur = cur->next; 486f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard xmlDebugDumpOneNode(output, tmp, depth); 487f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard } 488f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard} 4893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 49056a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic void 49156a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel VeillardxmlXPathDebugDumpNodeSet(FILE *output, xmlNodeSetPtr cur, int depth) { 4923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int i; 4933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor char shift[100]; 4943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 4953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor for (i = 0;((i < depth) && (i < 25));i++) 4963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor shift[2 * i] = shift[2 * i + 1] = ' '; 4973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor shift[2 * i] = shift[2 * i + 1] = 0; 4983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 4993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == NULL) { 5003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, shift); 5013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, "NodeSet is NULL !\n"); 5023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return; 5033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 5043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 5053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 506911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard if (cur != NULL) { 507911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard fprintf(output, "Set contains %d nodes:\n", cur->nodeNr); 508911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard for (i = 0;i < cur->nodeNr;i++) { 509911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard fprintf(output, shift); 510911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard fprintf(output, "%d", i + 1); 511911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard xmlXPathDebugDumpNode(output, cur->nodeTab[i], depth + 1); 512911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard } 5133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 5143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 5153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 51656a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic void 51756a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel VeillardxmlXPathDebugDumpValueTree(FILE *output, xmlNodeSetPtr cur, int depth) { 518f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard int i; 519f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard char shift[100]; 520f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard 521f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard for (i = 0;((i < depth) && (i < 25));i++) 522f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard shift[2 * i] = shift[2 * i + 1] = ' '; 523f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard shift[2 * i] = shift[2 * i + 1] = 0; 524f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard 525f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard if ((cur == NULL) || (cur->nodeNr == 0) || (cur->nodeTab[0] == NULL)) { 526f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard fprintf(output, shift); 527f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard fprintf(output, "Value Tree is NULL !\n"); 528f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard return; 529f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard 530f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard } 531f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard 532f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard fprintf(output, shift); 533f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard fprintf(output, "%d", i + 1); 534f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard xmlXPathDebugDumpNodeList(output, cur->nodeTab[0]->children, depth + 1); 535f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard} 5363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#if defined(LIBXML_XPTR_ENABLED) 53756a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic void 53856a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel VeillardxmlXPathDebugDumpLocationSet(FILE *output, xmlLocationSetPtr cur, int depth) { 5393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int i; 5403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor char shift[100]; 5413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 5423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor for (i = 0;((i < depth) && (i < 25));i++) 5433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor shift[2 * i] = shift[2 * i + 1] = ' '; 5443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor shift[2 * i] = shift[2 * i + 1] = 0; 5453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 5463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == NULL) { 5473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, shift); 5483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, "LocationSet is NULL !\n"); 5493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return; 5503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 5513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 5523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 5533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor for (i = 0;i < cur->locNr;i++) { 5543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, shift); 5553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, "%d : ", i + 1); 5563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathDebugDumpObject(output, cur->locTab[i], depth + 1); 5573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 5583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 559017b108fcf16dbce05ca7ebd75763f3d888abb5fDaniel Veillard#endif /* LIBXML_XPTR_ENABLED */ 5603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 561afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard/** 562afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathDebugDumpObject: 563afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * @output: the FILE * to dump the output 564afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * @cur: the object to inspect 565afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * @depth: indentation level 566afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * 567afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Dump the content of the object for debugging purposes 568afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard */ 569afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardvoid 570afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathDebugDumpObject(FILE *output, xmlXPathObjectPtr cur, int depth) { 5713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int i; 5723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor char shift[100]; 5733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 5743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor for (i = 0;((i < depth) && (i < 25));i++) 5753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor shift[2 * i] = shift[2 * i + 1] = ' '; 5763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor shift[2 * i] = shift[2 * i + 1] = 0; 5773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 5783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, shift); 5793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 5803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == NULL) { 5813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, "Object is empty (NULL)\n"); 5823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return; 5833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 5843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor switch(cur->type) { 5853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_UNDEFINED: 5863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, "Object is uninitialized\n"); 5873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 5883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_NODESET: 5893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, "Object is a Node Set :\n"); 5903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathDebugDumpNodeSet(output, cur->nodesetval, depth); 5913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 5923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_XSLT_TREE: 5933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, "Object is an XSLT value tree :\n"); 594f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard xmlXPathDebugDumpValueTree(output, cur->nodesetval, depth); 5953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 5963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_BOOLEAN: 5973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, "Object is a Boolean : "); 5983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur->boolval) fprintf(output, "true\n"); 5993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else fprintf(output, "false\n"); 6003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 6013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_NUMBER: 602cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard switch (xmlXPathIsInf(cur->floatval)) { 603357c960e4035ee2fb40d0072bb7bde4533be76f8Daniel Veillard case 1: 6045fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard fprintf(output, "Object is a number : Infinity\n"); 605357c960e4035ee2fb40d0072bb7bde4533be76f8Daniel Veillard break; 606357c960e4035ee2fb40d0072bb7bde4533be76f8Daniel Veillard case -1: 607357c960e4035ee2fb40d0072bb7bde4533be76f8Daniel Veillard fprintf(output, "Object is a number : -Infinity\n"); 608357c960e4035ee2fb40d0072bb7bde4533be76f8Daniel Veillard break; 609357c960e4035ee2fb40d0072bb7bde4533be76f8Daniel Veillard default: 610cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard if (xmlXPathIsNaN(cur->floatval)) { 611357c960e4035ee2fb40d0072bb7bde4533be76f8Daniel Veillard fprintf(output, "Object is a number : NaN\n"); 612d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard } else if (cur->floatval == 0 && xmlXPathGetSign(cur->floatval) != 0) { 613d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard fprintf(output, "Object is a number : 0\n"); 614357c960e4035ee2fb40d0072bb7bde4533be76f8Daniel Veillard } else { 615357c960e4035ee2fb40d0072bb7bde4533be76f8Daniel Veillard fprintf(output, "Object is a number : %0g\n", cur->floatval); 616357c960e4035ee2fb40d0072bb7bde4533be76f8Daniel Veillard } 617357c960e4035ee2fb40d0072bb7bde4533be76f8Daniel Veillard } 6183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 6193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_STRING: 6203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, "Object is a string : "); 6213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlDebugDumpString(output, cur->stringval); 6223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, "\n"); 6233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 6243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_POINT: 6253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, "Object is a point : index %d in node", cur->index); 6263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathDebugDumpNode(output, (xmlNodePtr) cur->user, depth + 1); 6273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, "\n"); 6283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 6293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_RANGE: 6303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((cur->user2 == NULL) || 6313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ((cur->user2 == cur->user) && (cur->index == cur->index2))) { 6323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, "Object is a collapsed range :\n"); 6333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, shift); 6343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur->index >= 0) 6353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, "index %d in ", cur->index); 6363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, "node\n"); 6373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathDebugDumpNode(output, (xmlNodePtr) cur->user, 6383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor depth + 1); 6393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else { 6403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, "Object is a range :\n"); 6413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, shift); 6423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, "From "); 6433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur->index >= 0) 6443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, "index %d in ", cur->index); 6453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, "node\n"); 6463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathDebugDumpNode(output, (xmlNodePtr) cur->user, 6473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor depth + 1); 6483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, shift); 6493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, "To "); 6503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur->index2 >= 0) 6513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, "index %d in ", cur->index2); 6523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, "node\n"); 6533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathDebugDumpNode(output, (xmlNodePtr) cur->user2, 6543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor depth + 1); 6553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, "\n"); 6563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 6573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 6583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_LOCATIONSET: 6593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#if defined(LIBXML_XPTR_ENABLED) 6603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, "Object is a Location Set:\n"); 6613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathDebugDumpLocationSet(output, 6623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor (xmlLocationSetPtr) cur->user, depth); 6633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 6643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 6653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_USERS: 6663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, "Object is user defined\n"); 6673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 6683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 6693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 6709e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 67156a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic void 67256a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel VeillardxmlXPathDebugDumpStepOp(FILE *output, xmlXPathCompExprPtr comp, 6739e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlXPathStepOpPtr op, int depth) { 6749e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard int i; 6759e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard char shift[100]; 6769e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 6779e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard for (i = 0;((i < depth) && (i < 25));i++) 6789e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard shift[2 * i] = shift[2 * i + 1] = ' '; 6799e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard shift[2 * i] = shift[2 * i + 1] = 0; 6809e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 6819e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, shift); 6829e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (op == NULL) { 6839e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "Step is NULL\n"); 6849e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard return; 6859e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } 6869e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard switch (op->op) { 6879e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case XPATH_OP_END: 6889e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "END"); break; 6899e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case XPATH_OP_AND: 6909e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "AND"); break; 6919e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case XPATH_OP_OR: 6929e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "OR"); break; 6939e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case XPATH_OP_EQUAL: 6949e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (op->value) 6959e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "EQUAL ="); 6969e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard else 6979e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "EQUAL !="); 6989e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard break; 6999e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case XPATH_OP_CMP: 7009e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (op->value) 7019e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "CMP <"); 7029e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard else 7039e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "CMP >"); 7049e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (!op->value2) 7059e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "="); 7069e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard break; 7079e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case XPATH_OP_PLUS: 7089e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (op->value == 0) 7099e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "PLUS -"); 7109e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard else if (op->value == 1) 7119e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "PLUS +"); 7129e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard else if (op->value == 2) 7139e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "PLUS unary -"); 7149e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard else if (op->value == 3) 7159e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "PLUS unary - -"); 7169e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard break; 7179e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case XPATH_OP_MULT: 7189e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (op->value == 0) 7199e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "MULT *"); 7209e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard else if (op->value == 1) 7219e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "MULT div"); 7229e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard else 7239e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "MULT mod"); 7249e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard break; 7259e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case XPATH_OP_UNION: 7269e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "UNION"); break; 7279e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case XPATH_OP_ROOT: 7289e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "ROOT"); break; 7299e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case XPATH_OP_NODE: 7309e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "NODE"); break; 7319e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case XPATH_OP_RESET: 7329e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "RESET"); break; 7339e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case XPATH_OP_SORT: 7349e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "SORT"); break; 7359e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case XPATH_OP_COLLECT: { 7369e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlXPathAxisVal axis = op->value; 7379e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlXPathTestVal test = op->value2; 7389e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlXPathTypeVal type = op->value3; 7399e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard const xmlChar *prefix = op->value4; 7409e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard const xmlChar *name = op->value5; 7419e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 7429e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "COLLECT "); 7439e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard switch (axis) { 7449e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case AXIS_ANCESTOR: 7459e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, " 'ancestors' "); break; 7469e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case AXIS_ANCESTOR_OR_SELF: 7479e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, " 'ancestors-or-self' "); break; 7489e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case AXIS_ATTRIBUTE: 7499e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, " 'attributes' "); break; 7509e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case AXIS_CHILD: 7519e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, " 'child' "); break; 7529e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case AXIS_DESCENDANT: 7539e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, " 'descendant' "); break; 7549e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case AXIS_DESCENDANT_OR_SELF: 7559e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, " 'descendant-or-self' "); break; 7569e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case AXIS_FOLLOWING: 7579e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, " 'following' "); break; 7589e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case AXIS_FOLLOWING_SIBLING: 7599e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, " 'following-siblings' "); break; 7609e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case AXIS_NAMESPACE: 7619e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, " 'namespace' "); break; 7629e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case AXIS_PARENT: 7639e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, " 'parent' "); break; 7649e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case AXIS_PRECEDING: 7659e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, " 'preceding' "); break; 7669e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case AXIS_PRECEDING_SIBLING: 7679e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, " 'preceding-sibling' "); break; 7689e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case AXIS_SELF: 7699e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, " 'self' "); break; 7709e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } 7719e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard switch (test) { 7729e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case NODE_TEST_NONE: 7739e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "'none' "); break; 7749e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case NODE_TEST_TYPE: 7759e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "'type' "); break; 7769e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case NODE_TEST_PI: 7779e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "'PI' "); break; 7789e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case NODE_TEST_ALL: 7799e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "'all' "); break; 7809e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case NODE_TEST_NS: 7819e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "'namespace' "); break; 7829e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case NODE_TEST_NAME: 7839e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "'name' "); break; 7849e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } 7859e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard switch (type) { 7869e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case NODE_TYPE_NODE: 7879e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "'node' "); break; 7889e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case NODE_TYPE_COMMENT: 7899e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "'comment' "); break; 7909e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case NODE_TYPE_TEXT: 7919e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "'text' "); break; 7929e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case NODE_TYPE_PI: 7939e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "'PI' "); break; 7949e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } 7959e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (prefix != NULL) 7969e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "%s:", prefix); 7979e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (name != NULL) 7989e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "%s", name); 7999e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard break; 8009e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 8019e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } 8029e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case XPATH_OP_VALUE: { 8039e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlXPathObjectPtr object = (xmlXPathObjectPtr) op->value4; 8049e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 8059e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "ELEM "); 8069e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlXPathDebugDumpObject(output, object, 0); 8079e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard goto finish; 8089e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } 8099e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case XPATH_OP_VARIABLE: { 8109e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard const xmlChar *prefix = op->value5; 8119e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard const xmlChar *name = op->value4; 8129e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 8139e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (prefix != NULL) 8149e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "VARIABLE %s:%s", prefix, name); 8159e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard else 8169e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "VARIABLE %s", name); 8179e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard break; 8189e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } 8199e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case XPATH_OP_FUNCTION: { 8209e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard int nbargs = op->value; 8219e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard const xmlChar *prefix = op->value5; 8229e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard const xmlChar *name = op->value4; 8239e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 8249e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (prefix != NULL) 8259e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "FUNCTION %s:%s(%d args)", 8269e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard prefix, name, nbargs); 8279e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard else 8289e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "FUNCTION %s(%d args)", name, nbargs); 8299e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard break; 8309e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } 8319e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case XPATH_OP_ARG: fprintf(output, "ARG"); break; 8329e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case XPATH_OP_PREDICATE: fprintf(output, "PREDICATE"); break; 833d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard case XPATH_OP_FILTER: fprintf(output, "FILTER"); break; 834fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard#ifdef LIBXML_XPTR_ENABLED 835fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard case XPATH_OP_RANGETO: fprintf(output, "RANGETO"); break; 836fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard#endif 8379e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard default: 8389e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "UNKNOWN %d\n", op->op); return; 8399e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } 8409e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "\n"); 8419e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillardfinish: 8429e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (op->ch1 >= 0) 8439e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlXPathDebugDumpStepOp(output, comp, &comp->steps[op->ch1], depth + 1); 8449e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (op->ch2 >= 0) 8459e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlXPathDebugDumpStepOp(output, comp, &comp->steps[op->ch2], depth + 1); 8469e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard} 84756a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillard 8485e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard/** 8495e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard * xmlXPathDebugDumpCompExpr: 8505e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard * @output: the FILE * for the output 8515e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard * @comp: the precompiled XPath expression 8525e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard * @depth: the indentation level. 8535e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard * 8545e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard * Dumps the tree of the compiled XPath expression. 8555e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard */ 85656a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardvoid 85756a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel VeillardxmlXPathDebugDumpCompExpr(FILE *output, xmlXPathCompExprPtr comp, 85856a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillard int depth) { 8599e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard int i; 8609e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard char shift[100]; 8619e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 8629e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard for (i = 0;((i < depth) && (i < 25));i++) 8639e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard shift[2 * i] = shift[2 * i + 1] = ' '; 8649e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard shift[2 * i] = shift[2 * i + 1] = 0; 8659e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 8669e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, shift); 8679e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 8689e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (comp == NULL) { 8699e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "Compiled Expression is NULL\n"); 8709e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard return; 8719e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } 8729e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "Compiled Expression : %d elements\n", 8739e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard comp->nbStep); 8749e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard i = comp->last; 8759e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlXPathDebugDumpStepOp(output, comp, &comp->steps[i], depth + 1); 8769e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard} 877017b108fcf16dbce05ca7ebd75763f3d888abb5fDaniel Veillard#endif /* LIBXML_DEBUG_ENABLED */ 8783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 8793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/************************************************************************ 8803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * * 8813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Parser stacks related functions and macros * 8823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * * 8833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ************************************************************************/ 8843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 8853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/* 8863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Generic function for accessing stacks in the Parser Context 8873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 8883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 8893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define PUSH_AND_POP(type, name) \ 8903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorextern int name##Push(xmlXPathParserContextPtr ctxt, type value) { \ 8913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->name##Nr >= ctxt->name##Max) { \ 8923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ctxt->name##Max *= 2; \ 8933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ctxt->name##Tab = (type *) xmlRealloc(ctxt->name##Tab, \ 8943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ctxt->name##Max * sizeof(ctxt->name##Tab[0])); \ 8953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->name##Tab == NULL) { \ 8963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, \ 8973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "realloc failed !\n"); \ 8983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(0); \ 8993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } \ 9003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } \ 9013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ctxt->name##Tab[ctxt->name##Nr] = value; \ 9023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ctxt->name = value; \ 9033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ctxt->name##Nr++); \ 9043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} \ 9053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorextern type name##Pop(xmlXPathParserContextPtr ctxt) { \ 9063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor type ret; \ 9073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->name##Nr <= 0) return(0); \ 9083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ctxt->name##Nr--; \ 9093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->name##Nr > 0) \ 9103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ctxt->name = ctxt->name##Tab[ctxt->name##Nr - 1]; \ 9113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else \ 9123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ctxt->name = NULL; \ 9133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = ctxt->name##Tab[ctxt->name##Nr]; \ 9143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ctxt->name##Tab[ctxt->name##Nr] = 0; \ 9153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ret); \ 9163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} \ 9173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 9185e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard/** 9195e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard * valuePop: 9205e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard * @ctxt: an XPath evaluation context 9215e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard * 9225e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard * Pops the top XPath object from the value stack 9235e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard * 9245e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard * Returns the XPath object just removed 9255e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard */ 9265e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard/** 9275e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard * valuePush: 9285e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard * @ctxt: an XPath evaluation context 9295e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard * @value: the XPath object 9305e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard * 9315e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard * Pushes a new XPath object on top of the value stack 932cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * 933cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * returns the number of items on the value stack 9345e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard */ 9353473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorPUSH_AND_POP(xmlXPathObjectPtr, value) 9363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 937f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/** 938f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathPopBoolean: 939f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @ctxt: an XPath parser context 940f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 941f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Pops a boolean from the stack, handling conversion if needed. 942f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Check error with #xmlXPathCheckError. 943f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 944f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns the boolean 945f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */ 946f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyerint 947f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathPopBoolean (xmlXPathParserContextPtr ctxt) { 948f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathObjectPtr obj; 949f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer int ret; 950f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 951f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer obj = valuePop(ctxt); 952f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (obj == NULL) { 953f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathSetError(ctxt, XPATH_INVALID_OPERAND); 954f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(0); 955f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer } 956f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer ret = xmlXPathCastToBoolean(obj); 957f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathFreeObject(obj); 958f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(ret); 959f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer} 960f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 961f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/** 962f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathPopNumber: 963f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @ctxt: an XPath parser context 964f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 965f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Pops a number from the stack, handling conversion if needed. 966f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Check error with #xmlXPathCheckError. 967f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 968f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns the number 969f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */ 970f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyerdouble 971f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathPopNumber (xmlXPathParserContextPtr ctxt) { 972f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathObjectPtr obj; 973f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer double ret; 974f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 975f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer obj = valuePop(ctxt); 976f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (obj == NULL) { 977f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathSetError(ctxt, XPATH_INVALID_OPERAND); 978f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(0); 979f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer } 980f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer ret = xmlXPathCastToNumber(obj); 981f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathFreeObject(obj); 982f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(ret); 983f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer} 984f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 985f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/** 986f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathPopString: 987f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @ctxt: an XPath parser context 988f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 989f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Pops a string from the stack, handling conversion if needed. 990f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Check error with #xmlXPathCheckError. 991f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 992f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns the string 993f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */ 994f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlChar * 995f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathPopString (xmlXPathParserContextPtr ctxt) { 996f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathObjectPtr obj; 997f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlChar * ret; 998f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 999f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer obj = valuePop(ctxt); 1000f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (obj == NULL) { 1001f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathSetError(ctxt, XPATH_INVALID_OPERAND); 1002f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(NULL); 1003f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer } 1004f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer ret = xmlXPathCastToString(obj); 1005f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer /* TODO: needs refactoring somewhere else */ 1006f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (obj->stringval == ret) 1007f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer obj->stringval = NULL; 1008f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathFreeObject(obj); 1009f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(ret); 1010f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer} 1011f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 1012f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/** 1013f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathPopNodeSet: 1014f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @ctxt: an XPath parser context 1015f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 1016f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Pops a node-set from the stack, handling conversion if needed. 1017f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Check error with #xmlXPathCheckError. 1018f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 1019f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns the node-set 1020f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */ 1021f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlNodeSetPtr 1022f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathPopNodeSet (xmlXPathParserContextPtr ctxt) { 1023f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathObjectPtr obj; 1024f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlNodeSetPtr ret; 1025f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 1026f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (ctxt->value == NULL) { 1027f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathSetError(ctxt, XPATH_INVALID_OPERAND); 1028f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(NULL); 1029f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer } 1030f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (!xmlXPathStackIsNodeSet(ctxt)) { 1031f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathSetTypeError(ctxt); 1032f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(NULL); 1033f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer } 1034f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer obj = valuePop(ctxt); 1035f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer ret = obj->nodesetval; 1036f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathFreeNodeSetList(obj); 1037f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(ret); 1038f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer} 1039f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 1040f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/** 1041f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathPopExternal: 1042f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @ctxt: an XPath parser context 1043f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 1044cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * Pops an external object from the stack, handling conversion if needed. 1045f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Check error with #xmlXPathCheckError. 1046f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 1047f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns the object 1048f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */ 1049f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyervoid * 1050f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathPopExternal (xmlXPathParserContextPtr ctxt) { 1051f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathObjectPtr obj; 1052f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer void * ret; 1053f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 1054f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (ctxt->value == NULL) { 1055f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathSetError(ctxt, XPATH_INVALID_OPERAND); 1056f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(NULL); 1057f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer } 1058f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (ctxt->value->type != XPATH_USERS) { 1059f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathSetTypeError(ctxt); 1060f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(NULL); 1061f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer } 1062f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer obj = valuePop(ctxt); 1063f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer ret = obj->user; 1064f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathFreeObject(obj); 1065f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(ret); 1066f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer} 1067f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 10683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/* 10693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Macros for accessing the content. Those should be used only by the parser, 10703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * and not exported. 10713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 10723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Dirty macros, i.e. one need to make assumption on the context to use them 10733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 10743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * CUR_PTR return the current pointer to the xmlChar to be parsed. 10753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * CUR returns the current xmlChar value, i.e. a 8 bit value 10763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * in ISO-Latin or UTF-8. 10773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * This should be used internally by the parser 10783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * only to compare to ASCII values otherwise it would break when 10793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * running with UTF-8 encoding. 10803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * NXT(n) returns the n'th next xmlChar. Same as CUR is should be used only 10813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * to compare on ASCII based substring. 10823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * SKIP(n) Skip n xmlChar, and must also be used only to skip ASCII defined 10833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * strings within the parser. 10843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * CURRENT Returns the current char value, with the full decoding of 10853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * UTF-8 if we are using this mode. It returns an int. 10863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * NEXT Skip to the next character, this does the proper decoding 10873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * in UTF-8 mode. It also pop-up unfinished entities on the fly. 10883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * It returns the pointer to the current xmlChar. 10893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 10903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 10913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define CUR (*ctxt->cur) 10923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define SKIP(val) ctxt->cur += (val) 10933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define NXT(val) ctxt->cur[(val)] 10943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define CUR_PTR ctxt->cur 109561d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard#define CUR_CHAR(l) xmlXPathCurrentChar(ctxt, &l) 109661d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard 109761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard#define COPY_BUF(l,b,i,v) \ 109861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard if (l == 1) b[i++] = (xmlChar) v; \ 109961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard else i += xmlCopyChar(l,&b[i],v) 110061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard 110161d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard#define NEXTL(l) ctxt->cur += l 11023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 11033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define SKIP_BLANKS \ 11043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while (IS_BLANK(*(ctxt->cur))) NEXT 11053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 11063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define CURRENT (*ctxt->cur) 11073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define NEXT ((*ctxt->cur) ? ctxt->cur++: ctxt->cur) 11083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1109e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese 1110e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese#ifndef DBL_DIG 1111e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese#define DBL_DIG 16 1112e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese#endif 1113e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese#ifndef DBL_EPSILON 1114e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese#define DBL_EPSILON 1E-9 1115e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese#endif 1116e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese 1117e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese#define UPPER_DOUBLE 1E9 1118e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese#define LOWER_DOUBLE 1E-5 1119e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese 1120e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese#define INTEGER_DIGITS DBL_DIG 1121e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese#define FRACTION_DIGITS (DBL_DIG + 1) 1122e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese#define EXPONENT_DIGITS (3 + 2) 1123e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese 1124e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese/** 1125e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese * xmlXPathFormatNumber: 1126e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese * @number: number to format 1127e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese * @buffer: output buffer 1128e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese * @buffersize: size of output buffer 1129e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese * 1130e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese * Convert the number into a string representation. 1131e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese */ 1132e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reesestatic void 1133e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn ReesexmlXPathFormatNumber(double number, char buffer[], int buffersize) 1134e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese{ 1135cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard switch (xmlXPathIsInf(number)) { 1136e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese case 1: 11375fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard if (buffersize > (int)sizeof("Infinity")) 113849cc97565fbe2928388a1e437c44429097a504aeAleksey Sanin snprintf(buffer, buffersize, "Infinity"); 1139e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese break; 1140e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese case -1: 1141e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese if (buffersize > (int)sizeof("-Infinity")) 114249cc97565fbe2928388a1e437c44429097a504aeAleksey Sanin snprintf(buffer, buffersize, "-Infinity"); 1143e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese break; 1144e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese default: 1145cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard if (xmlXPathIsNaN(number)) { 1146e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese if (buffersize > (int)sizeof("NaN")) 114749cc97565fbe2928388a1e437c44429097a504aeAleksey Sanin snprintf(buffer, buffersize, "NaN"); 1148d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard } else if (number == 0 && xmlXPathGetSign(number) != 0) { 114949cc97565fbe2928388a1e437c44429097a504aeAleksey Sanin snprintf(buffer, buffersize, "0"); 115028cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard } else if (number == ((int) number)) { 115128cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard char work[30]; 115228cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard char *ptr, *cur; 115328cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard int res, value = (int) number; 115428cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard 115528cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard ptr = &buffer[0]; 115628cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard if (value < 0) { 115728cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard *ptr++ = '-'; 115828cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard value = -value; 115928cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard } 116028cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard if (value == 0) { 116128cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard *ptr++ = '0'; 116228cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard } else { 116328cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard cur = &work[0]; 116428cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard while (value != 0) { 116528cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard res = value % 10; 116628cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard value = value / 10; 116728cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard *cur++ = '0' + res; 116828cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard } 116928cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard cur--; 117028cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard while ((cur >= &work[0]) && (ptr - buffer < buffersize)) { 117128cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard *ptr++ = *cur--; 117228cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard } 117328cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard } 117428cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard if (ptr - buffer < buffersize) { 117528cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard *ptr = 0; 117628cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard } else if (buffersize > 0) { 117728cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard ptr--; 117828cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard *ptr = 0; 117928cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard } 1180e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese } else { 118170a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese /* 3 is sign, decimal point, and terminating zero */ 118270a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese char work[DBL_DIG + EXPONENT_DIGITS + 3]; 118370a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese int integer_place, fraction_place; 118470a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese char *ptr; 118570a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese char *after_fraction; 118670a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese double absolute_value; 118770a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese int size; 118870a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese 118970a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese absolute_value = fabs(number); 119070a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese 119170a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese /* 119270a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese * First choose format - scientific or regular floating point. 119370a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese * In either case, result is in work, and after_fraction points 119470a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese * just past the fractional part. 119570a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese */ 119670a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese if ( ((absolute_value > UPPER_DOUBLE) || 119770a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese (absolute_value < LOWER_DOUBLE)) && 119870a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese (absolute_value != 0.0) ) { 119970a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese /* Use scientific notation */ 120070a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese integer_place = DBL_DIG + EXPONENT_DIGITS + 1; 120170a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese fraction_place = DBL_DIG - 1; 120270a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese snprintf(work, sizeof(work),"%*.*e", 120370a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese integer_place, fraction_place, number); 120470a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese after_fraction = strchr(work + DBL_DIG, 'e'); 1205e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese } 120670a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese else { 120770a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese /* Use regular notation */ 120856f0646e734ffbdd6945d86cc28b69b6569a82fcDaniel Veillard if (absolute_value > 0.0) 120956f0646e734ffbdd6945d86cc28b69b6569a82fcDaniel Veillard integer_place = 1 + (int)log10(absolute_value); 121056f0646e734ffbdd6945d86cc28b69b6569a82fcDaniel Veillard else 1211a3067d19ec3a96fd6e7997753e27a5422a2856f7Daniel Veillard integer_place = 0; 121270a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese fraction_place = (integer_place > 0) 121370a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese ? DBL_DIG - integer_place 121470a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese : DBL_DIG; 121570a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese size = snprintf(work, sizeof(work), "%0.*f", 121670a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese fraction_place, number); 121770a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese after_fraction = work + size; 1218e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese } 1219e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese 122070a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese /* Remove fractional trailing zeroes */ 122170a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese ptr = after_fraction; 122270a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese while (*(--ptr) == '0') 122370a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese ; 122470a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese if (*ptr != '.') 122570a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese ptr++; 122670a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese strcpy(ptr, after_fraction); 122770a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese 122870a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese /* Finally copy result back to caller */ 122970a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese size = strlen(work) + 1; 123070a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese if (size > buffersize) { 123170a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese work[buffersize - 1] = 0; 123270a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese size = buffersize; 123370a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese } 123470a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese memcpy(buffer, work, size); 1235e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese } 1236e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese break; 1237e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese } 1238e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese} 1239e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese 12403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/************************************************************************ 12413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * * 12423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Error handling routines * 12433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * * 12443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ************************************************************************/ 12453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 12463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1247b44025c72b7472971a061b022cfe422adc42715dDaniel Veillardstatic const char *xmlXPathErrorMessages[] = { 12483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "Ok", 12493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "Number encoding", 1250cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard "Unfinished literal", 1251cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard "Start of literal", 12523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "Expected $ for variable reference", 12533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "Undefined variable", 12543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "Invalid predicate", 12553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "Invalid expression", 12563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "Missing closing curly brace", 12573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "Unregistered function", 12583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "Invalid operand", 12593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "Invalid type", 12603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "Invalid number of arguments", 12613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "Invalid context size", 12623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "Invalid context position", 12633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "Memory allocation error", 12643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "Syntax error", 12653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "Resource error", 12663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "Sub resource error", 126761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard "Undefined namespace prefix", 126861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard "Encoding error", 126961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard "Char out of XML range" 12703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}; 12713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 12723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 12735e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard * xmlXPatherror: 12743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 12753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @file: the file name 12763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @line: the line number 12773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @no: the error number 12783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 1279f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Formats an error message. 12803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 12813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 128221458c85e209cd2621ac3eadfee075ae2dc0121dDaniel VeillardxmlXPatherror(xmlXPathParserContextPtr ctxt, ATTRIBUTE_UNUSED const char *file, 128321458c85e209cd2621ac3eadfee075ae2dc0121dDaniel Veillard ATTRIBUTE_UNUSED int line, int no) { 12843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int n; 12853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor const xmlChar *cur; 12863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor const xmlChar *base; 12873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 12885fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard/* xmlGenericError(xmlGenericErrorContext, 12893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "Error %s:%d: %s\n", file, line, 12903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathErrorMessages[no]); 12915fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard*/ 12925fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard xmlGenericError(xmlGenericErrorContext, 12935fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard "Error %s\n", xmlXPathErrorMessages[no]); 12943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 12953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur = ctxt->cur; 12963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor base = ctxt->base; 1297d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard if ((cur == NULL) || (base == NULL)) 1298d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard return; 1299d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard 13003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while ((cur > base) && ((*cur == '\n') || (*cur == '\r'))) { 13013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur--; 13023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 13033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor n = 0; 13043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while ((n++ < 80) && (cur > base) && (*cur != '\n') && (*cur != '\r')) 13053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur--; 13063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((*cur == '\n') || (*cur == '\r')) cur++; 13073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor base = cur; 13083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor n = 0; 13093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while ((*cur != 0) && (*cur != '\n') && (*cur != '\r') && (n < 79)) { 13103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, "%c", (unsigned char) *cur++); 13113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor n++; 13123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 13133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, "\n"); 13143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur = ctxt->cur; 13153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while ((*cur == '\n') || (*cur == '\r')) 13163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur--; 13173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor n = 0; 13183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while ((cur != base) && (n++ < 80)) { 13193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, " "); 13203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor base++; 13213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 13223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext,"^\n"); 13233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 13243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 13253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 13263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/************************************************************************ 13273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * * 13283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Routines to handle NodeSets * 13293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * * 13303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ************************************************************************/ 13313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 13323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 13333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathCmpNodes: 13343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @node1: the first node 13353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @node2: the second node 13363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 13373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Compare two nodes w.r.t document order 13383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 13393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns -2 in case of error 1 if first point < second point, 0 if 13403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * that's the same node, -1 otherwise 13413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 13423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorint 13433473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathCmpNodes(xmlNodePtr node1, xmlNodePtr node2) { 13443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int depth1, depth2; 13453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlNodePtr cur, root; 13463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 13473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((node1 == NULL) || (node2 == NULL)) 13483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(-2); 13493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 13503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * a couple of optimizations which will avoid computations in most cases 13513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 13523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (node1 == node2) 13533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(0); 1354b33c201978ed1c434877cdc6e2000b7012cc26f9Daniel Veillard if ((node1->type == XML_NAMESPACE_DECL) || 1355b33c201978ed1c434877cdc6e2000b7012cc26f9Daniel Veillard (node2->type == XML_NAMESPACE_DECL)) 1356b33c201978ed1c434877cdc6e2000b7012cc26f9Daniel Veillard return(1); 13573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (node1 == node2->prev) 13583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(1); 13593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (node1 == node2->next) 13603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(-1); 13613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 13623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 13633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * compute depth to root 13643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 13653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor for (depth2 = 0, cur = node2;cur->parent != NULL;cur = cur->parent) { 13663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == node1) 13673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(1); 13683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor depth2++; 13693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 13703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor root = cur; 13713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor for (depth1 = 0, cur = node1;cur->parent != NULL;cur = cur->parent) { 13723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == node2) 13733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(-1); 13743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor depth1++; 13753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 13763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 13773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Distinct document (or distinct entities :-( ) case. 13783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 13793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (root != cur) { 13803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(-2); 13813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 13823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 13833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * get the nearest common ancestor. 13843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 13853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while (depth1 > depth2) { 13863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor depth1--; 13873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor node1 = node1->parent; 13883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 13893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while (depth2 > depth1) { 13903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor depth2--; 13913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor node2 = node2->parent; 13923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 13933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while (node1->parent != node2->parent) { 13943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor node1 = node1->parent; 13953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor node2 = node2->parent; 13963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* should not happen but just in case ... */ 13973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((node1 == NULL) || (node2 == NULL)) 13983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(-2); 13993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 14003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 14013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Find who's first. 14023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 14033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (node1 == node2->next) 14043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(-1); 14053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor for (cur = node1->next;cur != NULL;cur = cur->next) 14063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == node2) 14073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(1); 14083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(-1); /* assume there is no sibling list corruption */ 14093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 14103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 14113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 14123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNodeSetSort: 14133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @set: the node set 14143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 14153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Sort the node set in document order 14163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 14173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 14183473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNodeSetSort(xmlNodeSetPtr set) { 1419e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese int i, j, incr, len; 14203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlNodePtr tmp; 14213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 14223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (set == NULL) 14233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return; 14243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 14253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* Use Shell's sort to sort the node-set */ 14263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor len = set->nodeNr; 14273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor for (incr = len / 2; incr > 0; incr /= 2) { 14283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor for (i = incr; i < len; i++) { 14293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor j = i - incr; 14303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while (j >= 0) { 1431e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese if (xmlXPathCmpNodes(set->nodeTab[j], 1432e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese set->nodeTab[j + incr]) == -1) { 14333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor tmp = set->nodeTab[j]; 14343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor set->nodeTab[j] = set->nodeTab[j + incr]; 14353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor set->nodeTab[j + incr] = tmp; 14363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor j -= incr; 14373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else 14383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 14393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 14403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 14413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 14423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 14433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 14443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define XML_NODESET_DEFAULT 10 14453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 1446044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * xmlXPathNodeSetDupNs: 1447044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * @node: the parent node of the namespace XPath node 1448044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * @ns: the libxml namespace declaration node. 1449044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * 1450044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * Namespace node in libxml don't match the XPath semantic. In a node set 1451044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * the namespace nodes are duplicated and the next pointer is set to the 1452044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * parent node in the XPath semantic. 1453044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * 1454044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * Returns the newly created object. 1455044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard */ 1456044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillardstatic xmlNodePtr 1457044fc6b7476798cbb95277b4905e5111d7c2775dDaniel VeillardxmlXPathNodeSetDupNs(xmlNodePtr node, xmlNsPtr ns) { 1458044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlNsPtr cur; 1459044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard 1460044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if ((ns == NULL) || (ns->type != XML_NAMESPACE_DECL)) 1461044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard return(NULL); 1462044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if ((node == NULL) || (node->type == XML_NAMESPACE_DECL)) 1463044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard return((xmlNodePtr) ns); 1464044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard 1465044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard /* 1466044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * Allocate a new Namespace and fill the fields. 1467044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard */ 1468044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard cur = (xmlNsPtr) xmlMalloc(sizeof(xmlNs)); 1469044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if (cur == NULL) { 1470044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlGenericError(xmlGenericErrorContext, 1471044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard "xmlXPathNodeSetDupNs : malloc failed\n"); 1472044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard return(NULL); 1473044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } 1474044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard memset(cur, 0, sizeof(xmlNs)); 1475044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard cur->type = XML_NAMESPACE_DECL; 1476044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if (ns->href != NULL) 1477044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard cur->href = xmlStrdup(ns->href); 1478044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if (ns->prefix != NULL) 1479044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard cur->prefix = xmlStrdup(ns->prefix); 1480044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard cur->next = (xmlNsPtr) node; 1481044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard return((xmlNodePtr) cur); 1482044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard} 1483044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard 1484044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard/** 1485044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * xmlXPathNodeSetFreeNs: 1486044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * @ns: the XPath namespace node found in a nodeset. 1487044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * 1488044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * Namespace node in libxml don't match the XPath semantic. In a node set 1489044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * the namespace nodes are duplicated and the next pointer is set to the 1490044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * parent node in the XPath semantic. Check if such a node need to be freed 1491044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard */ 1492f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Saninvoid 1493044fc6b7476798cbb95277b4905e5111d7c2775dDaniel VeillardxmlXPathNodeSetFreeNs(xmlNsPtr ns) { 1494044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if ((ns == NULL) || (ns->type != XML_NAMESPACE_DECL)) 1495044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard return; 1496044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard 1497044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if ((ns->next != NULL) && (ns->next->type != XML_NAMESPACE_DECL)) { 1498044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if (ns->href != NULL) 1499044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlFree((xmlChar *)ns->href); 1500044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if (ns->prefix != NULL) 1501044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlFree((xmlChar *)ns->prefix); 1502044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlFree(ns); 1503044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } 1504044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard} 1505044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard 1506044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard/** 15073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNodeSetCreate: 15083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val: an initial xmlNodePtr, or NULL 15093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 15103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Create a new xmlNodeSetPtr of type double and of value @val 15113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 15123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the newly created object. 15133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 15143473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNodeSetPtr 15153473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNodeSetCreate(xmlNodePtr val) { 15163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlNodeSetPtr ret; 15173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 15183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = (xmlNodeSetPtr) xmlMalloc(sizeof(xmlNodeSet)); 15193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ret == NULL) { 15203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 1521cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard "xmlXPathNodeSetCreate: out of memory\n"); 15223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 15233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 15243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor memset(ret, 0 , (size_t) sizeof(xmlNodeSet)); 15253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (val != NULL) { 15263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->nodeTab = (xmlNodePtr *) xmlMalloc(XML_NODESET_DEFAULT * 15273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor sizeof(xmlNodePtr)); 15283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ret->nodeTab == NULL) { 15293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 1530cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard "xmlXPathNodeSetCreate: out of memory\n"); 15313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 15323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 15333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor memset(ret->nodeTab, 0 , 15343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XML_NODESET_DEFAULT * (size_t) sizeof(xmlNodePtr)); 15353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->nodeMax = XML_NODESET_DEFAULT; 1536044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if (val->type == XML_NAMESPACE_DECL) { 1537044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlNsPtr ns = (xmlNsPtr) val; 1538044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard 1539044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard ret->nodeTab[ret->nodeNr++] = 1540044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlXPathNodeSetDupNs((xmlNodePtr) ns->next, ns); 1541044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } else 1542044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard ret->nodeTab[ret->nodeNr++] = val; 15433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 15443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ret); 15453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 15463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 15473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 1548f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathNodeSetContains: 1549f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @cur: the node-set 1550f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @val: the node 1551f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 1552f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * checks whether @cur contains @val 1553f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 1554f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns true (1) if @cur contains @val, false (0) otherwise 1555f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */ 1556f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyerint 1557f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathNodeSetContains (xmlNodeSetPtr cur, xmlNodePtr val) { 1558f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer int i; 1559f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 1560044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if (val->type == XML_NAMESPACE_DECL) { 1561044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard for (i = 0; i < cur->nodeNr; i++) { 1562044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if (cur->nodeTab[i]->type == XML_NAMESPACE_DECL) { 1563044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlNsPtr ns1, ns2; 1564044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard 1565044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard ns1 = (xmlNsPtr) val; 1566044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard ns2 = (xmlNsPtr) cur->nodeTab[i]; 1567044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if (ns1 == ns2) 1568044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard return(1); 1569044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if ((ns1->next != NULL) && (ns2->next == ns1->next) && 1570044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard (xmlStrEqual(ns1->prefix, ns2->prefix))) 1571044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard return(1); 1572044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } 1573044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } 1574044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } else { 1575044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard for (i = 0; i < cur->nodeNr; i++) { 1576044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if (cur->nodeTab[i] == val) 1577044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard return(1); 1578044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } 1579f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer } 1580f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(0); 1581f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer} 1582f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 1583f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/** 1584044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * xmlXPathNodeSetAddNs: 1585044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * @cur: the initial node set 1586044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * @node: the hosting node 1587044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * @ns: a the namespace node 1588044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * 1589044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * add a new namespace node to an existing NodeSet 1590044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard */ 159179376ba94845db7096c3917f4f40baeb450eb0e9Aleksey Saninvoid 1592044fc6b7476798cbb95277b4905e5111d7c2775dDaniel VeillardxmlXPathNodeSetAddNs(xmlNodeSetPtr cur, xmlNodePtr node, xmlNsPtr ns) { 1593044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard int i; 1594044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard 1595044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if ((ns == NULL) || (node == NULL) || (ns->type != XML_NAMESPACE_DECL) || 1596044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard (node->type != XML_ELEMENT_NODE)) 1597044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard return; 1598044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard 1599044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard /* @@ with_ns to check wether namespace nodes should be looked at @@ */ 1600044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard /* 1601044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * check against doublons 1602044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard */ 1603044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard for (i = 0;i < cur->nodeNr;i++) { 1604044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if ((cur->nodeTab[i] != NULL) && 1605044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard (cur->nodeTab[i]->type == XML_NAMESPACE_DECL) && 1606c62a147963b5839fc815267706eaec381f90ca16Daniel Veillard (((xmlNsPtr)cur->nodeTab[i])->next == (xmlNsPtr) node) && 1607044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard (xmlStrEqual(ns->prefix, ((xmlNsPtr)cur->nodeTab[i])->prefix))) 1608044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard return; 1609044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } 1610044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard 1611044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard /* 1612044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * grow the nodeTab if needed 1613044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard */ 1614044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if (cur->nodeMax == 0) { 1615044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard cur->nodeTab = (xmlNodePtr *) xmlMalloc(XML_NODESET_DEFAULT * 1616044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard sizeof(xmlNodePtr)); 1617044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if (cur->nodeTab == NULL) { 1618044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlGenericError(xmlGenericErrorContext, 1619044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard "xmlXPathNodeSetAdd: out of memory\n"); 1620044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard return; 1621044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } 1622044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard memset(cur->nodeTab, 0 , 1623044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard XML_NODESET_DEFAULT * (size_t) sizeof(xmlNodePtr)); 1624044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard cur->nodeMax = XML_NODESET_DEFAULT; 1625044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } else if (cur->nodeNr == cur->nodeMax) { 1626044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlNodePtr *temp; 1627044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard 1628044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard cur->nodeMax *= 2; 1629044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard temp = (xmlNodePtr *) xmlRealloc(cur->nodeTab, cur->nodeMax * 1630044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard sizeof(xmlNodePtr)); 1631044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if (temp == NULL) { 1632044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlGenericError(xmlGenericErrorContext, 1633044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard "xmlXPathNodeSetAdd: out of memory\n"); 1634044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard return; 1635044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } 1636044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard cur->nodeTab = temp; 1637044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } 1638044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard cur->nodeTab[cur->nodeNr++] = xmlXPathNodeSetDupNs(node, ns); 1639044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard} 1640044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard 1641044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard/** 16423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNodeSetAdd: 16433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur: the initial node set 16443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val: a new xmlNodePtr 16453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 1646cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * add a new xmlNodePtr to an existing NodeSet 16473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 16483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 16493473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNodeSetAdd(xmlNodeSetPtr cur, xmlNodePtr val) { 16503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int i; 16513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 16523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (val == NULL) return; 16533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1654044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard /* @@ with_ns to check wether namespace nodes should be looked at @@ */ 16553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 16563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * check against doublons 16573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 16583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor for (i = 0;i < cur->nodeNr;i++) 16593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur->nodeTab[i] == val) return; 16603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 16613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 16623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * grow the nodeTab if needed 16633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 16643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur->nodeMax == 0) { 16653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur->nodeTab = (xmlNodePtr *) xmlMalloc(XML_NODESET_DEFAULT * 16663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor sizeof(xmlNodePtr)); 16673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur->nodeTab == NULL) { 16683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 16693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "xmlXPathNodeSetAdd: out of memory\n"); 16703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return; 16713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 16723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor memset(cur->nodeTab, 0 , 16733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XML_NODESET_DEFAULT * (size_t) sizeof(xmlNodePtr)); 16743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur->nodeMax = XML_NODESET_DEFAULT; 16753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else if (cur->nodeNr == cur->nodeMax) { 16763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlNodePtr *temp; 16773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 16783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur->nodeMax *= 2; 16793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor temp = (xmlNodePtr *) xmlRealloc(cur->nodeTab, cur->nodeMax * 16803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor sizeof(xmlNodePtr)); 16813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (temp == NULL) { 16823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 16833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "xmlXPathNodeSetAdd: out of memory\n"); 16843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return; 16853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 16863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur->nodeTab = temp; 16873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 1688044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if (val->type == XML_NAMESPACE_DECL) { 1689044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlNsPtr ns = (xmlNsPtr) val; 1690044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard 1691044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard cur->nodeTab[cur->nodeNr++] = 1692044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlXPathNodeSetDupNs((xmlNodePtr) ns->next, ns); 1693044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } else 1694044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard cur->nodeTab[cur->nodeNr++] = val; 16953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 16963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 16973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 16983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNodeSetAddUnique: 16993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur: the initial node set 17003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val: a new xmlNodePtr 17013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 1702cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * add a new xmlNodePtr to an existing NodeSet, optimized version 17033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * when we are sure the node is not already in the set. 17043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 17053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 17063473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNodeSetAddUnique(xmlNodeSetPtr cur, xmlNodePtr val) { 17073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (val == NULL) return; 17083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1709044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard /* @@ with_ns to check wether namespace nodes should be looked at @@ */ 17103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 17113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * grow the nodeTab if needed 17123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 17133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur->nodeMax == 0) { 17143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur->nodeTab = (xmlNodePtr *) xmlMalloc(XML_NODESET_DEFAULT * 17153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor sizeof(xmlNodePtr)); 17163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur->nodeTab == NULL) { 17173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 17183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "xmlXPathNodeSetAddUnique: out of memory\n"); 17193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return; 17203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 17213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor memset(cur->nodeTab, 0 , 17223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XML_NODESET_DEFAULT * (size_t) sizeof(xmlNodePtr)); 17233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur->nodeMax = XML_NODESET_DEFAULT; 17243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else if (cur->nodeNr == cur->nodeMax) { 17253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlNodePtr *temp; 17263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 17273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur->nodeMax *= 2; 17283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor temp = (xmlNodePtr *) xmlRealloc(cur->nodeTab, cur->nodeMax * 17293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor sizeof(xmlNodePtr)); 17303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (temp == NULL) { 17313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 17323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "xmlXPathNodeSetAddUnique: out of memory\n"); 17333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return; 17343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 17353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur->nodeTab = temp; 17363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 1737044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if (val->type == XML_NAMESPACE_DECL) { 1738044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlNsPtr ns = (xmlNsPtr) val; 1739044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard 1740044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard cur->nodeTab[cur->nodeNr++] = 1741044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlXPathNodeSetDupNs((xmlNodePtr) ns->next, ns); 1742044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } else 1743044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard cur->nodeTab[cur->nodeNr++] = val; 17443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 17453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 17463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 17473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNodeSetMerge: 17483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val1: the first NodeSet or NULL 17493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val2: the second NodeSet 17503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 17513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Merges two nodesets, all nodes from @val2 are added to @val1 17523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * if @val1 is NULL, a new set is created and copied from @val2 17533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 1754cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * Returns @val1 once extended or NULL in case of error. 17553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 17563473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNodeSetPtr 17573473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNodeSetMerge(xmlNodeSetPtr val1, xmlNodeSetPtr val2) { 1758d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard int i, j, initNr, skip; 17593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 17603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (val2 == NULL) return(val1); 17613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (val1 == NULL) { 17623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor val1 = xmlXPathNodeSetCreate(NULL); 17633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 17643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1765044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard /* @@ with_ns to check wether namespace nodes should be looked at @@ */ 17663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor initNr = val1->nodeNr; 17673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 17683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor for (i = 0;i < val2->nodeNr;i++) { 17693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 17703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * check against doublons 17713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 1772d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard skip = 0; 1773d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard for (j = 0; j < initNr; j++) { 1774d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard if (val1->nodeTab[j] == val2->nodeTab[i]) { 1775d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard skip = 1; 1776d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard break; 1777044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } else if ((val1->nodeTab[j]->type == XML_NAMESPACE_DECL) && 1778044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard (val2->nodeTab[i]->type == XML_NAMESPACE_DECL)) { 1779044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlNsPtr ns1, ns2; 1780044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard ns1 = (xmlNsPtr) val1->nodeTab[j]; 1781044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard ns2 = (xmlNsPtr) val2->nodeTab[i]; 1782044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if ((ns1->next == ns2->next) && 1783044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard (xmlStrEqual(ns1->prefix, ns2->prefix))) { 1784044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard skip = 1; 1785044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard break; 1786044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } 1787d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard } 1788d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard } 1789d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard if (skip) 1790d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard continue; 17913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 17923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 17933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * grow the nodeTab if needed 17943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 17953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (val1->nodeMax == 0) { 17963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor val1->nodeTab = (xmlNodePtr *) xmlMalloc(XML_NODESET_DEFAULT * 17973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor sizeof(xmlNodePtr)); 17983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (val1->nodeTab == NULL) { 17993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 18003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "xmlXPathNodeSetMerge: out of memory\n"); 18013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 18023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 18033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor memset(val1->nodeTab, 0 , 18043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XML_NODESET_DEFAULT * (size_t) sizeof(xmlNodePtr)); 18053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor val1->nodeMax = XML_NODESET_DEFAULT; 18063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else if (val1->nodeNr == val1->nodeMax) { 18073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlNodePtr *temp; 18083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 18093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor val1->nodeMax *= 2; 18103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor temp = (xmlNodePtr *) xmlRealloc(val1->nodeTab, val1->nodeMax * 18113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor sizeof(xmlNodePtr)); 18123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (temp == NULL) { 18133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 18143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "xmlXPathNodeSetMerge: out of memory\n"); 18153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 18163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 18173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor val1->nodeTab = temp; 18183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 1819044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if (val2->nodeTab[i]->type == XML_NAMESPACE_DECL) { 1820044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlNsPtr ns = (xmlNsPtr) val2->nodeTab[i]; 1821044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard 1822044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard val1->nodeTab[val1->nodeNr++] = 1823044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlXPathNodeSetDupNs((xmlNodePtr) ns->next, ns); 1824044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } else 1825044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard val1->nodeTab[val1->nodeNr++] = val2->nodeTab[i]; 18263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 18273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 18283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(val1); 18293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 18303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 18313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 183275be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard * xmlXPathNodeSetMergeUnique: 183375be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard * @val1: the first NodeSet or NULL 183475be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard * @val2: the second NodeSet 183575be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard * 183675be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard * Merges two nodesets, all nodes from @val2 are added to @val1 183775be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard * if @val1 is NULL, a new set is created and copied from @val2 183875be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard * 183975be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard * Returns @val1 once extended or NULL in case of error. 184075be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard */ 184175be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillardstatic xmlNodeSetPtr 184275be0130855fe02d238bbbf19a04d3c5eb45f494Daniel VeillardxmlXPathNodeSetMergeUnique(xmlNodeSetPtr val1, xmlNodeSetPtr val2) { 184375be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard int i, initNr; 184475be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard 184575be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard if (val2 == NULL) return(val1); 184675be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard if (val1 == NULL) { 184775be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard val1 = xmlXPathNodeSetCreate(NULL); 184875be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard } 184975be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard 185075be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard /* @@ with_ns to check wether namespace nodes should be looked at @@ */ 185175be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard initNr = val1->nodeNr; 185275be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard 185375be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard for (i = 0;i < val2->nodeNr;i++) { 185475be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard /* 185575be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard * grow the nodeTab if needed 185675be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard */ 185775be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard if (val1->nodeMax == 0) { 185875be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard val1->nodeTab = (xmlNodePtr *) xmlMalloc(XML_NODESET_DEFAULT * 185975be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard sizeof(xmlNodePtr)); 186075be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard if (val1->nodeTab == NULL) { 186175be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard xmlGenericError(xmlGenericErrorContext, 186275be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard "xmlXPathNodeSetMerge: out of memory\n"); 186375be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard return(NULL); 186475be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard } 186575be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard memset(val1->nodeTab, 0 , 186675be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard XML_NODESET_DEFAULT * (size_t) sizeof(xmlNodePtr)); 186775be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard val1->nodeMax = XML_NODESET_DEFAULT; 186875be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard } else if (val1->nodeNr == val1->nodeMax) { 186975be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard xmlNodePtr *temp; 187075be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard 187175be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard val1->nodeMax *= 2; 187275be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard temp = (xmlNodePtr *) xmlRealloc(val1->nodeTab, val1->nodeMax * 187375be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard sizeof(xmlNodePtr)); 187475be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard if (temp == NULL) { 187575be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard xmlGenericError(xmlGenericErrorContext, 187675be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard "xmlXPathNodeSetMerge: out of memory\n"); 187775be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard return(NULL); 187875be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard } 187975be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard val1->nodeTab = temp; 188075be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard } 188175be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard if (val2->nodeTab[i]->type == XML_NAMESPACE_DECL) { 188275be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard xmlNsPtr ns = (xmlNsPtr) val2->nodeTab[i]; 188375be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard 188475be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard val1->nodeTab[val1->nodeNr++] = 188575be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard xmlXPathNodeSetDupNs((xmlNodePtr) ns->next, ns); 188675be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard } else 188775be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard val1->nodeTab[val1->nodeNr++] = val2->nodeTab[i]; 188875be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard } 188975be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard 189075be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard return(val1); 189175be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard} 189275be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard 189375be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard/** 18943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNodeSetDel: 18953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur: the initial node set 18963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val: an xmlNodePtr 18973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 18983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Removes an xmlNodePtr from an existing NodeSet 18993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 19003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 19013473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNodeSetDel(xmlNodeSetPtr cur, xmlNodePtr val) { 19023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int i; 19033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 19043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == NULL) return; 19053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (val == NULL) return; 19063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 19073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 19083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * check against doublons 19093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 19103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor for (i = 0;i < cur->nodeNr;i++) 19113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur->nodeTab[i] == val) break; 19123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 19133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (i >= cur->nodeNr) { 19143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG 19153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 19163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "xmlXPathNodeSetDel: Node %s wasn't found in NodeList\n", 19173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor val->name); 19183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 19193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return; 19203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 1921044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if ((cur->nodeTab[i] != NULL) && 1922044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard (cur->nodeTab[i]->type == XML_NAMESPACE_DECL)) 1923044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlXPathNodeSetFreeNs((xmlNsPtr) cur->nodeTab[i]); 19243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur->nodeNr--; 19253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor for (;i < cur->nodeNr;i++) 19263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur->nodeTab[i] = cur->nodeTab[i + 1]; 19273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur->nodeTab[cur->nodeNr] = NULL; 19283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 19293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 19303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 19313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNodeSetRemove: 19323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur: the initial node set 19333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val: the index to remove 19343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 19353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Removes an entry from an existing NodeSet list. 19363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 19373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 19383473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNodeSetRemove(xmlNodeSetPtr cur, int val) { 19393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == NULL) return; 19403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (val >= cur->nodeNr) return; 1941044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if ((cur->nodeTab[val] != NULL) && 1942044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard (cur->nodeTab[val]->type == XML_NAMESPACE_DECL)) 1943044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlXPathNodeSetFreeNs((xmlNsPtr) cur->nodeTab[val]); 19443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur->nodeNr--; 19453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor for (;val < cur->nodeNr;val++) 19463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur->nodeTab[val] = cur->nodeTab[val + 1]; 19473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur->nodeTab[cur->nodeNr] = NULL; 19483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 19493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 19503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 19513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathFreeNodeSet: 19523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @obj: the xmlNodeSetPtr to free 19533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 19543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Free the NodeSet compound (not the actual nodes !). 19553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 19563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 19573473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathFreeNodeSet(xmlNodeSetPtr obj) { 19583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (obj == NULL) return; 19593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (obj->nodeTab != NULL) { 1960044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard int i; 1961044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard 1962044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard /* @@ with_ns to check wether namespace nodes should be looked at @@ */ 1963044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard for (i = 0;i < obj->nodeNr;i++) 1964044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if ((obj->nodeTab[i] != NULL) && 1965044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard (obj->nodeTab[i]->type == XML_NAMESPACE_DECL)) 1966044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlXPathNodeSetFreeNs((xmlNsPtr) obj->nodeTab[i]); 19673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(obj->nodeTab); 19683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 19693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(obj); 19703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 19713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 19723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 19733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathFreeValueTree: 19743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @obj: the xmlNodeSetPtr to free 19753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 19763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Free the NodeSet compound and the actual tree, this is different 19773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * from xmlXPathFreeNodeSet() 19783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 197956a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic void 19803473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathFreeValueTree(xmlNodeSetPtr obj) { 19813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int i; 19823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 19833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (obj == NULL) return; 19843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 19853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (obj->nodeTab != NULL) { 1986044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard for (i = 0;i < obj->nodeNr;i++) { 1987044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if (obj->nodeTab[i] != NULL) { 1988044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if (obj->nodeTab[i]->type == XML_NAMESPACE_DECL) { 1989044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlXPathNodeSetFreeNs((xmlNsPtr) obj->nodeTab[i]); 1990044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } else { 1991044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlFreeNodeList(obj->nodeTab[i]); 1992044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } 1993044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } 1994044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } 19953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(obj->nodeTab); 19963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 19973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(obj); 19983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 19993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 20003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#if defined(DEBUG) || defined(DEBUG_STEP) 20013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 20023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlGenericErrorContextNodeSet: 20033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @output: a FILE * for the output 20043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @obj: the xmlNodeSetPtr to free 20053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 20063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Quick display of a NodeSet 20073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 20083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 20093473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlGenericErrorContextNodeSet(FILE *output, xmlNodeSetPtr obj) { 20103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int i; 20113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 20123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (output == NULL) output = xmlGenericErrorContext; 20133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (obj == NULL) { 20143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, "NodeSet == NULL !\n"); 20153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return; 20163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 20173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (obj->nodeNr == 0) { 20183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, "NodeSet is empty\n"); 20193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return; 20203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 20213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (obj->nodeTab == NULL) { 20223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, " nodeTab == NULL !\n"); 20233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return; 20243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 20253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor for (i = 0; i < obj->nodeNr; i++) { 20263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (obj->nodeTab[i] == NULL) { 20273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, " NULL !\n"); 20283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return; 20293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 20303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((obj->nodeTab[i]->type == XML_DOCUMENT_NODE) || 20313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor (obj->nodeTab[i]->type == XML_HTML_DOCUMENT_NODE)) 20323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, " /"); 20333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else if (obj->nodeTab[i]->name == NULL) 20343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, " noname!"); 20353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else fprintf(output, " %s", obj->nodeTab[i]->name); 20363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 20373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, "\n"); 20383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 20393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 20403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 20413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 20423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNewNodeSet: 20433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val: the NodePtr value 20443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 20453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Create a new xmlXPathObjectPtr of type NodeSet and initialize 20463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * it with the single Node @val 20473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 20483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the newly created object. 20493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 20503473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathObjectPtr 20513473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNewNodeSet(xmlNodePtr val) { 20523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr ret; 20533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 20543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject)); 20553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ret == NULL) { 20563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 20573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "xmlXPathNewNodeSet: out of memory\n"); 20583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 20593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 20603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor memset(ret, 0 , (size_t) sizeof(xmlXPathObject)); 20613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->type = XPATH_NODESET; 206277851710aba3a0effdc6af67ea4caf212307420cDaniel Veillard ret->boolval = 0; 20633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->nodesetval = xmlXPathNodeSetCreate(val); 2064044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard /* @@ with_ns to check wether namespace nodes should be looked at @@ */ 20653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ret); 20663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 20673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 20683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 20693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNewValueTree: 20703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val: the NodePtr value 20713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 20723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Create a new xmlXPathObjectPtr of type Value Tree (XSLT) and initialize 20733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * it with the tree root @val 20743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 20753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the newly created object. 20763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 20773473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathObjectPtr 20783473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNewValueTree(xmlNodePtr val) { 20793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr ret; 20803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 20813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject)); 20823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ret == NULL) { 20833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 20843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "xmlXPathNewNodeSet: out of memory\n"); 20853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 20863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 20873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor memset(ret, 0 , (size_t) sizeof(xmlXPathObject)); 20883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->type = XPATH_XSLT_TREE; 20890ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard ret->boolval = 1; 20900ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard ret->user = (void *) val; 20913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->nodesetval = xmlXPathNodeSetCreate(val); 20923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ret); 20933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 20943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 20953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 20963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNewNodeSetList: 20973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val: an existing NodeSet 20983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 20993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Create a new xmlXPathObjectPtr of type NodeSet and initialize 21003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * it with the Nodeset @val 21013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 21023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the newly created object. 21033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 21043473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathObjectPtr 2105044fc6b7476798cbb95277b4905e5111d7c2775dDaniel VeillardxmlXPathNewNodeSetList(xmlNodeSetPtr val) 2106044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard{ 21073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr ret; 21083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int i; 21093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 21103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (val == NULL) 2111044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard ret = NULL; 21123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else if (val->nodeTab == NULL) 2113044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard ret = xmlXPathNewNodeSet(NULL); 2114044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard else { 2115044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard ret = xmlXPathNewNodeSet(val->nodeTab[0]); 2116044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard for (i = 1; i < val->nodeNr; ++i) 2117044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlXPathNodeSetAddUnique(ret->nodesetval, val->nodeTab[i]); 2118044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } 21193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 2120044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard return (ret); 21213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 21223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 21233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 21243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathWrapNodeSet: 21253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val: the NodePtr value 21263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 21273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Wrap the Nodeset @val in a new xmlXPathObjectPtr 21283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 21293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the newly created object. 21303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 21313473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathObjectPtr 21323473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathWrapNodeSet(xmlNodeSetPtr val) { 21333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr ret; 21343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 21353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject)); 21363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ret == NULL) { 21373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 21383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "xmlXPathWrapNodeSet: out of memory\n"); 21393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 21403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 21413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor memset(ret, 0 , (size_t) sizeof(xmlXPathObject)); 21423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->type = XPATH_NODESET; 21433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->nodesetval = val; 21443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ret); 21453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 21463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 21473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 21483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathFreeNodeSetList: 21493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @obj: an existing NodeSetList object 21503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 21513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Free up the xmlXPathObjectPtr @obj but don't deallocate the objects in 21523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the list contrary to xmlXPathFreeObject(). 21533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 21543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 21553473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathFreeNodeSetList(xmlXPathObjectPtr obj) { 21563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (obj == NULL) return; 21573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(obj); 21583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 21593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 2160f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/** 2161f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathDifference: 2162f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes1: a node-set 2163f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes2: a node-set 2164f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 2165f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Implements the EXSLT - Sets difference() function: 2166f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * node-set set:difference (node-set, node-set) 2167f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 2168f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns the difference between the two node sets, or nodes1 if 2169f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * nodes2 is empty 2170f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */ 2171f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlNodeSetPtr 2172f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathDifference (xmlNodeSetPtr nodes1, xmlNodeSetPtr nodes2) { 2173f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlNodeSetPtr ret; 2174f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer int i, l1; 2175f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlNodePtr cur; 2176f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 2177f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (xmlXPathNodeSetIsEmpty(nodes2)) 2178f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(nodes1); 2179f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 2180f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer ret = xmlXPathNodeSetCreate(NULL); 2181f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (xmlXPathNodeSetIsEmpty(nodes1)) 2182f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(ret); 2183f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 2184f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer l1 = xmlXPathNodeSetGetLength(nodes1); 2185f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 2186f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer for (i = 0; i < l1; i++) { 2187f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer cur = xmlXPathNodeSetItem(nodes1, i); 2188f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (!xmlXPathNodeSetContains(nodes2, cur)) 2189f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathNodeSetAddUnique(ret, cur); 2190f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer } 2191f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(ret); 2192f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer} 2193f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 2194f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/** 2195f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathIntersection: 2196f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes1: a node-set 2197f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes2: a node-set 2198f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 2199f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Implements the EXSLT - Sets intersection() function: 2200f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * node-set set:intersection (node-set, node-set) 2201f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 2202f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns a node set comprising the nodes that are within both the 2203f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * node sets passed as arguments 2204f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */ 2205f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlNodeSetPtr 2206f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathIntersection (xmlNodeSetPtr nodes1, xmlNodeSetPtr nodes2) { 2207f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlNodeSetPtr ret = xmlXPathNodeSetCreate(NULL); 2208f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer int i, l1; 2209f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlNodePtr cur; 2210f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 2211f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (xmlXPathNodeSetIsEmpty(nodes1)) 2212f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(ret); 2213f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (xmlXPathNodeSetIsEmpty(nodes2)) 2214f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(ret); 2215f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 2216f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer l1 = xmlXPathNodeSetGetLength(nodes1); 2217f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 2218f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer for (i = 0; i < l1; i++) { 2219f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer cur = xmlXPathNodeSetItem(nodes1, i); 2220f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (xmlXPathNodeSetContains(nodes2, cur)) 2221f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathNodeSetAddUnique(ret, cur); 2222f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer } 2223f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(ret); 2224f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer} 2225f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 2226f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/** 2227f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathDistinctSorted: 2228f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes: a node-set, sorted by document order 2229f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 2230f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Implements the EXSLT - Sets distinct() function: 2231f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * node-set set:distinct (node-set) 2232f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 2233f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns a subset of the nodes contained in @nodes, or @nodes if 2234f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * it is empty 2235f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */ 2236f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlNodeSetPtr 2237f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathDistinctSorted (xmlNodeSetPtr nodes) { 2238f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlNodeSetPtr ret; 2239f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlHashTablePtr hash; 2240f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer int i, l; 2241f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlChar * strval; 2242f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlNodePtr cur; 2243f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 2244f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (xmlXPathNodeSetIsEmpty(nodes)) 2245f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(nodes); 2246f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 2247f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer ret = xmlXPathNodeSetCreate(NULL); 2248f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer l = xmlXPathNodeSetGetLength(nodes); 2249f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer hash = xmlHashCreate (l); 2250f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer for (i = 0; i < l; i++) { 2251f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer cur = xmlXPathNodeSetItem(nodes, i); 2252f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer strval = xmlXPathCastNodeToString(cur); 2253f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (xmlHashLookup(hash, strval) == NULL) { 2254f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlHashAddEntry(hash, strval, strval); 2255f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathNodeSetAddUnique(ret, cur); 2256f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer } else { 2257f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlFree(strval); 2258f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer } 2259f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer } 2260f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlHashFree(hash, (xmlHashDeallocator) xmlFree); 2261f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(ret); 2262f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer} 2263f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 2264f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/** 2265f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathDistinct: 2266f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes: a node-set 2267f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 2268f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Implements the EXSLT - Sets distinct() function: 2269f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * node-set set:distinct (node-set) 2270f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes is sorted by document order, then #exslSetsDistinctSorted 2271f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * is called with the sorted node-set 2272f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 2273f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns a subset of the nodes contained in @nodes, or @nodes if 2274f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * it is empty 2275f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */ 2276f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlNodeSetPtr 2277f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathDistinct (xmlNodeSetPtr nodes) { 2278f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (xmlXPathNodeSetIsEmpty(nodes)) 2279f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(nodes); 2280f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 2281f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathNodeSetSort(nodes); 2282f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(xmlXPathDistinctSorted(nodes)); 2283f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer} 2284f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 2285f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/** 2286f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathHasSameNodes: 2287f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes1: a node-set 2288f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes2: a node-set 2289f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 2290f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Implements the EXSLT - Sets has-same-nodes function: 2291f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * boolean set:has-same-node(node-set, node-set) 2292f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 2293f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns true (1) if @nodes1 shares any node with @nodes2, false (0) 2294f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * otherwise 2295f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */ 2296f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyerint 2297f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathHasSameNodes (xmlNodeSetPtr nodes1, xmlNodeSetPtr nodes2) { 2298f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer int i, l; 2299f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlNodePtr cur; 2300f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 2301f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (xmlXPathNodeSetIsEmpty(nodes1) || 2302f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathNodeSetIsEmpty(nodes2)) 2303f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(0); 2304f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 2305f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer l = xmlXPathNodeSetGetLength(nodes1); 2306f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer for (i = 0; i < l; i++) { 2307f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer cur = xmlXPathNodeSetItem(nodes1, i); 2308f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (xmlXPathNodeSetContains(nodes2, cur)) 2309f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(1); 2310f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer } 2311f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(0); 2312f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer} 2313f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 2314f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/** 2315f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathNodeLeadingSorted: 2316f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes: a node-set, sorted by document order 2317f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @node: a node 2318f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 2319f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Implements the EXSLT - Sets leading() function: 2320f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * node-set set:leading (node-set, node-set) 2321f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 2322f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns the nodes in @nodes that precede @node in document order, 2323f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes if @node is NULL or an empty node-set if @nodes 2324f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * doesn't contain @node 2325f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */ 2326f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlNodeSetPtr 2327f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathNodeLeadingSorted (xmlNodeSetPtr nodes, xmlNodePtr node) { 2328f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer int i, l; 2329f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlNodePtr cur; 2330f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlNodeSetPtr ret; 2331f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 2332f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (node == NULL) 2333f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(nodes); 2334f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 2335f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer ret = xmlXPathNodeSetCreate(NULL); 2336f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (xmlXPathNodeSetIsEmpty(nodes) || 2337f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer (!xmlXPathNodeSetContains(nodes, node))) 2338f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(ret); 2339f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 2340f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer l = xmlXPathNodeSetGetLength(nodes); 2341f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer for (i = 0; i < l; i++) { 2342f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer cur = xmlXPathNodeSetItem(nodes, i); 2343f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (cur == node) 2344f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer break; 2345f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathNodeSetAddUnique(ret, cur); 2346f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer } 2347f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(ret); 2348f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer} 2349f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 2350f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/** 2351f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathNodeLeading: 2352f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes: a node-set 2353f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @node: a node 2354f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 2355f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Implements the EXSLT - Sets leading() function: 2356f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * node-set set:leading (node-set, node-set) 2357f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes is sorted by document order, then #exslSetsNodeLeadingSorted 2358f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * is called. 2359f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 2360f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns the nodes in @nodes that precede @node in document order, 2361f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes if @node is NULL or an empty node-set if @nodes 2362f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * doesn't contain @node 2363f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */ 2364f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlNodeSetPtr 2365f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathNodeLeading (xmlNodeSetPtr nodes, xmlNodePtr node) { 2366f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathNodeSetSort(nodes); 2367f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(xmlXPathNodeLeadingSorted(nodes, node)); 2368f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer} 2369f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 2370f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/** 2371f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathLeadingSorted: 2372f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes1: a node-set, sorted by document order 2373f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes2: a node-set, sorted by document order 2374f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 2375f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Implements the EXSLT - Sets leading() function: 2376f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * node-set set:leading (node-set, node-set) 2377f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 2378f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns the nodes in @nodes1 that precede the first node in @nodes2 2379f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * in document order, @nodes1 if @nodes2 is NULL or empty or 2380f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * an empty node-set if @nodes1 doesn't contain @nodes2 2381f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */ 2382f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlNodeSetPtr 2383f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathLeadingSorted (xmlNodeSetPtr nodes1, xmlNodeSetPtr nodes2) { 2384f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (xmlXPathNodeSetIsEmpty(nodes2)) 2385f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(nodes1); 2386f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(xmlXPathNodeLeadingSorted(nodes1, 2387f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathNodeSetItem(nodes2, 1))); 2388f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer} 2389f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 2390f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/** 2391f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathLeading: 2392f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes1: a node-set 2393f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes2: a node-set 2394f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 2395f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Implements the EXSLT - Sets leading() function: 2396f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * node-set set:leading (node-set, node-set) 2397f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes1 and @nodes2 are sorted by document order, then 2398f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * #exslSetsLeadingSorted is called. 2399f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 2400f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns the nodes in @nodes1 that precede the first node in @nodes2 2401f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * in document order, @nodes1 if @nodes2 is NULL or empty or 2402f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * an empty node-set if @nodes1 doesn't contain @nodes2 2403f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */ 2404f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlNodeSetPtr 2405f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathLeading (xmlNodeSetPtr nodes1, xmlNodeSetPtr nodes2) { 2406f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (xmlXPathNodeSetIsEmpty(nodes2)) 2407f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(nodes1); 2408f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (xmlXPathNodeSetIsEmpty(nodes1)) 2409f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(xmlXPathNodeSetCreate(NULL)); 2410f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathNodeSetSort(nodes1); 2411f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathNodeSetSort(nodes2); 2412f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(xmlXPathNodeLeadingSorted(nodes1, 2413f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathNodeSetItem(nodes2, 1))); 2414f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer} 2415f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 2416f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/** 2417f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathNodeTrailingSorted: 2418f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes: a node-set, sorted by document order 2419f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @node: a node 2420f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 2421f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Implements the EXSLT - Sets trailing() function: 2422f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * node-set set:trailing (node-set, node-set) 2423f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 2424f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns the nodes in @nodes that follow @node in document order, 2425f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes if @node is NULL or an empty node-set if @nodes 2426f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * doesn't contain @node 2427f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */ 2428f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlNodeSetPtr 2429f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathNodeTrailingSorted (xmlNodeSetPtr nodes, xmlNodePtr node) { 2430f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer int i, l; 2431f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlNodePtr cur; 2432f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlNodeSetPtr ret; 2433f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 2434f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (node == NULL) 2435f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(nodes); 2436f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 2437f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer ret = xmlXPathNodeSetCreate(NULL); 2438f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (xmlXPathNodeSetIsEmpty(nodes) || 2439f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer (!xmlXPathNodeSetContains(nodes, node))) 2440f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(ret); 2441f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 2442f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer l = xmlXPathNodeSetGetLength(nodes); 2443f186c8259ae985cd56b3e14c1def484ab127fd14Thomas Broyer for (i = l; i > 0; i--) { 2444f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer cur = xmlXPathNodeSetItem(nodes, i); 2445f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (cur == node) 2446f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer break; 2447f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathNodeSetAddUnique(ret, cur); 2448f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer } 2449f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(ret); 2450f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer} 2451f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 2452f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/** 2453f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathNodeTrailing: 2454f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes: a node-set 2455f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @node: a node 2456f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 2457f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Implements the EXSLT - Sets trailing() function: 2458f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * node-set set:trailing (node-set, node-set) 2459f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes is sorted by document order, then #xmlXPathNodeTrailingSorted 2460f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * is called. 2461f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 2462f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns the nodes in @nodes that follow @node in document order, 2463f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes if @node is NULL or an empty node-set if @nodes 2464f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * doesn't contain @node 2465f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */ 2466f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlNodeSetPtr 2467f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathNodeTrailing (xmlNodeSetPtr nodes, xmlNodePtr node) { 2468f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathNodeSetSort(nodes); 2469f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(xmlXPathNodeTrailingSorted(nodes, node)); 2470f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer} 2471f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 2472f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/** 2473f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathTrailingSorted: 2474f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes1: a node-set, sorted by document order 2475f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes2: a node-set, sorted by document order 2476f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 2477f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Implements the EXSLT - Sets trailing() function: 2478f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * node-set set:trailing (node-set, node-set) 2479f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 2480f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns the nodes in @nodes1 that follow the first node in @nodes2 2481f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * in document order, @nodes1 if @nodes2 is NULL or empty or 2482f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * an empty node-set if @nodes1 doesn't contain @nodes2 2483f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */ 2484f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlNodeSetPtr 2485f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathTrailingSorted (xmlNodeSetPtr nodes1, xmlNodeSetPtr nodes2) { 2486f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (xmlXPathNodeSetIsEmpty(nodes2)) 2487f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(nodes1); 2488f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(xmlXPathNodeTrailingSorted(nodes1, 2489f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathNodeSetItem(nodes2, 0))); 2490f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer} 2491f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 2492f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/** 2493f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathTrailing: 2494f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes1: a node-set 2495f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes2: a node-set 2496f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 2497f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Implements the EXSLT - Sets trailing() function: 2498f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * node-set set:trailing (node-set, node-set) 2499f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes1 and @nodes2 are sorted by document order, then 2500f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * #xmlXPathTrailingSorted is called. 2501f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 2502f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns the nodes in @nodes1 that follow the first node in @nodes2 2503f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * in document order, @nodes1 if @nodes2 is NULL or empty or 2504f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * an empty node-set if @nodes1 doesn't contain @nodes2 2505f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */ 2506f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlNodeSetPtr 2507f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathTrailing (xmlNodeSetPtr nodes1, xmlNodeSetPtr nodes2) { 2508f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (xmlXPathNodeSetIsEmpty(nodes2)) 2509f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(nodes1); 2510f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (xmlXPathNodeSetIsEmpty(nodes1)) 2511f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(xmlXPathNodeSetCreate(NULL)); 2512f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathNodeSetSort(nodes1); 2513f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathNodeSetSort(nodes2); 2514f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(xmlXPathNodeTrailingSorted(nodes1, 2515f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathNodeSetItem(nodes2, 0))); 2516f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer} 2517f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 25183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/************************************************************************ 25193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * * 25203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Routines to handle extra functions * 25213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * * 25223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ************************************************************************/ 25233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 25243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 25253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathRegisterFunc: 25263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath context 25273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @name: the function name 25283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @f: the function implementation or NULL 25293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 25303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Register a new function. If @f is NULL it unregisters the function 25313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 25323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns 0 in case of success, -1 in case of error 25333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 25343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorint 25353473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathRegisterFunc(xmlXPathContextPtr ctxt, const xmlChar *name, 25363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFunction f) { 25373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(xmlXPathRegisterFuncNS(ctxt, name, NULL, f)); 25383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 25393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 25403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 25413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathRegisterFuncNS: 25423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath context 25433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @name: the function name 25443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ns_uri: the function namespace URI 25453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @f: the function implementation or NULL 25463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 25473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Register a new function. If @f is NULL it unregisters the function 25483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 25493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns 0 in case of success, -1 in case of error 25503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 25513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorint 25523473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathRegisterFuncNS(xmlXPathContextPtr ctxt, const xmlChar *name, 25533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor const xmlChar *ns_uri, xmlXPathFunction f) { 25543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt == NULL) 25553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(-1); 25563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (name == NULL) 25573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(-1); 25583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 25593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->funcHash == NULL) 25603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ctxt->funcHash = xmlHashCreate(0); 25613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->funcHash == NULL) 25623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(-1); 25633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(xmlHashAddEntry2(ctxt->funcHash, name, ns_uri, (void *) f)); 25643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 25653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 25663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 2567ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer * xmlXPathRegisterFuncLookup: 2568ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer * @ctxt: the XPath context 2569ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer * @f: the lookup function 2570cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * @funcCtxt: the lookup data 2571ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer * 2572cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * Registers an external mechanism to do function lookup. 2573ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer */ 2574ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyervoid 2575ba4ad3263bf7f5625329f115367e0c7018521a16Thomas BroyerxmlXPathRegisterFuncLookup (xmlXPathContextPtr ctxt, 2576ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer xmlXPathFuncLookupFunc f, 2577ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer void *funcCtxt) { 2578ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer if (ctxt == NULL) 2579ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer return; 2580ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer ctxt->funcLookupFunc = (void *) f; 2581ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer ctxt->funcLookupData = funcCtxt; 2582ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer} 2583ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer 2584ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer/** 25853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathFunctionLookup: 25863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath context 25873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @name: the function name 25883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 25893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Search in the Function array of the context for the given 25903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * function. 25913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 25923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the xmlXPathFunction or NULL if not found 25933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 25943473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathFunction 25953473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathFunctionLookup(xmlXPathContextPtr ctxt, const xmlChar *name) { 2596ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer if (ctxt == NULL) 2597ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer return (NULL); 2598ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer 2599ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer if (ctxt->funcLookupFunc != NULL) { 2600ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer xmlXPathFunction ret; 260199e55ebe945f6f4de33e8454f2770e02295a3a00Daniel Veillard xmlXPathFuncLookupFunc f; 2602ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer 260399e55ebe945f6f4de33e8454f2770e02295a3a00Daniel Veillard f = (xmlXPathFuncLookupFunc) ctxt->funcLookupFunc; 2604963d2ae41574066f9b44bcae610dd280c1e57dd8Daniel Veillard ret = f(ctxt->funcLookupData, name, NULL); 2605ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer if (ret != NULL) 2606ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer return(ret); 2607ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer } 26083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(xmlXPathFunctionLookupNS(ctxt, name, NULL)); 26093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 26103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 26113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 26123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathFunctionLookupNS: 26133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath context 26143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @name: the function name 26153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ns_uri: the function namespace URI 26163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 26173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Search in the Function array of the context for the given 26183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * function. 26193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 26203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the xmlXPathFunction or NULL if not found 26213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 26223473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathFunction 26233473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathFunctionLookupNS(xmlXPathContextPtr ctxt, const xmlChar *name, 26243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor const xmlChar *ns_uri) { 26253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt == NULL) 26263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 26273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (name == NULL) 26283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 26293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 2630ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer if (ctxt->funcLookupFunc != NULL) { 2631ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer xmlXPathFunction ret; 263299e55ebe945f6f4de33e8454f2770e02295a3a00Daniel Veillard xmlXPathFuncLookupFunc f; 2633ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer 263499e55ebe945f6f4de33e8454f2770e02295a3a00Daniel Veillard f = (xmlXPathFuncLookupFunc) ctxt->funcLookupFunc; 2635963d2ae41574066f9b44bcae610dd280c1e57dd8Daniel Veillard ret = f(ctxt->funcLookupData, name, ns_uri); 2636ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer if (ret != NULL) 2637ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer return(ret); 2638ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer } 2639ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer 2640ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer if (ctxt->funcHash == NULL) 2641ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer return(NULL); 2642ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer 26433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return((xmlXPathFunction) xmlHashLookup2(ctxt->funcHash, name, ns_uri)); 26443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 26453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 26463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 26473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathRegisteredFuncsCleanup: 26483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath context 26493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 26503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Cleanup the XPath context data associated to registered functions 26513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 26523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 26533473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathRegisteredFuncsCleanup(xmlXPathContextPtr ctxt) { 26543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt == NULL) 26553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return; 26563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 26573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlHashFree(ctxt->funcHash, NULL); 26583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ctxt->funcHash = NULL; 26593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 26603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 26613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/************************************************************************ 26623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * * 26633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Routines to handle Variable * 26643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * * 26653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ************************************************************************/ 26663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 26673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 26683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathRegisterVariable: 26693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath context 26703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @name: the variable name 26713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @value: the variable value or NULL 26723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 26733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Register a new variable value. If @value is NULL it unregisters 26743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the variable 26753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 26763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns 0 in case of success, -1 in case of error 26773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 26783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorint 26793473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathRegisterVariable(xmlXPathContextPtr ctxt, const xmlChar *name, 26803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr value) { 26813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(xmlXPathRegisterVariableNS(ctxt, name, NULL, value)); 26823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 26833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 26843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 26853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathRegisterVariableNS: 26863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath context 26873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @name: the variable name 26883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ns_uri: the variable namespace URI 26893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @value: the variable value or NULL 26903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 26913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Register a new variable value. If @value is NULL it unregisters 26923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the variable 26933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 26943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns 0 in case of success, -1 in case of error 26953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 26963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorint 26973473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathRegisterVariableNS(xmlXPathContextPtr ctxt, const xmlChar *name, 26983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor const xmlChar *ns_uri, 26993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr value) { 27003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt == NULL) 27013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(-1); 27023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (name == NULL) 27033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(-1); 27043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 27053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->varHash == NULL) 27063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ctxt->varHash = xmlHashCreate(0); 27073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->varHash == NULL) 27083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(-1); 27093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(xmlHashUpdateEntry2(ctxt->varHash, name, ns_uri, 27103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor (void *) value, 27113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor (xmlHashDeallocator)xmlXPathFreeObject)); 27123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 27133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 27143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 27153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathRegisterVariableLookup: 27163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath context 27173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @f: the lookup function 27183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @data: the lookup data 27193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 27203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * register an external mechanism to do variable lookup 27213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 27223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 27233473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathRegisterVariableLookup(xmlXPathContextPtr ctxt, 27243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathVariableLookupFunc f, void *data) { 27253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt == NULL) 27263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return; 27273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ctxt->varLookupFunc = (void *) f; 27283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ctxt->varLookupData = data; 27293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 27303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 27313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 27323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathVariableLookup: 27333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath context 27343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @name: the variable name 27353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 27363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Search in the Variable array of the context for the given 27373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * variable value. 27383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 273973c9c049195bf897dbcb6308a1ab9d16b3fe6b2cDaniel Veillard * Returns a copy of the value or NULL if not found 27403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 27413473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathObjectPtr 27423473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathVariableLookup(xmlXPathContextPtr ctxt, const xmlChar *name) { 27433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt == NULL) 27443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 27453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 27463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->varLookupFunc != NULL) { 27473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr ret; 27483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 27493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = ((xmlXPathVariableLookupFunc)ctxt->varLookupFunc) 27503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor (ctxt->varLookupData, name, NULL); 2751556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard return(ret); 27523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 27533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(xmlXPathVariableLookupNS(ctxt, name, NULL)); 27543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 27553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 27563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 27573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathVariableLookupNS: 27583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath context 27593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @name: the variable name 27603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ns_uri: the variable namespace URI 27613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 27623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Search in the Variable array of the context for the given 276373c9c049195bf897dbcb6308a1ab9d16b3fe6b2cDaniel Veillard * variable value. 27643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 276573c9c049195bf897dbcb6308a1ab9d16b3fe6b2cDaniel Veillard * Returns the a copy of the value or NULL if not found 27663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 27673473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathObjectPtr 27683473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathVariableLookupNS(xmlXPathContextPtr ctxt, const xmlChar *name, 27693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor const xmlChar *ns_uri) { 27703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt == NULL) 27713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 27723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 27733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->varLookupFunc != NULL) { 27743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr ret; 27753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 27763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = ((xmlXPathVariableLookupFunc)ctxt->varLookupFunc) 27773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor (ctxt->varLookupData, name, ns_uri); 27783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ret != NULL) return(ret); 27793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 27803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 27813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->varHash == NULL) 27823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 27833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (name == NULL) 27843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 27853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 27868c357d58c2d1dde022b67393a47dcb52100ce129Daniel Veillard return(xmlXPathObjectCopy((xmlXPathObjectPtr) 27878c357d58c2d1dde022b67393a47dcb52100ce129Daniel Veillard xmlHashLookup2(ctxt->varHash, name, ns_uri))); 27883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 27893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 27903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 27913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathRegisteredVariablesCleanup: 27923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath context 27933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 27943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Cleanup the XPath context data associated to registered variables 27953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 27963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 27973473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathRegisteredVariablesCleanup(xmlXPathContextPtr ctxt) { 27983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt == NULL) 27993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return; 28003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 280176d66f416d2d0d5db4a09d212b4e43087e9cdae7Daniel Veillard xmlHashFree(ctxt->varHash, (xmlHashDeallocator)xmlXPathFreeObject); 28023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ctxt->varHash = NULL; 28033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 28043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 28053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 28063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathRegisterNs: 28073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath context 28083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @prefix: the namespace prefix 28093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ns_uri: the namespace name 28103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 28113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Register a new namespace. If @ns_uri is NULL it unregisters 28123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the namespace 28133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 28143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns 0 in case of success, -1 in case of error 28153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 28163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorint 28173473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathRegisterNs(xmlXPathContextPtr ctxt, const xmlChar *prefix, 28183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor const xmlChar *ns_uri) { 28193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt == NULL) 28203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(-1); 28213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (prefix == NULL) 28223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(-1); 28233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 28243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->nsHash == NULL) 28253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ctxt->nsHash = xmlHashCreate(10); 28263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->nsHash == NULL) 28273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(-1); 28283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(xmlHashUpdateEntry(ctxt->nsHash, prefix, (void *) ns_uri, 28293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor (xmlHashDeallocator)xmlFree)); 28303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 28313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 28323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 28333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNsLookup: 28343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath context 28353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @prefix: the namespace prefix value 28363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 28373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Search in the namespace declaration array of the context for the given 28383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * namespace name associated to the given prefix 28393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 28403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the value or NULL if not found 28413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 28423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorconst xmlChar * 28433473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNsLookup(xmlXPathContextPtr ctxt, const xmlChar *prefix) { 28443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt == NULL) 28453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 28463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (prefix == NULL) 28473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 28483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 28493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef XML_XML_NAMESPACE 28503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (xmlStrEqual(prefix, (const xmlChar *) "xml")) 28513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(XML_XML_NAMESPACE); 28523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 28533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 2854c8f620ba7f95b3ceb687699e140eeaa33343e41aDaniel Veillard if (ctxt->namespaces != NULL) { 2855c8f620ba7f95b3ceb687699e140eeaa33343e41aDaniel Veillard int i; 2856c8f620ba7f95b3ceb687699e140eeaa33343e41aDaniel Veillard 2857c8f620ba7f95b3ceb687699e140eeaa33343e41aDaniel Veillard for (i = 0;i < ctxt->nsNr;i++) { 2858c8f620ba7f95b3ceb687699e140eeaa33343e41aDaniel Veillard if ((ctxt->namespaces[i] != NULL) && 2859c8f620ba7f95b3ceb687699e140eeaa33343e41aDaniel Veillard (xmlStrEqual(ctxt->namespaces[i]->prefix, prefix))) 2860c8f620ba7f95b3ceb687699e140eeaa33343e41aDaniel Veillard return(ctxt->namespaces[i]->href); 2861c8f620ba7f95b3ceb687699e140eeaa33343e41aDaniel Veillard } 2862c8f620ba7f95b3ceb687699e140eeaa33343e41aDaniel Veillard } 28633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 28643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return((const xmlChar *) xmlHashLookup(ctxt->nsHash, prefix)); 28653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 28663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 28673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 28685e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard * xmlXPathRegisteredNsCleanup: 28693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath context 28703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 28713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Cleanup the XPath context data associated to registered variables 28723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 28733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 28743473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathRegisteredNsCleanup(xmlXPathContextPtr ctxt) { 28753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt == NULL) 28763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return; 28773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 28783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlHashFree(ctxt->nsHash, NULL); 28793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ctxt->nsHash = NULL; 28803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 28813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 28823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/************************************************************************ 28833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * * 28843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Routines to handle Values * 28853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * * 28863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ************************************************************************/ 28873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 28883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/* Allocations are terrible, one need to optimize all this !!! */ 28893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 28903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 28913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNewFloat: 28923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val: the double value 28933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 28943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Create a new xmlXPathObjectPtr of type double and of value @val 28953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 28963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the newly created object. 28973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 28983473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathObjectPtr 28993473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNewFloat(double val) { 29003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr ret; 29013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 29023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject)); 29033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ret == NULL) { 29043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 29053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "xmlXPathNewFloat: out of memory\n"); 29063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 29073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 29083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor memset(ret, 0 , (size_t) sizeof(xmlXPathObject)); 29093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->type = XPATH_NUMBER; 29103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->floatval = val; 29113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ret); 29123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 29133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 29143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 29153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNewBoolean: 29163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val: the boolean value 29173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 29183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Create a new xmlXPathObjectPtr of type boolean and of value @val 29193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 29203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the newly created object. 29213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 29223473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathObjectPtr 29233473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNewBoolean(int val) { 29243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr ret; 29253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 29263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject)); 29273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ret == NULL) { 29283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 29293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "xmlXPathNewBoolean: out of memory\n"); 29303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 29313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 29323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor memset(ret, 0 , (size_t) sizeof(xmlXPathObject)); 29333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->type = XPATH_BOOLEAN; 29343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->boolval = (val != 0); 29353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ret); 29363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 29373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 29383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 29393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNewString: 29403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val: the xmlChar * value 29413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 29423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Create a new xmlXPathObjectPtr of type string and of value @val 29433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 29443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the newly created object. 29453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 29463473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathObjectPtr 29473473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNewString(const xmlChar *val) { 29483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr ret; 29493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 29503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject)); 29513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ret == NULL) { 29523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 29533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "xmlXPathNewString: out of memory\n"); 29543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 29553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 29563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor memset(ret, 0 , (size_t) sizeof(xmlXPathObject)); 29573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->type = XPATH_STRING; 29583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (val != NULL) 29593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->stringval = xmlStrdup(val); 29603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else 29613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->stringval = xmlStrdup((const xmlChar *)""); 29623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ret); 29633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 29643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 29653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 2966ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathWrapString: 2967ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @val: the xmlChar * value 2968ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 2969ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Wraps the @val string into an XPath object. 2970ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 2971ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns the newly created object. 2972ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */ 2973ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathObjectPtr 2974ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathWrapString (xmlChar *val) { 2975ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlXPathObjectPtr ret; 2976ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 2977ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject)); 2978ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard if (ret == NULL) { 2979ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlGenericError(xmlGenericErrorContext, 2980ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard "xmlXPathWrapString: out of memory\n"); 2981ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(NULL); 2982ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard } 2983ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard memset(ret, 0 , (size_t) sizeof(xmlXPathObject)); 2984ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret->type = XPATH_STRING; 2985ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret->stringval = val; 2986ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(ret); 2987ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard} 2988ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 2989ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/** 29903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNewCString: 29913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val: the char * value 29923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 29933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Create a new xmlXPathObjectPtr of type string and of value @val 29943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 29953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the newly created object. 29963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 29973473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathObjectPtr 29983473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNewCString(const char *val) { 29993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr ret; 30003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 30013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject)); 30023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ret == NULL) { 30033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 30043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "xmlXPathNewCString: out of memory\n"); 30053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 30063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 30073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor memset(ret, 0 , (size_t) sizeof(xmlXPathObject)); 30083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->type = XPATH_STRING; 30093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->stringval = xmlStrdup(BAD_CAST val); 30103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ret); 30113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 30123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 30133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 3014ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathWrapCString: 3015ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @val: the char * value 3016ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3017ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Wraps a string into an XPath object. 3018ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3019ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns the newly created object. 3020ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */ 3021ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathObjectPtr 3022ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathWrapCString (char * val) { 3023ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(xmlXPathWrapString((xmlChar *)(val))); 3024ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard} 3025ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 3026ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/** 3027f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathWrapExternal: 3028f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @val: the user data 3029f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 3030f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Wraps the @val data into an XPath object. 3031f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 3032f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns the newly created object. 3033f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */ 3034f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathObjectPtr 3035f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathWrapExternal (void *val) { 3036f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathObjectPtr ret; 3037f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 3038f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject)); 3039f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (ret == NULL) { 3040f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlGenericError(xmlGenericErrorContext, 3041cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard "xmlXPathWrapExternal: out of memory\n"); 3042f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(NULL); 3043f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer } 3044f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer memset(ret, 0 , (size_t) sizeof(xmlXPathObject)); 3045f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer ret->type = XPATH_USERS; 3046f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer ret->user = val; 3047f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(ret); 3048f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer} 3049f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 3050f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/** 30513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathObjectCopy: 30523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val: the original object 30533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 30543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * allocate a new copy of a given object 30553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 30563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the newly created object. 30573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 30583473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathObjectPtr 30593473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathObjectCopy(xmlXPathObjectPtr val) { 30603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr ret; 30613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 30623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (val == NULL) 30633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 30643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 30653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject)); 30663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ret == NULL) { 30673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 30683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "xmlXPathObjectCopy: out of memory\n"); 30693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 30703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 30713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor memcpy(ret, val , (size_t) sizeof(xmlXPathObject)); 30723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor switch (val->type) { 30733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_BOOLEAN: 30743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_NUMBER: 30753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_POINT: 30763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_RANGE: 30773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 30783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_STRING: 30793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->stringval = xmlStrdup(val->stringval); 30803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 30813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_XSLT_TREE: 30823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((val->nodesetval != NULL) && 30830ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard (val->nodesetval->nodeTab != NULL)) { 30840ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard ret->boolval = 1; 30856ab38386cc16642626d944b357580657e751d8baDaniel Veillard ret->user = xmlDocCopyNode(val->nodesetval->nodeTab[0], 30866ab38386cc16642626d944b357580657e751d8baDaniel Veillard val->nodesetval->nodeTab[0]->doc, 1); 30873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->nodesetval = xmlXPathNodeSetCreate( 30880ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard (xmlNodePtr) ret->user); 30890ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard } else 30903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->nodesetval = xmlXPathNodeSetCreate(NULL); 30910ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard /* Deallocate the copied tree value */ 30923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 30933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_NODESET: 30943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->nodesetval = xmlXPathNodeSetMerge(NULL, val->nodesetval); 30950ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard /* Do not deallocate the copied tree value */ 30960ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard ret->boolval = 0; 30973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 30983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_LOCATIONSET: 30993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef LIBXML_XPTR_ENABLED 31003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor { 31013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlLocationSetPtr loc = val->user; 31023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->user = (void *) xmlXPtrLocationSetMerge(NULL, loc); 31033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 31043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 31053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 310647334c09f4373e4cff71334e60a623fee73a525fThomas Broyer case XPATH_USERS: 310747334c09f4373e4cff71334e60a623fee73a525fThomas Broyer ret->user = val->user; 310847334c09f4373e4cff71334e60a623fee73a525fThomas Broyer break; 310947334c09f4373e4cff71334e60a623fee73a525fThomas Broyer case XPATH_UNDEFINED: 31103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 31113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "xmlXPathObjectCopy: unsupported type %d\n", 31123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor val->type); 31133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 31143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 31153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ret); 31163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 31173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 31183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 31193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathFreeObject: 31203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @obj: the object to free 31213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 31223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Free up an xmlXPathObjectPtr object. 31233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 31243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 31253473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathFreeObject(xmlXPathObjectPtr obj) { 31263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (obj == NULL) return; 31270ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard if ((obj->type == XPATH_NODESET) || (obj->type == XPATH_XSLT_TREE)) { 312877851710aba3a0effdc6af67ea4caf212307420cDaniel Veillard if (obj->boolval) { 31290ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard if (obj->user != NULL) { 31300ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard xmlXPathFreeNodeSet(obj->nodesetval); 313138bf6f042507c6051bfa2db5cc9b6666cfc35c2aDaniel Veillard xmlFreeNodeList((xmlNodePtr) obj->user); 31320ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard } else if (obj->nodesetval != NULL) 313377851710aba3a0effdc6af67ea4caf212307420cDaniel Veillard xmlXPathFreeValueTree(obj->nodesetval); 313477851710aba3a0effdc6af67ea4caf212307420cDaniel Veillard } else { 313577851710aba3a0effdc6af67ea4caf212307420cDaniel Veillard if (obj->nodesetval != NULL) 313677851710aba3a0effdc6af67ea4caf212307420cDaniel Veillard xmlXPathFreeNodeSet(obj->nodesetval); 313777851710aba3a0effdc6af67ea4caf212307420cDaniel Veillard } 31383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef LIBXML_XPTR_ENABLED 31393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else if (obj->type == XPATH_LOCATIONSET) { 31403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (obj->user != NULL) 31413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPtrFreeLocationSet(obj->user); 31423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 31433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else if (obj->type == XPATH_STRING) { 31443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (obj->stringval != NULL) 31453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(obj->stringval); 31463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 31473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 31483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(obj); 31493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 31503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 3151ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 3152ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/************************************************************************ 3153ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * * 3154ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Type Casting Routines * 3155ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * * 3156ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ************************************************************************/ 3157ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 3158ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/** 3159ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathCastBooleanToString: 3160ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @val: a boolean 3161ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3162ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts a boolean to its string value. 3163ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3164ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns a newly allocated string. 3165ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */ 3166ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlChar * 3167ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathCastBooleanToString (int val) { 3168ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlChar *ret; 3169ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard if (val) 3170ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = xmlStrdup((const xmlChar *) "true"); 3171ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard else 3172ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = xmlStrdup((const xmlChar *) "false"); 3173ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(ret); 3174ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard} 3175ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 3176ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/** 3177ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathCastNumberToString: 3178ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @val: a number 3179ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3180ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts a number to its string value. 3181ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3182ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns a newly allocated string. 3183ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */ 3184ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlChar * 3185ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathCastNumberToString (double val) { 3186ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlChar *ret; 3187cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard switch (xmlXPathIsInf(val)) { 3188ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case 1: 31895fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard ret = xmlStrdup((const xmlChar *) "Infinity"); 3190ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard break; 3191ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case -1: 3192ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = xmlStrdup((const xmlChar *) "-Infinity"); 3193ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard break; 3194ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard default: 3195cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard if (xmlXPathIsNaN(val)) { 3196ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = xmlStrdup((const xmlChar *) "NaN"); 3197d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard } else if (val == 0 && xmlXPathGetSign(val) != 0) { 3198d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret = xmlStrdup((const xmlChar *) "0"); 3199ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard } else { 3200ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard /* could be improved */ 3201ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard char buf[100]; 3202ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlXPathFormatNumber(val, buf, 100); 3203ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = xmlStrdup((const xmlChar *) buf); 3204ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard } 3205ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard } 3206ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(ret); 3207ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard} 3208ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 3209ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/** 3210ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathCastNodeToString: 3211ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @node: a node 3212ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3213ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts a node to its string value. 3214ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3215ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns a newly allocated string. 3216ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */ 3217ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlChar * 3218ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathCastNodeToString (xmlNodePtr node) { 321923b1f37bf53e07d2a36a86c9efa173af533c0266Daniel Veillard if ((node != NULL) && (node->type == XML_DOCUMENT_NODE)) 322023b1f37bf53e07d2a36a86c9efa173af533c0266Daniel Veillard node = xmlDocGetRootElement((xmlDocPtr) node); 3221ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(xmlNodeGetContent(node)); 3222ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard} 3223ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 3224ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/** 3225ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathCastNodeSetToString: 3226ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @ns: a node-set 3227ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3228ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts a node-set to its string value. 3229ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3230ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns a newly allocated string. 3231ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */ 3232ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlChar * 3233ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathCastNodeSetToString (xmlNodeSetPtr ns) { 3234ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard if ((ns == NULL) || (ns->nodeNr == 0) || (ns->nodeTab == NULL)) 3235ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(xmlStrdup((const xmlChar *) "")); 3236ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 3237ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlXPathNodeSetSort(ns); 3238ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(xmlXPathCastNodeToString(ns->nodeTab[0])); 3239ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard} 3240ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 3241ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/** 3242ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathCastToString: 3243ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @val: an XPath object 3244ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3245ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts an existing object to its string() equivalent 3246ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3247ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns the string value of the object, NULL in case of error. 3248cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * A new string is allocated only if needed (@val isn't a 3249ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * string object). 3250ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */ 3251ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlChar * 3252ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathCastToString(xmlXPathObjectPtr val) { 3253ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlChar *ret = NULL; 3254ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 3255ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard if (val == NULL) 3256ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(xmlStrdup((const xmlChar *) "")); 3257ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard switch (val->type) { 3258ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_UNDEFINED: 3259ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard#ifdef DEBUG_EXPR 3260ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlGenericError(xmlGenericErrorContext, "String: undefined\n"); 3261ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard#endif 3262ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = xmlStrdup((const xmlChar *) ""); 3263ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard break; 3264ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_XSLT_TREE: 3265ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_NODESET: 3266ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = xmlXPathCastNodeSetToString(val->nodesetval); 3267ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard break; 3268ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_STRING: 32694e2df54bb17645ef0d3f28b9665b2d2dde4b47a3Daniel Veillard return(xmlStrdup(val->stringval)); 3270ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_BOOLEAN: 3271ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = xmlXPathCastBooleanToString(val->boolval); 3272ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard break; 3273ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_NUMBER: { 3274ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = xmlXPathCastNumberToString(val->floatval); 3275ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard break; 3276ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard } 3277ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_USERS: 3278ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_POINT: 3279ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_RANGE: 3280ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_LOCATIONSET: 3281ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard TODO 3282ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = xmlStrdup((const xmlChar *) ""); 3283ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard break; 3284ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard } 3285ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(ret); 3286ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard} 3287ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 3288ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/** 3289ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathConvertString: 3290ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @val: an XPath object 3291ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3292ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts an existing object to its string() equivalent 3293ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3294ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns the new object, the old one is freed (or the operation 3295ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * is done directly on @val) 3296ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */ 3297ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathObjectPtr 3298ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathConvertString(xmlXPathObjectPtr val) { 3299ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlChar *res = NULL; 3300ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 3301ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard if (val == NULL) 3302ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(xmlXPathNewCString("")); 3303ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 3304ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard switch (val->type) { 3305ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_UNDEFINED: 3306ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard#ifdef DEBUG_EXPR 3307ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlGenericError(xmlGenericErrorContext, "STRING: undefined\n"); 3308ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard#endif 3309ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard break; 3310ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_XSLT_TREE: 3311ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_NODESET: 3312ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard res = xmlXPathCastNodeSetToString(val->nodesetval); 3313ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard break; 3314ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_STRING: 3315ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(val); 3316ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_BOOLEAN: 3317ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard res = xmlXPathCastBooleanToString(val->boolval); 3318ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard break; 3319ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_NUMBER: 3320ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard res = xmlXPathCastNumberToString(val->floatval); 3321ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard break; 3322ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_USERS: 3323ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_POINT: 3324ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_RANGE: 3325ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_LOCATIONSET: 3326ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard TODO; 3327ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard break; 3328ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard } 3329ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlXPathFreeObject(val); 3330ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard if (res == NULL) 3331ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(xmlXPathNewCString("")); 3332ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(xmlXPathWrapString(res)); 3333ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard} 3334ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 3335ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/** 3336ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathCastBooleanToNumber: 3337ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @val: a boolean 3338ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3339ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts a boolean to its number value 3340ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3341ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns the number value 3342ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */ 3343ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillarddouble 3344ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathCastBooleanToNumber(int val) { 3345ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard if (val) 3346ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(1.0); 3347ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(0.0); 3348ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard} 3349ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 3350ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/** 3351ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathCastStringToNumber: 3352ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @val: a string 3353ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3354ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts a string to its number value 3355ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3356ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns the number value 3357ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */ 3358ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillarddouble 3359ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathCastStringToNumber(const xmlChar * val) { 3360ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(xmlXPathStringEvalNumber(val)); 3361ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard} 3362ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 3363ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/** 3364ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathCastNodeToNumber: 3365ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @node: a node 3366ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3367ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts a node to its number value 3368ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3369ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns the number value 3370ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */ 3371ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillarddouble 3372ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathCastNodeToNumber (xmlNodePtr node) { 3373ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlChar *strval; 3374ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard double ret; 3375ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 3376ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard if (node == NULL) 3377ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(xmlXPathNAN); 3378ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard strval = xmlXPathCastNodeToString(node); 3379ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard if (strval == NULL) 3380ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(xmlXPathNAN); 3381ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = xmlXPathCastStringToNumber(strval); 3382ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlFree(strval); 3383ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 3384ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(ret); 3385ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard} 3386ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 3387ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/** 3388ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathCastNodeSetToNumber: 3389ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @ns: a node-set 3390ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3391ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts a node-set to its number value 3392ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3393ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns the number value 3394ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */ 3395ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillarddouble 3396ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathCastNodeSetToNumber (xmlNodeSetPtr ns) { 3397ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlChar *str; 3398ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard double ret; 3399ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 3400ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard if (ns == NULL) 3401ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(xmlXPathNAN); 3402ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard str = xmlXPathCastNodeSetToString(ns); 3403ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = xmlXPathCastStringToNumber(str); 3404ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlFree(str); 3405ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(ret); 3406ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard} 3407ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 3408ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/** 3409ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathCastToNumber: 3410ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @val: an XPath object 3411ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3412ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts an XPath object to its number value 3413ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3414ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns the number value 3415ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */ 3416ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillarddouble 3417ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathCastToNumber(xmlXPathObjectPtr val) { 3418ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard double ret = 0.0; 3419ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 3420ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard if (val == NULL) 3421ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(xmlXPathNAN); 3422ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard switch (val->type) { 3423ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_UNDEFINED: 3424ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard#ifdef DEGUB_EXPR 3425ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlGenericError(xmlGenericErrorContext, "NUMBER: undefined\n"); 3426ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard#endif 3427ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = xmlXPathNAN; 3428ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard break; 3429ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_XSLT_TREE: 3430ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_NODESET: 3431ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = xmlXPathCastNodeSetToNumber(val->nodesetval); 3432ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard break; 3433ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_STRING: 3434ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = xmlXPathCastStringToNumber(val->stringval); 3435ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard break; 3436ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_NUMBER: 3437ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = val->floatval; 3438ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard break; 3439ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_BOOLEAN: 3440ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = xmlXPathCastBooleanToNumber(val->boolval); 3441ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard break; 3442ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_USERS: 3443ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_POINT: 3444ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_RANGE: 3445ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_LOCATIONSET: 3446ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard TODO; 3447ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = xmlXPathNAN; 3448ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard break; 3449ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard } 3450ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(ret); 3451ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard} 3452ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 3453ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/** 3454ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathConvertNumber: 3455ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @val: an XPath object 3456ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3457ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts an existing object to its number() equivalent 3458ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3459ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns the new object, the old one is freed (or the operation 3460ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * is done directly on @val) 3461ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */ 3462ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathObjectPtr 3463ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathConvertNumber(xmlXPathObjectPtr val) { 3464ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlXPathObjectPtr ret; 3465ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 3466ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard if (val == NULL) 3467ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(xmlXPathNewFloat(0.0)); 3468ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard if (val->type == XPATH_NUMBER) 3469ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(val); 3470ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = xmlXPathNewFloat(xmlXPathCastToNumber(val)); 3471ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlXPathFreeObject(val); 3472ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(ret); 3473ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard} 3474ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 3475ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/** 3476ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathCastNumberToBoolean: 3477ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @val: a number 3478ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3479ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts a number to its boolean value 3480ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3481ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns the boolean value 3482ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */ 3483ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillardint 3484ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathCastNumberToBoolean (double val) { 3485cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard if (xmlXPathIsNaN(val) || (val == 0.0)) 3486ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(0); 3487ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(1); 3488ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard} 3489ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 3490ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/** 3491ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathCastStringToBoolean: 3492ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @val: a string 3493ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3494ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts a string to its boolean value 3495ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3496ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns the boolean value 3497ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */ 3498ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillardint 3499ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathCastStringToBoolean (const xmlChar *val) { 3500ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard if ((val == NULL) || (xmlStrlen(val) == 0)) 3501ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(0); 3502ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(1); 3503ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard} 3504ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 3505ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/** 3506ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathCastNodeSetToBoolean: 3507ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @ns: a node-set 3508ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3509ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts a node-set to its boolean value 3510ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3511ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns the boolean value 3512ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */ 3513ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillardint 3514ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathCastNodeSetToBoolean (xmlNodeSetPtr ns) { 3515ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard if ((ns == NULL) || (ns->nodeNr == 0)) 3516ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(0); 3517ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(1); 3518ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard} 3519ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 3520ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/** 35215e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard * xmlXPathCastToBoolean: 3522ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @val: an XPath object 3523ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3524ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts an XPath object to its boolean value 3525ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3526ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns the boolean value 3527ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */ 3528ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillardint 3529ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathCastToBoolean (xmlXPathObjectPtr val) { 3530ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard int ret = 0; 3531ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 3532ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard if (val == NULL) 3533ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(0); 3534ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard switch (val->type) { 3535ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_UNDEFINED: 3536ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard#ifdef DEBUG_EXPR 3537ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlGenericError(xmlGenericErrorContext, "BOOLEAN: undefined\n"); 3538ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard#endif 3539ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = 0; 3540ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard break; 3541ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_XSLT_TREE: 3542ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_NODESET: 3543ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = xmlXPathCastNodeSetToBoolean(val->nodesetval); 3544ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard break; 3545ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_STRING: 3546ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = xmlXPathCastStringToBoolean(val->stringval); 3547ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard break; 3548ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_NUMBER: 3549ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = xmlXPathCastNumberToBoolean(val->floatval); 3550ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard break; 3551ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_BOOLEAN: 3552ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = val->boolval; 3553ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard break; 3554ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_USERS: 3555ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_POINT: 3556ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_RANGE: 3557ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_LOCATIONSET: 3558ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard TODO; 3559ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = 0; 3560ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard break; 3561ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard } 3562ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(ret); 3563ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard} 3564ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 3565ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 3566ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/** 3567ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathConvertBoolean: 3568ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @val: an XPath object 3569ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3570ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts an existing object to its boolean() equivalent 3571ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3572ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns the new object, the old one is freed (or the operation 3573ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * is done directly on @val) 3574ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */ 3575ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathObjectPtr 3576ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathConvertBoolean(xmlXPathObjectPtr val) { 3577ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlXPathObjectPtr ret; 3578ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 3579ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard if (val == NULL) 3580ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(xmlXPathNewBoolean(0)); 3581ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard if (val->type == XPATH_BOOLEAN) 3582ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(val); 3583ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = xmlXPathNewBoolean(xmlXPathCastToBoolean(val)); 3584ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlXPathFreeObject(val); 3585ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(ret); 3586ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard} 3587ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 35883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/************************************************************************ 35893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * * 35903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Routines to handle XPath contexts * 35913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * * 35923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ************************************************************************/ 35933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 35943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 35953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNewContext: 35963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @doc: the XML document 35973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 35983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Create a new xmlXPathContext 35993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 3600af43f63aaabf0dc4b4a070773875d0927da3d8a2Daniel Veillard * Returns the xmlXPathContext just allocated. The caller will need to free it. 36013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 36023473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathContextPtr 36033473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNewContext(xmlDocPtr doc) { 36043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathContextPtr ret; 36053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 36063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = (xmlXPathContextPtr) xmlMalloc(sizeof(xmlXPathContext)); 36073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ret == NULL) { 36083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 36093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "xmlXPathNewContext: out of memory\n"); 36103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 36113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 36123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor memset(ret, 0 , (size_t) sizeof(xmlXPathContext)); 36133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->doc = doc; 36143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->node = NULL; 36153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 36163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->varHash = NULL; 36173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 36183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->nb_types = 0; 36193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->max_types = 0; 36203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->types = NULL; 36213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 36223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->funcHash = xmlHashCreate(0); 36233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 36243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->nb_axis = 0; 36253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->max_axis = 0; 36263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->axis = NULL; 36273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 36283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->nsHash = NULL; 36293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->user = NULL; 36303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 36313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->contextSize = -1; 36323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->proximityPosition = -1; 36333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 36343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisterAllFunctions(ret); 36353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 36363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ret); 36373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 36383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 36393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 36403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathFreeContext: 36413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the context to free 36423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 36433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Free up an xmlXPathContext 36443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 36453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 36463473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathFreeContext(xmlXPathContextPtr ctxt) { 36473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisteredNsCleanup(ctxt); 36483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisteredFuncsCleanup(ctxt); 36493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisteredVariablesCleanup(ctxt); 36503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(ctxt); 36513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 36523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 36533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/************************************************************************ 36543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * * 36553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Routines to handle XPath parser contexts * 36563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * * 36573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ************************************************************************/ 36583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 36593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define CHECK_CTXT(ctxt) \ 36603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt == NULL) { \ 36613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, \ 36623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "%s:%d Internal error: ctxt == NULL\n", \ 36633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor __FILE__, __LINE__); \ 36643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } \ 36653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 36663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 36673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define CHECK_CONTEXT(ctxt) \ 36683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt == NULL) { \ 36693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, \ 36703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "%s:%d Internal error: no context\n", \ 36713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor __FILE__, __LINE__); \ 36723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } \ 36733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else if (ctxt->doc == NULL) { \ 36743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, \ 36753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "%s:%d Internal error: no document\n", \ 36763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor __FILE__, __LINE__); \ 36773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } \ 36783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else if (ctxt->doc->children == NULL) { \ 36793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, \ 36803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "%s:%d Internal error: document without root\n", \ 36813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor __FILE__, __LINE__); \ 36823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } \ 36833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 36843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 36853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 36863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNewParserContext: 36873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @str: the XPath expression 36883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath context 36893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 36903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Create a new xmlXPathParserContext 36913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 36923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the xmlXPathParserContext just allocated. 36933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 36943473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathParserContextPtr 36953473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNewParserContext(const xmlChar *str, xmlXPathContextPtr ctxt) { 36963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathParserContextPtr ret; 36973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 36983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = (xmlXPathParserContextPtr) xmlMalloc(sizeof(xmlXPathParserContext)); 36993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ret == NULL) { 37003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 37013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "xmlXPathNewParserContext: out of memory\n"); 37023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 37033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 37043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor memset(ret, 0 , (size_t) sizeof(xmlXPathParserContext)); 37053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->cur = ret->base = str; 37063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->context = ctxt; 37073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 37089e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard ret->comp = xmlXPathNewCompExpr(); 37099e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (ret->comp == NULL) { 37109e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlFree(ret->valueTab); 37119e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlFree(ret); 37129e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard return(NULL); 37139e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } 37149e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 37159e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard return(ret); 37169e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard} 37179e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 37189e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard/** 37199e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * xmlXPathCompParserContext: 37209e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * @comp: the XPath compiled expression 37219e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * @ctxt: the XPath context 37229e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * 37239e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * Create a new xmlXPathParserContext when processing a compiled expression 37249e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * 37259e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * Returns the xmlXPathParserContext just allocated. 37269e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard */ 372756a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic xmlXPathParserContextPtr 37289e7160d45a18bfa26d708e22ba991f7670d0128bDaniel VeillardxmlXPathCompParserContext(xmlXPathCompExprPtr comp, xmlXPathContextPtr ctxt) { 37299e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlXPathParserContextPtr ret; 37309e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 37319e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard ret = (xmlXPathParserContextPtr) xmlMalloc(sizeof(xmlXPathParserContext)); 37329e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (ret == NULL) { 37339e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlGenericError(xmlGenericErrorContext, 3734cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard "xmlXPathCompParserContext: out of memory\n"); 37359e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard return(NULL); 37369e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } 37379e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard memset(ret, 0 , (size_t) sizeof(xmlXPathParserContext)); 37389e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 37393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* Allocate the value stack */ 37403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->valueTab = (xmlXPathObjectPtr *) 37413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlMalloc(10 * sizeof(xmlXPathObjectPtr)); 37429e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (ret->valueTab == NULL) { 37439e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlFree(ret); 37449e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlGenericError(xmlGenericErrorContext, 3745cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard "xmlXPathCompParserContext: out of memory\n"); 37469e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard return(NULL); 37479e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } 37483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->valueNr = 0; 37493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->valueMax = 10; 37503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->value = NULL; 37519e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 3752fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard ret->context = ctxt; 37539e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard ret->comp = comp; 37549e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 37553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ret); 37563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 37573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 37583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 37593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathFreeParserContext: 37603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the context to free 37613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 37623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Free up an xmlXPathParserContext 37633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 37643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 37653473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathFreeParserContext(xmlXPathParserContextPtr ctxt) { 37663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->valueTab != NULL) { 37673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(ctxt->valueTab); 37683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 37699e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (ctxt->comp) 37709e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlXPathFreeCompExpr(ctxt->comp); 37713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(ctxt); 37723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 37733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 37743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/************************************************************************ 37753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * * 37763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The implicit core function library * 37773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * * 37783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ************************************************************************/ 37793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 37803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 3781f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * xmlXPathNodeStringHash: 3782f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * @node: a node pointer 3783f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * 3784f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Function computing the beginning of the string value of the node, 3785f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * used to speed up comparisons 3786f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * 3787f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Returns an int usable as a hash 3788f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 3789f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillardstatic unsigned int 3790f06307e2c172284bb41376c396f757bdac9bdd19Daniel VeillardxmlXPathNodeValHash(xmlNodePtr node) { 3791f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard int len = 2; 3792f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard const xmlChar * string = NULL; 3793f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlNodePtr tmp = NULL; 3794f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard unsigned int ret = 0; 3795f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 3796f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (node == NULL) 3797f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return(0); 3798f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 3799f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 3800f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard switch (node->type) { 3801f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XML_COMMENT_NODE: 3802f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XML_PI_NODE: 3803f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XML_CDATA_SECTION_NODE: 3804f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XML_TEXT_NODE: 3805f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard string = node->content; 3806f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (string == NULL) 3807f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return(0); 3808f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (string[0] == 0) 3809f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return(0); 3810f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return(((unsigned int) string[0]) + 3811f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (((unsigned int) string[1]) << 8)); 3812f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XML_NAMESPACE_DECL: 3813f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard string = ((xmlNsPtr)node)->href; 3814f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (string == NULL) 3815f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return(0); 3816f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (string[0] == 0) 3817f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return(0); 3818f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return(((unsigned int) string[0]) + 3819f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (((unsigned int) string[1]) << 8)); 3820f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XML_ATTRIBUTE_NODE: 3821f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard tmp = ((xmlAttrPtr) node)->children; 3822f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 3823f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XML_ELEMENT_NODE: 3824f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard tmp = node->children; 3825f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 3826f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard default: 3827f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return(0); 3828f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 3829f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard while (tmp != NULL) { 3830f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard switch (tmp->type) { 3831f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XML_COMMENT_NODE: 3832f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XML_PI_NODE: 3833f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XML_CDATA_SECTION_NODE: 3834f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XML_TEXT_NODE: 3835f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard string = tmp->content; 3836f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 3837f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XML_NAMESPACE_DECL: 3838f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard string = ((xmlNsPtr)tmp)->href; 3839f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 3840f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard default: 3841f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 3842f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 3843f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((string != NULL) && (string[0] != 0)) { 3844f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (string[0] == 0) 3845f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return(0); 3846f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (len == 1) { 3847f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return(ret + (((unsigned int) string[0]) << 8)); 3848f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 3849f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (string[1] == 0) { 3850f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard len = 1; 3851f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ret = (unsigned int) string[0]; 3852f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } else { 3853f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return(((unsigned int) string[0]) + 3854f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (((unsigned int) string[1]) << 8)); 3855f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 3856f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 3857f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* 3858f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Skip to next node 3859f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 3860f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((tmp->children != NULL) && (tmp->type != XML_DTD_NODE)) { 3861f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (tmp->children->type != XML_ENTITY_DECL) { 3862f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard tmp = tmp->children; 3863f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard continue; 3864f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 3865f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 3866f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (tmp == node) 3867f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 3868f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 3869f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (tmp->next != NULL) { 3870f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard tmp = tmp->next; 3871f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard continue; 3872f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 3873f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 3874f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard do { 3875f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard tmp = tmp->parent; 3876f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (tmp == NULL) 3877f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 3878f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (tmp == node) { 3879f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard tmp = NULL; 3880f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 3881f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 3882f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (tmp->next != NULL) { 3883f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard tmp = tmp->next; 3884f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 3885f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 3886f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } while (tmp != NULL); 3887f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 3888f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return(ret); 3889f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard} 3890f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 3891f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard/** 3892f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * xmlXPathStringHash: 3893f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * @string: a string 3894f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * 3895f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Function computing the beginning of the string value of the node, 3896f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * used to speed up comparisons 3897f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * 3898f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Returns an int usable as a hash 3899f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 3900f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillardstatic unsigned int 3901f06307e2c172284bb41376c396f757bdac9bdd19Daniel VeillardxmlXPathStringHash(const xmlChar * string) { 3902f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (string == NULL) 3903f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return((unsigned int) 0); 3904f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (string[0] == 0) 3905f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return(0); 3906f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return(((unsigned int) string[0]) + 3907f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (((unsigned int) string[1]) << 8)); 3908f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard} 3909f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 3910f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard/** 39113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathCompareNodeSetFloat: 39123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 39133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @inf: less than (1) or greater than (0) 39143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @strict: is the comparison strict 39153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @arg: the node set 39163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @f: the value 39173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 39183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the compare operation between a nodeset and a number 39193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ns < @val (1, 1, ... 39203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ns <= @val (1, 0, ... 39213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ns > @val (0, 1, ... 39223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ns >= @val (0, 0, ... 39233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 39243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * If one object to be compared is a node-set and the other is a number, 39253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * then the comparison will be true if and only if there is a node in the 39263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * node-set such that the result of performing the comparison on the number 39273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * to be compared and on the result of converting the string-value of that 39283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * node to a number using the number function is true. 39293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 39303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns 0 or 1 depending on the results of the test. 39313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 393256a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic int 39333473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathCompareNodeSetFloat(xmlXPathParserContextPtr ctxt, int inf, int strict, 39343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr arg, xmlXPathObjectPtr f) { 39353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int i, ret = 0; 39363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlNodeSetPtr ns; 39373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlChar *str2; 39383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 39393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((f == NULL) || (arg == NULL) || 39403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ((arg->type != XPATH_NODESET) && (arg->type != XPATH_XSLT_TREE))) { 39413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(arg); 39423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(f); 39433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(0); 39443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 39453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ns = arg->nodesetval; 3946911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard if (ns != NULL) { 3947911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard for (i = 0;i < ns->nodeNr;i++) { 3948ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard str2 = xmlXPathCastNodeToString(ns->nodeTab[i]); 3949911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard if (str2 != NULL) { 3950911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard valuePush(ctxt, 3951911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard xmlXPathNewString(str2)); 3952911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard xmlFree(str2); 3953911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard xmlXPathNumberFunction(ctxt, 1); 3954911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard valuePush(ctxt, xmlXPathObjectCopy(f)); 3955911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard ret = xmlXPathCompareValues(ctxt, inf, strict); 3956911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard if (ret) 3957911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard break; 3958911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard } 3959911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard } 39603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 39613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(arg); 39623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(f); 39633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ret); 39643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 39653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 39663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 39673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathCompareNodeSetString: 39683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 39693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @inf: less than (1) or greater than (0) 39703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @strict: is the comparison strict 39713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @arg: the node set 39723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @s: the value 39733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 39743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the compare operation between a nodeset and a string 39753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ns < @val (1, 1, ... 39763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ns <= @val (1, 0, ... 39773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ns > @val (0, 1, ... 39783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ns >= @val (0, 0, ... 39793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 39803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * If one object to be compared is a node-set and the other is a string, 39813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * then the comparison will be true if and only if there is a node in 39823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the node-set such that the result of performing the comparison on the 39833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * string-value of the node and the other string is true. 39843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 39853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns 0 or 1 depending on the results of the test. 39863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 398756a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic int 39883473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathCompareNodeSetString(xmlXPathParserContextPtr ctxt, int inf, int strict, 39893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr arg, xmlXPathObjectPtr s) { 39903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int i, ret = 0; 39913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlNodeSetPtr ns; 39923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlChar *str2; 39933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 39943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((s == NULL) || (arg == NULL) || 39953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ((arg->type != XPATH_NODESET) && (arg->type != XPATH_XSLT_TREE))) { 39963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(arg); 39973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(s); 39983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(0); 39993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 40003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ns = arg->nodesetval; 4001911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard if (ns != NULL) { 4002911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard for (i = 0;i < ns->nodeNr;i++) { 4003ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard str2 = xmlXPathCastNodeToString(ns->nodeTab[i]); 4004911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard if (str2 != NULL) { 4005911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard valuePush(ctxt, 4006911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard xmlXPathNewString(str2)); 4007911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard xmlFree(str2); 4008911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard valuePush(ctxt, xmlXPathObjectCopy(s)); 4009911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard ret = xmlXPathCompareValues(ctxt, inf, strict); 4010911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard if (ret) 4011911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard break; 4012911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard } 4013911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard } 40143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 40153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(arg); 40163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(s); 40173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ret); 40183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 40193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 40203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 40213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathCompareNodeSets: 4022ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @inf: less than (1) or greater than (0) 40233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @strict: is the comparison strict 4024cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * @arg1: the first node set object 40253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @arg2: the second node set object 40263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 40273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the compare operation on nodesets: 40283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 40293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * If both objects to be compared are node-sets, then the comparison 40303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * will be true if and only if there is a node in the first node-set 40313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * and a node in the second node-set such that the result of performing 40323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the comparison on the string-values of the two nodes is true. 40333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * .... 40343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * When neither object to be compared is a node-set and the operator 40353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * is <=, <, >= or >, then the objects are compared by converting both 40363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * objects to numbers and comparing the numbers according to IEEE 754. 40373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * .... 40383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The number function converts its argument to a number as follows: 40393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * - a string that consists of optional whitespace followed by an 40403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * optional minus sign followed by a Number followed by whitespace 40413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * is converted to the IEEE 754 number that is nearest (according 40423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * to the IEEE 754 round-to-nearest rule) to the mathematical value 40433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * represented by the string; any other string is converted to NaN 40443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 40453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Conclusion all nodes need to be converted first to their string value 40463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * and then the comparison must be done when possible 40473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 404856a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic int 404956a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel VeillardxmlXPathCompareNodeSets(int inf, int strict, 40503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr arg1, xmlXPathObjectPtr arg2) { 40513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int i, j, init = 0; 40523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor double val1; 40533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor double *values2; 40543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int ret = 0; 40553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlNodeSetPtr ns1; 40563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlNodeSetPtr ns2; 40573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 40583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((arg1 == NULL) || 40594dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard ((arg1->type != XPATH_NODESET) && (arg1->type != XPATH_XSLT_TREE))) { 40604dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard xmlXPathFreeObject(arg2); 40613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(0); 40624dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard } 40633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((arg2 == NULL) || 40644dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard ((arg2->type != XPATH_NODESET) && (arg2->type != XPATH_XSLT_TREE))) { 40654dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard xmlXPathFreeObject(arg1); 40664dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard xmlXPathFreeObject(arg2); 40673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(0); 40684dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard } 40693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 40703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ns1 = arg1->nodesetval; 40713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ns2 = arg2->nodesetval; 40723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 4073d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard if ((ns1 == NULL) || (ns1->nodeNr <= 0)) { 40744dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard xmlXPathFreeObject(arg1); 40754dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard xmlXPathFreeObject(arg2); 40763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(0); 40774dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard } 4078d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard if ((ns2 == NULL) || (ns2->nodeNr <= 0)) { 40794dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard xmlXPathFreeObject(arg1); 40804dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard xmlXPathFreeObject(arg2); 40813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(0); 40824dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard } 40833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 40843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor values2 = (double *) xmlMalloc(ns2->nodeNr * sizeof(double)); 40853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (values2 == NULL) { 40864dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard xmlXPathFreeObject(arg1); 40874dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard xmlXPathFreeObject(arg2); 40883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(0); 40893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 40903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor for (i = 0;i < ns1->nodeNr;i++) { 4091ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard val1 = xmlXPathCastNodeToNumber(ns1->nodeTab[i]); 4092cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard if (xmlXPathIsNaN(val1)) 40933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor continue; 40943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor for (j = 0;j < ns2->nodeNr;j++) { 40953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (init == 0) { 4096ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard values2[j] = xmlXPathCastNodeToNumber(ns2->nodeTab[j]); 40973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 4098cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard if (xmlXPathIsNaN(values2[j])) 40993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor continue; 41003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (inf && strict) 41013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = (val1 < values2[j]); 41023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else if (inf && !strict) 41033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = (val1 <= values2[j]); 41043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else if (!inf && strict) 41053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = (val1 > values2[j]); 41063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else if (!inf && !strict) 41073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = (val1 >= values2[j]); 41083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ret) 41093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 41103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 41113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ret) 41123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 41133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor init = 1; 41143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 41153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(values2); 41164dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard xmlXPathFreeObject(arg1); 41174dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard xmlXPathFreeObject(arg2); 41183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ret); 41193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 41203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 41213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 41223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathCompareNodeSetValue: 41233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 41243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @inf: less than (1) or greater than (0) 41253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @strict: is the comparison strict 41263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @arg: the node set 41273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val: the value 41283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 41293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the compare operation between a nodeset and a value 41303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ns < @val (1, 1, ... 41313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ns <= @val (1, 0, ... 41323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ns > @val (0, 1, ... 41333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ns >= @val (0, 0, ... 41343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 41353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * If one object to be compared is a node-set and the other is a boolean, 41363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * then the comparison will be true if and only if the result of performing 41373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the comparison on the boolean and on the result of converting 41383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the node-set to a boolean using the boolean function is true. 41393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 41403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns 0 or 1 depending on the results of the test. 41413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 414256a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic int 41433473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathCompareNodeSetValue(xmlXPathParserContextPtr ctxt, int inf, int strict, 41443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr arg, xmlXPathObjectPtr val) { 41453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((val == NULL) || (arg == NULL) || 41463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ((arg->type != XPATH_NODESET) && (arg->type != XPATH_XSLT_TREE))) 41473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(0); 41483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 41493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor switch(val->type) { 41503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_NUMBER: 41513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(xmlXPathCompareNodeSetFloat(ctxt, inf, strict, arg, val)); 41523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_NODESET: 41533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_XSLT_TREE: 415456a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillard return(xmlXPathCompareNodeSets(inf, strict, arg, val)); 41553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_STRING: 41563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(xmlXPathCompareNodeSetString(ctxt, inf, strict, arg, val)); 41573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_BOOLEAN: 41583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, arg); 41593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathBooleanFunction(ctxt, 1); 41603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, val); 41613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(xmlXPathCompareValues(ctxt, inf, strict)); 41623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor default: 41633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor TODO 41643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 41653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(0); 41663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 41673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 41683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 41693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathEqualNodeSetString 41703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @arg: the nodeset object argument 41713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @str: the string to compare to. 41723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 41733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the equal operation on XPath objects content: @arg1 == @arg2 41743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * If one object to be compared is a node-set and the other is a string, 41753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * then the comparison will be true if and only if there is a node in 41763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the node-set such that the result of performing the comparison on the 41773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * string-value of the node and the other string is true. 41783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 41793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns 0 or 1 depending on the results of the test. 41803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 418156a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic int 4182f06307e2c172284bb41376c396f757bdac9bdd19Daniel VeillardxmlXPathEqualNodeSetString(xmlXPathObjectPtr arg, const xmlChar * str) 4183f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard{ 41843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int i; 41853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlNodeSetPtr ns; 41863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlChar *str2; 4187f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard unsigned int hash; 41883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 41893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((str == NULL) || (arg == NULL) || 4190f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ((arg->type != XPATH_NODESET) && (arg->type != XPATH_XSLT_TREE))) 4191f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (0); 41923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ns = arg->nodesetval; 4193f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard hash = xmlXPathStringHash(str); 4194d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard if (ns == NULL) 4195f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (0); 419673c9c049195bf897dbcb6308a1ab9d16b3fe6b2cDaniel Veillard if (ns->nodeNr <= 0) { 419773c9c049195bf897dbcb6308a1ab9d16b3fe6b2cDaniel Veillard if (hash == 0) 419873c9c049195bf897dbcb6308a1ab9d16b3fe6b2cDaniel Veillard return(1); 419973c9c049195bf897dbcb6308a1ab9d16b3fe6b2cDaniel Veillard return(0); 420073c9c049195bf897dbcb6308a1ab9d16b3fe6b2cDaniel Veillard } 4201f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard for (i = 0; i < ns->nodeNr; i++) { 4202f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (xmlXPathNodeValHash(ns->nodeTab[i]) == hash) { 4203f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard str2 = xmlNodeGetContent(ns->nodeTab[i]); 4204f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((str2 != NULL) && (xmlStrEqual(str, str2))) { 4205f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlFree(str2); 4206f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (1); 4207f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 4208f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (str2 != NULL) 4209f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlFree(str2); 4210f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 42113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 4212f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (0); 42133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 42143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 42153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 42163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathEqualNodeSetFloat 42173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @arg: the nodeset object argument 42183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @f: the float to compare to 42193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 42203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the equal operation on XPath objects content: @arg1 == @arg2 42213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * If one object to be compared is a node-set and the other is a number, 42223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * then the comparison will be true if and only if there is a node in 42233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the node-set such that the result of performing the comparison on the 42243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * number to be compared and on the result of converting the string-value 42253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * of that node to a number using the number function is true. 42263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 42273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns 0 or 1 depending on the results of the test. 42283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 422956a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic int 42303473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathEqualNodeSetFloat(xmlXPathObjectPtr arg, double f) { 42313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor char buf[100] = ""; 42323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 42333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((arg == NULL) || 42343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ((arg->type != XPATH_NODESET) && (arg->type != XPATH_XSLT_TREE))) 42353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(0); 42363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 4237e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese xmlXPathFormatNumber(f, buf, sizeof(buf)); 42383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(xmlXPathEqualNodeSetString(arg, BAD_CAST buf)); 42393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 42403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 42413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 42423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 42433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathEqualNodeSets 42443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @arg1: first nodeset object argument 42453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @arg2: second nodeset object argument 42463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 42473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the equal operation on XPath nodesets: @arg1 == @arg2 42483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * If both objects to be compared are node-sets, then the comparison 42493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * will be true if and only if there is a node in the first node-set and 42503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * a node in the second node-set such that the result of performing the 42513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * comparison on the string-values of the two nodes is true. 42523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 42533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * (needless to say, this is a costly operation) 42543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 42553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns 0 or 1 depending on the results of the test. 42563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 425756a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic int 42583473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathEqualNodeSets(xmlXPathObjectPtr arg1, xmlXPathObjectPtr arg2) { 42593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int i, j; 4260f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard unsigned int *hashs1; 4261f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard unsigned int *hashs2; 42623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlChar **values1; 42633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlChar **values2; 42643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int ret = 0; 42653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlNodeSetPtr ns1; 42663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlNodeSetPtr ns2; 42673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 42683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((arg1 == NULL) || 42693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ((arg1->type != XPATH_NODESET) && (arg1->type != XPATH_XSLT_TREE))) 42703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(0); 42713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((arg2 == NULL) || 42723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ((arg2->type != XPATH_NODESET) && (arg2->type != XPATH_XSLT_TREE))) 42733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(0); 42743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 42753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ns1 = arg1->nodesetval; 42763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ns2 = arg2->nodesetval; 42773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 4278911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard if ((ns1 == NULL) || (ns1->nodeNr <= 0)) 42793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(0); 4280911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard if ((ns2 == NULL) || (ns2->nodeNr <= 0)) 42813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(0); 42823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 42833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 42843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * check if there is a node pertaining to both sets 42853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 42863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor for (i = 0;i < ns1->nodeNr;i++) 42873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor for (j = 0;j < ns2->nodeNr;j++) 42883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ns1->nodeTab[i] == ns2->nodeTab[j]) 42893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(1); 42903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 42913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor values1 = (xmlChar **) xmlMalloc(ns1->nodeNr * sizeof(xmlChar *)); 42923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (values1 == NULL) 42933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(0); 4294f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard hashs1 = (unsigned int *) xmlMalloc(ns1->nodeNr * sizeof(unsigned int)); 4295f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (hashs1 == NULL) { 4296f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlFree(values1); 4297f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return(0); 4298f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 42993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor memset(values1, 0, ns1->nodeNr * sizeof(xmlChar *)); 43003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor values2 = (xmlChar **) xmlMalloc(ns2->nodeNr * sizeof(xmlChar *)); 43013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (values2 == NULL) { 4302f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlFree(hashs1); 43033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(values1); 43043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(0); 43053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 4306f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard hashs2 = (unsigned int *) xmlMalloc(ns2->nodeNr * sizeof(unsigned int)); 4307f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (hashs2 == NULL) { 4308f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlFree(hashs1); 4309f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlFree(values1); 4310f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlFree(values2); 4311f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return(0); 4312f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 43133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor memset(values2, 0, ns2->nodeNr * sizeof(xmlChar *)); 43143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor for (i = 0;i < ns1->nodeNr;i++) { 4315f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard hashs1[i] = xmlXPathNodeValHash(ns1->nodeTab[i]); 43163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor for (j = 0;j < ns2->nodeNr;j++) { 43173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (i == 0) 4318f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard hashs2[j] = xmlXPathNodeValHash(ns2->nodeTab[j]); 4319f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (hashs1[i] == hashs2[j]) { 4320f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (values1[i] == NULL) 4321f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard values1[i] = xmlNodeGetContent(ns1->nodeTab[i]); 4322f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (values2[j] == NULL) 4323f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard values2[j] = xmlNodeGetContent(ns2->nodeTab[j]); 4324f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ret = xmlStrEqual(values1[i], values2[j]); 4325f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (ret) 4326f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 4327f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 43283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 43293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ret) 43303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 43313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 43323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor for (i = 0;i < ns1->nodeNr;i++) 43333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (values1[i] != NULL) 43343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(values1[i]); 43353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor for (j = 0;j < ns2->nodeNr;j++) 43363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (values2[j] != NULL) 43373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(values2[j]); 43383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(values1); 43393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(values2); 4340f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlFree(hashs1); 4341f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlFree(hashs2); 43423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ret); 43433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 43443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 43453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 43463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathEqualValues: 43473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 43483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 43493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the equal operation on XPath objects content: @arg1 == @arg2 43503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 43513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns 0 or 1 depending on the results of the test. 43523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 43533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorint 43543473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathEqualValues(xmlXPathParserContextPtr ctxt) { 43553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr arg1, arg2; 43563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int ret = 0; 43573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 43583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor arg1 = valuePop(ctxt); 43593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (arg1 == NULL) 43603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XP_ERROR0(XPATH_INVALID_OPERAND); 43613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 43623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor arg2 = valuePop(ctxt); 43633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (arg2 == NULL) { 43643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(arg1); 43653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XP_ERROR0(XPATH_INVALID_OPERAND); 43663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 43673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 43683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (arg1 == arg2) { 43693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_EXPR 43703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 43713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "Equal: by pointer\n"); 43723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 43733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(1); 43743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 43753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 43763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor switch (arg1->type) { 43773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_UNDEFINED: 43783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_EXPR 43793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 43803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "Equal: undefined\n"); 43813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 43823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 43833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_XSLT_TREE: 43843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_NODESET: 43853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor switch (arg2->type) { 43863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_UNDEFINED: 43873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_EXPR 43883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 43893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "Equal: undefined\n"); 43903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 43913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 43923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_XSLT_TREE: 43933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_NODESET: 43943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = xmlXPathEqualNodeSets(arg1, arg2); 43953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 43963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_BOOLEAN: 43973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((arg1->nodesetval == NULL) || 43983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor (arg1->nodesetval->nodeNr == 0)) ret = 0; 43993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else 44003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = 1; 44013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = (ret == arg2->boolval); 44023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 44033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_NUMBER: 44043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = xmlXPathEqualNodeSetFloat(arg1, arg2->floatval); 44053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 44063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_STRING: 44073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = xmlXPathEqualNodeSetString(arg1, arg2->stringval); 44083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 44093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_USERS: 44103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_POINT: 44113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_RANGE: 44123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_LOCATIONSET: 44133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor TODO 44143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 44153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 44163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 44173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_BOOLEAN: 44183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor switch (arg2->type) { 44193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_UNDEFINED: 44203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_EXPR 44213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 44223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "Equal: undefined\n"); 44233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 44243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 44253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_NODESET: 44263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_XSLT_TREE: 44273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((arg2->nodesetval == NULL) || 4428bd6e63122f047d519a57611a187a965c6a1c0b1cDaniel Veillard (arg2->nodesetval->nodeNr == 0)) 4429bd6e63122f047d519a57611a187a965c6a1c0b1cDaniel Veillard ret = 0; 44303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else 44313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = 1; 4432bd6e63122f047d519a57611a187a965c6a1c0b1cDaniel Veillard ret = (ret == arg1->boolval); 44333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 44343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_BOOLEAN: 44353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_EXPR 44363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 44373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "Equal: %d boolean %d \n", 44383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor arg1->boolval, arg2->boolval); 44393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 44403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = (arg1->boolval == arg2->boolval); 44413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 44423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_NUMBER: 44433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (arg2->floatval) ret = 1; 44443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else ret = 0; 44453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = (arg1->boolval == ret); 44463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 44473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_STRING: 44483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((arg2->stringval == NULL) || 44493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor (arg2->stringval[0] == 0)) ret = 0; 44503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else 44513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = 1; 44523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = (arg1->boolval == ret); 44533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 44543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_USERS: 44553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_POINT: 44563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_RANGE: 44573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_LOCATIONSET: 44583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor TODO 44593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 44603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 44613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 44623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_NUMBER: 44633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor switch (arg2->type) { 44643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_UNDEFINED: 44653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_EXPR 44663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 44673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "Equal: undefined\n"); 44683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 44693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 44703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_NODESET: 44713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_XSLT_TREE: 44723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = xmlXPathEqualNodeSetFloat(arg2, arg1->floatval); 44733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 44743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_BOOLEAN: 44753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (arg1->floatval) ret = 1; 44763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else ret = 0; 44773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = (arg2->boolval == ret); 44783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 44793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_STRING: 44803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, arg2); 44813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathNumberFunction(ctxt, 1); 44823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor arg2 = valuePop(ctxt); 44833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* no break on purpose */ 44843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_NUMBER: 4485d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard /* Hand check NaN and Infinity equalities */ 448621458c85e209cd2621ac3eadfee075ae2dc0121dDaniel Veillard if (xmlXPathIsNaN(arg1->floatval) || xmlXPathIsNaN(arg2->floatval)) { 448721458c85e209cd2621ac3eadfee075ae2dc0121dDaniel Veillard ret = 0; 4488d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard } else if (xmlXPathIsInf(arg1->floatval) == 1) { 4489d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard if (xmlXPathIsInf(arg2->floatval) == 1) 4490d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret = 1; 4491d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard else 4492d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret = 0; 4493d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard } else if (xmlXPathIsInf(arg1->floatval) == -1) { 4494d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard if (xmlXPathIsInf(arg2->floatval) == -1) 4495d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret = 1; 4496d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard else 4497d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret = 0; 4498d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard } else if (xmlXPathIsInf(arg2->floatval) == 1) { 4499d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard if (xmlXPathIsInf(arg1->floatval) == 1) 4500d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret = 1; 4501d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard else 4502d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret = 0; 4503d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard } else if (xmlXPathIsInf(arg2->floatval) == -1) { 4504d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard if (xmlXPathIsInf(arg1->floatval) == -1) 4505d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret = 1; 4506d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard else 4507d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret = 0; 450821458c85e209cd2621ac3eadfee075ae2dc0121dDaniel Veillard } else { 450921458c85e209cd2621ac3eadfee075ae2dc0121dDaniel Veillard ret = (arg1->floatval == arg2->floatval); 451021458c85e209cd2621ac3eadfee075ae2dc0121dDaniel Veillard } 45113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 45123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_USERS: 45133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_POINT: 45143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_RANGE: 45153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_LOCATIONSET: 45163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor TODO 45173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 45183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 45193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 45203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_STRING: 45213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor switch (arg2->type) { 45223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_UNDEFINED: 45233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_EXPR 45243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 45253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "Equal: undefined\n"); 45263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 45273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 45283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_NODESET: 45293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_XSLT_TREE: 45303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = xmlXPathEqualNodeSetString(arg2, arg1->stringval); 45313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 45323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_BOOLEAN: 45333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((arg1->stringval == NULL) || 45343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor (arg1->stringval[0] == 0)) ret = 0; 45353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else 45363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = 1; 45373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = (arg2->boolval == ret); 45383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 45393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_STRING: 45403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = xmlStrEqual(arg1->stringval, arg2->stringval); 45413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 45423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_NUMBER: 45433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, arg1); 45443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathNumberFunction(ctxt, 1); 45453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor arg1 = valuePop(ctxt); 4546d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard /* Hand check NaN and Infinity equalities */ 454721458c85e209cd2621ac3eadfee075ae2dc0121dDaniel Veillard if (xmlXPathIsNaN(arg1->floatval) || xmlXPathIsNaN(arg2->floatval)) { 454821458c85e209cd2621ac3eadfee075ae2dc0121dDaniel Veillard ret = 0; 4549d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard } else if (xmlXPathIsInf(arg1->floatval) == 1) { 4550d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard if (xmlXPathIsInf(arg2->floatval) == 1) 4551d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret = 1; 4552d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard else 4553d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret = 0; 4554d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard } else if (xmlXPathIsInf(arg1->floatval) == -1) { 4555d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard if (xmlXPathIsInf(arg2->floatval) == -1) 4556d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret = 1; 4557d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard else 4558d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret = 0; 4559d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard } else if (xmlXPathIsInf(arg2->floatval) == 1) { 4560d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard if (xmlXPathIsInf(arg1->floatval) == 1) 4561d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret = 1; 4562d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard else 4563d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret = 0; 4564d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard } else if (xmlXPathIsInf(arg2->floatval) == -1) { 4565d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard if (xmlXPathIsInf(arg1->floatval) == -1) 4566d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret = 1; 4567d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard else 4568d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret = 0; 456921458c85e209cd2621ac3eadfee075ae2dc0121dDaniel Veillard } else { 457021458c85e209cd2621ac3eadfee075ae2dc0121dDaniel Veillard ret = (arg1->floatval == arg2->floatval); 457121458c85e209cd2621ac3eadfee075ae2dc0121dDaniel Veillard } 45723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 45733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_USERS: 45743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_POINT: 45753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_RANGE: 45763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_LOCATIONSET: 45773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor TODO 45783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 45793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 45803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 45813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_USERS: 45823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_POINT: 45833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_RANGE: 45843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_LOCATIONSET: 45853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor TODO 45863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 45873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 45883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(arg1); 45893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(arg2); 45903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ret); 45913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 45923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 45933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 45943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 45953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathCompareValues: 45963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 45973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @inf: less than (1) or greater than (0) 45983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @strict: is the comparison strict 45993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 46003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the compare operation on XPath objects: 46013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @arg1 < @arg2 (1, 1, ... 46023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @arg1 <= @arg2 (1, 0, ... 46033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @arg1 > @arg2 (0, 1, ... 46043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @arg1 >= @arg2 (0, 0, ... 46053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 46063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * When neither object to be compared is a node-set and the operator is 46073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * <=, <, >=, >, then the objects are compared by converted both objects 46083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * to numbers and comparing the numbers according to IEEE 754. The < 46093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * comparison will be true if and only if the first number is less than the 46103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * second number. The <= comparison will be true if and only if the first 46113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * number is less than or equal to the second number. The > comparison 46123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * will be true if and only if the first number is greater than the second 46133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * number. The >= comparison will be true if and only if the first number 46143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * is greater than or equal to the second number. 46153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 4616cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * Returns 1 if the comparison succeeded, 0 if it failed 46173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 46183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorint 46193473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathCompareValues(xmlXPathParserContextPtr ctxt, int inf, int strict) { 4620d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard int ret = 0, arg1i = 0, arg2i = 0; 46213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr arg1, arg2; 46223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 46233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor arg2 = valuePop(ctxt); 46243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (arg2 == NULL) { 46253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XP_ERROR0(XPATH_INVALID_OPERAND); 46263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 46273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 46283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor arg1 = valuePop(ctxt); 46293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (arg1 == NULL) { 46303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(arg2); 46313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XP_ERROR0(XPATH_INVALID_OPERAND); 46323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 46333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 46343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((arg2->type == XPATH_NODESET) || (arg1->type == XPATH_NODESET)) { 46353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((arg2->type == XPATH_NODESET) && (arg1->type == XPATH_NODESET)) { 463656a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillard ret = xmlXPathCompareNodeSets(inf, strict, arg1, arg2); 46373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else { 46383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (arg1->type == XPATH_NODESET) { 46394af6b6e801346d1c832cf19b7c3833a831871db2Daniel Veillard ret = xmlXPathCompareNodeSetValue(ctxt, inf, strict, 46404af6b6e801346d1c832cf19b7c3833a831871db2Daniel Veillard arg1, arg2); 46413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else { 46424af6b6e801346d1c832cf19b7c3833a831871db2Daniel Veillard ret = xmlXPathCompareNodeSetValue(ctxt, !inf, strict, 46434af6b6e801346d1c832cf19b7c3833a831871db2Daniel Veillard arg2, arg1); 46443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 46453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 46463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ret); 46473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 46483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 46493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (arg1->type != XPATH_NUMBER) { 46503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, arg1); 46513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathNumberFunction(ctxt, 1); 46523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor arg1 = valuePop(ctxt); 46533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 46543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (arg1->type != XPATH_NUMBER) { 46553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(arg1); 46563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(arg2); 46573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XP_ERROR0(XPATH_INVALID_OPERAND); 46583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 46593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (arg2->type != XPATH_NUMBER) { 46603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, arg2); 46613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathNumberFunction(ctxt, 1); 46623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor arg2 = valuePop(ctxt); 46633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 46643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (arg2->type != XPATH_NUMBER) { 46653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(arg1); 46663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(arg2); 46673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XP_ERROR0(XPATH_INVALID_OPERAND); 46683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 46693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 46703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Add tests for infinity and nan 46713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * => feedback on 3.4 for Inf and NaN 46723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 4673d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard /* Hand check NaN and Infinity comparisons */ 467421458c85e209cd2621ac3eadfee075ae2dc0121dDaniel Veillard if (xmlXPathIsNaN(arg1->floatval) || xmlXPathIsNaN(arg2->floatval)) { 4675d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret=0; 467621458c85e209cd2621ac3eadfee075ae2dc0121dDaniel Veillard } else { 4677d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard arg1i=xmlXPathIsInf(arg1->floatval); 4678d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard arg2i=xmlXPathIsInf(arg2->floatval); 4679d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard if (inf && strict) { 4680d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard if ((arg1i == -1 && arg2i != -1) || 4681d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard (arg2i == 1 && arg1i != 1)) { 4682d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret = 1; 4683d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard } else if (arg1i == 0 && arg2i == 0) { 4684d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret = (arg1->floatval < arg2->floatval); 4685d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard } else { 4686d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret = 0; 4687d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard } 4688d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard } 4689d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard else if (inf && !strict) { 4690d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard if (arg1i == -1 || arg2i == 1) { 4691d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret = 1; 4692d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard } else if (arg1i == 0 && arg2i == 0) { 4693d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret = (arg1->floatval <= arg2->floatval); 4694d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard } else { 4695d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret = 0; 4696d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard } 4697d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard } 4698d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard else if (!inf && strict) { 4699d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard if ((arg1i == 1 && arg2i != 1) || 4700d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard (arg2i == -1 && arg1i != -1)) { 4701d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret = 1; 4702d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard } else if (arg1i == 0 && arg2i == 0) { 4703d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret = (arg1->floatval > arg2->floatval); 4704d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard } else { 4705d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret = 0; 4706d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard } 4707d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard } 4708d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard else if (!inf && !strict) { 4709d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard if (arg1i == 1 || arg2i == -1) { 4710d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret = 1; 4711d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard } else if (arg1i == 0 && arg2i == 0) { 4712d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret = (arg1->floatval >= arg2->floatval); 4713d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard } else { 4714d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret = 0; 4715d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard } 4716d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard } 471721458c85e209cd2621ac3eadfee075ae2dc0121dDaniel Veillard } 47183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(arg1); 47193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(arg2); 47203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ret); 47213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 47223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 47233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 47243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathValueFlipSign: 47253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 47263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 47273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the unary - operation on an XPath object 47283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The numeric operators convert their operands to numbers as if 47293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * by calling the number function. 47303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 47313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 47323473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathValueFlipSign(xmlXPathParserContextPtr ctxt) { 4733ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard CAST_TO_NUMBER; 4734ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard CHECK_TYPE(XPATH_NUMBER); 4735eca82810f0fb81f3e9936d2018347e1e19de513aDaniel Veillard if (xmlXPathIsNaN(ctxt->value->floatval)) 4736eca82810f0fb81f3e9936d2018347e1e19de513aDaniel Veillard ctxt->value->floatval=xmlXPathNAN; 4737eca82810f0fb81f3e9936d2018347e1e19de513aDaniel Veillard else if (xmlXPathIsInf(ctxt->value->floatval) == 1) 4738eca82810f0fb81f3e9936d2018347e1e19de513aDaniel Veillard ctxt->value->floatval=xmlXPathNINF; 4739eca82810f0fb81f3e9936d2018347e1e19de513aDaniel Veillard else if (xmlXPathIsInf(ctxt->value->floatval) == -1) 4740eca82810f0fb81f3e9936d2018347e1e19de513aDaniel Veillard ctxt->value->floatval=xmlXPathPINF; 4741eca82810f0fb81f3e9936d2018347e1e19de513aDaniel Veillard else if (ctxt->value->floatval == 0) { 47425fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard if (xmlXPathGetSign(ctxt->value->floatval) == 0) 47435fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard ctxt->value->floatval = xmlXPathNZERO; 47445fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard else 47455fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard ctxt->value->floatval = 0; 47465fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard } 47475fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard else 47485fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard ctxt->value->floatval = - ctxt->value->floatval; 47493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 47503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 47513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 47523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathAddValues: 47533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 47543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 47553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the add operation on XPath objects: 47563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The numeric operators convert their operands to numbers as if 47573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * by calling the number function. 47583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 47593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 47603473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathAddValues(xmlXPathParserContextPtr ctxt) { 47613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr arg; 47623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor double val; 47633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 4764ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard arg = valuePop(ctxt); 4765ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard if (arg == NULL) 4766ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard XP_ERROR(XPATH_INVALID_OPERAND); 4767ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard val = xmlXPathCastToNumber(arg); 47683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(arg); 47693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 4770ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard CAST_TO_NUMBER; 4771ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard CHECK_TYPE(XPATH_NUMBER); 4772ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ctxt->value->floatval += val; 47733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 47743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 47753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 47763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathSubValues: 47773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 47783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 4779cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * Implement the subtraction operation on XPath objects: 47803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The numeric operators convert their operands to numbers as if 47813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * by calling the number function. 47823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 47833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 47843473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathSubValues(xmlXPathParserContextPtr ctxt) { 47853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr arg; 47863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor double val; 47873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 4788ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard arg = valuePop(ctxt); 4789ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard if (arg == NULL) 4790ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard XP_ERROR(XPATH_INVALID_OPERAND); 4791ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard val = xmlXPathCastToNumber(arg); 47923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(arg); 47933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 4794ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard CAST_TO_NUMBER; 4795ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard CHECK_TYPE(XPATH_NUMBER); 4796ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ctxt->value->floatval -= val; 47973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 47983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 47993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 48003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathMultValues: 48013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 48023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 48033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the multiply operation on XPath objects: 48043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The numeric operators convert their operands to numbers as if 48053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * by calling the number function. 48063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 48073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 48083473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathMultValues(xmlXPathParserContextPtr ctxt) { 48093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr arg; 48103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor double val; 48113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 4812ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard arg = valuePop(ctxt); 4813ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard if (arg == NULL) 4814ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard XP_ERROR(XPATH_INVALID_OPERAND); 4815ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard val = xmlXPathCastToNumber(arg); 48163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(arg); 48173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 4818ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard CAST_TO_NUMBER; 4819ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard CHECK_TYPE(XPATH_NUMBER); 4820ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ctxt->value->floatval *= val; 48213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 48223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 48233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 48243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathDivValues: 48253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 48263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 48273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the div operation on XPath objects @arg1 / @arg2: 48283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The numeric operators convert their operands to numbers as if 48293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * by calling the number function. 48303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 48313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 48323473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathDivValues(xmlXPathParserContextPtr ctxt) { 48333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr arg; 48343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor double val; 48353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 4836ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard arg = valuePop(ctxt); 4837ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard if (arg == NULL) 4838ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard XP_ERROR(XPATH_INVALID_OPERAND); 4839ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard val = xmlXPathCastToNumber(arg); 48403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(arg); 48413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 4842ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard CAST_TO_NUMBER; 4843ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard CHECK_TYPE(XPATH_NUMBER); 4844eca82810f0fb81f3e9936d2018347e1e19de513aDaniel Veillard if (xmlXPathIsNaN(val) || xmlXPathIsNaN(ctxt->value->floatval)) 4845eca82810f0fb81f3e9936d2018347e1e19de513aDaniel Veillard ctxt->value->floatval = xmlXPathNAN; 4846eca82810f0fb81f3e9936d2018347e1e19de513aDaniel Veillard else if (val == 0 && xmlXPathGetSign(val) != 0) { 48475fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard if (ctxt->value->floatval == 0) 48485fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard ctxt->value->floatval = xmlXPathNAN; 48495fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard else if (ctxt->value->floatval > 0) 48505fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard ctxt->value->floatval = xmlXPathNINF; 48515fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard else if (ctxt->value->floatval < 0) 48525fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard ctxt->value->floatval = xmlXPathPINF; 48535fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard } 48545fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard else if (val == 0) { 48555f4b5999b4eeda2ca68e6d9f54a3c534a8474b38Daniel Veillard if (ctxt->value->floatval == 0) 48565f4b5999b4eeda2ca68e6d9f54a3c534a8474b38Daniel Veillard ctxt->value->floatval = xmlXPathNAN; 48575f4b5999b4eeda2ca68e6d9f54a3c534a8474b38Daniel Veillard else if (ctxt->value->floatval > 0) 48585f4b5999b4eeda2ca68e6d9f54a3c534a8474b38Daniel Veillard ctxt->value->floatval = xmlXPathPINF; 48595f4b5999b4eeda2ca68e6d9f54a3c534a8474b38Daniel Veillard else if (ctxt->value->floatval < 0) 48605f4b5999b4eeda2ca68e6d9f54a3c534a8474b38Daniel Veillard ctxt->value->floatval = xmlXPathNINF; 48615f4b5999b4eeda2ca68e6d9f54a3c534a8474b38Daniel Veillard } else 48625f4b5999b4eeda2ca68e6d9f54a3c534a8474b38Daniel Veillard ctxt->value->floatval /= val; 48633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 48643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 48653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 48663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathModValues: 48673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 48683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 48693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the mod operation on XPath objects: @arg1 / @arg2 48703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The numeric operators convert their operands to numbers as if 48713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * by calling the number function. 48723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 48733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 48743473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathModValues(xmlXPathParserContextPtr ctxt) { 48753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr arg; 48765fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard double arg1, arg2, tmp; 48773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 4878ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard arg = valuePop(ctxt); 4879ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard if (arg == NULL) 4880ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard XP_ERROR(XPATH_INVALID_OPERAND); 48815fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard arg2 = xmlXPathCastToNumber(arg); 48823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(arg); 48833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 4884ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard CAST_TO_NUMBER; 4885ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard CHECK_TYPE(XPATH_NUMBER); 48865fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard arg1 = ctxt->value->floatval; 4887268fd1bc97f79b43290041cfda2287fb0b0ef2d6Daniel Veillard if (arg2 == 0) 4888268fd1bc97f79b43290041cfda2287fb0b0ef2d6Daniel Veillard ctxt->value->floatval = xmlXPathNAN; 48895fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard else { 48905fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard tmp=arg1/arg2; 48915fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard ctxt->value->floatval = arg2 * (tmp - (double)((int)tmp)); 48925fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard } 48933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 48943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 48953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/************************************************************************ 48963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * * 48973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The traversal functions * 48983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * * 48993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ************************************************************************/ 49003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 49013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/* 49023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * A traversal function enumerates nodes along an axis. 49033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Initially it must be called with NULL, and it indicates 49043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * termination on the axis by returning NULL. 49053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 49063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylortypedef xmlNodePtr (*xmlXPathTraversalFunction) 49073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor (xmlXPathParserContextPtr ctxt, xmlNodePtr cur); 49083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 49093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 49103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNextSelf: 49113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 49123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur: the current node in the traversal 49133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 49143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Traversal function for the "self" direction 49153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The self axis contains just the context node itself 49163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 49173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the next element following that axis 49183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 49193473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNodePtr 49203473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNextSelf(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) { 49213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == NULL) 49223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ctxt->context->node); 49233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 49243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 49253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 49263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 49273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNextChild: 49283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 49293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur: the current node in the traversal 49303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 49313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Traversal function for the "child" direction 49323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The child axis contains the children of the context node in document order. 49333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 49343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the next element following that axis 49353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 49363473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNodePtr 49373473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNextChild(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) { 49383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == NULL) { 49393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->context->node == NULL) return(NULL); 49403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor switch (ctxt->context->node->type) { 49413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ELEMENT_NODE: 49423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_TEXT_NODE: 49433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_CDATA_SECTION_NODE: 49443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ENTITY_REF_NODE: 49453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ENTITY_NODE: 49463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_PI_NODE: 49473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_COMMENT_NODE: 49483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_NOTATION_NODE: 49493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_DTD_NODE: 49503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ctxt->context->node->children); 49513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_DOCUMENT_NODE: 49523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_DOCUMENT_TYPE_NODE: 49533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_DOCUMENT_FRAG_NODE: 49543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_HTML_DOCUMENT_NODE: 4955eae522a0d8aa9f830d2e447f29b504030dbb6bbdDaniel Veillard#ifdef LIBXML_DOCB_ENABLED 4956eae522a0d8aa9f830d2e447f29b504030dbb6bbdDaniel Veillard case XML_DOCB_DOCUMENT_NODE: 49573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 49583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(((xmlDocPtr) ctxt->context->node)->children); 49593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ELEMENT_DECL: 49603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ATTRIBUTE_DECL: 49613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ENTITY_DECL: 49623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ATTRIBUTE_NODE: 49633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_NAMESPACE_DECL: 49643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_XINCLUDE_START: 49653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_XINCLUDE_END: 49663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 49673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 49683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 49693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 49703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((cur->type == XML_DOCUMENT_NODE) || 49713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor (cur->type == XML_HTML_DOCUMENT_NODE)) 49723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 49733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(cur->next); 49743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 49753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 49763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 49773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNextDescendant: 49783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 49793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur: the current node in the traversal 49803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 49813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Traversal function for the "descendant" direction 49823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the descendant axis contains the descendants of the context node in document 49833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * order; a descendant is a child or a child of a child and so on. 49843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 49853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the next element following that axis 49863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 49873473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNodePtr 49883473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNextDescendant(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) { 49893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == NULL) { 49903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->context->node == NULL) 49913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 49923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((ctxt->context->node->type == XML_ATTRIBUTE_NODE) || 49933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor (ctxt->context->node->type == XML_NAMESPACE_DECL)) 49943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 49953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 49963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->context->node == (xmlNodePtr) ctxt->context->doc) 49973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ctxt->context->doc->children); 49983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ctxt->context->node->children); 49993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 50003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 5001567e1b48e8664163894742d5674c24baa4282f9eDaniel Veillard if (cur->children != NULL) { 50023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur->children->type != XML_ENTITY_DECL) 5003567e1b48e8664163894742d5674c24baa4282f9eDaniel Veillard return(cur->children); 5004567e1b48e8664163894742d5674c24baa4282f9eDaniel Veillard } 5005567e1b48e8664163894742d5674c24baa4282f9eDaniel Veillard 5006567e1b48e8664163894742d5674c24baa4282f9eDaniel Veillard if (cur == ctxt->context->node) return(NULL); 5007567e1b48e8664163894742d5674c24baa4282f9eDaniel Veillard 50083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur->next != NULL) return(cur->next); 50093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 50103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor do { 50113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur = cur->parent; 50123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == NULL) return(NULL); 50133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == ctxt->context->node) return(NULL); 50143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur->next != NULL) { 50153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur = cur->next; 50163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(cur); 50173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 50183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } while (cur != NULL); 50193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(cur); 50203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 50213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 50223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 50233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNextDescendantOrSelf: 50243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 50253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur: the current node in the traversal 50263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 50273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Traversal function for the "descendant-or-self" direction 50283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the descendant-or-self axis contains the context node and the descendants 50293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * of the context node in document order; thus the context node is the first 50303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * node on the axis, and the first child of the context node is the second node 50313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * on the axis 50323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 50333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the next element following that axis 50343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 50353473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNodePtr 50363473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNextDescendantOrSelf(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) { 50373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == NULL) { 50383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->context->node == NULL) 50393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 50403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((ctxt->context->node->type == XML_ATTRIBUTE_NODE) || 50413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor (ctxt->context->node->type == XML_NAMESPACE_DECL)) 50423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 50433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ctxt->context->node); 50443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 50453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 50463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(xmlXPathNextDescendant(ctxt, cur)); 50473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 50483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 50493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 50503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNextParent: 50513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 50523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur: the current node in the traversal 50533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 50543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Traversal function for the "parent" direction 50553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The parent axis contains the parent of the context node, if there is one. 50563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 50573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the next element following that axis 50583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 50593473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNodePtr 50603473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNextParent(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) { 50613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 50623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the parent of an attribute or namespace node is the element 50633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * to which the attribute or namespace node is attached 50643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Namespace handling !!! 50653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 50663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == NULL) { 50673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->context->node == NULL) return(NULL); 50683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor switch (ctxt->context->node->type) { 50693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ELEMENT_NODE: 50703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_TEXT_NODE: 50713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_CDATA_SECTION_NODE: 50723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ENTITY_REF_NODE: 50733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ENTITY_NODE: 50743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_PI_NODE: 50753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_COMMENT_NODE: 50763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_NOTATION_NODE: 50773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_DTD_NODE: 50783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ELEMENT_DECL: 50793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ATTRIBUTE_DECL: 50803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_XINCLUDE_START: 50813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_XINCLUDE_END: 50823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ENTITY_DECL: 50833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->context->node->parent == NULL) 50843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return((xmlNodePtr) ctxt->context->doc); 50853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ctxt->context->node->parent); 50863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ATTRIBUTE_NODE: { 50873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlAttrPtr att = (xmlAttrPtr) ctxt->context->node; 50883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 50893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(att->parent); 50903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 50913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_DOCUMENT_NODE: 50923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_DOCUMENT_TYPE_NODE: 50933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_DOCUMENT_FRAG_NODE: 50943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_HTML_DOCUMENT_NODE: 5095eae522a0d8aa9f830d2e447f29b504030dbb6bbdDaniel Veillard#ifdef LIBXML_DOCB_ENABLED 5096eae522a0d8aa9f830d2e447f29b504030dbb6bbdDaniel Veillard case XML_DOCB_DOCUMENT_NODE: 50973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 50983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 5099044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard case XML_NAMESPACE_DECL: { 5100044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlNsPtr ns = (xmlNsPtr) ctxt->context->node; 5101044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard 5102044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if ((ns->next != NULL) && 5103044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard (ns->next->type != XML_NAMESPACE_DECL)) 5104044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard return((xmlNodePtr) ns->next); 51053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 5106044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } 51073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 51083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 51093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 51103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 51113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 51123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 51133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNextAncestor: 51143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 51153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur: the current node in the traversal 51163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 51173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Traversal function for the "ancestor" direction 51183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the ancestor axis contains the ancestors of the context node; the ancestors 51193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * of the context node consist of the parent of context node and the parent's 51203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * parent and so on; the nodes are ordered in reverse document order; thus the 51213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * parent is the first node on the axis, and the parent's parent is the second 51223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * node on the axis 51233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 51243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the next element following that axis 51253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 51263473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNodePtr 51273473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNextAncestor(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) { 51283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 51293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the parent of an attribute or namespace node is the element 51303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * to which the attribute or namespace node is attached 51313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * !!!!!!!!!!!!! 51323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 51333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == NULL) { 51343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->context->node == NULL) return(NULL); 51353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor switch (ctxt->context->node->type) { 51363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ELEMENT_NODE: 51373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_TEXT_NODE: 51383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_CDATA_SECTION_NODE: 51393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ENTITY_REF_NODE: 51403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ENTITY_NODE: 51413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_PI_NODE: 51423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_COMMENT_NODE: 51433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_DTD_NODE: 51443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ELEMENT_DECL: 51453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ATTRIBUTE_DECL: 51463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ENTITY_DECL: 51473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_NOTATION_NODE: 51483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_XINCLUDE_START: 51493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_XINCLUDE_END: 51503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->context->node->parent == NULL) 51513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return((xmlNodePtr) ctxt->context->doc); 51523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ctxt->context->node->parent); 51533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ATTRIBUTE_NODE: { 515456a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillard xmlAttrPtr tmp = (xmlAttrPtr) ctxt->context->node; 51553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 515656a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillard return(tmp->parent); 51573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 51583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_DOCUMENT_NODE: 51593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_DOCUMENT_TYPE_NODE: 51603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_DOCUMENT_FRAG_NODE: 51613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_HTML_DOCUMENT_NODE: 5162eae522a0d8aa9f830d2e447f29b504030dbb6bbdDaniel Veillard#ifdef LIBXML_DOCB_ENABLED 5163eae522a0d8aa9f830d2e447f29b504030dbb6bbdDaniel Veillard case XML_DOCB_DOCUMENT_NODE: 51643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 51653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 5166044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard case XML_NAMESPACE_DECL: { 5167044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlNsPtr ns = (xmlNsPtr) ctxt->context->node; 5168044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard 5169044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if ((ns->next != NULL) && 5170044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard (ns->next->type != XML_NAMESPACE_DECL)) 5171044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard return((xmlNodePtr) ns->next); 5172044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard /* Bad, how did that namespace ended-up there ? */ 51733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 5174044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } 51753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 51763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 51773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 51783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == ctxt->context->doc->children) 51793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return((xmlNodePtr) ctxt->context->doc); 51803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == (xmlNodePtr) ctxt->context->doc) 51813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 51823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor switch (cur->type) { 51833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ELEMENT_NODE: 51843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_TEXT_NODE: 51853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_CDATA_SECTION_NODE: 51863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ENTITY_REF_NODE: 51873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ENTITY_NODE: 51883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_PI_NODE: 51893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_COMMENT_NODE: 51903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_NOTATION_NODE: 51913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_DTD_NODE: 51923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ELEMENT_DECL: 51933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ATTRIBUTE_DECL: 51943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ENTITY_DECL: 51953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_XINCLUDE_START: 51963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_XINCLUDE_END: 51973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(cur->parent); 51983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ATTRIBUTE_NODE: { 51993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlAttrPtr att = (xmlAttrPtr) ctxt->context->node; 52003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 52013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(att->parent); 52023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 5203dffd5c8dbc7b9052db7ae69dce419a96e22acc68Aleksey Sanin case XML_NAMESPACE_DECL: { 5204dffd5c8dbc7b9052db7ae69dce419a96e22acc68Aleksey Sanin xmlNsPtr ns = (xmlNsPtr) ctxt->context->node; 5205dffd5c8dbc7b9052db7ae69dce419a96e22acc68Aleksey Sanin 5206dffd5c8dbc7b9052db7ae69dce419a96e22acc68Aleksey Sanin if ((ns->next != NULL) && 5207dffd5c8dbc7b9052db7ae69dce419a96e22acc68Aleksey Sanin (ns->next->type != XML_NAMESPACE_DECL)) 5208dffd5c8dbc7b9052db7ae69dce419a96e22acc68Aleksey Sanin return((xmlNodePtr) ns->next); 5209dffd5c8dbc7b9052db7ae69dce419a96e22acc68Aleksey Sanin /* Bad, how did that namespace ended-up there ? */ 5210dffd5c8dbc7b9052db7ae69dce419a96e22acc68Aleksey Sanin return(NULL); 5211dffd5c8dbc7b9052db7ae69dce419a96e22acc68Aleksey Sanin } 52123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_DOCUMENT_NODE: 52133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_DOCUMENT_TYPE_NODE: 52143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_DOCUMENT_FRAG_NODE: 52153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_HTML_DOCUMENT_NODE: 5216eae522a0d8aa9f830d2e447f29b504030dbb6bbdDaniel Veillard#ifdef LIBXML_DOCB_ENABLED 5217eae522a0d8aa9f830d2e447f29b504030dbb6bbdDaniel Veillard case XML_DOCB_DOCUMENT_NODE: 52183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 52193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 52203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 52213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 52223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 52233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 52243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 52253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNextAncestorOrSelf: 52263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 52273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur: the current node in the traversal 52283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 52293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Traversal function for the "ancestor-or-self" direction 52303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * he ancestor-or-self axis contains the context node and ancestors of 52313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the context node in reverse document order; thus the context node is 52323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the first node on the axis, and the context node's parent the second; 52333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * parent here is defined the same as with the parent axis. 52343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 52353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the next element following that axis 52363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 52373473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNodePtr 52383473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNextAncestorOrSelf(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) { 52393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == NULL) 52403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ctxt->context->node); 52413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(xmlXPathNextAncestor(ctxt, cur)); 52423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 52433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 52443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 52453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNextFollowingSibling: 52463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 52473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur: the current node in the traversal 52483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 52493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Traversal function for the "following-sibling" direction 52503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The following-sibling axis contains the following siblings of the context 52513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * node in document order. 52523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 52533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the next element following that axis 52543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 52553473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNodePtr 52563473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNextFollowingSibling(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) { 52573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((ctxt->context->node->type == XML_ATTRIBUTE_NODE) || 52583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor (ctxt->context->node->type == XML_NAMESPACE_DECL)) 52593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 52603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == (xmlNodePtr) ctxt->context->doc) 52613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 52623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == NULL) 52633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ctxt->context->node->next); 52643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(cur->next); 52653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 52663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 52673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 52683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNextPrecedingSibling: 52693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 52703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur: the current node in the traversal 52713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 52723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Traversal function for the "preceding-sibling" direction 52733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The preceding-sibling axis contains the preceding siblings of the context 52743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * node in reverse document order; the first preceding sibling is first on the 52753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * axis; the sibling preceding that node is the second on the axis and so on. 52763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 52773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the next element following that axis 52783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 52793473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNodePtr 52803473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNextPrecedingSibling(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) { 52813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((ctxt->context->node->type == XML_ATTRIBUTE_NODE) || 52823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor (ctxt->context->node->type == XML_NAMESPACE_DECL)) 52833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 52843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == (xmlNodePtr) ctxt->context->doc) 52853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 52863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == NULL) 52873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ctxt->context->node->prev); 5288f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((cur->prev != NULL) && (cur->prev->type == XML_DTD_NODE)) { 5289f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard cur = cur->prev; 5290f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (cur == NULL) 5291f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return(ctxt->context->node->prev); 5292f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 52933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(cur->prev); 52943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 52953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 52963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 52973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNextFollowing: 52983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 52993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur: the current node in the traversal 53003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 53013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Traversal function for the "following" direction 53023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The following axis contains all nodes in the same document as the context 53033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * node that are after the context node in document order, excluding any 53043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * descendants and excluding attribute nodes and namespace nodes; the nodes 53053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * are ordered in document order 53063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 53073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the next element following that axis 53083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 53093473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNodePtr 53103473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNextFollowing(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) { 53113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur != NULL && cur->children != NULL) 53123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return cur->children ; 53133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == NULL) cur = ctxt->context->node; 53143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == NULL) return(NULL) ; /* ERROR */ 53153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur->next != NULL) return(cur->next) ; 53163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor do { 53173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur = cur->parent; 53183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == NULL) return(NULL); 53193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == (xmlNodePtr) ctxt->context->doc) return(NULL); 53203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur->next != NULL) return(cur->next); 53213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } while (cur != NULL); 53223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(cur); 53233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 53243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 53253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/* 53263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathIsAncestor: 53273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ancestor: the ancestor node 53283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @node: the current node 53293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 53303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Check that @ancestor is a @node's ancestor 53313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 53323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * returns 1 if @ancestor is a @node's ancestor, 0 otherwise. 53333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 53343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorstatic int 53353473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathIsAncestor(xmlNodePtr ancestor, xmlNodePtr node) { 53363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((ancestor == NULL) || (node == NULL)) return(0); 53373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* nodes need to be in the same document */ 53383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ancestor->doc != node->doc) return(0); 53393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* avoid searching if ancestor or node is the root node */ 53403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ancestor == (xmlNodePtr) node->doc) return(1); 53413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (node == (xmlNodePtr) ancestor->doc) return(0); 53423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while (node->parent != NULL) { 53433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (node->parent == ancestor) 53443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(1); 53453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor node = node->parent; 53463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 53473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(0); 53483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 53493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 53503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 53513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNextPreceding: 53523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 53533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur: the current node in the traversal 53543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 53553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Traversal function for the "preceding" direction 53563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the preceding axis contains all nodes in the same document as the context 53573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * node that are before the context node in document order, excluding any 53583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * ancestors and excluding attribute nodes and namespace nodes; the nodes are 53593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * ordered in reverse document order 53603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 53613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the next element following that axis 53623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 53633473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNodePtr 5364f06307e2c172284bb41376c396f757bdac9bdd19Daniel VeillardxmlXPathNextPreceding(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) 5365f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard{ 5366f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (cur == NULL) 5367f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard cur = ctxt->context->node; 53683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == NULL) 5369f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (NULL); 5370f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((cur->prev != NULL) && (cur->prev->type == XML_DTD_NODE)) 5371f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard cur = cur->prev; 53723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor do { 53733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur->prev != NULL) { 5374f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard for (cur = cur->prev; cur->last != NULL; cur = cur->last) ; 5375f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (cur); 53763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 53773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 53783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur = cur->parent; 5379f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (cur == NULL) 5380f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (NULL); 5381f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (cur == ctxt->context->doc->children) 5382f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (NULL); 53833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } while (xmlXPathIsAncestor(cur, ctxt->context->node)); 5384f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (cur); 5385f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard} 5386f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 5387f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard/** 5388f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * xmlXPathNextPrecedingInternal: 5389f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * @ctxt: the XPath Parser context 5390f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * @cur: the current node in the traversal 5391f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * 5392f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Traversal function for the "preceding" direction 5393f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * the preceding axis contains all nodes in the same document as the context 5394f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * node that are before the context node in document order, excluding any 5395f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * ancestors and excluding attribute nodes and namespace nodes; the nodes are 5396f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * ordered in reverse document order 5397f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * This is a faster implementation but internal only since it requires a 5398f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * state kept in the parser context: ctxt->ancestor. 5399f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * 5400f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Returns the next element following that axis 5401f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 5402f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillardstatic xmlNodePtr 5403f06307e2c172284bb41376c396f757bdac9bdd19Daniel VeillardxmlXPathNextPrecedingInternal(xmlXPathParserContextPtr ctxt, 5404f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlNodePtr cur) 5405f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard{ 5406f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (cur == NULL) { 5407f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard cur = ctxt->context->node; 5408f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (cur == NULL) 5409f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (NULL); 5410f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->ancestor = cur->parent; 5411f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 5412f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((cur->prev != NULL) && (cur->prev->type == XML_DTD_NODE)) 5413f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard cur = cur->prev; 5414f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard while (cur->prev == NULL) { 5415f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard cur = cur->parent; 5416f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (cur == NULL) 5417f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (NULL); 5418f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (cur == ctxt->context->doc->children) 5419f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (NULL); 5420f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (cur != ctxt->ancestor) 5421f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (cur); 5422f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->ancestor = cur->parent; 5423f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 5424f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard cur = cur->prev; 5425f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard while (cur->last != NULL) 5426f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard cur = cur->last; 5427f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (cur); 54283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 54293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 54303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 54313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNextNamespace: 54323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 54333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur: the current attribute in the traversal 54343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 54353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Traversal function for the "namespace" direction 54363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the namespace axis contains the namespace nodes of the context node; 54373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the order of nodes on this axis is implementation-defined; the axis will 54383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * be empty unless the context node is an element 54393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 544020ee8c03107e5d5724765da513d595fdaf290dceDaniel Veillard * We keep the XML namespace node at the end of the list. 544120ee8c03107e5d5724765da513d595fdaf290dceDaniel Veillard * 54423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the next element following that axis 54433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 54443473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNodePtr 54453473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNextNamespace(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) { 54467d7e37919fc6c7f257769c867122d885d2aae26fDaniel Veillard xmlNodePtr ret; 54477d7e37919fc6c7f257769c867122d885d2aae26fDaniel Veillard 54483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->context->node->type != XML_ELEMENT_NODE) return(NULL); 544920ee8c03107e5d5724765da513d595fdaf290dceDaniel Veillard if (cur == (xmlNodePtr) xmlXPathXMLNamespace) 545020ee8c03107e5d5724765da513d595fdaf290dceDaniel Veillard return(NULL); 54517d7e37919fc6c7f257769c867122d885d2aae26fDaniel Veillard if ((cur == NULL) || (ctxt->context->tmpNsList == NULL)) { 54527d7e37919fc6c7f257769c867122d885d2aae26fDaniel Veillard if (ctxt->context->tmpNsList != NULL) 54537d7e37919fc6c7f257769c867122d885d2aae26fDaniel Veillard xmlFree(ctxt->context->tmpNsList); 54547d7e37919fc6c7f257769c867122d885d2aae26fDaniel Veillard ctxt->context->tmpNsList = 54553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGetNsList(ctxt->context->doc, ctxt->context->node); 54567d7e37919fc6c7f257769c867122d885d2aae26fDaniel Veillard if (ctxt->context->tmpNsList == NULL) return(NULL); 54577d7e37919fc6c7f257769c867122d885d2aae26fDaniel Veillard ctxt->context->tmpNsNr = 0; 54587d7e37919fc6c7f257769c867122d885d2aae26fDaniel Veillard } 54597d7e37919fc6c7f257769c867122d885d2aae26fDaniel Veillard ret = (xmlNodePtr)ctxt->context->tmpNsList[ctxt->context->tmpNsNr++]; 54607d7e37919fc6c7f257769c867122d885d2aae26fDaniel Veillard if (ret == NULL) { 54617d7e37919fc6c7f257769c867122d885d2aae26fDaniel Veillard xmlFree(ctxt->context->tmpNsList); 54627d7e37919fc6c7f257769c867122d885d2aae26fDaniel Veillard ctxt->context->tmpNsList = NULL; 546320ee8c03107e5d5724765da513d595fdaf290dceDaniel Veillard return((xmlNodePtr) xmlXPathXMLNamespace); 54643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 54657d7e37919fc6c7f257769c867122d885d2aae26fDaniel Veillard return(ret); 54663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 54673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 54683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 54693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNextAttribute: 54703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 54713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur: the current attribute in the traversal 54723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 54733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Traversal function for the "attribute" direction 54743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * TODO: support DTD inherited default attributes 54753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 54763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the next element following that axis 54773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 54783473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNodePtr 54793473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNextAttribute(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) { 5480e470df7fdd3505c6232d6498f3b8834ebfce522dDaniel Veillard if (ctxt->context->node == NULL) 5481e470df7fdd3505c6232d6498f3b8834ebfce522dDaniel Veillard return(NULL); 5482e470df7fdd3505c6232d6498f3b8834ebfce522dDaniel Veillard if (ctxt->context->node->type != XML_ELEMENT_NODE) 5483e470df7fdd3505c6232d6498f3b8834ebfce522dDaniel Veillard return(NULL); 54843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == NULL) { 54853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->context->node == (xmlNodePtr) ctxt->context->doc) 54863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 54873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return((xmlNodePtr)ctxt->context->node->properties); 54883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 54893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return((xmlNodePtr)cur->next); 54903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 54913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 54923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/************************************************************************ 54933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * * 54943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * NodeTest Functions * 54953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * * 54963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ************************************************************************/ 54973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 54983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define IS_FUNCTION 200 54993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 5500d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard 5501d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard/************************************************************************ 5502d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * * 5503d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * Implicit tree core function library * 5504d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * * 5505d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard ************************************************************************/ 5506d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard 55073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 5508d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * xmlXPathRoot: 55093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 55103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 5511d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * Initialize the context to the root of the document 55123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 5513d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillardvoid 5514d8df6c0e8c883e1d618388d266015dda36731440Daniel VeillardxmlXPathRoot(xmlXPathParserContextPtr ctxt) { 5515d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard ctxt->context->node = (xmlNodePtr) ctxt->context->doc; 5516d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard valuePush(ctxt, xmlXPathNewNodeSet(ctxt->context->node)); 5517d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard} 55183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 5519d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard/************************************************************************ 5520d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * * 5521d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * The explicit core function library * 5522d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard *http://www.w3.org/Style/XSL/Group/1999/07/xpath-19990705.html#corelib * 5523d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * * 5524d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard ************************************************************************/ 55253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 5526d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard 5527d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard/** 5528d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * xmlXPathLastFunction: 5529d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * @ctxt: the XPath Parser context 5530d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * @nargs: the number of arguments 5531d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * 5532d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * Implement the last() XPath function 5533d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * number last() 5534d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * The last function returns the number of nodes in the context node list. 5535d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard */ 5536d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillardvoid 5537d8df6c0e8c883e1d618388d266015dda36731440Daniel VeillardxmlXPathLastFunction(xmlXPathParserContextPtr ctxt, int nargs) { 5538d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard CHECK_ARITY(0); 5539d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard if (ctxt->context->contextSize >= 0) { 5540d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard valuePush(ctxt, xmlXPathNewFloat((double) ctxt->context->contextSize)); 5541d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_EXPR 5542d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard xmlGenericError(xmlGenericErrorContext, 5543d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard "last() : %d\n", ctxt->context->contextSize); 55443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 5545d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard } else { 5546d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard XP_ERROR(XPATH_INVALID_CTXT_SIZE); 55473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 5548d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard} 55493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 5550d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard/** 5551d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * xmlXPathPositionFunction: 5552d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * @ctxt: the XPath Parser context 5553d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * @nargs: the number of arguments 5554d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * 5555d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * Implement the position() XPath function 5556d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * number position() 5557d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * The position function returns the position of the context node in the 5558cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * context node list. The first position is 1, and so the last position 5559d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * will be equal to last(). 5560d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard */ 5561d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillardvoid 5562d8df6c0e8c883e1d618388d266015dda36731440Daniel VeillardxmlXPathPositionFunction(xmlXPathParserContextPtr ctxt, int nargs) { 5563d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard CHECK_ARITY(0); 5564d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard if (ctxt->context->proximityPosition >= 0) { 5565d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard valuePush(ctxt, 5566d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard xmlXPathNewFloat((double) ctxt->context->proximityPosition)); 5567d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_EXPR 5568d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard xmlGenericError(xmlGenericErrorContext, "position() : %d\n", 5569d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard ctxt->context->proximityPosition); 55703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 5571d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard } else { 5572d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard XP_ERROR(XPATH_INVALID_CTXT_POSITION); 5573d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard } 5574d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard} 55753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 55763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 55773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathCountFunction: 55783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 55793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs: the number of arguments 55803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 55813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the count() XPath function 55823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * number count(node-set) 55833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 55843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 55853473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathCountFunction(xmlXPathParserContextPtr ctxt, int nargs) { 55863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr cur; 55873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 55883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ARITY(1); 55893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((ctxt->value == NULL) || 55903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ((ctxt->value->type != XPATH_NODESET) && 55913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor (ctxt->value->type != XPATH_XSLT_TREE))) 55923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XP_ERROR(XPATH_INVALID_TYPE); 55933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur = valuePop(ctxt); 55943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 5595911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard if ((cur == NULL) || (cur->nodesetval == NULL)) 5596911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard valuePush(ctxt, xmlXPathNewFloat((double) 0)); 5597fe70332f7f29f146a364c73450729a8b3274daeeDaniel Veillard else if (cur->type == XPATH_NODESET) { 5598911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard valuePush(ctxt, xmlXPathNewFloat((double) cur->nodesetval->nodeNr)); 5599fe70332f7f29f146a364c73450729a8b3274daeeDaniel Veillard } else { 5600fe70332f7f29f146a364c73450729a8b3274daeeDaniel Veillard if ((cur->nodesetval->nodeNr != 1) || 5601fe70332f7f29f146a364c73450729a8b3274daeeDaniel Veillard (cur->nodesetval->nodeTab == NULL)) { 5602fe70332f7f29f146a364c73450729a8b3274daeeDaniel Veillard valuePush(ctxt, xmlXPathNewFloat((double) 0)); 5603fe70332f7f29f146a364c73450729a8b3274daeeDaniel Veillard } else { 5604fe70332f7f29f146a364c73450729a8b3274daeeDaniel Veillard xmlNodePtr tmp; 5605fe70332f7f29f146a364c73450729a8b3274daeeDaniel Veillard int i = 0; 5606fe70332f7f29f146a364c73450729a8b3274daeeDaniel Veillard 5607fe70332f7f29f146a364c73450729a8b3274daeeDaniel Veillard tmp = cur->nodesetval->nodeTab[0]; 5608fe70332f7f29f146a364c73450729a8b3274daeeDaniel Veillard if (tmp != NULL) { 5609fe70332f7f29f146a364c73450729a8b3274daeeDaniel Veillard tmp = tmp->children; 5610fe70332f7f29f146a364c73450729a8b3274daeeDaniel Veillard while (tmp != NULL) { 5611fe70332f7f29f146a364c73450729a8b3274daeeDaniel Veillard tmp = tmp->next; 5612fe70332f7f29f146a364c73450729a8b3274daeeDaniel Veillard i++; 5613fe70332f7f29f146a364c73450729a8b3274daeeDaniel Veillard } 5614fe70332f7f29f146a364c73450729a8b3274daeeDaniel Veillard } 5615fe70332f7f29f146a364c73450729a8b3274daeeDaniel Veillard valuePush(ctxt, xmlXPathNewFloat((double) i)); 5616fe70332f7f29f146a364c73450729a8b3274daeeDaniel Veillard } 5617fe70332f7f29f146a364c73450729a8b3274daeeDaniel Veillard } 56183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(cur); 56193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 56203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 56213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 5622ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathGetElementsByIds: 5623ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @doc: the document 5624ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @ids: a whitespace separated list of IDs 5625ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 5626ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Selects elements by their unique ID. 5627ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 5628ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns a node-set of selected elements. 5629ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */ 5630ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillardstatic xmlNodeSetPtr 5631ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathGetElementsByIds (xmlDocPtr doc, const xmlChar *ids) { 5632ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlNodeSetPtr ret; 5633ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard const xmlChar *cur = ids; 5634ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlChar *ID; 5635ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlAttrPtr attr; 5636ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlNodePtr elem = NULL; 5637ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 5638ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = xmlXPathNodeSetCreate(NULL); 5639ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 5640ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard while (IS_BLANK(*cur)) cur++; 5641ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard while (*cur != 0) { 5642ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard while ((IS_LETTER(*cur)) || (IS_DIGIT(*cur)) || 5643ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard (*cur == '.') || (*cur == '-') || 5644ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard (*cur == '_') || (*cur == ':') || 5645ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard (IS_COMBINING(*cur)) || 5646ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard (IS_EXTENDER(*cur))) 5647ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard cur++; 5648ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 5649ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard if ((!IS_BLANK(*cur)) && (*cur != 0)) break; 5650ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 5651ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ID = xmlStrndup(ids, cur - ids); 5652ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard attr = xmlGetID(doc, ID); 5653ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard if (attr != NULL) { 5654ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard elem = attr->parent; 5655ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlXPathNodeSetAdd(ret, elem); 5656ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard } 5657ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard if (ID != NULL) 5658ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlFree(ID); 5659ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 5660ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard while (IS_BLANK(*cur)) cur++; 5661ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ids = cur; 5662ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard } 5663ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(ret); 5664ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard} 5665ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 5666ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/** 56673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathIdFunction: 56683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 56693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs: the number of arguments 56703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 56713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the id() XPath function 56723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * node-set id(object) 56733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The id function selects elements by their unique ID 56743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * (see [5.2.1 Unique IDs]). When the argument to id is of type node-set, 56753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * then the result is the union of the result of applying id to the 56763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * string value of each of the nodes in the argument node-set. When the 56773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * argument to id is of any other type, the argument is converted to a 56783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * string as if by a call to the string function; the string is split 56793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * into a whitespace-separated list of tokens (whitespace is any sequence 56803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * of characters matching the production S); the result is a node-set 56813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * containing the elements in the same document as the context node that 56823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * have a unique ID equal to any of the tokens in the list. 56833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 56843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 56853473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathIdFunction(xmlXPathParserContextPtr ctxt, int nargs) { 5686ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlChar *tokens; 5687ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlNodeSetPtr ret; 5688ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlXPathObjectPtr obj; 56893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 56903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ARITY(1); 56913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor obj = valuePop(ctxt); 56923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (obj == NULL) XP_ERROR(XPATH_INVALID_OPERAND); 56933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (obj->type == XPATH_NODESET) { 5694ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlNodeSetPtr ns; 56953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int i; 56963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 5697ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = xmlXPathNodeSetCreate(NULL); 56983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 5699911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard if (obj->nodesetval != NULL) { 5700911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard for (i = 0; i < obj->nodesetval->nodeNr; i++) { 5701ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard tokens = 5702ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlXPathCastNodeToString(obj->nodesetval->nodeTab[i]); 5703ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ns = xmlXPathGetElementsByIds(ctxt->context->doc, tokens); 5704ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = xmlXPathNodeSetMerge(ret, ns); 5705ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlXPathFreeNodeSet(ns); 5706ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard if (tokens != NULL) 5707ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlFree(tokens); 5708911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard } 57093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 57103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 57113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(obj); 5712ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard valuePush(ctxt, xmlXPathWrapNodeSet(ret)); 57133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return; 57143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 5715ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard obj = xmlXPathConvertString(obj); 57163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 5717ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = xmlXPathGetElementsByIds(ctxt->context->doc, obj->stringval); 5718ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard valuePush(ctxt, xmlXPathWrapNodeSet(ret)); 57193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 57203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(obj); 57213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return; 57223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 57233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 57243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 57253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathLocalNameFunction: 57263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 57273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs: the number of arguments 57283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 57293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the local-name() XPath function 57303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * string local-name(node-set?) 57313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The local-name function returns a string containing the local part 57323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * of the name of the node in the argument node-set that is first in 57333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * document order. If the node-set is empty or the first node has no 57343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * name, an empty string is returned. If the argument is omitted it 57353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * defaults to the context node. 57363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 57373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 57383473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathLocalNameFunction(xmlXPathParserContextPtr ctxt, int nargs) { 57393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr cur; 57403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 57413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (nargs == 0) { 57423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, xmlXPathNewNodeSet(ctxt->context->node)); 57433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor nargs = 1; 57443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 57453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 57463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ARITY(1); 57473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((ctxt->value == NULL) || 57483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ((ctxt->value->type != XPATH_NODESET) && 57493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor (ctxt->value->type != XPATH_XSLT_TREE))) 57503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XP_ERROR(XPATH_INVALID_TYPE); 57513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur = valuePop(ctxt); 57523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 5753911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard if ((cur->nodesetval == NULL) || (cur->nodesetval->nodeNr == 0)) { 57543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, xmlXPathNewCString("")); 57553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else { 57563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int i = 0; /* Should be first in document order !!!!! */ 57573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor switch (cur->nodesetval->nodeTab[i]->type) { 57583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ELEMENT_NODE: 57593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ATTRIBUTE_NODE: 57603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_PI_NODE: 57613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, 57623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathNewString(cur->nodesetval->nodeTab[i]->name)); 57633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 57643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_NAMESPACE_DECL: 57653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, xmlXPathNewString( 57663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ((xmlNsPtr)cur->nodesetval->nodeTab[i])->prefix)); 57673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 57683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor default: 57693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, xmlXPathNewCString("")); 57703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 57713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 57723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(cur); 57733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 57743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 57753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 57763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNamespaceURIFunction: 57773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 57783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs: the number of arguments 57793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 57803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the namespace-uri() XPath function 57813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * string namespace-uri(node-set?) 57823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The namespace-uri function returns a string containing the 57833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * namespace URI of the expanded name of the node in the argument 57843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * node-set that is first in document order. If the node-set is empty, 57853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the first node has no name, or the expanded name has no namespace 57863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * URI, an empty string is returned. If the argument is omitted it 57873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * defaults to the context node. 57883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 57893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 57903473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNamespaceURIFunction(xmlXPathParserContextPtr ctxt, int nargs) { 57913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr cur; 57923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 57933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (nargs == 0) { 57943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, xmlXPathNewNodeSet(ctxt->context->node)); 57953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor nargs = 1; 57963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 57973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ARITY(1); 57983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((ctxt->value == NULL) || 57993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ((ctxt->value->type != XPATH_NODESET) && 58003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor (ctxt->value->type != XPATH_XSLT_TREE))) 58013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XP_ERROR(XPATH_INVALID_TYPE); 58023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur = valuePop(ctxt); 58033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 5804911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard if ((cur->nodesetval == NULL) || (cur->nodesetval->nodeNr == 0)) { 58053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, xmlXPathNewCString("")); 58063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else { 58073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int i = 0; /* Should be first in document order !!!!! */ 58083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor switch (cur->nodesetval->nodeTab[i]->type) { 58093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ELEMENT_NODE: 58103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ATTRIBUTE_NODE: 58113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur->nodesetval->nodeTab[i]->ns == NULL) 58123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, xmlXPathNewCString("")); 58133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else 58143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, xmlXPathNewString( 58153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur->nodesetval->nodeTab[i]->ns->href)); 58163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 58173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor default: 58183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, xmlXPathNewCString("")); 58193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 58203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 58213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(cur); 58223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 58233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 58243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 58253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNameFunction: 58263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 58273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs: the number of arguments 58283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 58293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the name() XPath function 58303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * string name(node-set?) 58313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The name function returns a string containing a QName representing 5832cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * the name of the node in the argument node-set that is first in document 58333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * order. The QName must represent the name with respect to the namespace 58343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * declarations in effect on the node whose name is being represented. 58353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Typically, this will be the form in which the name occurred in the XML 58363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * source. This need not be the case if there are namespace declarations 58373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * in effect on the node that associate multiple prefixes with the same 58383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * namespace. However, an implementation may include information about 58393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the original prefix in its representation of nodes; in this case, an 58403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * implementation can ensure that the returned string is always the same 58413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * as the QName used in the XML source. If the argument it omitted it 58423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * defaults to the context node. 58433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Libxml keep the original prefix so the "real qualified name" used is 58443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * returned. 58453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 584656a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic void 58470438375d2e6be47d0179826271081ae64df94f8bDaniel VeillardxmlXPathNameFunction(xmlXPathParserContextPtr ctxt, int nargs) 58480438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard{ 58493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr cur; 58503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 58513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (nargs == 0) { 58520438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard valuePush(ctxt, xmlXPathNewNodeSet(ctxt->context->node)); 58530438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard nargs = 1; 58543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 58553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 58563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ARITY(1); 58570438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard if ((ctxt->value == NULL) || 58580438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard ((ctxt->value->type != XPATH_NODESET) && 58590438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard (ctxt->value->type != XPATH_XSLT_TREE))) 58600438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard XP_ERROR(XPATH_INVALID_TYPE); 58613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur = valuePop(ctxt); 58623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 5863911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard if ((cur->nodesetval == NULL) || (cur->nodesetval->nodeNr == 0)) { 58640438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard valuePush(ctxt, xmlXPathNewCString("")); 58653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else { 58660438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard int i = 0; /* Should be first in document order !!!!! */ 58673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 58680438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard switch (cur->nodesetval->nodeTab[i]->type) { 58690438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard case XML_ELEMENT_NODE: 58700438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard case XML_ATTRIBUTE_NODE: 58710438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard if ((cur->nodesetval->nodeTab[i]->ns == NULL) || 58720438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard (cur->nodesetval->nodeTab[i]->ns->prefix == NULL)) 58730438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard valuePush(ctxt, 58740438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard xmlXPathNewString(cur->nodesetval-> 58750438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard nodeTab[i]->name)); 58760438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard 58770438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard else { 58780438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard char name[2000]; 58790438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard 58800438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard snprintf(name, sizeof(name), "%s:%s", 58810438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard (char *) cur->nodesetval->nodeTab[i]->ns-> 58820438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard prefix, 58830438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard (char *) cur->nodesetval->nodeTab[i]->name); 58840438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard name[sizeof(name) - 1] = 0; 58850438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard valuePush(ctxt, xmlXPathNewCString(name)); 58860438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard } 58870438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard break; 58880438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard default: 58890438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard valuePush(ctxt, 58900438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard xmlXPathNewNodeSet(cur->nodesetval->nodeTab[i])); 58910438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard xmlXPathLocalNameFunction(ctxt, 1); 58920438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard } 58933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 58943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(cur); 58953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 58963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 5897fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard 5898fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard/** 58993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathStringFunction: 59003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 59013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs: the number of arguments 59023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 59033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the string() XPath function 59043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * string string(object?) 59053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * he string function converts an object to a string as follows: 59063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * - A node-set is converted to a string by returning the value of 59073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the node in the node-set that is first in document order. 59083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * If the node-set is empty, an empty string is returned. 59093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * - A number is converted to a string as follows 59103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * + NaN is converted to the string NaN 59113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * + positive zero is converted to the string 0 59123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * + negative zero is converted to the string 0 59133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * + positive infinity is converted to the string Infinity 59143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * + negative infinity is converted to the string -Infinity 59153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * + if the number is an integer, the number is represented in 59163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * decimal form as a Number with no decimal point and no leading 59173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * zeros, preceded by a minus sign (-) if the number is negative 59183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * + otherwise, the number is represented in decimal form as a 59193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Number including a decimal point with at least one digit 59203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * before the decimal point and at least one digit after the 59213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * decimal point, preceded by a minus sign (-) if the number 59223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * is negative; there must be no leading zeros before the decimal 5923cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * point apart possibly from the one required digit immediately 59243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * before the decimal point; beyond the one required digit 59253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * after the decimal point there must be as many, but only as 59263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * many, more digits as are needed to uniquely distinguish the 59273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * number from all other IEEE 754 numeric values. 59283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * - The boolean false value is converted to the string false. 59293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The boolean true value is converted to the string true. 59303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 59313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * If the argument is omitted, it defaults to a node-set with the 59323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * context node as its only member. 59333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 59343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 59353473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathStringFunction(xmlXPathParserContextPtr ctxt, int nargs) { 59363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr cur; 59373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 59383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (nargs == 0) { 5939ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard valuePush(ctxt, 5940ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlXPathWrapString( 5941ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlXPathCastNodeToString(ctxt->context->node))); 5942ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return; 59433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 59443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 59453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ARITY(1); 59463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur = valuePop(ctxt); 59473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == NULL) XP_ERROR(XPATH_INVALID_OPERAND); 5948fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard cur = xmlXPathConvertString(cur); 5949fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard valuePush(ctxt, cur); 59503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 59513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 59523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 59533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathStringLengthFunction: 59543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 59553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs: the number of arguments 59563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 59573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the string-length() XPath function 59583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * number string-length(string?) 59593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The string-length returns the number of characters in the string 59603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * (see [3.6 Strings]). If the argument is omitted, it defaults to 59613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the context node converted to a string, in other words the value 59623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * of the context node. 59633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 59643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 59653473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathStringLengthFunction(xmlXPathParserContextPtr ctxt, int nargs) { 59663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr cur; 59673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 59683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (nargs == 0) { 59693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->context->node == NULL) { 59703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, xmlXPathNewFloat(0)); 59713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else { 59723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlChar *content; 59733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 5974ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard content = xmlXPathCastNodeToString(ctxt->context->node); 5975e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard valuePush(ctxt, xmlXPathNewFloat(xmlUTF8Strlen(content))); 59763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(content); 59773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 59783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return; 59793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 59803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ARITY(1); 59813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CAST_TO_STRING; 59823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_TYPE(XPATH_STRING); 59833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur = valuePop(ctxt); 5984e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard valuePush(ctxt, xmlXPathNewFloat(xmlUTF8Strlen(cur->stringval))); 59853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(cur); 59863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 59873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 59883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 59893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathConcatFunction: 59903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 59913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs: the number of arguments 59923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 59933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the concat() XPath function 59943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * string concat(string, string, string*) 59953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The concat function returns the concatenation of its arguments. 59963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 59973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 59983473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathConcatFunction(xmlXPathParserContextPtr ctxt, int nargs) { 59993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr cur, newobj; 60003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlChar *tmp; 60013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 60023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (nargs < 2) { 60033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ARITY(2); 60043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 60053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 60063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CAST_TO_STRING; 60073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur = valuePop(ctxt); 60083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((cur == NULL) || (cur->type != XPATH_STRING)) { 60093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(cur); 60103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return; 60113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 60123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor nargs--; 60133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 60143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while (nargs > 0) { 60153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CAST_TO_STRING; 60163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor newobj = valuePop(ctxt); 60173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((newobj == NULL) || (newobj->type != XPATH_STRING)) { 60183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(newobj); 60193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(cur); 60203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XP_ERROR(XPATH_INVALID_TYPE); 60213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 60223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor tmp = xmlStrcat(newobj->stringval, cur->stringval); 60233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor newobj->stringval = cur->stringval; 60243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur->stringval = tmp; 60253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 60263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(newobj); 60273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor nargs--; 60283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 60293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, cur); 60303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 60313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 60323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 60333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathContainsFunction: 60343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 60353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs: the number of arguments 60363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 60373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the contains() XPath function 60383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * boolean contains(string, string) 60393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The contains function returns true if the first argument string 60403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * contains the second argument string, and otherwise returns false. 60413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 60423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 60433473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathContainsFunction(xmlXPathParserContextPtr ctxt, int nargs) { 60443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr hay, needle; 60453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 60463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ARITY(2); 60473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CAST_TO_STRING; 60483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_TYPE(XPATH_STRING); 60493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor needle = valuePop(ctxt); 60503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CAST_TO_STRING; 60513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor hay = valuePop(ctxt); 60523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((hay == NULL) || (hay->type != XPATH_STRING)) { 60533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(hay); 60543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(needle); 60553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XP_ERROR(XPATH_INVALID_TYPE); 60563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 60573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (xmlStrstr(hay->stringval, needle->stringval)) 60583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, xmlXPathNewBoolean(1)); 60593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else 60603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, xmlXPathNewBoolean(0)); 60613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(hay); 60623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(needle); 60633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 60643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 60653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 60663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathStartsWithFunction: 60673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 60683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs: the number of arguments 60693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 60703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the starts-with() XPath function 60713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * boolean starts-with(string, string) 60723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The starts-with function returns true if the first argument string 60733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * starts with the second argument string, and otherwise returns false. 60743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 60753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 60763473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathStartsWithFunction(xmlXPathParserContextPtr ctxt, int nargs) { 60773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr hay, needle; 60783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int n; 60793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 60803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ARITY(2); 60813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CAST_TO_STRING; 60823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_TYPE(XPATH_STRING); 60833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor needle = valuePop(ctxt); 60843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CAST_TO_STRING; 60853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor hay = valuePop(ctxt); 60863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((hay == NULL) || (hay->type != XPATH_STRING)) { 60873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(hay); 60883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(needle); 60893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XP_ERROR(XPATH_INVALID_TYPE); 60903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 60913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor n = xmlStrlen(needle->stringval); 60923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (xmlStrncmp(hay->stringval, needle->stringval, n)) 60933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, xmlXPathNewBoolean(0)); 60943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else 60953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, xmlXPathNewBoolean(1)); 60963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(hay); 60973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(needle); 60983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 60993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 61003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 61013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathSubstringFunction: 61023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 61033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs: the number of arguments 61043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 61053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the substring() XPath function 61063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * string substring(string, number, number?) 61073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The substring function returns the substring of the first argument 61083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * starting at the position specified in the second argument with 61093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * length specified in the third argument. For example, 61103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * substring("12345",2,3) returns "234". If the third argument is not 61113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * specified, it returns the substring starting at the position specified 61123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * in the second argument and continuing to the end of the string. For 61133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * example, substring("12345",2) returns "2345". More precisely, each 61143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * character in the string (see [3.6 Strings]) is considered to have a 61153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * numeric position: the position of the first character is 1, the position 61163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * of the second character is 2 and so on. The returned substring contains 61173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * those characters for which the position of the character is greater than 61183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * or equal to the second argument and, if the third argument is specified, 61193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * less than the sum of the second and third arguments; the comparisons 61203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * and addition used for the above follow the standard IEEE 754 rules. Thus: 61213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * - substring("12345", 1.5, 2.6) returns "234" 61223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * - substring("12345", 0, 3) returns "12" 61233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * - substring("12345", 0 div 0, 3) returns "" 61243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * - substring("12345", 1, 0 div 0) returns "" 61253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * - substring("12345", -42, 1 div 0) returns "12345" 61263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * - substring("12345", -1 div 0, 1 div 0) returns "" 61273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 61283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 61293473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathSubstringFunction(xmlXPathParserContextPtr ctxt, int nargs) { 61303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr str, start, len; 613197ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard double le=0, in; 613297ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard int i, l, m; 61333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlChar *ret; 61343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 61353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (nargs < 2) { 61363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ARITY(2); 61373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 61383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (nargs > 3) { 61393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ARITY(3); 61403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 614197ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard /* 614297ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard * take care of possible last (position) argument 614397ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard */ 61443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (nargs == 3) { 61453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CAST_TO_NUMBER; 61463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_TYPE(XPATH_NUMBER); 61473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor len = valuePop(ctxt); 61483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor le = len->floatval; 61493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(len); 61503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 615197ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard 61523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CAST_TO_NUMBER; 61533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_TYPE(XPATH_NUMBER); 61543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor start = valuePop(ctxt); 61553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor in = start->floatval; 61563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(start); 61573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CAST_TO_STRING; 61583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_TYPE(XPATH_STRING); 61593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor str = valuePop(ctxt); 616097ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard m = xmlUTF8Strlen((const unsigned char *)str->stringval); 616197ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard 616297ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard /* 616397ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard * If last pos not present, calculate last position 616497ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard */ 61659e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard if (nargs != 3) { 61669e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard le = (double)m; 61679e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard if (in < 1.0) 61689e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard in = 1.0; 61699e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard } 617097ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard 61710eafdef9881c396ce4c014359d8f497cc088cfabDaniel Veillard /* Need to check for the special cases where either 61720eafdef9881c396ce4c014359d8f497cc088cfabDaniel Veillard * the index is NaN, the length is NaN, or both 61730eafdef9881c396ce4c014359d8f497cc088cfabDaniel Veillard * arguments are infinity (relying on Inf + -Inf = NaN) 617497ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard */ 61759e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard if (!xmlXPathIsNaN(in + le) && !xmlXPathIsInf(in)) { 61760eafdef9881c396ce4c014359d8f497cc088cfabDaniel Veillard /* 61779e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard * To meet the requirements of the spec, the arguments 61789e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard * must be converted to integer format before 61799e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard * initial index calculations are done 61800eafdef9881c396ce4c014359d8f497cc088cfabDaniel Veillard * 61819e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard * First we go to integer form, rounding up 61829e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard * and checking for special cases 61830eafdef9881c396ce4c014359d8f497cc088cfabDaniel Veillard */ 61840eafdef9881c396ce4c014359d8f497cc088cfabDaniel Veillard i = (int) in; 61859e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard if (((double)i)+0.5 <= in) i++; 61869e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard 61879e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard if (xmlXPathIsInf(le) == 1) { 61889e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard l = m; 61899e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard if (i < 1) 61909e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard i = 1; 61919e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard } 61929e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard else if (xmlXPathIsInf(le) == -1 || le < 0.0) 61939e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard l = 0; 61949e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard else { 61959e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard l = (int) le; 61969e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard if (((double)l)+0.5 <= le) l++; 61979e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard } 61980eafdef9881c396ce4c014359d8f497cc088cfabDaniel Veillard 61999e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard /* Now we normalize inidices */ 62009e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard i -= 1; 62019e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard l += i; 62029e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard if (i < 0) 62039e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard i = 0; 62049e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard if (l > m) 62059e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard l = m; 62063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 62070eafdef9881c396ce4c014359d8f497cc088cfabDaniel Veillard /* number of chars to copy */ 62080eafdef9881c396ce4c014359d8f497cc088cfabDaniel Veillard l -= i; 62093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 62100eafdef9881c396ce4c014359d8f497cc088cfabDaniel Veillard ret = xmlUTF8Strsub(str->stringval, i, l); 62110eafdef9881c396ce4c014359d8f497cc088cfabDaniel Veillard } 62120eafdef9881c396ce4c014359d8f497cc088cfabDaniel Veillard else { 62130eafdef9881c396ce4c014359d8f497cc088cfabDaniel Veillard ret = NULL; 62140eafdef9881c396ce4c014359d8f497cc088cfabDaniel Veillard } 62153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 62163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ret == NULL) 62173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, xmlXPathNewCString("")); 62183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else { 62193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, xmlXPathNewString(ret)); 62203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(ret); 62213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 622297ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard 62233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(str); 62243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 62253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 62263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 62273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathSubstringBeforeFunction: 62283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 62293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs: the number of arguments 62303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 62313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the substring-before() XPath function 62323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * string substring-before(string, string) 62333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The substring-before function returns the substring of the first 62343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * argument string that precedes the first occurrence of the second 62353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * argument string in the first argument string, or the empty string 62363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * if the first argument string does not contain the second argument 62373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * string. For example, substring-before("1999/04/01","/") returns 1999. 62383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 62393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 62403473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathSubstringBeforeFunction(xmlXPathParserContextPtr ctxt, int nargs) { 62413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr str; 62423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr find; 62433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlBufferPtr target; 62443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor const xmlChar *point; 62453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int offset; 62463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 62473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ARITY(2); 62483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CAST_TO_STRING; 62493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor find = valuePop(ctxt); 62503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CAST_TO_STRING; 62513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor str = valuePop(ctxt); 62523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 62533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor target = xmlBufferCreate(); 62543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (target) { 62553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor point = xmlStrstr(str->stringval, find->stringval); 62563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (point) { 62573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor offset = (int)(point - str->stringval); 62583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlBufferAdd(target, str->stringval, offset); 62593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 62603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, xmlXPathNewString(xmlBufferContent(target))); 62613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlBufferFree(target); 62623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 62633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 62643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(str); 62653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(find); 62663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 62673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 62683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 62693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathSubstringAfterFunction: 62703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 62713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs: the number of arguments 62723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 62733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the substring-after() XPath function 62743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * string substring-after(string, string) 62753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The substring-after function returns the substring of the first 62763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * argument string that follows the first occurrence of the second 62773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * argument string in the first argument string, or the empty stringi 62783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * if the first argument string does not contain the second argument 62793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * string. For example, substring-after("1999/04/01","/") returns 04/01, 62803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * and substring-after("1999/04/01","19") returns 99/04/01. 62813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 62823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 62833473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathSubstringAfterFunction(xmlXPathParserContextPtr ctxt, int nargs) { 62843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr str; 62853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr find; 62863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlBufferPtr target; 62873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor const xmlChar *point; 62883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int offset; 62893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 62903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ARITY(2); 62913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CAST_TO_STRING; 62923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor find = valuePop(ctxt); 62933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CAST_TO_STRING; 62943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor str = valuePop(ctxt); 62953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 62963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor target = xmlBufferCreate(); 62973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (target) { 62983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor point = xmlStrstr(str->stringval, find->stringval); 62993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (point) { 63003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor offset = (int)(point - str->stringval) + xmlStrlen(find->stringval); 63013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlBufferAdd(target, &str->stringval[offset], 63023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlStrlen(str->stringval) - offset); 63033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 63043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, xmlXPathNewString(xmlBufferContent(target))); 63053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlBufferFree(target); 63063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 63073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 63083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(str); 63093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(find); 63103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 63113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 63123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 63133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNormalizeFunction: 63143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 63153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs: the number of arguments 63163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 63173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the normalize-space() XPath function 63183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * string normalize-space(string?) 63193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The normalize-space function returns the argument string with white 63203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * space normalized by stripping leading and trailing whitespace 63213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * and replacing sequences of whitespace characters by a single 63223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * space. Whitespace characters are the same allowed by the S production 63233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * in XML. If the argument is omitted, it defaults to the context 63243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * node converted to a string, in other words the value of the context node. 63253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 63263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 63273473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNormalizeFunction(xmlXPathParserContextPtr ctxt, int nargs) { 63283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr obj = NULL; 63293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlChar *source = NULL; 63303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlBufferPtr target; 63313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlChar blank; 63323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 63333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (nargs == 0) { 63343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* Use current context node */ 6335ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard valuePush(ctxt, 6336ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlXPathWrapString( 6337ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlXPathCastNodeToString(ctxt->context->node))); 63383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor nargs = 1; 63393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 63403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 63413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ARITY(1); 63423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CAST_TO_STRING; 63433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_TYPE(XPATH_STRING); 63443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor obj = valuePop(ctxt); 63453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor source = obj->stringval; 63463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 63473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor target = xmlBufferCreate(); 63483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (target && source) { 63493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 63503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* Skip leading whitespaces */ 63513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while (IS_BLANK(*source)) 63523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor source++; 63533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 63543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* Collapse intermediate whitespaces, and skip trailing whitespaces */ 63553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor blank = 0; 63563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while (*source) { 63573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (IS_BLANK(*source)) { 635897ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard blank = 0x20; 63593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else { 63603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (blank) { 63613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlBufferAdd(target, &blank, 1); 63623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor blank = 0; 63633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 63643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlBufferAdd(target, source, 1); 63653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 63663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor source++; 63673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 63683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 63693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, xmlXPathNewString(xmlBufferContent(target))); 63703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlBufferFree(target); 63713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 63723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(obj); 63733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 63743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 63753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 63763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathTranslateFunction: 63773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 63783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs: the number of arguments 63793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 63803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the translate() XPath function 63813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * string translate(string, string, string) 63823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The translate function returns the first argument string with 63833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * occurrences of characters in the second argument string replaced 63843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * by the character at the corresponding position in the third argument 63853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * string. For example, translate("bar","abc","ABC") returns the string 63863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * BAr. If there is a character in the second argument string with no 63873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * character at a corresponding position in the third argument string 63883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * (because the second argument string is longer than the third argument 63893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * string), then occurrences of that character in the first argument 63903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * string are removed. For example, translate("--aaa--","abc-","ABC") 63913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * returns "AAA". If a character occurs more than once in second 63923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * argument string, then the first occurrence determines the replacement 63933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * character. If the third argument string is longer than the second 63943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * argument string, then excess characters are ignored. 63953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 63963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 63973473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathTranslateFunction(xmlXPathParserContextPtr ctxt, int nargs) { 6398e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard xmlXPathObjectPtr str; 6399e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard xmlXPathObjectPtr from; 6400e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard xmlXPathObjectPtr to; 6401e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard xmlBufferPtr target; 640297ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard int offset, max; 6403e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard xmlChar ch; 640497ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard xmlChar *point; 640597ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard xmlChar *cptr; 64063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 6407e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard CHECK_ARITY(3); 64083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 6409e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard CAST_TO_STRING; 6410e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard to = valuePop(ctxt); 6411e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard CAST_TO_STRING; 6412e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard from = valuePop(ctxt); 6413e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard CAST_TO_STRING; 6414e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard str = valuePop(ctxt); 64153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 6416e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard target = xmlBufferCreate(); 6417e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard if (target) { 641897ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard max = xmlUTF8Strlen(to->stringval); 641997ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard for (cptr = str->stringval; (ch=*cptr); ) { 642097ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard offset = xmlUTF8Strloc(from->stringval, cptr); 642197ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard if (offset >= 0) { 642297ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard if (offset < max) { 642397ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard point = xmlUTF8Strpos(to->stringval, offset); 642497ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard if (point) 642597ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard xmlBufferAdd(target, point, xmlUTF8Strsize(point, 1)); 642697ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard } 642797ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard } else 642897ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard xmlBufferAdd(target, cptr, xmlUTF8Strsize(cptr, 1)); 642997ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard 643097ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard /* Step to next character in input */ 643197ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard cptr++; 643297ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard if ( ch & 0x80 ) { 643397ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard /* if not simple ascii, verify proper format */ 643497ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard if ( (ch & 0xc0) != 0xc0 ) { 643597ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard xmlGenericError(xmlGenericErrorContext, 643697ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard "xmlXPathTranslateFunction: Invalid UTF8 string\n"); 643797ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard break; 643897ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard } 643997ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard /* then skip over remaining bytes for this char */ 644097ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard while ( (ch <<= 1) & 0x80 ) 644197ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard if ( (*cptr++ & 0xc0) != 0x80 ) { 644297ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard xmlGenericError(xmlGenericErrorContext, 644397ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard "xmlXPathTranslateFunction: Invalid UTF8 string\n"); 644497ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard break; 644597ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard } 644697ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard if (ch & 0x80) /* must have had error encountered */ 644797ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard break; 644897ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard } 6449e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard } 64503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 6451e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard valuePush(ctxt, xmlXPathNewString(xmlBufferContent(target))); 6452e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard xmlBufferFree(target); 6453e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard xmlXPathFreeObject(str); 6454e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard xmlXPathFreeObject(from); 6455e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard xmlXPathFreeObject(to); 64563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 64573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 64583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 6459fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * xmlXPathBooleanFunction: 6460fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * @ctxt: the XPath Parser context 6461fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * @nargs: the number of arguments 6462fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * 6463fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * Implement the boolean() XPath function 6464fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * boolean boolean(object) 6465fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * he boolean function converts its argument to a boolean as follows: 6466fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * - a number is true if and only if it is neither positive or 6467fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * negative zero nor NaN 6468fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * - a node-set is true if and only if it is non-empty 6469fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * - a string is true if and only if its length is non-zero 6470fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard */ 6471fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillardvoid 6472fbf8a2d0c8145b713099df63d174154a8442e60dDaniel VeillardxmlXPathBooleanFunction(xmlXPathParserContextPtr ctxt, int nargs) { 6473fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard xmlXPathObjectPtr cur; 6474fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard 6475fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard CHECK_ARITY(1); 6476fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard cur = valuePop(ctxt); 6477fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard if (cur == NULL) XP_ERROR(XPATH_INVALID_OPERAND); 6478fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard cur = xmlXPathConvertBoolean(cur); 6479fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard valuePush(ctxt, cur); 64803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 64813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 64823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 64833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNotFunction: 64843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 64853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs: the number of arguments 64863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 64873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the not() XPath function 64883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * boolean not(boolean) 64893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The not function returns true if its argument is false, 64903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * and false otherwise. 64913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 64923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 64933473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNotFunction(xmlXPathParserContextPtr ctxt, int nargs) { 64943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ARITY(1); 64953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CAST_TO_BOOLEAN; 64963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_TYPE(XPATH_BOOLEAN); 64973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ctxt->value->boolval = ! ctxt->value->boolval; 64983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 64993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 65003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 65013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathTrueFunction: 65023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 65033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs: the number of arguments 65043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 65053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the true() XPath function 65063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * boolean true() 65073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 65083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 65093473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathTrueFunction(xmlXPathParserContextPtr ctxt, int nargs) { 65103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ARITY(0); 65113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, xmlXPathNewBoolean(1)); 65123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 65133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 65143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 65153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathFalseFunction: 65163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 65173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs: the number of arguments 65183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 65193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the false() XPath function 65203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * boolean false() 65213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 65223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 65233473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathFalseFunction(xmlXPathParserContextPtr ctxt, int nargs) { 65243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ARITY(0); 65253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, xmlXPathNewBoolean(0)); 65263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 65273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 65283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 65293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathLangFunction: 65303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 65313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs: the number of arguments 65323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 65333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the lang() XPath function 65343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * boolean lang(string) 65353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The lang function returns true or false depending on whether the 65363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * language of the context node as specified by xml:lang attributes 65373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * is the same as or is a sublanguage of the language specified by 65383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the argument string. The language of the context node is determined 65393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * by the value of the xml:lang attribute on the context node, or, if 65403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the context node has no xml:lang attribute, by the value of the 65413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xml:lang attribute on the nearest ancestor of the context node that 65423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * has an xml:lang attribute. If there is no such attribute, then lang 65433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * returns false. If there is such an attribute, then lang returns 65443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * true if the attribute value is equal to the argument ignoring case, 65453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * or if there is some suffix starting with - such that the attribute 65463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * value is equal to the argument ignoring that suffix of the attribute 65473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * value and ignoring case. 65483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 65493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 65503473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathLangFunction(xmlXPathParserContextPtr ctxt, int nargs) { 65513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr val; 65523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor const xmlChar *theLang; 65533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor const xmlChar *lang; 65543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int ret = 0; 65553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int i; 65563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 65573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ARITY(1); 65583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CAST_TO_STRING; 65593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_TYPE(XPATH_STRING); 65603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor val = valuePop(ctxt); 65613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor lang = val->stringval; 65623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor theLang = xmlNodeGetLang(ctxt->context->node); 65633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((theLang != NULL) && (lang != NULL)) { 65643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor for (i = 0;lang[i] != 0;i++) 65653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (toupper(lang[i]) != toupper(theLang[i])) 65663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor goto not_equal; 65673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = 1; 65683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 65693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylornot_equal: 65703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(val); 65713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, xmlXPathNewBoolean(ret)); 65723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 65733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 65743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 65753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNumberFunction: 65763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 65773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs: the number of arguments 65783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 65793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the number() XPath function 65803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * number number(object?) 65813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 65823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 65833473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNumberFunction(xmlXPathParserContextPtr ctxt, int nargs) { 65843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr cur; 65853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor double res; 65863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 65873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (nargs == 0) { 65883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->context->node == NULL) { 65893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, xmlXPathNewFloat(0.0)); 65903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else { 65913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlChar* content = xmlNodeGetContent(ctxt->context->node); 65923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 65933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor res = xmlXPathStringEvalNumber(content); 65943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, xmlXPathNewFloat(res)); 65953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(content); 65963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 65973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return; 65983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 65993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 66003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ARITY(1); 66013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur = valuePop(ctxt); 6602fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard cur = xmlXPathConvertNumber(cur); 6603fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard valuePush(ctxt, cur); 66043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 66053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 66063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 66073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathSumFunction: 66083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 66093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs: the number of arguments 66103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 66113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the sum() XPath function 66123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * number sum(node-set) 66133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The sum function returns the sum of the values of the nodes in 66143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the argument node-set. 66153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 66163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 66173473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathSumFunction(xmlXPathParserContextPtr ctxt, int nargs) { 66183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr cur; 66193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int i; 6620ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard double res = 0.0; 66213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 66223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ARITY(1); 66233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((ctxt->value == NULL) || 66243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ((ctxt->value->type != XPATH_NODESET) && 66253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor (ctxt->value->type != XPATH_XSLT_TREE))) 66263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XP_ERROR(XPATH_INVALID_TYPE); 66273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur = valuePop(ctxt); 66283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 6629d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard if ((cur->nodesetval == NULL) || (cur->nodesetval->nodeNr == 0)) { 66303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, xmlXPathNewFloat(0.0)); 66313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else { 6632ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard for (i = 0; i < cur->nodesetval->nodeNr; i++) { 6633ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard res += xmlXPathCastNodeToNumber(cur->nodesetval->nodeTab[i]); 66343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 6635ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard valuePush(ctxt, xmlXPathNewFloat(res)); 66363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 66373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(cur); 66383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 66393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 66403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 66413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathFloorFunction: 66423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 66433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs: the number of arguments 66443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 66453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the floor() XPath function 66463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * number floor(number) 66473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The floor function returns the largest (closest to positive infinity) 66483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * number that is not greater than the argument and that is an integer. 66493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 66503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 66513473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathFloorFunction(xmlXPathParserContextPtr ctxt, int nargs) { 665256cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard double f; 665356cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard 66543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ARITY(1); 66553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CAST_TO_NUMBER; 66563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_TYPE(XPATH_NUMBER); 665756cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard 665856cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard f = (double)((int) ctxt->value->floatval); 665956cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard if (f != ctxt->value->floatval) { 666056cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard if (ctxt->value->floatval > 0) 666156cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard ctxt->value->floatval = f; 666256cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard else 666356cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard ctxt->value->floatval = f - 1; 666456cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard } 66653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 66663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 66673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 66683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathCeilingFunction: 66693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 66703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs: the number of arguments 66713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 66723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the ceiling() XPath function 66733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * number ceiling(number) 66743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The ceiling function returns the smallest (closest to negative infinity) 66753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * number that is not less than the argument and that is an integer. 66763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 66773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 66783473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathCeilingFunction(xmlXPathParserContextPtr ctxt, int nargs) { 66793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor double f; 66803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 66813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ARITY(1); 66823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CAST_TO_NUMBER; 66833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_TYPE(XPATH_NUMBER); 66843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 66853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#if 0 66863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ctxt->value->floatval = ceil(ctxt->value->floatval); 66873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#else 66883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor f = (double)((int) ctxt->value->floatval); 668956cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard if (f != ctxt->value->floatval) { 669056cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard if (ctxt->value->floatval > 0) 669156cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard ctxt->value->floatval = f + 1; 66925fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard else { 66935fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard if (ctxt->value->floatval < 0 && f == 0) 66945fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard ctxt->value->floatval = xmlXPathNZERO; 66955fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard else 66965fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard ctxt->value->floatval = f; 66975fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard } 66985fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard 669956cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard } 67003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 67013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 67023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 67033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 67043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathRoundFunction: 67053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 67063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs: the number of arguments 67073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 67083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the round() XPath function 67093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * number round(number) 67103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The round function returns the number that is closest to the 67113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * argument and that is an integer. If there are two such numbers, 67123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * then the one that is even is returned. 67133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 67143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 67153473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathRoundFunction(xmlXPathParserContextPtr ctxt, int nargs) { 67163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor double f; 67173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 67183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ARITY(1); 67193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CAST_TO_NUMBER; 67203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_TYPE(XPATH_NUMBER); 67213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 6722cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard if ((xmlXPathIsNaN(ctxt->value->floatval)) || 6723cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard (xmlXPathIsInf(ctxt->value->floatval) == 1) || 6724cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard (xmlXPathIsInf(ctxt->value->floatval) == -1) || 67253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor (ctxt->value->floatval == 0.0)) 67263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return; 67273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 67283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor f = (double)((int) ctxt->value->floatval); 672956cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard if (ctxt->value->floatval < 0) { 673056cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard if (ctxt->value->floatval < f - 0.5) 673156cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard ctxt->value->floatval = f - 1; 673256cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard else 673356cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard ctxt->value->floatval = f; 67345fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard if (ctxt->value->floatval == 0) 67355fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard ctxt->value->floatval = xmlXPathNZERO; 673656cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard } else { 673756cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard if (ctxt->value->floatval < f + 0.5) 673856cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard ctxt->value->floatval = f; 673956cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard else 674056cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard ctxt->value->floatval = f + 1; 674156cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard } 67423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 67433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 67443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/************************************************************************ 67453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * * 67463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The Parser * 67473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * * 67483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ************************************************************************/ 67493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 67503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/* 67513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * a couple of forward declarations since we use a recursive call based 67523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * implementation. 67533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 6754afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void xmlXPathCompileExpr(xmlXPathParserContextPtr ctxt); 6755d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillardstatic void xmlXPathCompPredicate(xmlXPathParserContextPtr ctxt, int filter); 6756afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void xmlXPathCompLocationPath(xmlXPathParserContextPtr ctxt); 67573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef VMS 6758afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void xmlXPathCompRelLocationPath(xmlXPathParserContextPtr ctxt); 6759afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard#define xmlXPathCompRelativeLocationPath xmlXPathCompRelLocationPath 67603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#else 6761afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void xmlXPathCompRelativeLocationPath(xmlXPathParserContextPtr ctxt); 67623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 67632156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillardstatic xmlChar * xmlXPathParseNameComplex(xmlXPathParserContextPtr ctxt, 67642156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard int qualified); 67653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 67663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 676761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard * xmlXPathCurrentChar: 676861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard * @ctxt: the XPath parser context 676961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard * @cur: pointer to the beginning of the char 677061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard * @len: pointer to the length of the char read 677161d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard * 6772cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * The current char value, if using UTF-8 this may actually span multiple 677361d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard * bytes in the input buffer. 677461d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard * 677560087f30f3b4cf21de48f39181736e7d71e7a661Daniel Veillard * Returns the current char value and its length 677661d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard */ 677761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard 677861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillardstatic int 677961d80a2822b2678dee885ac2850295cc96277c63Daniel VeillardxmlXPathCurrentChar(xmlXPathParserContextPtr ctxt, int *len) { 678061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard unsigned char c; 678161d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard unsigned int val; 678261d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard const xmlChar *cur; 678361d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard 678461d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard if (ctxt == NULL) 678561d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard return(0); 678661d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard cur = ctxt->cur; 678761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard 678861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard /* 678961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard * We are supposed to handle UTF8, check it's valid 679061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard * From rfc2044: encoding of the Unicode values on UTF-8: 679161d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard * 679261d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard * UCS-4 range (hex.) UTF-8 octet sequence (binary) 679361d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard * 0000 0000-0000 007F 0xxxxxxx 679461d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard * 0000 0080-0000 07FF 110xxxxx 10xxxxxx 679561d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard * 0000 0800-0000 FFFF 1110xxxx 10xxxxxx 10xxxxxx 679661d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard * 679761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard * Check for the 0x110000 limit too 679861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard */ 679961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard c = *cur; 680061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard if (c & 0x80) { 680161d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard if ((cur[1] & 0xc0) != 0x80) 680261d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard goto encoding_error; 680361d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard if ((c & 0xe0) == 0xe0) { 680461d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard 680561d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard if ((cur[2] & 0xc0) != 0x80) 680661d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard goto encoding_error; 680761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard if ((c & 0xf0) == 0xf0) { 680861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard if (((c & 0xf8) != 0xf0) || 680961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard ((cur[3] & 0xc0) != 0x80)) 681061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard goto encoding_error; 681161d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard /* 4-byte code */ 681261d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard *len = 4; 681361d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard val = (cur[0] & 0x7) << 18; 681461d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard val |= (cur[1] & 0x3f) << 12; 681561d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard val |= (cur[2] & 0x3f) << 6; 681661d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard val |= cur[3] & 0x3f; 681761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard } else { 681861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard /* 3-byte code */ 681961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard *len = 3; 682061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard val = (cur[0] & 0xf) << 12; 682161d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard val |= (cur[1] & 0x3f) << 6; 682261d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard val |= cur[2] & 0x3f; 682361d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard } 682461d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard } else { 682561d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard /* 2-byte code */ 682661d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard *len = 2; 682761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard val = (cur[0] & 0x1f) << 6; 682861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard val |= cur[1] & 0x3f; 682961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard } 683061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard if (!IS_CHAR(val)) { 683161d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard XP_ERROR0(XPATH_INVALID_CHAR_ERROR); 683261d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard } 683361d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard return(val); 683461d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard } else { 683561d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard /* 1-byte code */ 683661d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard *len = 1; 683761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard return((int) *cur); 683861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard } 683961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillardencoding_error: 684061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard /* 684161d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard * If we detect an UTF8 error that probably mean that the 684261d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard * input encoding didn't get properly advertized in the 684361d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard * declaration header. Report the error and switch the encoding 684461d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard * to ISO-Latin-1 (if you don't like this policy, just declare the 684561d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard * encoding !) 684661d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard */ 684742596ad20cdf1925dd79ea801cbe598b6e7b7aecDaniel Veillard *len = 0; 684861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard XP_ERROR0(XPATH_ENCODING_ERROR); 684961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard} 685061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard 685161d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard/** 68523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathParseNCName: 68533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 68543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 68553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * parse an XML namespace non qualified name. 68563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 68573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [NS 3] NCName ::= (Letter | '_') (NCNameChar)* 68583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 68593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [NS 4] NCNameChar ::= Letter | Digit | '.' | '-' | '_' | 68603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * CombiningChar | Extender 68613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 68623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the namespace name or NULL 68633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 68643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 68653473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlChar * 68663473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathParseNCName(xmlXPathParserContextPtr ctxt) { 68672156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard const xmlChar *in; 68682156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard xmlChar *ret; 68692156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard int count = 0; 68703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 68712156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard /* 68722156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard * Accelerator for simple ASCII names 68732156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard */ 68742156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard in = ctxt->cur; 68752156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard if (((*in >= 0x61) && (*in <= 0x7A)) || 68762156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard ((*in >= 0x41) && (*in <= 0x5A)) || 68772156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard (*in == '_')) { 68782156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard in++; 68792156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard while (((*in >= 0x61) && (*in <= 0x7A)) || 68802156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard ((*in >= 0x41) && (*in <= 0x5A)) || 68812156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard ((*in >= 0x30) && (*in <= 0x39)) || 68829a89a8ab80bc021deec9da7d79bda20995c4e78dDaniel Veillard (*in == '_') || (*in == '.') || 68839a89a8ab80bc021deec9da7d79bda20995c4e78dDaniel Veillard (*in == '-')) 68842156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard in++; 68852156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard if ((*in == ' ') || (*in == '>') || (*in == '/') || 68862156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard (*in == '[') || (*in == ']') || (*in == ':') || 68872156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard (*in == '@') || (*in == '*')) { 68882156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard count = in - ctxt->cur; 68892156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard if (count == 0) 68902156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard return(NULL); 68912156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard ret = xmlStrndup(ctxt->cur, count); 68922156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard ctxt->cur = in; 68932156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard return(ret); 68942156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard } 68952156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard } 68962156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard return(xmlXPathParseNameComplex(ctxt, 0)); 68973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 68983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 68992156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard 69003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 69013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathParseQName: 69023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 69033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @prefix: a xmlChar ** 69043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 69053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * parse an XML qualified name 69063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 69073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [NS 5] QName ::= (Prefix ':')? LocalPart 69083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 69093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [NS 6] Prefix ::= NCName 69103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 69113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [NS 7] LocalPart ::= NCName 69123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 69133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the function returns the local part, and prefix is updated 69143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * to get the Prefix if any. 69153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 69163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 691756a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic xmlChar * 69183473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathParseQName(xmlXPathParserContextPtr ctxt, xmlChar **prefix) { 69193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlChar *ret = NULL; 69203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 69213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *prefix = NULL; 69223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = xmlXPathParseNCName(ctxt); 69233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (CUR == ':') { 69243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *prefix = ret; 69253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 69263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = xmlXPathParseNCName(ctxt); 69273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 69283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ret); 69293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 69303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 69313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 69323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathParseName: 69333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 69343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 69353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * parse an XML name 69363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 69373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [4] NameChar ::= Letter | Digit | '.' | '-' | '_' | ':' | 69383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * CombiningChar | Extender 69393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 69403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [5] Name ::= (Letter | '_' | ':') (NameChar)* 69413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 69423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the namespace name or NULL 69433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 69443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 69453473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlChar * 69463473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathParseName(xmlXPathParserContextPtr ctxt) { 694761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard const xmlChar *in; 694861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard xmlChar *ret; 694961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard int count = 0; 69503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 695161d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard /* 695261d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard * Accelerator for simple ASCII names 695361d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard */ 695461d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard in = ctxt->cur; 695561d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard if (((*in >= 0x61) && (*in <= 0x7A)) || 695661d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard ((*in >= 0x41) && (*in <= 0x5A)) || 695761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard (*in == '_') || (*in == ':')) { 695861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard in++; 695961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard while (((*in >= 0x61) && (*in <= 0x7A)) || 696061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard ((*in >= 0x41) && (*in <= 0x5A)) || 696161d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard ((*in >= 0x30) && (*in <= 0x39)) || 696276d66f416d2d0d5db4a09d212b4e43087e9cdae7Daniel Veillard (*in == '_') || (*in == '-') || 696376d66f416d2d0d5db4a09d212b4e43087e9cdae7Daniel Veillard (*in == ':') || (*in == '.')) 696461d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard in++; 696576d66f416d2d0d5db4a09d212b4e43087e9cdae7Daniel Veillard if ((*in > 0) && (*in < 0x80)) { 696661d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard count = in - ctxt->cur; 696761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard ret = xmlStrndup(ctxt->cur, count); 696861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard ctxt->cur = in; 696961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard return(ret); 697061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard } 697161d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard } 69722156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard return(xmlXPathParseNameComplex(ctxt, 1)); 697361d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard} 69743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 697561d80a2822b2678dee885ac2850295cc96277c63Daniel Veillardstatic xmlChar * 69762156a56bcbf5d83fb3d694123be01beebf84d273Daniel VeillardxmlXPathParseNameComplex(xmlXPathParserContextPtr ctxt, int qualified) { 697761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard xmlChar buf[XML_MAX_NAMELEN + 5]; 697861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard int len = 0, l; 697961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard int c; 69803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 698161d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard /* 698261d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard * Handler for more complex cases 698361d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard */ 698461d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard c = CUR_CHAR(l); 698561d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard if ((c == ' ') || (c == '>') || (c == '/') || /* accelerators */ 69862156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard (c == '[') || (c == ']') || (c == '@') || /* accelerators */ 69872156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard (c == '*') || /* accelerators */ 698861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard (!IS_LETTER(c) && (c != '_') && 69892156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard ((qualified) && (c != ':')))) { 699061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard return(NULL); 699161d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard } 69923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 699361d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard while ((c != ' ') && (c != '>') && (c != '/') && /* test bigname.xml */ 699461d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard ((IS_LETTER(c)) || (IS_DIGIT(c)) || 699561d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard (c == '.') || (c == '-') || 69962156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard (c == '_') || ((qualified) && (c == ':')) || 699761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard (IS_COMBINING(c)) || 699861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard (IS_EXTENDER(c)))) { 699961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard COPY_BUF(l,buf,len,c); 700061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard NEXTL(l); 700161d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard c = CUR_CHAR(l); 700261d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard if (len >= XML_MAX_NAMELEN) { 700361d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard /* 700461d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard * Okay someone managed to make a huge name, so he's ready to pay 700561d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard * for the processing speed. 700661d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard */ 700761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard xmlChar *buffer; 700861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard int max = len * 2; 700961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard 701061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard buffer = (xmlChar *) xmlMalloc(max * sizeof(xmlChar)); 701161d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard if (buffer == NULL) { 701261d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard XP_ERROR0(XPATH_MEMORY_ERROR); 701361d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard } 701461d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard memcpy(buffer, buf, len); 701561d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard while ((IS_LETTER(c)) || (IS_DIGIT(c)) || /* test bigname.xml */ 701661d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard (c == '.') || (c == '-') || 70172156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard (c == '_') || ((qualified) && (c == ':')) || 701861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard (IS_COMBINING(c)) || 701961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard (IS_EXTENDER(c))) { 702061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard if (len + 10 > max) { 702161d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard max *= 2; 702261d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard buffer = (xmlChar *) xmlRealloc(buffer, 702361d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard max * sizeof(xmlChar)); 702461d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard if (buffer == NULL) { 702561d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard XP_ERROR0(XPATH_MEMORY_ERROR); 702661d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard } 702761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard } 702861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard COPY_BUF(l,buffer,len,c); 702961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard NEXTL(l); 703061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard c = CUR_CHAR(l); 703161d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard } 703261d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard buffer[len] = 0; 703361d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard return(buffer); 703461d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard } 703561d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard } 70362156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard if (len == 0) 70372156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard return(NULL); 703861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard return(xmlStrndup(buf, len)); 703961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard} 70403cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard 70413cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard#define MAX_FRAC 20 70423cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard 70433cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillardstatic double my_pow10[MAX_FRAC] = { 70443cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard 1.0, 10.0, 100.0, 1000.0, 10000.0, 70453cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard 100000.0, 1000000.0, 10000000.0, 100000000.0, 1000000000.0, 70463cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard 10000000000.0, 100000000000.0, 1000000000000.0, 10000000000000.0, 70473cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard 100000000000000.0, 70483cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard 1000000000000000.0, 10000000000000000.0, 100000000000000000.0, 70493cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard 1000000000000000000.0, 10000000000000000000.0 70503cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard}; 70513cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard 70523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 70533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathStringEvalNumber: 70543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @str: A string to scan 70553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 705670a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese * [30a] Float ::= Number ('e' Digits?)? 705770a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese * 70583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [30] Number ::= Digits ('.' Digits?)? 70593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | '.' Digits 70603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [31] Digits ::= [0-9]+ 70613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 7062afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile a Number in the string 70633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * In complement of the Number expression, this function also handles 70643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * negative values : '-' Number. 70653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 70663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the double value. 70673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 70683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylordouble 70693473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathStringEvalNumber(const xmlChar *str) { 70703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor const xmlChar *cur = str; 70717b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard double ret; 7072b06c61455f86758511aa050a06ff1bbd33f8c3c3Daniel Veillard int ok = 0; 70733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int isneg = 0; 707470a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese int exponent = 0; 707570a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese int is_exponent_negative = 0; 7076b06c61455f86758511aa050a06ff1bbd33f8c3c3Daniel Veillard#ifdef __GNUC__ 7077b06c61455f86758511aa050a06ff1bbd33f8c3c3Daniel Veillard unsigned long tmp = 0; 70787b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard double temp; 7079b06c61455f86758511aa050a06ff1bbd33f8c3c3Daniel Veillard#endif 7080eca82810f0fb81f3e9936d2018347e1e19de513aDaniel Veillard if (cur == NULL) return(0); 70813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while (IS_BLANK(*cur)) cur++; 70823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((*cur != '.') && ((*cur < '0') || (*cur > '9')) && (*cur != '-')) { 70833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(xmlXPathNAN); 70843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 70853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (*cur == '-') { 70863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor isneg = 1; 70873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur++; 70883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 7089b06c61455f86758511aa050a06ff1bbd33f8c3c3Daniel Veillard 7090b06c61455f86758511aa050a06ff1bbd33f8c3c3Daniel Veillard#ifdef __GNUC__ 7091d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard /* 70927b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard * tmp/temp is a workaround against a gcc compiler bug 70937b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard * http://veillard.com/gcc.bug 7094d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard */ 70957b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard ret = 0; 70963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while ((*cur >= '0') && (*cur <= '9')) { 70977b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard ret = ret * 10; 70987b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard tmp = (*cur - '0'); 70993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ok = 1; 71003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur++; 71017b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard temp = (double) tmp; 71027b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard ret = ret + temp; 71033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 7104b06c61455f86758511aa050a06ff1bbd33f8c3c3Daniel Veillard#else 71057b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard ret = 0; 7106b06c61455f86758511aa050a06ff1bbd33f8c3c3Daniel Veillard while ((*cur >= '0') && (*cur <= '9')) { 7107b06c61455f86758511aa050a06ff1bbd33f8c3c3Daniel Veillard ret = ret * 10 + (*cur - '0'); 7108b06c61455f86758511aa050a06ff1bbd33f8c3c3Daniel Veillard ok = 1; 7109b06c61455f86758511aa050a06ff1bbd33f8c3c3Daniel Veillard cur++; 7110b06c61455f86758511aa050a06ff1bbd33f8c3c3Daniel Veillard } 7111b06c61455f86758511aa050a06ff1bbd33f8c3c3Daniel Veillard#endif 7112d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard 71133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (*cur == '.') { 71143cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard int v, frac = 0; 71153cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard double fraction = 0; 71163cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard 71173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur++; 71183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (((*cur < '0') || (*cur > '9')) && (!ok)) { 71193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(xmlXPathNAN); 71203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 71213cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard while (((*cur >= '0') && (*cur <= '9')) && (frac < MAX_FRAC)) { 71223cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard v = (*cur - '0'); 71233cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard fraction = fraction * 10 + v; 71243cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard frac = frac + 1; 71253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur++; 71263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 71273cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard fraction /= my_pow10[frac]; 71283cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard ret = ret + fraction; 71293cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard while ((*cur >= '0') && (*cur <= '9')) 71303cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard cur++; 71313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 713270a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese if ((*cur == 'e') || (*cur == 'E')) { 713370a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese cur++; 713470a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese if (*cur == '-') { 713570a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese is_exponent_negative = 1; 713670a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese cur++; 713770a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese } 713870a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese while ((*cur >= '0') && (*cur <= '9')) { 713970a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese exponent = exponent * 10 + (*cur - '0'); 714070a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese cur++; 714170a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese } 714270a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese } 71433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while (IS_BLANK(*cur)) cur++; 71443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (*cur != 0) return(xmlXPathNAN); 71453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (isneg) ret = -ret; 714670a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese if (is_exponent_negative) exponent = -exponent; 714770a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese ret *= pow(10.0, (double)exponent); 71483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ret); 71493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 71503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 71513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 7152afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompNumber: 71533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 71543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 71553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [30] Number ::= Digits ('.' Digits?)? 71563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | '.' Digits 71573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [31] Digits ::= [0-9]+ 71583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 7159afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile a Number, then push it on the stack 71603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 71613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 7162afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void 7163d79bcd1b36412a7996ace1900ab613e38a609b60Daniel VeillardxmlXPathCompNumber(xmlXPathParserContextPtr ctxt) 7164d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard{ 71653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor double ret = 0.0; 71663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor double mult = 1; 71677b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard int ok = 0; 716870a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese int exponent = 0; 716970a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese int is_exponent_negative = 0; 71707b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard#ifdef __GNUC__ 71717b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard unsigned long tmp = 0; 71727b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard double temp; 71737b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard#endif 71743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 71753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ERROR; 71763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((CUR != '.') && ((CUR < '0') || (CUR > '9'))) { 71773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XP_ERROR(XPATH_NUMBER_ERROR); 71783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 71797b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard#ifdef __GNUC__ 7180d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard /* 71817b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard * tmp/temp is a workaround against a gcc compiler bug 71827b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard * http://veillard.com/gcc.bug 7183d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard */ 71847b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard ret = 0; 71853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while ((CUR >= '0') && (CUR <= '9')) { 71867b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard ret = ret * 10; 71877b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard tmp = (CUR - '0'); 7188d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard ok = 1; 7189d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard NEXT; 71907b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard temp = (double) tmp; 71917b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard ret = ret + temp; 71923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 71937b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard#else 71947b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard ret = 0; 71957b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard while ((CUR >= '0') && (CUR <= '9')) { 71967b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard ret = ret * 10 + (CUR - '0'); 71977b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard ok = 1; 71987b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard NEXT; 71997b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard } 72007b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard#endif 72013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (CUR == '.') { 72023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 7203d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard if (((CUR < '0') || (CUR > '9')) && (!ok)) { 7204d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard XP_ERROR(XPATH_NUMBER_ERROR); 7205d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard } 7206d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard while ((CUR >= '0') && (CUR <= '9')) { 7207d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard mult /= 10; 7208d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard ret = ret + (CUR - '0') * mult; 7209d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard NEXT; 7210d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard } 72113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 721270a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese if ((CUR == 'e') || (CUR == 'E')) { 7213d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard NEXT; 7214d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard if (CUR == '-') { 7215d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard is_exponent_negative = 1; 7216d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard NEXT; 7217d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard } 7218d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard while ((CUR >= '0') && (CUR <= '9')) { 7219d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard exponent = exponent * 10 + (CUR - '0'); 7220d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard NEXT; 7221d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard } 7222d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard if (is_exponent_negative) 7223d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard exponent = -exponent; 7224d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard ret *= pow(10.0, (double) exponent); 722570a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese } 72269e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard PUSH_LONG_EXPR(XPATH_OP_VALUE, XPATH_NUMBER, 0, 0, 7227d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard xmlXPathNewFloat(ret), NULL); 72283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 72293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 72303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 7231fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * xmlXPathParseLiteral: 7232fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * @ctxt: the XPath Parser context 7233fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * 7234fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * Parse a Literal 7235fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * 7236fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * [29] Literal ::= '"' [^"]* '"' 7237fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * | "'" [^']* "'" 7238fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * 7239fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * Returns the value found or NULL in case of error 7240fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard */ 7241fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillardstatic xmlChar * 7242fbf8a2d0c8145b713099df63d174154a8442e60dDaniel VeillardxmlXPathParseLiteral(xmlXPathParserContextPtr ctxt) { 7243fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard const xmlChar *q; 7244fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard xmlChar *ret = NULL; 7245fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard 7246fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard if (CUR == '"') { 7247fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard NEXT; 7248fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard q = CUR_PTR; 7249fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard while ((IS_CHAR(CUR)) && (CUR != '"')) 7250fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard NEXT; 7251fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard if (!IS_CHAR(CUR)) { 7252fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard XP_ERROR0(XPATH_UNFINISHED_LITERAL_ERROR); 7253fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard } else { 7254fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard ret = xmlStrndup(q, CUR_PTR - q); 7255fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard NEXT; 7256fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard } 7257fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard } else if (CUR == '\'') { 7258fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard NEXT; 7259fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard q = CUR_PTR; 7260fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard while ((IS_CHAR(CUR)) && (CUR != '\'')) 7261fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard NEXT; 7262fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard if (!IS_CHAR(CUR)) { 7263fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard XP_ERROR0(XPATH_UNFINISHED_LITERAL_ERROR); 7264fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard } else { 7265fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard ret = xmlStrndup(q, CUR_PTR - q); 7266fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard NEXT; 7267fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard } 7268fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard } else { 7269fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard XP_ERROR0(XPATH_START_LITERAL_ERROR); 7270fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard } 7271fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard return(ret); 7272fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard} 7273fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard 7274fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard/** 7275afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompLiteral: 72763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 72773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 72783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Parse a Literal and push it on the stack. 72793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 72803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [29] Literal ::= '"' [^"]* '"' 72813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | "'" [^']* "'" 72823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 7283afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * TODO: xmlXPathCompLiteral memory allocation could be improved. 72843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 7285afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void 7286afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompLiteral(xmlXPathParserContextPtr ctxt) { 72873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor const xmlChar *q; 72883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlChar *ret = NULL; 72893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 72903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (CUR == '"') { 72913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 72923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor q = CUR_PTR; 72933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while ((IS_CHAR(CUR)) && (CUR != '"')) 72943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 72953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (!IS_CHAR(CUR)) { 72963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XP_ERROR(XPATH_UNFINISHED_LITERAL_ERROR); 72973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else { 72983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = xmlStrndup(q, CUR_PTR - q); 72993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 73003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 73013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else if (CUR == '\'') { 73023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 73033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor q = CUR_PTR; 73043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while ((IS_CHAR(CUR)) && (CUR != '\'')) 73053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 73063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (!IS_CHAR(CUR)) { 73073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XP_ERROR(XPATH_UNFINISHED_LITERAL_ERROR); 73083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else { 73093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = xmlStrndup(q, CUR_PTR - q); 73103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 73113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 73123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else { 73133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XP_ERROR(XPATH_START_LITERAL_ERROR); 73143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 73153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ret == NULL) return; 73169e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard PUSH_LONG_EXPR(XPATH_OP_VALUE, XPATH_STRING, 0, 0, 73179e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlXPathNewString(ret), NULL); 73183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(ret); 73193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 73203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 73213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 7322afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompVariableReference: 73233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 73243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 73253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Parse a VariableReference, evaluate it and push it on the stack. 73263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 73273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The variable bindings consist of a mapping from variable names 73283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * to variable values. The value of a variable is an object, which 73293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * of any of the types that are possible for the value of an expression, 73303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * and may also be of additional types not specified here. 73313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 73323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Early evaluation is possible since: 73333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The variable bindings [...] used to evaluate a subexpression are 73343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * always the same as those used to evaluate the containing expression. 73353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 73363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [36] VariableReference ::= '$' QName 73373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 7338afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void 7339afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompVariableReference(xmlXPathParserContextPtr ctxt) { 73403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlChar *name; 73413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlChar *prefix; 73423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 73433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 73443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (CUR != '$') { 73453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XP_ERROR(XPATH_VARIABLE_REF_ERROR); 73463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 73473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 73483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor name = xmlXPathParseQName(ctxt, &prefix); 73493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (name == NULL) { 73503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XP_ERROR(XPATH_VARIABLE_REF_ERROR); 73513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 7352fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard ctxt->comp->last = -1; 73539e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard PUSH_LONG_EXPR(XPATH_OP_VARIABLE, 0, 0, 0, 73549e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard name, prefix); 73553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 73563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 73573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 73583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 73593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathIsNodeType: 73603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 73613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @name: a name string 73623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 73633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Is the name given a NodeType one. 73643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 73653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [38] NodeType ::= 'comment' 73663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | 'text' 73673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | 'processing-instruction' 73683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | 'node' 73693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 73703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns 1 if true 0 otherwise 73713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 73723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorint 73733473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathIsNodeType(const xmlChar *name) { 73743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (name == NULL) 73753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(0); 73763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 73771971ee2698cb84c7699c96d3302f00e20d42c0d3Daniel Veillard if (xmlStrEqual(name, BAD_CAST "node")) 73783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(1); 73793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (xmlStrEqual(name, BAD_CAST "text")) 73803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(1); 73811971ee2698cb84c7699c96d3302f00e20d42c0d3Daniel Veillard if (xmlStrEqual(name, BAD_CAST "comment")) 73823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(1); 73831971ee2698cb84c7699c96d3302f00e20d42c0d3Daniel Veillard if (xmlStrEqual(name, BAD_CAST "processing-instruction")) 73843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(1); 73853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(0); 73863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 73873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 73883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 7389afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompFunctionCall: 73903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 73913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 73923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [16] FunctionCall ::= FunctionName '(' ( Argument ( ',' Argument)*)? ')' 73933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [17] Argument ::= Expr 73943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 7395afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile a function call, the evaluation of all arguments are 73963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * pushed on the stack 73973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 7398afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void 7399afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompFunctionCall(xmlXPathParserContextPtr ctxt) { 74003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlChar *name; 74013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlChar *prefix; 74023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int nbargs = 0; 74033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 74043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor name = xmlXPathParseQName(ctxt, &prefix); 74053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (name == NULL) { 74063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XP_ERROR(XPATH_EXPR_ERROR); 74073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 74083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 74093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_EXPR 74103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (prefix == NULL) 74113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, "Calling function %s\n", 74123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor name); 74133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else 74143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, "Calling function %s:%s\n", 74153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor prefix, name); 74163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 74173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 74183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (CUR != '(') { 74193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XP_ERROR(XPATH_EXPR_ERROR); 74203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 74213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 74223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 74233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 74249e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard ctxt->comp->last = -1; 74253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while (CUR != ')') { 74269e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard int op1 = ctxt->comp->last; 74279e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard ctxt->comp->last = -1; 7428afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompileExpr(ctxt); 742950fe8b1732048003f47b32b009507fe6cdecd39fAleksey Sanin CHECK_ERROR; 74309e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard PUSH_BINARY_EXPR(XPATH_OP_ARG, op1, ctxt->comp->last, 0, 0); 74313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor nbargs++; 74323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (CUR == ')') break; 74333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (CUR != ',') { 74343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XP_ERROR(XPATH_EXPR_ERROR); 74353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 74363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 74373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 74383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 74399e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard PUSH_LONG_EXPR(XPATH_OP_FUNCTION, nbargs, 0, 0, 74409e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard name, prefix); 74413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 74423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 74433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 74443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 74453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 7446afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompPrimaryExpr: 74473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 74483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 74493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [15] PrimaryExpr ::= VariableReference 74503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | '(' Expr ')' 74513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | Literal 74523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | Number 74533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | FunctionCall 74543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 7455afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile a primary expression. 74563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 7457afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void 7458afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompPrimaryExpr(xmlXPathParserContextPtr ctxt) { 74593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 7460afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard if (CUR == '$') xmlXPathCompVariableReference(ctxt); 74613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else if (CUR == '(') { 74623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 74633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 7464afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompileExpr(ctxt); 746550fe8b1732048003f47b32b009507fe6cdecd39fAleksey Sanin CHECK_ERROR; 74663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (CUR != ')') { 74673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XP_ERROR(XPATH_EXPR_ERROR); 74683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 74693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 74703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 747101917aa1cb20fb33e6fa2b1e0ca2125051e491e0Daniel Veillard } else if (IS_DIGIT(CUR) || (CUR == '.' && IS_DIGIT(NXT(1)))) { 7472afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompNumber(ctxt); 74733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else if ((CUR == '\'') || (CUR == '"')) { 7474afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompLiteral(ctxt); 74753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else { 7476afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompFunctionCall(ctxt); 74773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 74783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 74793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 74803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 74813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 7482afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompFilterExpr: 74833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 74843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 74853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [20] FilterExpr ::= PrimaryExpr 74863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | FilterExpr Predicate 74873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 7488afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile a filter expression. 74893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Square brackets are used to filter expressions in the same way that 74903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * they are used in location paths. It is an error if the expression to 74913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * be filtered does not evaluate to a node-set. The context node list 74923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * used for evaluating the expression in square brackets is the node-set 74933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * to be filtered listed in document order. 74943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 74953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 7496afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void 7497afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompFilterExpr(xmlXPathParserContextPtr ctxt) { 7498afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompPrimaryExpr(ctxt); 74993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ERROR; 75003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 75013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 75023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while (CUR == '[') { 7503d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard xmlXPathCompPredicate(ctxt, 1); 75043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 75053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 75063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 75073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 75083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 75093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 75103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 75113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathScanName: 75123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 75133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 75143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Trickery: parse an XML name but without consuming the input flow 75153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Needed to avoid insanity in the parser state. 75163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 75173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [4] NameChar ::= Letter | Digit | '.' | '-' | '_' | ':' | 75183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * CombiningChar | Extender 75193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 75203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [5] Name ::= (Letter | '_' | ':') (NameChar)* 75213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 75223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [6] Names ::= Name (S Name)* 75233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 75243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the Name parsed or NULL 75253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 75263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 752756a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic xmlChar * 75283473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathScanName(xmlXPathParserContextPtr ctxt) { 75293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlChar buf[XML_MAX_NAMELEN]; 75303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int len = 0; 75313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 75323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 75333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (!IS_LETTER(CUR) && (CUR != '_') && 75343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor (CUR != ':')) { 75353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 75363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 75373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 75383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while ((IS_LETTER(NXT(len))) || (IS_DIGIT(NXT(len))) || 75393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor (NXT(len) == '.') || (NXT(len) == '-') || 75403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor (NXT(len) == '_') || (NXT(len) == ':') || 75413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor (IS_COMBINING(NXT(len))) || 75423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor (IS_EXTENDER(NXT(len)))) { 75433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor buf[len] = NXT(len); 75443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor len++; 75453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (len >= XML_MAX_NAMELEN) { 75463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 75473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "xmlScanName: reached XML_MAX_NAMELEN limit\n"); 75483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while ((IS_LETTER(NXT(len))) || (IS_DIGIT(NXT(len))) || 75493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor (NXT(len) == '.') || (NXT(len) == '-') || 75503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor (NXT(len) == '_') || (NXT(len) == ':') || 75513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor (IS_COMBINING(NXT(len))) || 75523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor (IS_EXTENDER(NXT(len)))) 75533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor len++; 75543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 75553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 75563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 75573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(xmlStrndup(buf, len)); 75583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 75593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 75603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 7561afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompPathExpr: 75623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 75633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 75643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [19] PathExpr ::= LocationPath 75653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | FilterExpr 75663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | FilterExpr '/' RelativeLocationPath 75673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | FilterExpr '//' RelativeLocationPath 75683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 7569afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile a path expression. 75703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The / operator and // operators combine an arbitrary expression 75713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * and a relative location path. It is an error if the expression 75723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * does not evaluate to a node-set. 75733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The / operator does composition in the same way as when / is 75743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * used in a location path. As in location paths, // is short for 75753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * /descendant-or-self::node()/. 75763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 75773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 7578afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void 7579afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompPathExpr(xmlXPathParserContextPtr ctxt) { 75803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int lc = 1; /* Should we branch to LocationPath ? */ 75813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlChar *name = NULL; /* we may have to preparse a name to find out */ 75823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 75833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 75843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((CUR == '$') || (CUR == '(') || (IS_DIGIT(CUR)) || 758501917aa1cb20fb33e6fa2b1e0ca2125051e491e0Daniel Veillard (CUR == '\'') || (CUR == '"') || (CUR == '.' && IS_DIGIT(NXT(1)))) { 75863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor lc = 0; 75873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else if (CUR == '*') { 75883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* relative or absolute location path */ 75893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor lc = 1; 75903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else if (CUR == '/') { 75913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* relative or absolute location path */ 75923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor lc = 1; 75933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else if (CUR == '@') { 75943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* relative abbreviated attribute location path */ 75953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor lc = 1; 75963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else if (CUR == '.') { 75973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* relative abbreviated attribute location path */ 75983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor lc = 1; 75993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else { 76003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 76013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Problem is finding if we have a name here whether it's: 76023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * - a nodetype 76033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * - a function call in which case it's followed by '(' 76043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * - an axis in which case it's followed by ':' 76053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * - a element name 76063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * We do an a priori analysis here rather than having to 76073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * maintain parsed token content through the recursive function 76083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * calls. This looks uglier but makes the code quite easier to 76093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * read/write/debug. 76103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 76113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 76123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor name = xmlXPathScanName(ctxt); 76133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((name != NULL) && (xmlStrstr(name, (xmlChar *) "::") != NULL)) { 76143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_STEP 76153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 76163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "PathExpr: Axis\n"); 76173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 76183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor lc = 1; 76193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(name); 76203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else if (name != NULL) { 76213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int len =xmlStrlen(name); 76223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int blank = 0; 76233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 76243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 76253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while (NXT(len) != 0) { 76263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (NXT(len) == '/') { 76273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* element name */ 76283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_STEP 76293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 76303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "PathExpr: AbbrRelLocation\n"); 76313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 76323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor lc = 1; 76333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 76343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else if (IS_BLANK(NXT(len))) { 76353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* skip to next */ 76363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor blank = 1; 76373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else if (NXT(len) == ':') { 76383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_STEP 76393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 76403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "PathExpr: AbbrRelLocation\n"); 76413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 76423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor lc = 1; 76433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 76443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else if ((NXT(len) == '(')) { 76453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* Note Type or Function */ 76463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (xmlXPathIsNodeType(name)) { 76473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_STEP 76483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 76493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "PathExpr: Type search\n"); 76503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 76513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor lc = 1; 76523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else { 76533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_STEP 76543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 76553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "PathExpr: function call\n"); 76563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 76573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor lc = 0; 76583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 76593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 76603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else if ((NXT(len) == '[')) { 76613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* element name */ 76623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_STEP 76633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 76643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "PathExpr: AbbrRelLocation\n"); 76653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 76663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor lc = 1; 76673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 76683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else if ((NXT(len) == '<') || (NXT(len) == '>') || 76693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor (NXT(len) == '=')) { 76703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor lc = 1; 76713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 76723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else { 76733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor lc = 1; 76743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 76753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 76763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor len++; 76773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 76783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (NXT(len) == 0) { 76793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_STEP 76803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 76813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "PathExpr: AbbrRelLocation\n"); 76823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 76833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* element name */ 76843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor lc = 1; 76853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 76863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(name); 76873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else { 76883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* make sure all cases are covered explicitely */ 76893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XP_ERROR(XPATH_EXPR_ERROR); 76903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 76913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 76923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 76933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (lc) { 76949e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (CUR == '/') { 76959e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard PUSH_LEAVE_EXPR(XPATH_OP_ROOT, 0, 0); 76969e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } else { 76979e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard PUSH_LEAVE_EXPR(XPATH_OP_NODE, 0, 0); 76983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 7699afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompLocationPath(ctxt); 77003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else { 7701afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompFilterExpr(ctxt); 77023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ERROR; 77033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((CUR == '/') && (NXT(1) == '/')) { 77043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP(2); 77053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 77069e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 77079e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard PUSH_LONG_EXPR(XPATH_OP_COLLECT, AXIS_DESCENDANT_OR_SELF, 77089e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard NODE_TEST_TYPE, NODE_TYPE_NODE, NULL, NULL); 77099e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard PUSH_UNARY_EXPR(XPATH_OP_RESET, ctxt->comp->last, 1, 0); 77109e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 7711afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompRelativeLocationPath(ctxt); 77123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else if (CUR == '/') { 7713afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompRelativeLocationPath(ctxt); 77143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 77153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 77163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 77173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 77183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 77193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 7720afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompUnionExpr: 77213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 77223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 77233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [18] UnionExpr ::= PathExpr 77243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | UnionExpr '|' PathExpr 77253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 7726afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile an union expression. 77273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 77283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 7729afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void 7730afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompUnionExpr(xmlXPathParserContextPtr ctxt) { 7731afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompPathExpr(ctxt); 77323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ERROR; 77333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 77343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while (CUR == '|') { 77359e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard int op1 = ctxt->comp->last; 77369e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard PUSH_LEAVE_EXPR(XPATH_OP_NODE, 0, 0); 77373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 77383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 77393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 7740afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompPathExpr(ctxt); 77413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 77429e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard PUSH_BINARY_EXPR(XPATH_OP_UNION, op1, ctxt->comp->last, 0, 0); 77439e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 77443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 77453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 77463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 77473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 77483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 7749afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompUnaryExpr: 77503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 77513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 77523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [27] UnaryExpr ::= UnionExpr 77533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | '-' UnaryExpr 77543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 7755afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile an unary expression. 77563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 77573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 7758afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void 7759afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompUnaryExpr(xmlXPathParserContextPtr ctxt) { 77603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int minus = 0; 77619e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard int found = 0; 77623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 77633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 776468d7b67ada0941ad7e1d02602f48de4015a67af3Daniel Veillard while (CUR == '-') { 776568d7b67ada0941ad7e1d02602f48de4015a67af3Daniel Veillard minus = 1 - minus; 77669e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard found = 1; 77673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 77683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 77693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 77709e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 7771afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompUnionExpr(ctxt); 77723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ERROR; 77739e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (found) { 77749e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (minus) 77759e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard PUSH_UNARY_EXPR(XPATH_OP_PLUS, ctxt->comp->last, 2, 0); 77769e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard else 77779e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard PUSH_UNARY_EXPR(XPATH_OP_PLUS, ctxt->comp->last, 3, 0); 77783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 77793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 77803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 77813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 7782afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompMultiplicativeExpr: 77833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 77843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 77853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [26] MultiplicativeExpr ::= UnaryExpr 77863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | MultiplicativeExpr MultiplyOperator UnaryExpr 77873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | MultiplicativeExpr 'div' UnaryExpr 77883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | MultiplicativeExpr 'mod' UnaryExpr 77893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [34] MultiplyOperator ::= '*' 77903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 7791afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile an Additive expression. 77923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 77933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 7794afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void 7795afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompMultiplicativeExpr(xmlXPathParserContextPtr ctxt) { 7796afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompUnaryExpr(ctxt); 77973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ERROR; 77983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 77993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while ((CUR == '*') || 78003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ((CUR == 'd') && (NXT(1) == 'i') && (NXT(2) == 'v')) || 78013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ((CUR == 'm') && (NXT(1) == 'o') && (NXT(2) == 'd'))) { 78023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int op = -1; 78039e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard int op1 = ctxt->comp->last; 78043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 78053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (CUR == '*') { 78063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor op = 0; 78073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 78083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else if (CUR == 'd') { 78093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor op = 1; 78103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP(3); 78113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else if (CUR == 'm') { 78123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor op = 2; 78133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP(3); 78143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 78153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 7816afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompUnaryExpr(ctxt); 78173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ERROR; 78189e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard PUSH_BINARY_EXPR(XPATH_OP_MULT, op1, ctxt->comp->last, op, 0); 78193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 78203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 78213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 78223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 78233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 7824afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompAdditiveExpr: 78253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 78263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 78273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [25] AdditiveExpr ::= MultiplicativeExpr 78283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | AdditiveExpr '+' MultiplicativeExpr 78293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | AdditiveExpr '-' MultiplicativeExpr 78303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 7831afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile an Additive expression. 78323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 78333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 7834afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void 7835afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompAdditiveExpr(xmlXPathParserContextPtr ctxt) { 78369e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 7837afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompMultiplicativeExpr(ctxt); 78383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ERROR; 78393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 78403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while ((CUR == '+') || (CUR == '-')) { 78413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int plus; 78429e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard int op1 = ctxt->comp->last; 78433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 78443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (CUR == '+') plus = 1; 78453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else plus = 0; 78463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 78473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 7848afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompMultiplicativeExpr(ctxt); 78493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ERROR; 78509e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard PUSH_BINARY_EXPR(XPATH_OP_PLUS, op1, ctxt->comp->last, plus, 0); 78513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 78523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 78533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 78543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 78553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 7856afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompRelationalExpr: 78573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 78583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 78593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [24] RelationalExpr ::= AdditiveExpr 78603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | RelationalExpr '<' AdditiveExpr 78613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | RelationalExpr '>' AdditiveExpr 78623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | RelationalExpr '<=' AdditiveExpr 78633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | RelationalExpr '>=' AdditiveExpr 78643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 78653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * A <= B > C is allowed ? Answer from James, yes with 78663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * (AdditiveExpr <= AdditiveExpr) > AdditiveExpr 78673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * which is basically what got implemented. 78683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 7869afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile a Relational expression, then push the result 78703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * on the stack 78713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 78723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 7873afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void 7874afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompRelationalExpr(xmlXPathParserContextPtr ctxt) { 7875afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompAdditiveExpr(ctxt); 78763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ERROR; 78773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 78783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while ((CUR == '<') || 78793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor (CUR == '>') || 78803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ((CUR == '<') && (NXT(1) == '=')) || 78813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ((CUR == '>') && (NXT(1) == '='))) { 78829e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard int inf, strict; 78839e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard int op1 = ctxt->comp->last; 78843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 78853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (CUR == '<') inf = 1; 78863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else inf = 0; 78873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (NXT(1) == '=') strict = 0; 78883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else strict = 1; 78893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 78903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (!strict) NEXT; 78913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 7892afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompAdditiveExpr(ctxt); 78933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ERROR; 78949e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard PUSH_BINARY_EXPR(XPATH_OP_CMP, op1, ctxt->comp->last, inf, strict); 78953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 78963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 78973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 78983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 78993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 7900afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompEqualityExpr: 79013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 79023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 79033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [23] EqualityExpr ::= RelationalExpr 79043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | EqualityExpr '=' RelationalExpr 79053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | EqualityExpr '!=' RelationalExpr 79063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 79073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * A != B != C is allowed ? Answer from James, yes with 79083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * (RelationalExpr = RelationalExpr) = RelationalExpr 79093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * (RelationalExpr != RelationalExpr) != RelationalExpr 79103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * which is basically what got implemented. 79113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 7912afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile an Equality expression. 79133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 79143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 7915afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void 7916afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompEqualityExpr(xmlXPathParserContextPtr ctxt) { 7917afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompRelationalExpr(ctxt); 79183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ERROR; 79193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 79203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while ((CUR == '=') || ((CUR == '!') && (NXT(1) == '='))) { 79219e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard int eq; 79229e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard int op1 = ctxt->comp->last; 79233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 79243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (CUR == '=') eq = 1; 79253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else eq = 0; 79263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 79273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (!eq) NEXT; 79283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 7929afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompRelationalExpr(ctxt); 79303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ERROR; 79319e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard PUSH_BINARY_EXPR(XPATH_OP_EQUAL, op1, ctxt->comp->last, eq, 0); 79323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 79333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 79343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 79353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 79363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 7937afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompAndExpr: 79383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 79393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 79403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [22] AndExpr ::= EqualityExpr 79413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | AndExpr 'and' EqualityExpr 79423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 7943afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile an AND expression. 79443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 79453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 7946afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void 7947afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompAndExpr(xmlXPathParserContextPtr ctxt) { 7948afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompEqualityExpr(ctxt); 79493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ERROR; 79503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 79513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while ((CUR == 'a') && (NXT(1) == 'n') && (NXT(2) == 'd')) { 79529e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard int op1 = ctxt->comp->last; 79533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP(3); 79543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 7955afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompEqualityExpr(ctxt); 79563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ERROR; 79579e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard PUSH_BINARY_EXPR(XPATH_OP_AND, op1, ctxt->comp->last, 0, 0); 79583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 79593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 79603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 79613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 79623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 7963afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompExpr: 79643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 79653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 79663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [14] Expr ::= OrExpr 79673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [21] OrExpr ::= AndExpr 79683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | OrExpr 'or' AndExpr 79693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 7970afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Parse and compile an expression 79713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 7972afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void 7973afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompileExpr(xmlXPathParserContextPtr ctxt) { 7974afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompAndExpr(ctxt); 79753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ERROR; 79763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 79773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while ((CUR == 'o') && (NXT(1) == 'r')) { 79789e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard int op1 = ctxt->comp->last; 79793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP(2); 79803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 7981afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompAndExpr(ctxt); 79823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ERROR; 79839e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard PUSH_BINARY_EXPR(XPATH_OP_OR, op1, ctxt->comp->last, 0, 0); 79849e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard op1 = ctxt->comp->nbStep; 79853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 79863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 79879e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (ctxt->comp->steps[ctxt->comp->last].op != XPATH_OP_VALUE) { 79889e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard /* more ops could be optimized too */ 79899e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard PUSH_UNARY_EXPR(XPATH_OP_SORT, ctxt->comp->last , 0, 0); 79909e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } 79913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 79923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 79933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 7994afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompPredicate: 79953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 7996d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * @filter: act as a filter 79973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 79983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [8] Predicate ::= '[' PredicateExpr ']' 79993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [9] PredicateExpr ::= Expr 80003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 8001afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile a predicate expression 80029e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard */ 8003afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void 8004d8df6c0e8c883e1d618388d266015dda36731440Daniel VeillardxmlXPathCompPredicate(xmlXPathParserContextPtr ctxt, int filter) { 80059e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard int op1 = ctxt->comp->last; 80069e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 80079e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard SKIP_BLANKS; 80089e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (CUR != '[') { 80099e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard XP_ERROR(XPATH_INVALID_PREDICATE_ERROR); 80109e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } 80119e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard NEXT; 80129e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard SKIP_BLANKS; 80139e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 80149e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard ctxt->comp->last = -1; 8015afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompileExpr(ctxt); 80169e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard CHECK_ERROR; 80179e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 80189e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (CUR != ']') { 80199e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard XP_ERROR(XPATH_INVALID_PREDICATE_ERROR); 80209e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } 80219e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 8022d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard if (filter) 8023d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard PUSH_BINARY_EXPR(XPATH_OP_FILTER, op1, ctxt->comp->last, 0, 0); 8024d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard else 8025d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard PUSH_BINARY_EXPR(XPATH_OP_PREDICATE, op1, ctxt->comp->last, 0, 0); 80269e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 80279e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard NEXT; 80289e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard SKIP_BLANKS; 80299e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard} 80309e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 80319e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard/** 8032afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompNodeTest: 80333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 80343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @test: pointer to a xmlXPathTestVal 80353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @type: pointer to a xmlXPathTypeVal 80363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @prefix: placeholder for a possible name prefix 80373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 80383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [7] NodeTest ::= NameTest 80393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | NodeType '(' ')' 80403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | 'processing-instruction' '(' Literal ')' 80413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 80423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [37] NameTest ::= '*' 80433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | NCName ':' '*' 80443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | QName 80453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [38] NodeType ::= 'comment' 80463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | 'text' 80473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | 'processing-instruction' 80483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | 'node' 80493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 80503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the name found and update @test, @type and @prefix appropriately 80513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 805256a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic xmlChar * 8053afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompNodeTest(xmlXPathParserContextPtr ctxt, xmlXPathTestVal *test, 8054afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathTypeVal *type, const xmlChar **prefix, 8055afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlChar *name) { 80563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int blanks; 80573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 80583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((test == NULL) || (type == NULL) || (prefix == NULL)) { 80593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor STRANGE; 80603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 80613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 80623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *type = 0; 80633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *test = 0; 80643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *prefix = NULL; 80653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 80663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 80673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((name == NULL) && (CUR == '*')) { 80683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 80693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * All elements 80703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 80713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 80723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *test = NODE_TEST_ALL; 80733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 80743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 80753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 80763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (name == NULL) 80773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor name = xmlXPathParseNCName(ctxt); 80783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (name == NULL) { 80793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XP_ERROR0(XPATH_EXPR_ERROR); 80803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 80813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 80823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor blanks = IS_BLANK(CUR); 80833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 80843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (CUR == '(') { 80853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 80863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 80873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * NodeType or PI search 80883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 80893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (xmlStrEqual(name, BAD_CAST "comment")) 80903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *type = NODE_TYPE_COMMENT; 80913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else if (xmlStrEqual(name, BAD_CAST "node")) 80923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *type = NODE_TYPE_NODE; 80933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else if (xmlStrEqual(name, BAD_CAST "processing-instruction")) 80943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *type = NODE_TYPE_PI; 80953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else if (xmlStrEqual(name, BAD_CAST "text")) 80963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *type = NODE_TYPE_TEXT; 80973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else { 80983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (name != NULL) 80993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(name); 81003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XP_ERROR0(XPATH_EXPR_ERROR); 81013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 81023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 81033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *test = NODE_TEST_TYPE; 81043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 81053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 81063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (*type == NODE_TYPE_PI) { 81073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 81083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Specific case: search a PI by name. 81093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 81103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (name != NULL) 81113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(name); 811282e4971dc2f470c9b6f19cf8b15ff32781067167Daniel Veillard name = NULL; 811382e4971dc2f470c9b6f19cf8b15ff32781067167Daniel Veillard if (CUR != ')') { 811482e4971dc2f470c9b6f19cf8b15ff32781067167Daniel Veillard name = xmlXPathParseLiteral(ctxt); 811582e4971dc2f470c9b6f19cf8b15ff32781067167Daniel Veillard CHECK_ERROR 0; 8116ed23b7dc73f6c1146701ece20ed3f03d68366516Daniel Veillard *test = NODE_TEST_PI; 811782e4971dc2f470c9b6f19cf8b15ff32781067167Daniel Veillard SKIP_BLANKS; 811882e4971dc2f470c9b6f19cf8b15ff32781067167Daniel Veillard } 81193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 81203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (CUR != ')') { 81213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (name != NULL) 81223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(name); 81233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XP_ERROR0(XPATH_UNCLOSED_ERROR); 81243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 81253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 81263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(name); 81273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 81283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *test = NODE_TEST_NAME; 81293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((!blanks) && (CUR == ':')) { 81303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 81313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 81323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 8133fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * Since currently the parser context don't have a 8134fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * namespace list associated: 8135fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * The namespace name for this prefix can be computed 8136fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * only at evaluation time. The compilation is done 8137fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * outside of any context. 81383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 8139fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard#if 0 81403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *prefix = xmlXPathNsLookup(ctxt->context, name); 81413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (name != NULL) 81423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(name); 81433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (*prefix == NULL) { 81443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XP_ERROR0(XPATH_UNDEF_PREFIX_ERROR); 81453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 8146fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard#else 8147fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard *prefix = name; 8148fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard#endif 81493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 81503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (CUR == '*') { 81513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 81523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * All elements 81533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 81543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 81553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *test = NODE_TEST_ALL; 81563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 81573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 81583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 81593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor name = xmlXPathParseNCName(ctxt); 81603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (name == NULL) { 81613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XP_ERROR0(XPATH_EXPR_ERROR); 81623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 81633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 81643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(name); 81653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 81663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 81673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 81683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathIsAxisName: 81693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @name: a preparsed name token 81703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 81713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [6] AxisName ::= 'ancestor' 81723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | 'ancestor-or-self' 81733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | 'attribute' 81743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | 'child' 81753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | 'descendant' 81763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | 'descendant-or-self' 81773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | 'following' 81783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | 'following-sibling' 81793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | 'namespace' 81803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | 'parent' 81813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | 'preceding' 81823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | 'preceding-sibling' 81833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | 'self' 81843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 81853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the axis or 0 81863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 818756a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic xmlXPathAxisVal 81883473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathIsAxisName(const xmlChar *name) { 81893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathAxisVal ret = 0; 81903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor switch (name[0]) { 81913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case 'a': 81923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (xmlStrEqual(name, BAD_CAST "ancestor")) 81933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = AXIS_ANCESTOR; 81943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (xmlStrEqual(name, BAD_CAST "ancestor-or-self")) 81953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = AXIS_ANCESTOR_OR_SELF; 81963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (xmlStrEqual(name, BAD_CAST "attribute")) 81973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = AXIS_ATTRIBUTE; 81983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 81993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case 'c': 82003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (xmlStrEqual(name, BAD_CAST "child")) 82013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = AXIS_CHILD; 82023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 82033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case 'd': 82043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (xmlStrEqual(name, BAD_CAST "descendant")) 82053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = AXIS_DESCENDANT; 82063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (xmlStrEqual(name, BAD_CAST "descendant-or-self")) 82073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = AXIS_DESCENDANT_OR_SELF; 82083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 82093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case 'f': 82103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (xmlStrEqual(name, BAD_CAST "following")) 82113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = AXIS_FOLLOWING; 82123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (xmlStrEqual(name, BAD_CAST "following-sibling")) 82133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = AXIS_FOLLOWING_SIBLING; 82143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 82153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case 'n': 82163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (xmlStrEqual(name, BAD_CAST "namespace")) 82173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = AXIS_NAMESPACE; 82183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 82193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case 'p': 82203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (xmlStrEqual(name, BAD_CAST "parent")) 82213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = AXIS_PARENT; 82223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (xmlStrEqual(name, BAD_CAST "preceding")) 82233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = AXIS_PRECEDING; 82243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (xmlStrEqual(name, BAD_CAST "preceding-sibling")) 82253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = AXIS_PRECEDING_SIBLING; 82263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 82273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case 's': 82283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (xmlStrEqual(name, BAD_CAST "self")) 82293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = AXIS_SELF; 82303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 82313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 82323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ret); 82333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 82343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 82353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 8236afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompStep: 82373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 82383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 82393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [4] Step ::= AxisSpecifier NodeTest Predicate* 82403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | AbbreviatedStep 82413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 82423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [12] AbbreviatedStep ::= '.' | '..' 82433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 82443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [5] AxisSpecifier ::= AxisName '::' 82453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | AbbreviatedAxisSpecifier 82463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 82473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [13] AbbreviatedAxisSpecifier ::= '@'? 82483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 82493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Modified for XPtr range support as: 82503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 82513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [4xptr] Step ::= AxisSpecifier NodeTest Predicate* 82523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | AbbreviatedStep 82533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | 'range-to' '(' Expr ')' Predicate* 82543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 8255afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile one step in a Location Path 82563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * A location step of . is short for self::node(). This is 82573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * particularly useful in conjunction with //. For example, the 82583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * location path .//para is short for 82593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * self::node()/descendant-or-self::node()/child::para 82603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * and so will select all para descendant elements of the context 82613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * node. 82623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Similarly, a location step of .. is short for parent::node(). 82633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * For example, ../title is short for parent::node()/child::title 82643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * and so will select the title children of the parent of the context 82653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * node. 82663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 8267afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void 8268afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompStep(xmlXPathParserContextPtr ctxt) { 8269fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard#ifdef LIBXML_XPTR_ENABLED 8270fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard int rangeto = 0; 8271fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard int op2 = -1; 8272fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard#endif 8273fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard 82743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 82753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((CUR == '.') && (NXT(1) == '.')) { 82763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP(2); 82773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 82789e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard PUSH_LONG_EXPR(XPATH_OP_COLLECT, AXIS_PARENT, 82799e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard NODE_TEST_TYPE, NODE_TYPE_NODE, NULL, NULL); 82803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else if (CUR == '.') { 82813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 82823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 82833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else { 82843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlChar *name = NULL; 82853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor const xmlChar *prefix = NULL; 82863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathTestVal test; 8287d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard xmlXPathAxisVal axis = 0; 82883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathTypeVal type; 8289d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard int op1; 82903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 82913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 82923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The modification needed for XPointer change to the production 82933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 82943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef LIBXML_XPTR_ENABLED 8295fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard if (ctxt->xptr) { 82963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor name = xmlXPathParseNCName(ctxt); 82973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((name != NULL) && (xmlStrEqual(name, BAD_CAST "range-to"))) { 8298fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard op2 = ctxt->comp->last; 82993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(name); 83003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 83013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (CUR != '(') { 83023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XP_ERROR(XPATH_EXPR_ERROR); 83033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 83043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 83053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 83063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 8307afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompileExpr(ctxt); 8308fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard /* PUSH_BINARY_EXPR(XPATH_OP_RANGETO, op2, ctxt->comp->last, 0, 0); */ 83093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ERROR; 83103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 83113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 83123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (CUR != ')') { 83133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XP_ERROR(XPATH_EXPR_ERROR); 83143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 83153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 8316fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard rangeto = 1; 83173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor goto eval_predicates; 83183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 83193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 83203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 83212156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard if (CUR == '*') { 83222156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard axis = AXIS_CHILD; 83232156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard } else { 83242156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard if (name == NULL) 83252156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard name = xmlXPathParseNCName(ctxt); 83262156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard if (name != NULL) { 83272156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard axis = xmlXPathIsAxisName(name); 83282156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard if (axis != 0) { 83292156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard SKIP_BLANKS; 83302156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard if ((CUR == ':') && (NXT(1) == ':')) { 83312156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard SKIP(2); 83322156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard xmlFree(name); 83332156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard name = NULL; 83342156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard } else { 83352156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard /* an element name can conflict with an axis one :-\ */ 83362156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard axis = AXIS_CHILD; 83372156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard } 83383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else { 83393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor axis = AXIS_CHILD; 83403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 83412156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard } else if (CUR == '@') { 83422156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard NEXT; 83432156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard axis = AXIS_ATTRIBUTE; 83443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else { 83452156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard axis = AXIS_CHILD; 83463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 83473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 83483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 83493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ERROR; 83503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 8351afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard name = xmlXPathCompNodeTest(ctxt, &test, &type, &prefix, name); 83523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (test == 0) 83533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return; 83543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 83553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_STEP 83563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 83573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "Basis : computing new set\n"); 83583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 83599e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 83603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_STEP 83613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, "Basis : "); 8362fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard if (ctxt->value == NULL) 8363fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard xmlGenericError(xmlGenericErrorContext, "no value\n"); 8364fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard else if (ctxt->value->nodesetval == NULL) 8365fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard xmlGenericError(xmlGenericErrorContext, "Empty\n"); 8366fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard else 8367fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard xmlGenericErrorContextNodeSet(stdout, ctxt->value->nodesetval); 83683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 83693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 83703473f88a7abdf4e585e267288fb77e898c580d2bOwen Tayloreval_predicates: 8371d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard op1 = ctxt->comp->last; 8372d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard ctxt->comp->last = -1; 8373d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard 83743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 83753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while (CUR == '[') { 8376d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard xmlXPathCompPredicate(ctxt, 0); 83773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 8378d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard 8379fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard#ifdef LIBXML_XPTR_ENABLED 8380fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard if (rangeto) { 8381fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard PUSH_BINARY_EXPR(XPATH_OP_RANGETO, op2, op1, 0, 0); 8382fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard } else 8383fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard#endif 8384fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard PUSH_FULL_EXPR(XPATH_OP_COLLECT, op1, ctxt->comp->last, axis, 8385fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard test, type, (void *)prefix, (void *)name); 8386d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard 83873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 83883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_STEP 83893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, "Step : "); 8390fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard if (ctxt->value == NULL) 8391fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard xmlGenericError(xmlGenericErrorContext, "no value\n"); 8392fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard else if (ctxt->value->nodesetval == NULL) 8393fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard xmlGenericError(xmlGenericErrorContext, "Empty\n"); 8394fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard else 8395fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard xmlGenericErrorContextNodeSet(xmlGenericErrorContext, 8396fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard ctxt->value->nodesetval); 83973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 83983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 83993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 84003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 8401afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompRelativeLocationPath: 84023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 84033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 84043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [3] RelativeLocationPath ::= Step 84053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | RelativeLocationPath '/' Step 84063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | AbbreviatedRelativeLocationPath 84073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [11] AbbreviatedRelativeLocationPath ::= RelativeLocationPath '//' Step 84083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 8409afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile a relative location path. 84103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 8411afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void 84123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef VMS 8413afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompRelLocationPath 84143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#else 8415afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompRelativeLocationPath 84163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 84173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor(xmlXPathParserContextPtr ctxt) { 84183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 84193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((CUR == '/') && (NXT(1) == '/')) { 84203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP(2); 84213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 84229e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard PUSH_LONG_EXPR(XPATH_OP_COLLECT, AXIS_DESCENDANT_OR_SELF, 84239e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard NODE_TEST_TYPE, NODE_TYPE_NODE, NULL, NULL); 84243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else if (CUR == '/') { 84253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 84263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 84273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 8428afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompStep(ctxt); 84293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 84303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while (CUR == '/') { 84313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((CUR == '/') && (NXT(1) == '/')) { 84323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP(2); 84333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 84349e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard PUSH_LONG_EXPR(XPATH_OP_COLLECT, AXIS_DESCENDANT_OR_SELF, 84353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NODE_TEST_TYPE, NODE_TYPE_NODE, NULL, NULL); 8436afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompStep(ctxt); 84373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else if (CUR == '/') { 84383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 84393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 8440afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompStep(ctxt); 84413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 84423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 84433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 84443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 84453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 84463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 8447afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompLocationPath: 84483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 84493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 84503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [1] LocationPath ::= RelativeLocationPath 84513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | AbsoluteLocationPath 84523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [2] AbsoluteLocationPath ::= '/' RelativeLocationPath? 84533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | AbbreviatedAbsoluteLocationPath 84543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [10] AbbreviatedAbsoluteLocationPath ::= 84553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * '//' RelativeLocationPath 84563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 8457afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile a location path 8458afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * 84593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * // is short for /descendant-or-self::node()/. For example, 84603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * //para is short for /descendant-or-self::node()/child::para and 84613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * so will select any para element in the document (even a para element 84623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * that is a document element will be selected by //para since the 84633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * document element node is a child of the root node); div//para is 84643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * short for div/descendant-or-self::node()/child::para and so will 84653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * select all para descendants of div children. 84663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 8467afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void 8468afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompLocationPath(xmlXPathParserContextPtr ctxt) { 84693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 84703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (CUR != '/') { 8471afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompRelativeLocationPath(ctxt); 84723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else { 84733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while (CUR == '/') { 84743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((CUR == '/') && (NXT(1) == '/')) { 84753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP(2); 84763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 84779e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard PUSH_LONG_EXPR(XPATH_OP_COLLECT, AXIS_DESCENDANT_OR_SELF, 84789e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard NODE_TEST_TYPE, NODE_TYPE_NODE, NULL, NULL); 8479afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompRelativeLocationPath(ctxt); 84803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else if (CUR == '/') { 84813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 8482608ad0791b3b35072c8021ea4f66cf9d700394b9Daniel Veillard SKIP_BLANKS; 8483608ad0791b3b35072c8021ea4f66cf9d700394b9Daniel Veillard if ((CUR != 0 ) && 8484608ad0791b3b35072c8021ea4f66cf9d700394b9Daniel Veillard ((IS_LETTER(CUR)) || (CUR == '_') || (CUR == '.') || 8485608ad0791b3b35072c8021ea4f66cf9d700394b9Daniel Veillard (CUR == '@') || (CUR == '*'))) 8486afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompRelativeLocationPath(ctxt); 84873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 84883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 84893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 84903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 84913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 84929e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard/************************************************************************ 84939e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * * 84949e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * XPath precompiled expression evaluation * 84959e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * * 84969e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard ************************************************************************/ 84979e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 8498f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillardstatic int 8499d8df6c0e8c883e1d618388d266015dda36731440Daniel VeillardxmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op); 8500d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard 85019e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard/** 8502d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * xmlXPathNodeCollectAndTest: 8503d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * @ctxt: the XPath Parser context 8504d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * @op: the XPath precompiled step operation 8505f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * @first: pointer to the first element in document order 8506f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * @last: pointer to the last element in document order 85079e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * 8508d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * This is the function implementing a step: based on the current list 8509d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * of nodes, it builds up a new list, looking at all nodes under that 8510d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * axis and selecting them it also do the predicate filtering 8511d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * 8512d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * Pushes the new NodeSet resulting from the search. 8513f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * 8514f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Returns the number of node traversed 85159e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard */ 8516f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillardstatic int 8517d8df6c0e8c883e1d618388d266015dda36731440Daniel VeillardxmlXPathNodeCollectAndTest(xmlXPathParserContextPtr ctxt, 8518f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathStepOpPtr op, 8519f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlNodePtr * first, xmlNodePtr * last) 8520f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard{ 8521d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard xmlXPathAxisVal axis = op->value; 8522d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard xmlXPathTestVal test = op->value2; 8523d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard xmlXPathTypeVal type = op->value3; 8524d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard const xmlChar *prefix = op->value4; 8525d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard const xmlChar *name = op->value5; 8526e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard const xmlChar *URI = NULL; 85279e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 8528d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP 8529f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard int n = 0; 8530d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif 8531f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard int i, t = 0; 8532d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard xmlNodeSetPtr ret, list; 8533d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard xmlXPathTraversalFunction next = NULL; 8534f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard void (*addNode) (xmlNodeSetPtr, xmlNodePtr); 853575be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard xmlNodeSetPtr (*mergeNodeSet) (xmlNodeSetPtr, xmlNodeSetPtr); 8536d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard xmlNodePtr cur = NULL; 8537d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard xmlXPathObjectPtr obj; 8538d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard xmlNodeSetPtr nodelist; 8539d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard xmlNodePtr tmp; 8540d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard 8541f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard CHECK_TYPE0(XPATH_NODESET); 8542d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard obj = valuePop(ctxt); 8543d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard addNode = xmlXPathNodeSetAdd; 854475be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard mergeNodeSet = xmlXPathNodeSetMerge; 8545e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard if (prefix != NULL) { 8546f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard URI = xmlXPathNsLookup(ctxt->context, prefix); 8547f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (URI == NULL) 8548f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard XP_ERROR0(XPATH_UNDEF_PREFIX_ERROR); 8549e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard } 8550d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP 8551f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, "new step : "); 8552d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif 8553d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard switch (axis) { 8554d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard case AXIS_ANCESTOR: 8555d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP 8556f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, "axis 'ancestors' "); 8557d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif 8558f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard first = NULL; 8559f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard next = xmlXPathNextAncestor; 8560f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 8561d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard case AXIS_ANCESTOR_OR_SELF: 8562d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP 8563f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, 8564f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard "axis 'ancestors-or-self' "); 8565d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif 8566f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard first = NULL; 8567f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard next = xmlXPathNextAncestorOrSelf; 8568f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 8569d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard case AXIS_ATTRIBUTE: 8570d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP 8571f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, "axis 'attributes' "); 8572d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif 8573f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard first = NULL; 8574f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard last = NULL; 8575f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard next = xmlXPathNextAttribute; 857675be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard mergeNodeSet = xmlXPathNodeSetMergeUnique; 8577f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 8578d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard case AXIS_CHILD: 8579d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP 8580f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, "axis 'child' "); 8581d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif 8582f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard last = NULL; 8583f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard next = xmlXPathNextChild; 858475be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard mergeNodeSet = xmlXPathNodeSetMergeUnique; 8585f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 8586d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard case AXIS_DESCENDANT: 8587d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP 8588f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, "axis 'descendant' "); 8589d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif 8590f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard last = NULL; 8591f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard next = xmlXPathNextDescendant; 8592f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 8593d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard case AXIS_DESCENDANT_OR_SELF: 8594d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP 8595f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, 8596f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard "axis 'descendant-or-self' "); 8597d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif 8598f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard last = NULL; 8599f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard next = xmlXPathNextDescendantOrSelf; 8600f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 8601d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard case AXIS_FOLLOWING: 8602d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP 8603f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, "axis 'following' "); 8604d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif 8605f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard last = NULL; 8606f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard next = xmlXPathNextFollowing; 8607f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 8608d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard case AXIS_FOLLOWING_SIBLING: 8609d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP 8610f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, 8611f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard "axis 'following-siblings' "); 8612d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif 8613f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard last = NULL; 8614f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard next = xmlXPathNextFollowingSibling; 8615f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 8616d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard case AXIS_NAMESPACE: 8617d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP 8618f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, "axis 'namespace' "); 8619d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif 8620f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard first = NULL; 8621f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard last = NULL; 8622f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard next = (xmlXPathTraversalFunction) xmlXPathNextNamespace; 862375be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard mergeNodeSet = xmlXPathNodeSetMergeUnique; 8624f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 8625d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard case AXIS_PARENT: 8626d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP 8627f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, "axis 'parent' "); 8628d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif 8629f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard first = NULL; 8630f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard next = xmlXPathNextParent; 8631f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 8632d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard case AXIS_PRECEDING: 8633d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP 8634f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, "axis 'preceding' "); 8635d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif 8636f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard first = NULL; 8637f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard next = xmlXPathNextPrecedingInternal; 8638f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 8639d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard case AXIS_PRECEDING_SIBLING: 8640d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP 8641f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, 8642f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard "axis 'preceding-sibling' "); 8643d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif 8644f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard first = NULL; 8645f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard next = xmlXPathNextPrecedingSibling; 8646f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 8647d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard case AXIS_SELF: 8648d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP 8649f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, "axis 'self' "); 8650d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif 8651f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard first = NULL; 8652f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard last = NULL; 8653f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard next = xmlXPathNextSelf; 865475be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard mergeNodeSet = xmlXPathNodeSetMergeUnique; 8655f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 8656d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard } 8657d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard if (next == NULL) 8658f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return(0); 8659d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard 8660d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard nodelist = obj->nodesetval; 8661d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard if (nodelist == NULL) { 8662f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathFreeObject(obj); 8663f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard valuePush(ctxt, xmlXPathWrapNodeSet(NULL)); 8664f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return(0); 8665d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard } 8666d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard addNode = xmlXPathNodeSetAddUnique; 8667d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard ret = NULL; 8668d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP 8669d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard xmlGenericError(xmlGenericErrorContext, 8670f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard " context contains %d nodes\n", nodelist->nodeNr); 8671d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard switch (test) { 8672f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case NODE_TEST_NONE: 8673f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, 8674f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard " searching for none !!!\n"); 8675f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 8676f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case NODE_TEST_TYPE: 8677f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, 8678f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard " searching for type %d\n", type); 8679f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 8680f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case NODE_TEST_PI: 8681f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, 8682f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard " searching for PI !!!\n"); 8683f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 8684f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case NODE_TEST_ALL: 8685f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, 8686f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard " searching for *\n"); 8687f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 8688f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case NODE_TEST_NS: 8689f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, 8690f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard " searching for namespace %s\n", 8691f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard prefix); 8692f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 8693f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case NODE_TEST_NAME: 8694f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, 8695f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard " searching for name %s\n", name); 8696f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (prefix != NULL) 8697f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, 8698f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard " with namespace %s\n", prefix); 8699f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 8700d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard } 8701d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard xmlGenericError(xmlGenericErrorContext, "Testing : "); 8702d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif 8703d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard /* 8704d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * 2.3 Node Tests 8705d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * - For the attribute axis, the principal node type is attribute. 8706d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * - For the namespace axis, the principal node type is namespace. 8707d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * - For other axes, the principal node type is element. 8708d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * 8709d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * A node test * is true for any node of the 8710cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * principal node type. For example, child::* will 8711d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * select all element children of the context node 8712d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard */ 8713d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard tmp = ctxt->context->node; 8714f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard for (i = 0; i < nodelist->nodeNr; i++) { 8715d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard ctxt->context->node = nodelist->nodeTab[i]; 8716d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard 8717f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard cur = NULL; 8718f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard list = xmlXPathNodeSetCreate(NULL); 8719f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard do { 8720f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard cur = next(ctxt, cur); 8721f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (cur == NULL) 8722f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 8723f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((first != NULL) && (*first == cur)) 8724f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 8725f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (((t % 256) == 0) && 8726f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (first != NULL) && (*first != NULL) && 8727f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (xmlXPathCmpNodes(*first, cur) >= 0)) 8728f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 8729f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((last != NULL) && (*last == cur)) 8730f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 8731f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (((t % 256) == 0) && 8732f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (last != NULL) && (*last != NULL) && 8733f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (xmlXPathCmpNodes(cur, *last) >= 0)) 8734f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 8735d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard t++; 8736f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#ifdef DEBUG_STEP 8737d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard xmlGenericError(xmlGenericErrorContext, " %s", cur->name); 8738d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif 8739f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard switch (test) { 8740d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard case NODE_TEST_NONE: 8741f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->node = tmp; 8742f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard STRANGE return(t); 8743d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard case NODE_TEST_TYPE: 8744f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((cur->type == type) || 8745f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ((type == NODE_TYPE_NODE) && 8746f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ((cur->type == XML_DOCUMENT_NODE) || 8747f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (cur->type == XML_HTML_DOCUMENT_NODE) || 8748f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (cur->type == XML_ELEMENT_NODE) || 8749f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin (cur->type == XML_NAMESPACE_DECL) || 8750f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin (cur->type == XML_ATTRIBUTE_NODE) || 8751f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (cur->type == XML_PI_NODE) || 8752f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (cur->type == XML_COMMENT_NODE) || 8753f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (cur->type == XML_CDATA_SECTION_NODE) || 87547583a59b5a0792599a181f77aaf0a39749fada27Daniel Veillard (cur->type == XML_TEXT_NODE))) || 87557583a59b5a0792599a181f77aaf0a39749fada27Daniel Veillard ((type == NODE_TYPE_TEXT) && 87567583a59b5a0792599a181f77aaf0a39749fada27Daniel Veillard (cur->type == XML_CDATA_SECTION_NODE))) { 8757d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP 8758d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard n++; 8759d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif 8760f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard addNode(list, cur); 8761f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 8762f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 8763d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard case NODE_TEST_PI: 8764f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (cur->type == XML_PI_NODE) { 8765f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((name != NULL) && 8766f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (!xmlStrEqual(name, cur->name))) 8767f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 8768d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP 8769f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard n++; 8770d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif 8771f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard addNode(list, cur); 8772f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 8773f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 8774d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard case NODE_TEST_ALL: 8775f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (axis == AXIS_ATTRIBUTE) { 8776f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (cur->type == XML_ATTRIBUTE_NODE) { 8777d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP 8778f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard n++; 8779d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif 8780f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard addNode(list, cur); 8781f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 8782f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } else if (axis == AXIS_NAMESPACE) { 8783f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (cur->type == XML_NAMESPACE_DECL) { 8784d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP 8785f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard n++; 8786d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif 8787044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlXPathNodeSetAddNs(list, ctxt->context->node, 8788044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard (xmlNsPtr) cur); 8789f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 8790f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } else { 8791f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (cur->type == XML_ELEMENT_NODE) { 8792f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (prefix == NULL) { 8793d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP 8794f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard n++; 8795d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif 8796f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard addNode(list, cur); 8797f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } else if ((cur->ns != NULL) && 8798f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (xmlStrEqual(URI, cur->ns->href))) { 8799d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP 8800f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard n++; 8801d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif 8802f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard addNode(list, cur); 8803f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 8804f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 8805f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 8806f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 8807f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case NODE_TEST_NS:{ 8808f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard TODO; 8809f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 8810f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 8811d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard case NODE_TEST_NAME: 8812f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard switch (cur->type) { 8813f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XML_ELEMENT_NODE: 8814f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (xmlStrEqual(name, cur->name)) { 8815f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (prefix == NULL) { 8816f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (cur->ns == NULL) { 8817d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP 8818f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard n++; 8819d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif 8820f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard addNode(list, cur); 8821f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 8822f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } else { 8823f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((cur->ns != NULL) && 8824f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (xmlStrEqual(URI, 8825f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard cur->ns->href))) { 8826d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP 8827f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard n++; 8828d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif 8829f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard addNode(list, cur); 8830f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 8831f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 8832f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 8833f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 8834f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XML_ATTRIBUTE_NODE:{ 8835f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlAttrPtr attr = (xmlAttrPtr) cur; 8836f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 8837f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (xmlStrEqual(name, attr->name)) { 8838f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (prefix == NULL) { 8839f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((attr->ns == NULL) || 8840f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (attr->ns->prefix == NULL)) { 8841d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP 8842f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard n++; 8843d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif 8844f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard addNode(list, 8845f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (xmlNodePtr) attr); 8846f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 8847f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } else { 8848f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((attr->ns != NULL) && 8849f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (xmlStrEqual(URI, 8850f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard attr->ns-> 8851f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard href))) { 8852d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP 8853f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard n++; 8854d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif 8855f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard addNode(list, 8856f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (xmlNodePtr) attr); 8857f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 8858f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 8859f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 8860f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 8861f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 8862f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XML_NAMESPACE_DECL: 8863f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (cur->type == XML_NAMESPACE_DECL) { 8864f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlNsPtr ns = (xmlNsPtr) cur; 8865f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 8866f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((ns->prefix != NULL) && (name != NULL) 8867f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard && (xmlStrEqual(ns->prefix, name))) { 88688b8d2254fa1604efd37b3ba92eaeb2e40b2909a8Daniel Veillard#ifdef DEBUG_STEP 8869f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard n++; 88708b8d2254fa1604efd37b3ba92eaeb2e40b2909a8Daniel Veillard#endif 8871044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlXPathNodeSetAddNs(list, 8872044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard ctxt->context->node, (xmlNsPtr) cur); 8873f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 8874f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 8875f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 8876f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard default: 8877f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 8878f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 8879f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 8880f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 8881f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 8882f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } while (cur != NULL); 8883f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 8884f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* 8885f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * If there is some predicate filtering do it now 8886f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 88876fbcf42aa301dca50737c65fb738752328ca3a4cDaniel Veillard if ((op->ch2 != -1) && (list != NULL) && (list->nodeNr > 0)) { 8888f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathObjectPtr obj2; 8889f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 8890f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard valuePush(ctxt, xmlXPathWrapNodeSet(list)); 8891f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathCompOpEval(ctxt, &ctxt->comp->steps[op->ch2]); 8892f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard CHECK_TYPE0(XPATH_NODESET); 8893f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard obj2 = valuePop(ctxt); 8894f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard list = obj2->nodesetval; 8895f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard obj2->nodesetval = NULL; 8896f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathFreeObject(obj2); 8897f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 8898f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (ret == NULL) { 8899f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ret = list; 8900f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } else { 890175be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard ret = mergeNodeSet(ret, list); 8902f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathFreeNodeSet(list); 8903f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 8904d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard } 8905d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard ctxt->context->node = tmp; 8906d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP 8907d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard xmlGenericError(xmlGenericErrorContext, 8908f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard "\nExamined %d nodes, found %d nodes at that step\n", 8909f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard t, n); 8910d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif 8911d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard valuePush(ctxt, xmlXPathWrapNodeSet(ret)); 89120ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard if ((obj->boolval) && (obj->user != NULL)) { 89130ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard ctxt->value->boolval = 1; 89140ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard ctxt->value->user = obj->user; 89150ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard obj->user = NULL; 89160ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard obj->boolval = 0; 89170ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard } 89180ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard xmlXPathFreeObject(obj); 8919f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return(t); 8920d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard} 8921d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard 8922d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard/** 8923f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * xmlXPathNodeCollectAndTestNth: 8924f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * @ctxt: the XPath Parser context 8925f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * @op: the XPath precompiled step operation 8926f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * @indx: the index to collect 8927f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * @first: pointer to the first element in document order 8928f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * @last: pointer to the last element in document order 8929f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * 8930f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * This is the function implementing a step: based on the current list 8931f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * of nodes, it builds up a new list, looking at all nodes under that 8932f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * axis and selecting them it also do the predicate filtering 8933f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * 8934f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Pushes the new NodeSet resulting from the search. 8935f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Returns the number of node traversed 8936f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 8937f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillardstatic int 8938f06307e2c172284bb41376c396f757bdac9bdd19Daniel VeillardxmlXPathNodeCollectAndTestNth(xmlXPathParserContextPtr ctxt, 8939f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathStepOpPtr op, int indx, 8940f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlNodePtr * first, xmlNodePtr * last) 8941f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard{ 8942f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathAxisVal axis = op->value; 8943f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathTestVal test = op->value2; 8944f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathTypeVal type = op->value3; 8945f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard const xmlChar *prefix = op->value4; 8946f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard const xmlChar *name = op->value5; 8947f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard const xmlChar *URI = NULL; 8948f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard int n = 0, t = 0; 8949f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 8950f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard int i; 8951f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlNodeSetPtr list; 8952f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathTraversalFunction next = NULL; 8953f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard void (*addNode) (xmlNodeSetPtr, xmlNodePtr); 8954f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlNodePtr cur = NULL; 8955f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathObjectPtr obj; 8956f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlNodeSetPtr nodelist; 8957f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlNodePtr tmp; 8958f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 8959f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard CHECK_TYPE0(XPATH_NODESET); 8960f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard obj = valuePop(ctxt); 8961f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard addNode = xmlXPathNodeSetAdd; 8962f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (prefix != NULL) { 8963f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard URI = xmlXPathNsLookup(ctxt->context, prefix); 8964f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (URI == NULL) 8965f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard XP_ERROR0(XPATH_UNDEF_PREFIX_ERROR); 8966f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 8967f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#ifdef DEBUG_STEP_NTH 8968f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, "new step : "); 8969f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (first != NULL) { 8970f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (*first != NULL) 8971f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, "first = %s ", 8972f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (*first)->name); 8973f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard else 8974f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, "first = NULL "); 8975f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 8976f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (last != NULL) { 8977f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (*last != NULL) 8978f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, "last = %s ", 8979f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (*last)->name); 8980f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard else 8981f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, "last = NULL "); 8982f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 8983f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#endif 8984f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard switch (axis) { 8985f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case AXIS_ANCESTOR: 8986f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#ifdef DEBUG_STEP_NTH 8987f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, "axis 'ancestors' "); 8988f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#endif 8989f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard first = NULL; 8990f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard next = xmlXPathNextAncestor; 8991f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 8992f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case AXIS_ANCESTOR_OR_SELF: 8993f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#ifdef DEBUG_STEP_NTH 8994f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, 8995f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard "axis 'ancestors-or-self' "); 8996f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#endif 8997f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard first = NULL; 8998f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard next = xmlXPathNextAncestorOrSelf; 8999f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9000f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case AXIS_ATTRIBUTE: 9001f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#ifdef DEBUG_STEP_NTH 9002f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, "axis 'attributes' "); 9003f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#endif 9004f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard first = NULL; 9005f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard last = NULL; 9006f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard next = xmlXPathNextAttribute; 9007f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9008f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case AXIS_CHILD: 9009f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#ifdef DEBUG_STEP_NTH 9010f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, "axis 'child' "); 9011f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#endif 9012f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard last = NULL; 9013f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard next = xmlXPathNextChild; 9014f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9015f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case AXIS_DESCENDANT: 9016f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#ifdef DEBUG_STEP_NTH 9017f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, "axis 'descendant' "); 9018f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#endif 9019f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard last = NULL; 9020f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard next = xmlXPathNextDescendant; 9021f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9022f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case AXIS_DESCENDANT_OR_SELF: 9023f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#ifdef DEBUG_STEP_NTH 9024f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, 9025f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard "axis 'descendant-or-self' "); 9026f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#endif 9027f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard last = NULL; 9028f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard next = xmlXPathNextDescendantOrSelf; 9029f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9030f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case AXIS_FOLLOWING: 9031f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#ifdef DEBUG_STEP_NTH 9032f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, "axis 'following' "); 9033f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#endif 9034f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard last = NULL; 9035f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard next = xmlXPathNextFollowing; 9036f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9037f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case AXIS_FOLLOWING_SIBLING: 9038f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#ifdef DEBUG_STEP_NTH 9039f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, 9040f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard "axis 'following-siblings' "); 9041f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#endif 9042f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard last = NULL; 9043f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard next = xmlXPathNextFollowingSibling; 9044f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9045f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case AXIS_NAMESPACE: 9046f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#ifdef DEBUG_STEP_NTH 9047f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, "axis 'namespace' "); 9048f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#endif 9049f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard last = NULL; 9050f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard first = NULL; 9051f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard next = (xmlXPathTraversalFunction) xmlXPathNextNamespace; 9052f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9053f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case AXIS_PARENT: 9054f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#ifdef DEBUG_STEP_NTH 9055f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, "axis 'parent' "); 9056f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#endif 9057f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard first = NULL; 9058f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard next = xmlXPathNextParent; 9059f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9060f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case AXIS_PRECEDING: 9061f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#ifdef DEBUG_STEP_NTH 9062f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, "axis 'preceding' "); 9063f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#endif 9064f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard first = NULL; 9065f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard next = xmlXPathNextPrecedingInternal; 9066f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9067f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case AXIS_PRECEDING_SIBLING: 9068f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#ifdef DEBUG_STEP_NTH 9069f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, 9070f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard "axis 'preceding-sibling' "); 9071f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#endif 9072f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard first = NULL; 9073f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard next = xmlXPathNextPrecedingSibling; 9074f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9075f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case AXIS_SELF: 9076f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#ifdef DEBUG_STEP_NTH 9077f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, "axis 'self' "); 9078f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#endif 9079f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard first = NULL; 9080f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard last = NULL; 9081f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard next = xmlXPathNextSelf; 9082f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9083f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9084f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (next == NULL) 9085f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return(0); 9086f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 9087f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard nodelist = obj->nodesetval; 9088f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (nodelist == NULL) { 9089f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathFreeObject(obj); 9090f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard valuePush(ctxt, xmlXPathWrapNodeSet(NULL)); 9091f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return(0); 9092f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9093f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard addNode = xmlXPathNodeSetAddUnique; 9094f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#ifdef DEBUG_STEP_NTH 9095f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, 9096f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard " context contains %d nodes\n", nodelist->nodeNr); 9097f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard switch (test) { 9098f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case NODE_TEST_NONE: 9099f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, 9100f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard " searching for none !!!\n"); 9101f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9102f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case NODE_TEST_TYPE: 9103f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, 9104f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard " searching for type %d\n", type); 9105f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9106f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case NODE_TEST_PI: 9107f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, 9108f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard " searching for PI !!!\n"); 9109f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9110f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case NODE_TEST_ALL: 9111f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, 9112f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard " searching for *\n"); 9113f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9114f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case NODE_TEST_NS: 9115f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, 9116f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard " searching for namespace %s\n", 9117f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard prefix); 9118f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9119f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case NODE_TEST_NAME: 9120f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, 9121f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard " searching for name %s\n", name); 9122f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (prefix != NULL) 9123f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, 9124f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard " with namespace %s\n", prefix); 9125f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9126f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9127f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, "Testing : "); 9128f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#endif 9129f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* 9130f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * 2.3 Node Tests 9131f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * - For the attribute axis, the principal node type is attribute. 9132f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * - For the namespace axis, the principal node type is namespace. 9133f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * - For other axes, the principal node type is element. 9134f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * 9135f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * A node test * is true for any node of the 9136cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * principal node type. For example, child::* will 9137f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * select all element children of the context node 9138f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 9139f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard tmp = ctxt->context->node; 9140f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard list = xmlXPathNodeSetCreate(NULL); 9141f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard for (i = 0; i < nodelist->nodeNr; i++) { 9142f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->node = nodelist->nodeTab[i]; 9143f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 9144f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard cur = NULL; 9145f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard n = 0; 9146f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard do { 9147f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard cur = next(ctxt, cur); 9148f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (cur == NULL) 9149f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9150f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((first != NULL) && (*first == cur)) 9151f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9152f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (((t % 256) == 0) && 9153f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (first != NULL) && (*first != NULL) && 9154f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (xmlXPathCmpNodes(*first, cur) >= 0)) 9155f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9156f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((last != NULL) && (*last == cur)) 9157f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9158f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (((t % 256) == 0) && 9159f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (last != NULL) && (*last != NULL) && 9160f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (xmlXPathCmpNodes(cur, *last) >= 0)) 9161f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9162f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard t++; 9163f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard switch (test) { 9164f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case NODE_TEST_NONE: 9165f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->node = tmp; 9166f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard STRANGE return(0); 9167f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case NODE_TEST_TYPE: 9168f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((cur->type == type) || 9169f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ((type == NODE_TYPE_NODE) && 9170f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ((cur->type == XML_DOCUMENT_NODE) || 9171f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (cur->type == XML_HTML_DOCUMENT_NODE) || 9172f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (cur->type == XML_ELEMENT_NODE) || 9173f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (cur->type == XML_PI_NODE) || 9174f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (cur->type == XML_COMMENT_NODE) || 9175f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (cur->type == XML_CDATA_SECTION_NODE) || 9176f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (cur->type == XML_TEXT_NODE)))) { 9177f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard n++; 9178f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (n == indx) 9179f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard addNode(list, cur); 9180f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9181f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9182f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case NODE_TEST_PI: 9183f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (cur->type == XML_PI_NODE) { 9184f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((name != NULL) && 9185f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (!xmlStrEqual(name, cur->name))) 9186f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9187f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard n++; 9188f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (n == indx) 9189f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard addNode(list, cur); 9190f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9191f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9192f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case NODE_TEST_ALL: 9193f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (axis == AXIS_ATTRIBUTE) { 9194f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (cur->type == XML_ATTRIBUTE_NODE) { 9195f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard n++; 9196f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (n == indx) 9197f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard addNode(list, cur); 9198f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9199f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } else if (axis == AXIS_NAMESPACE) { 9200f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (cur->type == XML_NAMESPACE_DECL) { 9201f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard n++; 9202f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (n == indx) 9203044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlXPathNodeSetAddNs(list, ctxt->context->node, 9204044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard (xmlNsPtr) cur); 9205f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9206f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } else { 9207f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (cur->type == XML_ELEMENT_NODE) { 9208f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (prefix == NULL) { 9209f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard n++; 9210f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (n == indx) 9211f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard addNode(list, cur); 9212f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } else if ((cur->ns != NULL) && 9213f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (xmlStrEqual(URI, cur->ns->href))) { 9214f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard n++; 9215f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (n == indx) 9216f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard addNode(list, cur); 9217f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9218f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9219f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9220f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9221f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case NODE_TEST_NS:{ 9222f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard TODO; 9223f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9224f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9225f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case NODE_TEST_NAME: 9226f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard switch (cur->type) { 9227f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XML_ELEMENT_NODE: 9228f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (xmlStrEqual(name, cur->name)) { 9229f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (prefix == NULL) { 9230f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (cur->ns == NULL) { 9231f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard n++; 9232f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (n == indx) 9233f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard addNode(list, cur); 9234f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9235f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } else { 9236f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((cur->ns != NULL) && 9237f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (xmlStrEqual(URI, 9238f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard cur->ns->href))) { 9239f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard n++; 9240f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (n == indx) 9241f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard addNode(list, cur); 9242f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9243f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9244f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9245f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9246f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XML_ATTRIBUTE_NODE:{ 9247f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlAttrPtr attr = (xmlAttrPtr) cur; 9248f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 9249f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (xmlStrEqual(name, attr->name)) { 9250f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (prefix == NULL) { 9251f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((attr->ns == NULL) || 9252f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (attr->ns->prefix == NULL)) { 9253f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard n++; 9254f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (n == indx) 9255f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard addNode(list, cur); 9256f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9257f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } else { 9258f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((attr->ns != NULL) && 9259f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (xmlStrEqual(URI, 9260f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard attr->ns-> 9261f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard href))) { 9262f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard n++; 9263f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (n == indx) 9264f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard addNode(list, cur); 9265f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9266f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9267f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9268f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9269f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9270f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XML_NAMESPACE_DECL: 9271f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (cur->type == XML_NAMESPACE_DECL) { 9272f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlNsPtr ns = (xmlNsPtr) cur; 9273f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 9274f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((ns->prefix != NULL) && (name != NULL) 9275f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard && (xmlStrEqual(ns->prefix, name))) { 9276f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard n++; 9277f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (n == indx) 9278044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlXPathNodeSetAddNs(list, 9279044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard ctxt->context->node, (xmlNsPtr) cur); 9280f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9281f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9282f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9283f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard default: 9284f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9285f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9286f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9287f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9288f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9289f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } while (n < indx); 9290f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9291f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->node = tmp; 9292f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#ifdef DEBUG_STEP_NTH 9293f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, 9294f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard "\nExamined %d nodes, found %d nodes at that step\n", 9295f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard t, list->nodeNr); 9296f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#endif 9297f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard valuePush(ctxt, xmlXPathWrapNodeSet(list)); 92980ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard if ((obj->boolval) && (obj->user != NULL)) { 92990ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard ctxt->value->boolval = 1; 93000ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard ctxt->value->user = obj->user; 93010ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard obj->user = NULL; 93020ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard obj->boolval = 0; 93030ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard } 93040ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard xmlXPathFreeObject(obj); 9305f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return(t); 9306f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard} 9307f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 9308f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard/** 9309f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * xmlXPathCompOpEvalFirst: 9310d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * @ctxt: the XPath parser context with the compiled expression 9311d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * @op: an XPath compiled operation 9312f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * @first: the first elem found so far 9313d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * 9314f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Evaluate the Precompiled XPath operation searching only the first 9315f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * element in document order 9316f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * 9317f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Returns the number of examined objects. 9318d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard */ 9319f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillardstatic int 9320f06307e2c172284bb41376c396f757bdac9bdd19Daniel VeillardxmlXPathCompOpEvalFirst(xmlXPathParserContextPtr ctxt, 9321f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathStepOpPtr op, xmlNodePtr * first) 9322f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard{ 9323f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard int total = 0, cur; 9324d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard xmlXPathCompExprPtr comp; 9325d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard xmlXPathObjectPtr arg1, arg2; 9326d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard 9327556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 9328d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard comp = ctxt->comp; 9329d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard switch (op->op) { 9330f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_END: 9331f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (0); 9332f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_UNION: 9333f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total = 9334f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathCompOpEvalFirst(ctxt, &comp->steps[op->ch1], 9335f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard first); 9336556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 9337f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((ctxt->value != NULL) 9338f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard && (ctxt->value->type == XPATH_NODESET) 9339f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard && (ctxt->value->nodesetval != NULL) 9340f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard && (ctxt->value->nodesetval->nodeNr >= 1)) { 9341f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* 9342f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * limit tree traversing to first node in the result 9343f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 9344f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathNodeSetSort(ctxt->value->nodesetval); 9345f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard *first = ctxt->value->nodesetval->nodeTab[0]; 9346f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9347f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard cur = 9348f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathCompOpEvalFirst(ctxt, &comp->steps[op->ch2], 9349f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard first); 9350556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 9351f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard CHECK_TYPE0(XPATH_NODESET); 9352f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard arg2 = valuePop(ctxt); 9353f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 9354f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard CHECK_TYPE0(XPATH_NODESET); 9355f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard arg1 = valuePop(ctxt); 9356f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 9357f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard arg1->nodesetval = xmlXPathNodeSetMerge(arg1->nodesetval, 9358f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard arg2->nodesetval); 9359f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard valuePush(ctxt, arg1); 9360f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathFreeObject(arg2); 9361f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* optimizer */ 9362f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (total > cur) 9363f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathCompSwap(op); 9364f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total + cur); 9365f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_ROOT: 9366f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathRoot(ctxt); 9367f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (0); 9368f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_NODE: 9369f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch1 != -1) 9370f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]); 9371556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 9372f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch2 != -1) 9373f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]); 9374556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 9375f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard valuePush(ctxt, xmlXPathNewNodeSet(ctxt->context->node)); 9376f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 9377f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_RESET: 9378f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch1 != -1) 9379f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]); 9380556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 9381f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch2 != -1) 9382f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]); 9383556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 9384f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->node = NULL; 9385f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 9386f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_COLLECT:{ 9387f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch1 == -1) 9388f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 9389f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 9390f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total = xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]); 9391556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 9392f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 9393f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* 9394f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Optimization for [n] selection where n is a number 9395f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 9396f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((op->ch2 != -1) && 9397f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (comp->steps[op->ch2].op == XPATH_OP_PREDICATE) && 9398f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (comp->steps[op->ch2].ch1 == -1) && 9399f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (comp->steps[op->ch2].ch2 != -1) && 9400f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (comp->steps[comp->steps[op->ch2].ch2].op == 9401f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard XPATH_OP_VALUE)) { 9402f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathObjectPtr val; 9403f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 9404f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard val = comp->steps[comp->steps[op->ch2].ch2].value4; 9405f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((val != NULL) && (val->type == XPATH_NUMBER)) { 9406f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard int indx = (int) val->floatval; 9407f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 9408f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (val->floatval == (float) indx) { 9409f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathNodeCollectAndTestNth(ctxt, op, indx, 9410f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard first, NULL); 9411f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 9412f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9413f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9414f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9415f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathNodeCollectAndTest(ctxt, op, first, NULL); 9416f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 9417f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9418f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_VALUE: 9419f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard valuePush(ctxt, 9420f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathObjectCopy((xmlXPathObjectPtr) op->value4)); 9421f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (0); 9422f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_SORT: 9423f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch1 != -1) 9424f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += 9425f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathCompOpEvalFirst(ctxt, &comp->steps[op->ch1], 9426f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard first); 9427556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 9428f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((ctxt->value != NULL) 9429f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard && (ctxt->value->type == XPATH_NODESET) 9430f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard && (ctxt->value->nodesetval != NULL)) 9431f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathNodeSetSort(ctxt->value->nodesetval); 9432f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 9433f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard default: 9434f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (xmlXPathCompOpEval(ctxt, op)); 9435f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9436f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard} 943742596ad20cdf1925dd79ea801cbe598b6e7b7aecDaniel Veillard 9438f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard/** 9439f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * xmlXPathCompOpEvalLast: 9440f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * @ctxt: the XPath parser context with the compiled expression 9441f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * @op: an XPath compiled operation 9442f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * @last: the last elem found so far 9443f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * 9444f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Evaluate the Precompiled XPath operation searching only the last 9445f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * element in document order 9446f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * 9447f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Returns the number of node traversed 9448f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 9449f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillardstatic int 9450f06307e2c172284bb41376c396f757bdac9bdd19Daniel VeillardxmlXPathCompOpEvalLast(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op, 9451f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlNodePtr * last) 9452f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard{ 9453f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard int total = 0, cur; 9454f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathCompExprPtr comp; 9455f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathObjectPtr arg1, arg2; 94569e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 9457556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 9458f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard comp = ctxt->comp; 9459f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard switch (op->op) { 9460f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_END: 9461f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (0); 9462f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_UNION: 9463f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total = 9464f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathCompOpEvalLast(ctxt, &comp->steps[op->ch1], last); 9465556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 9466f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((ctxt->value != NULL) 9467f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard && (ctxt->value->type == XPATH_NODESET) 9468f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard && (ctxt->value->nodesetval != NULL) 9469f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard && (ctxt->value->nodesetval->nodeNr >= 1)) { 9470f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* 9471f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * limit tree traversing to first node in the result 9472f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 9473f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathNodeSetSort(ctxt->value->nodesetval); 9474f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard *last = 9475f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->value->nodesetval->nodeTab[ctxt->value-> 9476f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard nodesetval->nodeNr - 9477f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 1]; 9478f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9479f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard cur = 9480f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathCompOpEvalLast(ctxt, &comp->steps[op->ch2], last); 9481556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 9482f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((ctxt->value != NULL) 9483f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard && (ctxt->value->type == XPATH_NODESET) 9484f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard && (ctxt->value->nodesetval != NULL) 9485f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard && (ctxt->value->nodesetval->nodeNr >= 1)) { 9486f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9487f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard CHECK_TYPE0(XPATH_NODESET); 9488f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard arg2 = valuePop(ctxt); 9489f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 9490f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard CHECK_TYPE0(XPATH_NODESET); 9491f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard arg1 = valuePop(ctxt); 9492f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 9493f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard arg1->nodesetval = xmlXPathNodeSetMerge(arg1->nodesetval, 9494f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard arg2->nodesetval); 9495f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard valuePush(ctxt, arg1); 9496f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathFreeObject(arg2); 9497f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* optimizer */ 9498f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (total > cur) 9499f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathCompSwap(op); 9500f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total + cur); 9501f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_ROOT: 9502f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathRoot(ctxt); 9503f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (0); 9504f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_NODE: 9505f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch1 != -1) 9506f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]); 9507556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 9508f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch2 != -1) 9509f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]); 9510556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 9511f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard valuePush(ctxt, xmlXPathNewNodeSet(ctxt->context->node)); 9512f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 9513f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_RESET: 9514f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch1 != -1) 9515f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]); 9516556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 9517f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch2 != -1) 9518f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]); 9519556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 9520f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->node = NULL; 9521f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 9522f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_COLLECT:{ 9523f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch1 == -1) 9524f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (0); 9525f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 9526f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]); 9527556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 9528f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 9529f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* 9530f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Optimization for [n] selection where n is a number 9531f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 9532f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((op->ch2 != -1) && 9533f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (comp->steps[op->ch2].op == XPATH_OP_PREDICATE) && 9534f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (comp->steps[op->ch2].ch1 == -1) && 9535f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (comp->steps[op->ch2].ch2 != -1) && 9536f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (comp->steps[comp->steps[op->ch2].ch2].op == 9537f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard XPATH_OP_VALUE)) { 9538f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathObjectPtr val; 9539f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 9540f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard val = comp->steps[comp->steps[op->ch2].ch2].value4; 9541f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((val != NULL) && (val->type == XPATH_NUMBER)) { 9542f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard int indx = (int) val->floatval; 9543f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 9544f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (val->floatval == (float) indx) { 9545f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += 9546f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathNodeCollectAndTestNth(ctxt, op, 9547f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard indx, NULL, 9548f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard last); 9549f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 9550f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9551f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9552f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9553f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathNodeCollectAndTest(ctxt, op, NULL, last); 9554f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 9555f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9556f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_VALUE: 9557f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard valuePush(ctxt, 9558f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathObjectCopy((xmlXPathObjectPtr) op->value4)); 9559f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (0); 9560f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_SORT: 9561f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch1 != -1) 9562f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += 9563f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathCompOpEvalLast(ctxt, &comp->steps[op->ch1], 9564f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard last); 9565556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 9566f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((ctxt->value != NULL) 9567f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard && (ctxt->value->type == XPATH_NODESET) 9568f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard && (ctxt->value->nodesetval != NULL)) 9569f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathNodeSetSort(ctxt->value->nodesetval); 9570f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 9571f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard default: 9572f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (xmlXPathCompOpEval(ctxt, op)); 9573f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9574f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard} 95759e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 9576f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard/** 9577f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * xmlXPathCompOpEval: 9578f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * @ctxt: the XPath parser context with the compiled expression 9579f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * @op: an XPath compiled operation 9580f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * 9581f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Evaluate the Precompiled XPath operation 9582f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Returns the number of node traversed 9583f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 9584f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillardstatic int 9585f06307e2c172284bb41376c396f757bdac9bdd19Daniel VeillardxmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op) 9586f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard{ 9587f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard int total = 0; 9588f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard int equal, ret; 9589f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathCompExprPtr comp; 9590f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathObjectPtr arg1, arg2; 95917089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard xmlNodePtr bak; 95927089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard xmlDocPtr bakd; 95936000af549b49464a3b1947fc582998a1c9ff7c79William M. Brack int pp; 9594692092b5886073a8cd1c97bb7d57579e4a9cfc3fWilliam M. Brack int cs; 95959e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 9596556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 9597f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard comp = ctxt->comp; 9598f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard switch (op->op) { 9599f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_END: 9600f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (0); 9601f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_AND: 96027089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard bakd = ctxt->context->doc; 96037089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard bak = ctxt->context->node; 96046000af549b49464a3b1947fc582998a1c9ff7c79William M. Brack pp = ctxt->context->proximityPosition; 9605692092b5886073a8cd1c97bb7d57579e4a9cfc3fWilliam M. Brack cs = ctxt->context->contextSize; 9606f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]); 9607556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 9608f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathBooleanFunction(ctxt, 1); 9609f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((ctxt->value == NULL) || (ctxt->value->boolval == 0)) 9610f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 9611f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard arg2 = valuePop(ctxt); 96127089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard ctxt->context->doc = bakd; 96137089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard ctxt->context->node = bak; 96146000af549b49464a3b1947fc582998a1c9ff7c79William M. Brack ctxt->context->proximityPosition = pp; 9615692092b5886073a8cd1c97bb7d57579e4a9cfc3fWilliam M. Brack ctxt->context->contextSize = cs; 9616f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]); 9617556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard if (ctxt->error) { 9618556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard xmlXPathFreeObject(arg2); 9619556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard return(0); 9620556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard } 9621f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathBooleanFunction(ctxt, 1); 9622f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard arg1 = valuePop(ctxt); 9623f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard arg1->boolval &= arg2->boolval; 9624f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard valuePush(ctxt, arg1); 9625f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathFreeObject(arg2); 9626f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 9627f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_OR: 96287089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard bakd = ctxt->context->doc; 96297089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard bak = ctxt->context->node; 96306000af549b49464a3b1947fc582998a1c9ff7c79William M. Brack pp = ctxt->context->proximityPosition; 9631692092b5886073a8cd1c97bb7d57579e4a9cfc3fWilliam M. Brack cs = ctxt->context->contextSize; 9632f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]); 9633556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 9634f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathBooleanFunction(ctxt, 1); 9635f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((ctxt->value == NULL) || (ctxt->value->boolval == 1)) 9636f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 9637f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard arg2 = valuePop(ctxt); 96387089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard ctxt->context->doc = bakd; 96397089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard ctxt->context->node = bak; 96406000af549b49464a3b1947fc582998a1c9ff7c79William M. Brack ctxt->context->proximityPosition = pp; 9641692092b5886073a8cd1c97bb7d57579e4a9cfc3fWilliam M. Brack ctxt->context->contextSize = cs; 9642f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]); 9643556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard if (ctxt->error) { 9644556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard xmlXPathFreeObject(arg2); 9645556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard return(0); 9646556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard } 9647f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathBooleanFunction(ctxt, 1); 9648f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard arg1 = valuePop(ctxt); 9649f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard arg1->boolval |= arg2->boolval; 9650f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard valuePush(ctxt, arg1); 9651f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathFreeObject(arg2); 9652f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 9653f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_EQUAL: 96547089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard bakd = ctxt->context->doc; 96557089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard bak = ctxt->context->node; 96566000af549b49464a3b1947fc582998a1c9ff7c79William M. Brack pp = ctxt->context->proximityPosition; 9657692092b5886073a8cd1c97bb7d57579e4a9cfc3fWilliam M. Brack cs = ctxt->context->contextSize; 9658f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]); 9659556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 96607089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard ctxt->context->doc = bakd; 96617089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard ctxt->context->node = bak; 96626000af549b49464a3b1947fc582998a1c9ff7c79William M. Brack ctxt->context->proximityPosition = pp; 9663692092b5886073a8cd1c97bb7d57579e4a9cfc3fWilliam M. Brack ctxt->context->contextSize = cs; 9664f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]); 9665556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 9666f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard equal = xmlXPathEqualValues(ctxt); 9667f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->value) 9668f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard valuePush(ctxt, xmlXPathNewBoolean(equal)); 9669f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard else 9670f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard valuePush(ctxt, xmlXPathNewBoolean(!equal)); 9671f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 9672f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_CMP: 96737089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard bakd = ctxt->context->doc; 96747089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard bak = ctxt->context->node; 96756000af549b49464a3b1947fc582998a1c9ff7c79William M. Brack pp = ctxt->context->proximityPosition; 9676692092b5886073a8cd1c97bb7d57579e4a9cfc3fWilliam M. Brack cs = ctxt->context->contextSize; 9677f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]); 9678556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 96797089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard ctxt->context->doc = bakd; 96807089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard ctxt->context->node = bak; 96816000af549b49464a3b1947fc582998a1c9ff7c79William M. Brack ctxt->context->proximityPosition = pp; 9682692092b5886073a8cd1c97bb7d57579e4a9cfc3fWilliam M. Brack ctxt->context->contextSize = cs; 9683f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]); 9684556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 9685f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ret = xmlXPathCompareValues(ctxt, op->value, op->value2); 9686f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard valuePush(ctxt, xmlXPathNewBoolean(ret)); 9687f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 9688f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_PLUS: 96897089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard bakd = ctxt->context->doc; 96907089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard bak = ctxt->context->node; 96916000af549b49464a3b1947fc582998a1c9ff7c79William M. Brack pp = ctxt->context->proximityPosition; 9692692092b5886073a8cd1c97bb7d57579e4a9cfc3fWilliam M. Brack cs = ctxt->context->contextSize; 9693f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]); 9694556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 96957089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard if (op->ch2 != -1) { 96967089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard ctxt->context->doc = bakd; 96977089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard ctxt->context->node = bak; 96986000af549b49464a3b1947fc582998a1c9ff7c79William M. Brack ctxt->context->proximityPosition = pp; 9699692092b5886073a8cd1c97bb7d57579e4a9cfc3fWilliam M. Brack ctxt->context->contextSize = cs; 9700f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]); 97017089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard } 9702556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 9703f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->value == 0) 9704f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathSubValues(ctxt); 9705f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard else if (op->value == 1) 9706f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathAddValues(ctxt); 9707f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard else if (op->value == 2) 9708f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathValueFlipSign(ctxt); 9709f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard else if (op->value == 3) { 9710f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard CAST_TO_NUMBER; 9711f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard CHECK_TYPE0(XPATH_NUMBER); 9712f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9713f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 9714f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_MULT: 97157089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard bakd = ctxt->context->doc; 97167089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard bak = ctxt->context->node; 97176000af549b49464a3b1947fc582998a1c9ff7c79William M. Brack pp = ctxt->context->proximityPosition; 9718692092b5886073a8cd1c97bb7d57579e4a9cfc3fWilliam M. Brack cs = ctxt->context->contextSize; 9719f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]); 9720556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 97217089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard ctxt->context->doc = bakd; 97227089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard ctxt->context->node = bak; 97236000af549b49464a3b1947fc582998a1c9ff7c79William M. Brack ctxt->context->proximityPosition = pp; 9724692092b5886073a8cd1c97bb7d57579e4a9cfc3fWilliam M. Brack ctxt->context->contextSize = cs; 9725f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]); 9726556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 9727f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->value == 0) 9728f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathMultValues(ctxt); 9729f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard else if (op->value == 1) 9730f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathDivValues(ctxt); 9731f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard else if (op->value == 2) 9732f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathModValues(ctxt); 9733f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 9734f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_UNION: 97357089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard bakd = ctxt->context->doc; 97367089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard bak = ctxt->context->node; 97376000af549b49464a3b1947fc582998a1c9ff7c79William M. Brack pp = ctxt->context->proximityPosition; 9738692092b5886073a8cd1c97bb7d57579e4a9cfc3fWilliam M. Brack cs = ctxt->context->contextSize; 9739f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]); 9740556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 97417089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard ctxt->context->doc = bakd; 97427089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard ctxt->context->node = bak; 97436000af549b49464a3b1947fc582998a1c9ff7c79William M. Brack ctxt->context->proximityPosition = pp; 9744692092b5886073a8cd1c97bb7d57579e4a9cfc3fWilliam M. Brack ctxt->context->contextSize = cs; 9745f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]); 9746556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 9747f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard CHECK_TYPE0(XPATH_NODESET); 9748f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard arg2 = valuePop(ctxt); 9749f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 9750f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard CHECK_TYPE0(XPATH_NODESET); 9751f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard arg1 = valuePop(ctxt); 9752f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 9753f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard arg1->nodesetval = xmlXPathNodeSetMerge(arg1->nodesetval, 9754f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard arg2->nodesetval); 9755f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard valuePush(ctxt, arg1); 9756f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathFreeObject(arg2); 9757f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 9758f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_ROOT: 9759f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathRoot(ctxt); 9760f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 9761f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_NODE: 9762f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch1 != -1) 9763f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]); 9764556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 9765f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch2 != -1) 9766f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]); 9767556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 9768f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard valuePush(ctxt, xmlXPathNewNodeSet(ctxt->context->node)); 9769f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 9770f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_RESET: 9771f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch1 != -1) 9772f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]); 9773556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 9774f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch2 != -1) 9775f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]); 9776556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 9777f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->node = NULL; 9778f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 9779f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_COLLECT:{ 9780f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch1 == -1) 9781f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 9782f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 9783f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]); 9784556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 9785f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 9786f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* 9787f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Optimization for [n] selection where n is a number 9788f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 9789f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((op->ch2 != -1) && 9790f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (comp->steps[op->ch2].op == XPATH_OP_PREDICATE) && 9791f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (comp->steps[op->ch2].ch1 == -1) && 9792f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (comp->steps[op->ch2].ch2 != -1) && 9793f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (comp->steps[comp->steps[op->ch2].ch2].op == 9794f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard XPATH_OP_VALUE)) { 9795f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathObjectPtr val; 9796f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 9797f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard val = comp->steps[comp->steps[op->ch2].ch2].value4; 9798f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((val != NULL) && (val->type == XPATH_NUMBER)) { 9799f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard int indx = (int) val->floatval; 9800f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 9801f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (val->floatval == (float) indx) { 9802f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += 9803f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathNodeCollectAndTestNth(ctxt, op, 9804f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard indx, NULL, 9805f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard NULL); 9806f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 9807f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9808f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9809f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9810f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathNodeCollectAndTest(ctxt, op, NULL, NULL); 9811f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 9812f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9813f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_VALUE: 9814f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard valuePush(ctxt, 9815f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathObjectCopy((xmlXPathObjectPtr) op->value4)); 9816f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 9817f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_VARIABLE:{ 9818556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard xmlXPathObjectPtr val; 9819556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard 9820f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch1 != -1) 9821f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += 9822f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]); 9823556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard if (op->value5 == NULL) { 9824556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard val = xmlXPathVariableLookup(ctxt->context, op->value4); 9825556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard if (val == NULL) { 9826556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard ctxt->error = XPATH_UNDEF_VARIABLE_ERROR; 9827556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard return(0); 9828556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard } 9829556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard valuePush(ctxt, val); 9830556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard } else { 9831f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard const xmlChar *URI; 9832f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 9833f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard URI = xmlXPathNsLookup(ctxt->context, op->value5); 9834f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (URI == NULL) { 9835f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, 9836cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard "xmlXPathCompOpEval: variable %s bound to undefined prefix %s\n", 9837f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard op->value4, op->value5); 9838f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 9839f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9840556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard val = xmlXPathVariableLookupNS(ctxt->context, 9841556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard op->value4, URI); 9842556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard if (val == NULL) { 9843556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard ctxt->error = XPATH_UNDEF_VARIABLE_ERROR; 9844556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard return(0); 9845556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard } 9846556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard valuePush(ctxt, val); 9847f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9848f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 9849f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9850f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_FUNCTION:{ 9851f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathFunction func; 9852f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard const xmlChar *oldFunc, *oldFuncURI; 9853556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard int i; 9854f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 9855f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch1 != -1) 9856f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += 9857f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]); 9858556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard if (ctxt->valueNr < op->value) { 9859556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, 9860cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard "xmlXPathCompOpEval: parameter error\n"); 9861556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard ctxt->error = XPATH_INVALID_OPERAND; 9862556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard return (total); 9863556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard } 9864556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard for (i = 0; i < op->value; i++) 9865556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard if (ctxt->valueTab[(ctxt->valueNr - 1) - i] == NULL) { 9866556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, 9867cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard "xmlXPathCompOpEval: parameter error\n"); 9868556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard ctxt->error = XPATH_INVALID_OPERAND; 9869556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard return (total); 9870556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard } 9871f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->cache != NULL) 9872f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard func = (xmlXPathFunction) op->cache; 9873f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard else { 9874f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard const xmlChar *URI = NULL; 9875f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 9876f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->value5 == NULL) 9877f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard func = 9878f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathFunctionLookup(ctxt->context, 9879f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard op->value4); 9880f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard else { 9881f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard URI = xmlXPathNsLookup(ctxt->context, op->value5); 9882f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (URI == NULL) { 9883f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, 9884cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard "xmlXPathCompOpEval: function %s bound to undefined prefix %s\n", 9885f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard op->value4, op->value5); 9886f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 9887f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9888f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard func = xmlXPathFunctionLookupNS(ctxt->context, 9889f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard op->value4, URI); 9890f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9891f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (func == NULL) { 9892f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, 9893cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard "xmlXPathCompOpEval: function %s not found\n", 9894f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard op->value4); 9895f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard XP_ERROR0(XPATH_UNKNOWN_FUNC_ERROR); 9896f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9897f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard op->cache = (void *) func; 9898f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard op->cacheURI = (void *) URI; 9899f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9900f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard oldFunc = ctxt->context->function; 9901f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard oldFuncURI = ctxt->context->functionURI; 9902f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->function = op->value4; 9903f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->functionURI = op->cacheURI; 9904f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard func(ctxt, op->value); 9905f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->function = oldFunc; 9906f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->functionURI = oldFuncURI; 9907f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 9908f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9909f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_ARG: 9910088bf1163080cbbb72ba9d4a52ab08cc7c8ff6c7Daniel Veillard bakd = ctxt->context->doc; 9911088bf1163080cbbb72ba9d4a52ab08cc7c8ff6c7Daniel Veillard bak = ctxt->context->node; 9912f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch1 != -1) 9913f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]); 9914088bf1163080cbbb72ba9d4a52ab08cc7c8ff6c7Daniel Veillard ctxt->context->doc = bakd; 9915088bf1163080cbbb72ba9d4a52ab08cc7c8ff6c7Daniel Veillard ctxt->context->node = bak; 9916556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 9917f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch2 != -1) 9918f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]); 9919088bf1163080cbbb72ba9d4a52ab08cc7c8ff6c7Daniel Veillard ctxt->context->doc = bakd; 9920088bf1163080cbbb72ba9d4a52ab08cc7c8ff6c7Daniel Veillard ctxt->context->node = bak; 9921556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 9922f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 9923f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_PREDICATE: 9924f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_FILTER:{ 9925f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathObjectPtr res; 9926f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathObjectPtr obj, tmp; 9927f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlNodeSetPtr newset = NULL; 9928f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlNodeSetPtr oldset; 9929f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlNodePtr oldnode; 9930f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard int i; 9931f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 9932f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* 9933f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Optimization for ()[1] selection i.e. the first elem 9934f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 9935f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((op->ch1 != -1) && (op->ch2 != -1) && 9936f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (comp->steps[op->ch1].op == XPATH_OP_SORT) && 9937f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (comp->steps[op->ch2].op == XPATH_OP_VALUE)) { 9938f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathObjectPtr val; 9939f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 9940f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard val = comp->steps[op->ch2].value4; 9941f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((val != NULL) && (val->type == XPATH_NUMBER) && 9942f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (val->floatval == 1.0)) { 9943f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlNodePtr first = NULL; 9944f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 9945f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += 9946f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathCompOpEvalFirst(ctxt, 9947f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard &comp->steps[op->ch1], 9948f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard &first); 9949556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 9950f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* 9951f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * The nodeset should be in document order, 9952f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Keep only the first value 9953f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 9954f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((ctxt->value != NULL) && 9955f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (ctxt->value->type == XPATH_NODESET) && 9956f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (ctxt->value->nodesetval != NULL) && 9957f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (ctxt->value->nodesetval->nodeNr > 1)) 9958f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->value->nodesetval->nodeNr = 1; 9959f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 9960f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9961f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9962f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* 9963f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Optimization for ()[last()] selection i.e. the last elem 9964f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 9965f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((op->ch1 != -1) && (op->ch2 != -1) && 9966f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (comp->steps[op->ch1].op == XPATH_OP_SORT) && 9967f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (comp->steps[op->ch2].op == XPATH_OP_SORT)) { 9968f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard int f = comp->steps[op->ch2].ch1; 9969f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 9970f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((f != -1) && 9971f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (comp->steps[f].op == XPATH_OP_FUNCTION) && 9972f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (comp->steps[f].value5 == NULL) && 9973f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (comp->steps[f].value == 0) && 9974f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (comp->steps[f].value4 != NULL) && 9975f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (xmlStrEqual 9976f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (comp->steps[f].value4, BAD_CAST "last"))) { 9977f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlNodePtr last = NULL; 9978f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 9979f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += 9980f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathCompOpEvalLast(ctxt, 9981f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard &comp->steps[op->ch1], 9982f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard &last); 9983556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 9984f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* 9985f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * The nodeset should be in document order, 9986f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Keep only the last value 9987f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 9988f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((ctxt->value != NULL) && 9989f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (ctxt->value->type == XPATH_NODESET) && 9990f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (ctxt->value->nodesetval != NULL) && 9991f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (ctxt->value->nodesetval->nodeTab != NULL) && 9992f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (ctxt->value->nodesetval->nodeNr > 1)) { 9993f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->value->nodesetval->nodeTab[0] = 9994f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->value->nodesetval->nodeTab[ctxt-> 9995f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard value-> 9996f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard nodesetval-> 9997f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard nodeNr - 9998f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 1]; 9999f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->value->nodesetval->nodeNr = 1; 10000f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10001f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 10002f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10003f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10004f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10005f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch1 != -1) 10006f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += 10007f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]); 10008556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 10009f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch2 == -1) 10010f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 10011f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (ctxt->value == NULL) 10012f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 10013f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10014f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard oldnode = ctxt->context->node; 100159e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 10016f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#ifdef LIBXML_XPTR_ENABLED 10017f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* 10018f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Hum are we filtering the result of an XPointer expression 10019f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 10020f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (ctxt->value->type == XPATH_LOCATIONSET) { 10021f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlLocationSetPtr newlocset = NULL; 10022f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlLocationSetPtr oldlocset; 10023f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10024f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* 10025f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Extract the old locset, and then evaluate the result of the 10026f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * expression for all the element in the locset. use it to grow 10027f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * up a new locset. 10028f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 10029f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard CHECK_TYPE0(XPATH_LOCATIONSET); 10030f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard obj = valuePop(ctxt); 10031f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard oldlocset = obj->user; 10032f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->node = NULL; 10033f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10034f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((oldlocset == NULL) || (oldlocset->locNr == 0)) { 10035f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->contextSize = 0; 10036f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->proximityPosition = 0; 10037f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch2 != -1) 10038f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += 10039f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathCompOpEval(ctxt, 10040f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard &comp->steps[op->ch2]); 10041f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard res = valuePop(ctxt); 10042f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (res != NULL) 10043f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathFreeObject(res); 10044f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard valuePush(ctxt, obj); 10045f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard CHECK_ERROR0; 10046f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 10047f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10048f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard newlocset = xmlXPtrLocationSetCreate(NULL); 10049f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10050f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard for (i = 0; i < oldlocset->locNr; i++) { 10051f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* 10052f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Run the evaluation with a node list made of a 10053f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * single item in the nodelocset. 10054f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 10055f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->node = oldlocset->locTab[i]->user; 10056f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard tmp = xmlXPathNewNodeSet(ctxt->context->node); 10057f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard valuePush(ctxt, tmp); 10058f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->contextSize = oldlocset->locNr; 10059f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->proximityPosition = i + 1; 10060f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10061f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch2 != -1) 10062f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += 10063f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathCompOpEval(ctxt, 10064f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard &comp->steps[op->ch2]); 10065f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard CHECK_ERROR0; 10066f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10067f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* 10068f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * The result of the evaluation need to be tested to 10069f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * decided whether the filter succeeded or not 10070f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 10071f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard res = valuePop(ctxt); 10072f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (xmlXPathEvaluatePredicateResult(ctxt, res)) { 10073f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPtrLocationSetAdd(newlocset, 10074f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathObjectCopy 10075f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (oldlocset->locTab[i])); 10076f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10077f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10078f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* 10079f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Cleanup 10080f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 10081f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (res != NULL) 10082f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathFreeObject(res); 10083f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (ctxt->value == tmp) { 10084f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard res = valuePop(ctxt); 10085f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathFreeObject(res); 10086f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10087f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10088f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->node = NULL; 10089f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10090f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10091f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* 10092f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * The result is used as the new evaluation locset. 10093f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 10094f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathFreeObject(obj); 10095f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->node = NULL; 10096f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->contextSize = -1; 10097f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->proximityPosition = -1; 10098f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard valuePush(ctxt, xmlXPtrWrapLocationSet(newlocset)); 10099f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->node = oldnode; 10100f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 10101f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 101029e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard#endif /* LIBXML_XPTR_ENABLED */ 101039e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 10104f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* 10105f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Extract the old set, and then evaluate the result of the 10106f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * expression for all the element in the set. use it to grow 10107f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * up a new set. 10108f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 10109f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard CHECK_TYPE0(XPATH_NODESET); 10110f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard obj = valuePop(ctxt); 10111f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard oldset = obj->nodesetval; 10112f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10113f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard oldnode = ctxt->context->node; 10114f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->node = NULL; 10115f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10116f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((oldset == NULL) || (oldset->nodeNr == 0)) { 10117f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->contextSize = 0; 10118f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->proximityPosition = 0; 10119f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch2 != -1) 10120f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += 10121f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathCompOpEval(ctxt, 10122f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard &comp->steps[op->ch2]); 10123556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 10124f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard res = valuePop(ctxt); 10125f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (res != NULL) 10126f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathFreeObject(res); 10127f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard valuePush(ctxt, obj); 10128f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->node = oldnode; 10129f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard CHECK_ERROR0; 10130f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } else { 10131f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* 10132f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Initialize the new set. 10133f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 10134f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard newset = xmlXPathNodeSetCreate(NULL); 10135f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10136f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard for (i = 0; i < oldset->nodeNr; i++) { 10137f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* 10138f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Run the evaluation with a node list made of 10139f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * a single item in the nodeset. 10140f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 10141f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->node = oldset->nodeTab[i]; 10142f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard tmp = xmlXPathNewNodeSet(ctxt->context->node); 10143f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard valuePush(ctxt, tmp); 10144f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->contextSize = oldset->nodeNr; 10145f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->proximityPosition = i + 1; 10146f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10147f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch2 != -1) 10148f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += 10149f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathCompOpEval(ctxt, 10150f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard &comp->steps[op->ch2]); 10151f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard CHECK_ERROR0; 10152f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10153f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* 10154f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * The result of the evaluation need to be tested to 10155f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * decided whether the filter succeeded or not 10156f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 10157f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard res = valuePop(ctxt); 10158f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (xmlXPathEvaluatePredicateResult(ctxt, res)) { 10159f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathNodeSetAdd(newset, oldset->nodeTab[i]); 10160f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10161f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10162f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* 10163f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Cleanup 10164f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 10165f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (res != NULL) 10166f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathFreeObject(res); 10167f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (ctxt->value == tmp) { 10168f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard res = valuePop(ctxt); 10169f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathFreeObject(res); 10170f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10171f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10172f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->node = NULL; 10173f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10174f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10175f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* 10176f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * The result is used as the new evaluation set. 10177f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 10178f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathFreeObject(obj); 10179f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->node = NULL; 10180f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->contextSize = -1; 10181f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->proximityPosition = -1; 10182f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard valuePush(ctxt, xmlXPathWrapNodeSet(newset)); 10183f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10184f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->node = oldnode; 10185f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 10186f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10187f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_SORT: 10188f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch1 != -1) 10189f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]); 10190556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 10191f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((ctxt->value != NULL) && 10192f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (ctxt->value->type == XPATH_NODESET) && 10193f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (ctxt->value->nodesetval != NULL)) 10194f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathNodeSetSort(ctxt->value->nodesetval); 10195f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 101969e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard#ifdef LIBXML_XPTR_ENABLED 10197f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_RANGETO:{ 10198f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathObjectPtr range; 10199f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathObjectPtr res, obj; 10200f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathObjectPtr tmp; 10201f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlLocationSetPtr newset = NULL; 10202f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlNodeSetPtr oldset; 10203f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard int i; 10204f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10205f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch1 != -1) 10206f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += 10207f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]); 10208f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch2 == -1) 10209f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 10210f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10211f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard CHECK_TYPE0(XPATH_NODESET); 10212f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard obj = valuePop(ctxt); 10213f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard oldset = obj->nodesetval; 10214f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->node = NULL; 10215f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10216f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard newset = xmlXPtrLocationSetCreate(NULL); 10217f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10218f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (oldset != NULL) { 10219f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard for (i = 0; i < oldset->nodeNr; i++) { 10220f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* 10221f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Run the evaluation with a node list made of a single item 10222f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * in the nodeset. 10223f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 10224f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->node = oldset->nodeTab[i]; 10225f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard tmp = xmlXPathNewNodeSet(ctxt->context->node); 10226f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard valuePush(ctxt, tmp); 10227f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10228f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch2 != -1) 10229f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += 10230f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathCompOpEval(ctxt, 10231f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard &comp->steps[op->ch2]); 10232f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard CHECK_ERROR0; 10233f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10234f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* 10235f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * The result of the evaluation need to be tested to 10236f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * decided whether the filter succeeded or not 10237f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 10238f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard res = valuePop(ctxt); 10239f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard range = 10240f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPtrNewRangeNodeObject(oldset->nodeTab[i], 10241f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard res); 10242f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (range != NULL) { 10243f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPtrLocationSetAdd(newset, range); 10244f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10245f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10246f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* 10247f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Cleanup 10248f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 10249f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (res != NULL) 10250f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathFreeObject(res); 10251f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (ctxt->value == tmp) { 10252f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard res = valuePop(ctxt); 10253f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathFreeObject(res); 10254f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10255f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10256f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->node = NULL; 10257f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10258f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10259f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10260f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* 10261f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * The result is used as the new evaluation set. 10262f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 10263f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathFreeObject(obj); 10264f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->node = NULL; 10265f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->contextSize = -1; 10266f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->proximityPosition = -1; 10267f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard valuePush(ctxt, xmlXPtrWrapLocationSet(newset)); 10268f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 10269f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 102709e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard#endif /* LIBXML_XPTR_ENABLED */ 102719e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } 102729e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlGenericError(xmlGenericErrorContext, 10273f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard "XPath: unknown precompiled operation %d\n", op->op); 10274f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 102759e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard} 102769e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 102779e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard/** 102789e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * xmlXPathRunEval: 102799e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * @ctxt: the XPath parser context with the compiled expression 102809e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * 102819e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * Evaluate the Precompiled XPath expression in the given context. 102829e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard */ 10283fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillardstatic void 102849e7160d45a18bfa26d708e22ba991f7670d0128bDaniel VeillardxmlXPathRunEval(xmlXPathParserContextPtr ctxt) { 102859e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlXPathCompExprPtr comp; 102869e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 102879e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if ((ctxt == NULL) || (ctxt->comp == NULL)) 102889e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard return; 102899e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 102909e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (ctxt->valueTab == NULL) { 102919e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard /* Allocate the value stack */ 102929e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard ctxt->valueTab = (xmlXPathObjectPtr *) 102939e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlMalloc(10 * sizeof(xmlXPathObjectPtr)); 102949e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (ctxt->valueTab == NULL) { 102959e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlFree(ctxt); 102969e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } 102979e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard ctxt->valueNr = 0; 102989e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard ctxt->valueMax = 10; 102999e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard ctxt->value = NULL; 103009e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } 103019e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard comp = ctxt->comp; 1030229b6f76c5326616aed5dcff9cb55145137863e97Aleksey Sanin if(comp->last < 0) { 1030329b6f76c5326616aed5dcff9cb55145137863e97Aleksey Sanin xmlGenericError(xmlGenericErrorContext, 1030429b6f76c5326616aed5dcff9cb55145137863e97Aleksey Sanin "xmlXPathRunEval: last is less than zero\n"); 1030529b6f76c5326616aed5dcff9cb55145137863e97Aleksey Sanin return; 1030629b6f76c5326616aed5dcff9cb55145137863e97Aleksey Sanin } 103079e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlXPathCompOpEval(ctxt, &comp->steps[comp->last]); 103089e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard} 103099e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 10310afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard/************************************************************************ 10311afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * * 10312afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Public interfaces * 10313afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * * 10314afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard ************************************************************************/ 10315afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard 10316afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard/** 10317fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * xmlXPathEvalPredicate: 10318fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * @ctxt: the XPath context 10319fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * @res: the Predicate Expression evaluation result 10320fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * 10321fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * Evaluate a predicate result for the current node. 10322fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * A PredicateExpr is evaluated by evaluating the Expr and converting 10323fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * the result to a boolean. If the result is a number, the result will 10324fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * be converted to true if the number is equal to the position of the 10325fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * context node in the context node list (as returned by the position 10326fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * function) and will be converted to false otherwise; if the result 10327fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * is not a number, then the result will be converted as if by a call 10328fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * to the boolean function. 10329fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * 10330cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * Returns 1 if predicate is true, 0 otherwise 10331fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard */ 10332fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillardint 10333fbf8a2d0c8145b713099df63d174154a8442e60dDaniel VeillardxmlXPathEvalPredicate(xmlXPathContextPtr ctxt, xmlXPathObjectPtr res) { 10334fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard if (res == NULL) return(0); 10335fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard switch (res->type) { 10336fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard case XPATH_BOOLEAN: 10337fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard return(res->boolval); 10338fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard case XPATH_NUMBER: 10339fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard return(res->floatval == ctxt->proximityPosition); 10340fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard case XPATH_NODESET: 10341fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard case XPATH_XSLT_TREE: 10342d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard if (res->nodesetval == NULL) 10343d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard return(0); 10344fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard return(res->nodesetval->nodeNr != 0); 10345fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard case XPATH_STRING: 10346fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard return((res->stringval != NULL) && 10347fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard (xmlStrlen(res->stringval) != 0)); 10348fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard default: 10349fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard STRANGE 10350fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard } 10351fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard return(0); 10352fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard} 10353fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard 10354fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard/** 10355afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathEvaluatePredicateResult: 10356afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * @ctxt: the XPath Parser context 10357afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * @res: the Predicate Expression evaluation result 10358afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * 10359afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Evaluate a predicate result for the current node. 10360afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * A PredicateExpr is evaluated by evaluating the Expr and converting 10361afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * the result to a boolean. If the result is a number, the result will 10362afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * be converted to true if the number is equal to the position of the 10363afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * context node in the context node list (as returned by the position 10364afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * function) and will be converted to false otherwise; if the result 10365afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * is not a number, then the result will be converted as if by a call 10366afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * to the boolean function. 10367afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * 10368cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * Returns 1 if predicate is true, 0 otherwise 10369afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard */ 10370afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardint 10371afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathEvaluatePredicateResult(xmlXPathParserContextPtr ctxt, 10372afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathObjectPtr res) { 10373afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard if (res == NULL) return(0); 10374afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard switch (res->type) { 10375afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard case XPATH_BOOLEAN: 10376afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard return(res->boolval); 10377afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard case XPATH_NUMBER: 10378afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard return(res->floatval == ctxt->context->proximityPosition); 10379afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard case XPATH_NODESET: 10380afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard case XPATH_XSLT_TREE: 1038173639a73c5a51c3739595f54c338bb531c1319c2Daniel Veillard if (res->nodesetval == NULL) 10382911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard return(0); 10383afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard return(res->nodesetval->nodeNr != 0); 10384afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard case XPATH_STRING: 10385afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard return((res->stringval != NULL) && 10386afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard (xmlStrlen(res->stringval) != 0)); 10387afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard default: 10388afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard STRANGE 10389afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard } 10390afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard return(0); 10391afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard} 10392afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard 10393afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard/** 10394afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompile: 10395afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * @str: the XPath expression 10396afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * 10397afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile an XPath expression 10398afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * 10399cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * Returns the xmlXPathObjectPtr resulting from the evaluation or NULL. 10400afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * the caller has to free the object. 10401afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard */ 10402afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompExprPtr 10403afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompile(const xmlChar *str) { 10404afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathParserContextPtr ctxt; 10405afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompExprPtr comp; 10406afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard 10407afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathInit(); 10408afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard 10409afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard ctxt = xmlXPathNewParserContext(str, NULL); 10410afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompileExpr(ctxt); 1041150fe8b1732048003f47b32b009507fe6cdecd39fAleksey Sanin 1041240af649f9b5b32f97879f10432c56bb5ef60c958Daniel Veillard if (*ctxt->cur != 0) { 1041350fe8b1732048003f47b32b009507fe6cdecd39fAleksey Sanin /* 1041450fe8b1732048003f47b32b009507fe6cdecd39fAleksey Sanin * aleksey: in some cases this line prints *second* error message 1041550fe8b1732048003f47b32b009507fe6cdecd39fAleksey Sanin * (see bug #78858) and probably this should be fixed. 1041650fe8b1732048003f47b32b009507fe6cdecd39fAleksey Sanin * However, we are not sure that all error messages are printed 1041750fe8b1732048003f47b32b009507fe6cdecd39fAleksey Sanin * out in other places. It's not critical so we leave it as-is for now 1041850fe8b1732048003f47b32b009507fe6cdecd39fAleksey Sanin */ 1041940af649f9b5b32f97879f10432c56bb5ef60c958Daniel Veillard xmlXPatherror(ctxt, __FILE__, __LINE__, XPATH_EXPR_ERROR); 1042040af649f9b5b32f97879f10432c56bb5ef60c958Daniel Veillard comp = NULL; 1042140af649f9b5b32f97879f10432c56bb5ef60c958Daniel Veillard } else { 1042240af649f9b5b32f97879f10432c56bb5ef60c958Daniel Veillard comp = ctxt->comp; 1042340af649f9b5b32f97879f10432c56bb5ef60c958Daniel Veillard ctxt->comp = NULL; 1042440af649f9b5b32f97879f10432c56bb5ef60c958Daniel Veillard } 10425afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathFreeParserContext(ctxt); 10426f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#ifdef DEBUG_EVAL_COUNTS 10427f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (comp != NULL) { 10428f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard comp->string = xmlStrdup(str); 10429f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard comp->nb = 0; 10430f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10431f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#endif 10432afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard return(comp); 10433afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard} 10434afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard 104359e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard/** 104369e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * xmlXPathCompiledEval: 104379e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * @comp: the compiled XPath expression 104389e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * @ctx: the XPath context 104399e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * 104409e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * Evaluate the Precompiled XPath expression in the given context. 104419e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * 10442cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * Returns the xmlXPathObjectPtr resulting from the evaluation or NULL. 104439e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * the caller has to free the object. 104449e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard */ 104459e7160d45a18bfa26d708e22ba991f7670d0128bDaniel VeillardxmlXPathObjectPtr 104469e7160d45a18bfa26d708e22ba991f7670d0128bDaniel VeillardxmlXPathCompiledEval(xmlXPathCompExprPtr comp, xmlXPathContextPtr ctx) { 104479e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlXPathParserContextPtr ctxt; 104489e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlXPathObjectPtr res, tmp, init = NULL; 104499e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard int stack = 0; 104508146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard#ifndef LIBXML_THREAD_ENABLED 104518146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard static int reentance = 0; 104528146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard#endif 104539e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 104549e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if ((comp == NULL) || (ctx == NULL)) 104559e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard return(NULL); 104569e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlXPathInit(); 104579e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 104589e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard CHECK_CONTEXT(ctx) 104599e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 104608146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard#ifndef LIBXML_THREAD_ENABLED 104618146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard reentance++; 104628146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard if (reentance > 1) 104638146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard xmlXPathDisableOptimizer = 1; 104648146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard#endif 104658146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard 10466f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#ifdef DEBUG_EVAL_COUNTS 10467f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard comp->nb++; 10468f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((comp->string != NULL) && (comp->nb > 100)) { 10469f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard fprintf(stderr, "100 x %s\n", comp->string); 10470f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard comp->nb = 0; 10471f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10472f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#endif 104739e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard ctxt = xmlXPathCompParserContext(comp, ctx); 104749e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlXPathRunEval(ctxt); 104759e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 104769e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (ctxt->value == NULL) { 104779e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlGenericError(xmlGenericErrorContext, 10478cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard "xmlXPathCompiledEval: evaluation failed\n"); 104799e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard res = NULL; 104809e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } else { 104819e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard res = valuePop(ctxt); 104829e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } 104839e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 10484f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 104859e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard do { 104869e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard tmp = valuePop(ctxt); 104879e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (tmp != NULL) { 104889e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (tmp != init) 104899e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard stack++; 104909e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlXPathFreeObject(tmp); 104919e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } 104929e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } while (tmp != NULL); 104939e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if ((stack != 0) && (res != NULL)) { 104949e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlGenericError(xmlGenericErrorContext, 10495cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard "xmlXPathCompiledEval: %d object left on the stack\n", 104969e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard stack); 104979e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } 104989e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (ctxt->error != XPATH_EXPRESSION_OK) { 104999e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlXPathFreeObject(res); 105009e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard res = NULL; 105019e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } 105029e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 105039e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 10504afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard ctxt->comp = NULL; 105059e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlXPathFreeParserContext(ctxt); 105068146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard#ifndef LIBXML_THREAD_ENABLED 105078146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard reentance--; 105088146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard#endif 105099e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard return(res); 105109e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard} 105119e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 10512afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard/** 10513afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathEvalExpr: 10514afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * @ctxt: the XPath Parser context 10515afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * 10516afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Parse and evaluate an XPath expression in the given context, 10517afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * then push the result on the context stack 10518afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard */ 10519afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardvoid 10520afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathEvalExpr(xmlXPathParserContextPtr ctxt) { 10521afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompileExpr(ctxt); 1052250fe8b1732048003f47b32b009507fe6cdecd39fAleksey Sanin CHECK_ERROR; 10523afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathRunEval(ctxt); 10524afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard} 105259e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 105263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 105273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathEval: 105283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @str: the XPath expression 105293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctx: the XPath context 105303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 105313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Evaluate the XPath Location Path in the given context. 105323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 10533cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * Returns the xmlXPathObjectPtr resulting from the evaluation or NULL. 105343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the caller has to free the object. 105353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 105363473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathObjectPtr 105373473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathEval(const xmlChar *str, xmlXPathContextPtr ctx) { 105383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathParserContextPtr ctxt; 105393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr res, tmp, init = NULL; 105403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int stack = 0; 105413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 105423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathInit(); 105433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 105443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_CONTEXT(ctx) 105453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 105463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ctxt = xmlXPathNewParserContext(str, ctx); 105473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathEvalExpr(ctxt); 105483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 105493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->value == NULL) { 105503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 105513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "xmlXPathEval: evaluation failed\n"); 105523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor res = NULL; 105533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else if (*ctxt->cur != 0) { 105543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPatherror(ctxt, __FILE__, __LINE__, XPATH_EXPR_ERROR); 105553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor res = NULL; 105563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else { 105573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor res = valuePop(ctxt); 105583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 105593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 105603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor do { 105613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor tmp = valuePop(ctxt); 105623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (tmp != NULL) { 105633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (tmp != init) 105643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor stack++; 105653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(tmp); 105663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 105673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } while (tmp != NULL); 105683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((stack != 0) && (res != NULL)) { 105693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 105703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "xmlXPathEval: %d object left on the stack\n", 105713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor stack); 105723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 105733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->error != XPATH_EXPRESSION_OK) { 105743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(res); 105753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor res = NULL; 105763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 105779e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 105783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeParserContext(ctxt); 105793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(res); 105803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 105813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 105823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 105833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathEvalExpression: 105843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @str: the XPath expression 105853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath context 105863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 105873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Evaluate the XPath expression in the given context. 105883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 105893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the xmlXPathObjectPtr resulting from the evaluation or NULL. 105903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the caller has to free the object. 105913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 105923473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathObjectPtr 105933473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathEvalExpression(const xmlChar *str, xmlXPathContextPtr ctxt) { 105943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathParserContextPtr pctxt; 105953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr res, tmp; 105963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int stack = 0; 105973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 105983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathInit(); 105993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 106003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_CONTEXT(ctxt) 106013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 106023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor pctxt = xmlXPathNewParserContext(str, ctxt); 106033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathEvalExpr(pctxt); 106043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 106053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (*pctxt->cur != 0) { 106063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPatherror(pctxt, __FILE__, __LINE__, XPATH_EXPR_ERROR); 106073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor res = NULL; 106083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else { 106093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor res = valuePop(pctxt); 106103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 106113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor do { 106123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor tmp = valuePop(pctxt); 106133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (tmp != NULL) { 106143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(tmp); 106153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor stack++; 106163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 106173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } while (tmp != NULL); 106183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((stack != 0) && (res != NULL)) { 106193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 106203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "xmlXPathEvalExpression: %d object left on the stack\n", 106213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor stack); 106223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 106233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeParserContext(pctxt); 106243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(res); 106253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 106263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 106273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 106283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathRegisterAllFunctions: 106293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath context 106303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 106313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Registers all default XPath functions in this context 106323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 106333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 106343473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathRegisterAllFunctions(xmlXPathContextPtr ctxt) 106353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor{ 106363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisterFunc(ctxt, (const xmlChar *)"boolean", 106373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathBooleanFunction); 106383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisterFunc(ctxt, (const xmlChar *)"ceiling", 106393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathCeilingFunction); 106403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisterFunc(ctxt, (const xmlChar *)"count", 106413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathCountFunction); 106423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisterFunc(ctxt, (const xmlChar *)"concat", 106433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathConcatFunction); 106443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisterFunc(ctxt, (const xmlChar *)"contains", 106453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathContainsFunction); 106463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisterFunc(ctxt, (const xmlChar *)"id", 106473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathIdFunction); 106483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisterFunc(ctxt, (const xmlChar *)"false", 106493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFalseFunction); 106503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisterFunc(ctxt, (const xmlChar *)"floor", 106513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFloorFunction); 106523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisterFunc(ctxt, (const xmlChar *)"last", 106533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathLastFunction); 106543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisterFunc(ctxt, (const xmlChar *)"lang", 106553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathLangFunction); 106563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisterFunc(ctxt, (const xmlChar *)"local-name", 106573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathLocalNameFunction); 106583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisterFunc(ctxt, (const xmlChar *)"not", 106593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathNotFunction); 106603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisterFunc(ctxt, (const xmlChar *)"name", 106613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathNameFunction); 106623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisterFunc(ctxt, (const xmlChar *)"namespace-uri", 106633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathNamespaceURIFunction); 106643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisterFunc(ctxt, (const xmlChar *)"normalize-space", 106653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathNormalizeFunction); 106663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisterFunc(ctxt, (const xmlChar *)"number", 106673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathNumberFunction); 106683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisterFunc(ctxt, (const xmlChar *)"position", 106693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathPositionFunction); 106703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisterFunc(ctxt, (const xmlChar *)"round", 106713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRoundFunction); 106723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisterFunc(ctxt, (const xmlChar *)"string", 106733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathStringFunction); 106743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisterFunc(ctxt, (const xmlChar *)"string-length", 106753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathStringLengthFunction); 106763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisterFunc(ctxt, (const xmlChar *)"starts-with", 106773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathStartsWithFunction); 106783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisterFunc(ctxt, (const xmlChar *)"substring", 106793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathSubstringFunction); 106803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisterFunc(ctxt, (const xmlChar *)"substring-before", 106813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathSubstringBeforeFunction); 106823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisterFunc(ctxt, (const xmlChar *)"substring-after", 106833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathSubstringAfterFunction); 106843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisterFunc(ctxt, (const xmlChar *)"sum", 106853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathSumFunction); 106863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisterFunc(ctxt, (const xmlChar *)"true", 106873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathTrueFunction); 106883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisterFunc(ctxt, (const xmlChar *)"translate", 106893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathTranslateFunction); 106903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 106913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 106923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif /* LIBXML_XPATH_ENABLED */ 10693