xpath.c revision 2bdabbd711356e534940431053523f1538d1a93e
13473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/* 23473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xpath.c: XML Path Language implementation 33473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * XPath is a language for addressing parts of an XML document, 43473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * designed to be used by both XSLT and XPointer 53473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 63473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Reference: W3C Recommendation 16 November 1999 73473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * http://www.w3.org/TR/1999/REC-xpath-19991116 83473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Public reference: 93473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * http://www.w3.org/TR/xpath 103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 11cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * See Copyright for the status of this software 123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 13c5d64345cf19bfd72418eb0a837869b0462e9130Daniel Veillard * Author: daniel@veillard.com 143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1734ce8bece2f22cc99d25221b77315cd008f4866bDaniel Veillard#define IN_LIBXML 1870a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese#include "libxml.h" 193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include <string.h> 213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef HAVE_SYS_TYPES_H 233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include <sys/types.h> 243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef HAVE_MATH_H 263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include <math.h> 273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef HAVE_FLOAT_H 293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include <float.h> 303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef HAVE_CTYPE_H 323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include <ctype.h> 333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 345792e16f0562d206e1ef4e611f7b43ec53c92149Daniel Veillard#ifdef HAVE_SIGNAL_H 35b45c43be206b8c824558269731128c6a64599a54Daniel Veillard#include <signal.h> 36b45c43be206b8c824558269731128c6a64599a54Daniel Veillard#endif 373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include <libxml/xmlmemory.h> 393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include <libxml/tree.h> 403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include <libxml/valid.h> 413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include <libxml/xpath.h> 423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include <libxml/xpathInternals.h> 433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include <libxml/parserInternals.h> 443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include <libxml/hash.h> 453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef LIBXML_XPTR_ENABLED 463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include <libxml/xpointer.h> 473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef LIBXML_DEBUG_ENABLED 493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include <libxml/debugXML.h> 503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include <libxml/xmlerror.h> 528146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard#include <libxml/threads.h> 533c01b1d81b696fe8624b6d7e26ec0ebffcc7c06bDaniel Veillard#include <libxml/globals.h> 5456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard#ifdef LIBXML_PATTERN_ENABLED 5556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard#include <libxml/pattern.h> 5656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard#endif 5756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard 5856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard#ifdef LIBXML_PATTERN_ENABLED 59fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard#define XPATH_STREAMING 6056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard#endif 613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 62d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard#define TODO \ 63d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard xmlGenericError(xmlGenericErrorContext, \ 64d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard "Unimplemented block at %s:%d\n", \ 65d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard __FILE__, __LINE__); 66d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard 67d1757abcb891e01a9017f4aad041cc306d0d467bWilliam M. Brack/* 6897258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik* XP_PATTERN_TO_ANY_NODE_ENABLED: when an XPath expression can be 6997258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik* evaluated using the streaming mode (pattern.c) then this is used to 7097258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik* enable resolution to nodes of type text-node, cdata-section-node, 7197258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik* comment-node and pi-node. The only known scenario where this is 7297258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik* needed is an expression like "foo//.", "//.", etc.; i.e. an expression 7397258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik* where the final node to be selected can be of any type. 7497258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik* Disabling this #define will result in an incorrect evaluation to 7597258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik* only element-nodes and the document node. 7697258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik*/ 7797258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik#define XP_PATTERN_TO_ANY_NODE_ENABLED 782bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik 792bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik/* 802bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik* XP_FAST_NON_ELEM_COMPARISON: 812bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik* If defined, this will use xmlXPathCmpNodesExt() instead of 822bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik* xmlXPathCmpNodes(). The new function is optimized comparison of 832bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik* non-element nodes; actually it will speed up comparison only if 842bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik* xmlXPathOrderDocElems() was called in order to index the elements of 852bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik* a tree in document order; Libxslt does such an indexing, thus it will 862bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik* benefit from this optimization. 872bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik*/ 882bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik#define XP_FAST_NON_ELEM_COMPARISON 8997258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik/* 90d1757abcb891e01a9017f4aad041cc306d0d467bWilliam M. Brack * TODO: 91d1757abcb891e01a9017f4aad041cc306d0d467bWilliam M. Brack * There are a few spots where some tests are done which depend upon ascii 92d1757abcb891e01a9017f4aad041cc306d0d467bWilliam M. Brack * data. These should be enhanced for full UTF8 support (see particularly 93d1757abcb891e01a9017f4aad041cc306d0d467bWilliam M. Brack * any use of the macros IS_ASCII_CHARACTER and IS_ASCII_DIGIT) 94d1757abcb891e01a9017f4aad041cc306d0d467bWilliam M. Brack */ 9597258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik 9621e4ef20f64ebd740ebac0ead5d85a5631d2db5eWilliam M. Brack#if defined(LIBXML_XPATH_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED) 979e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard/************************************************************************ 989e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * * 999e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * Floating point stuff * 1009e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * * 1019e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard ************************************************************************/ 1029e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 103c0631a608f62902eca453096f0b2fc5b449b0b0aDaniel Veillard#ifndef TRIO_REPLACE_STDIO 104cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard#define TRIO_PUBLIC static 105c0631a608f62902eca453096f0b2fc5b449b0b0aDaniel Veillard#endif 106cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard#include "trionan.c" 107cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard 1083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/* 1093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The lack of portability of this section of the libc is annoying ! 1103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 1113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylordouble xmlXPathNAN = 0; 1123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylordouble xmlXPathPINF = 1; 1133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylordouble xmlXPathNINF = -1; 11424505b0f5c872c5afb6da5093565e5a6e09ca541Daniel Veillardstatic double xmlXPathNZERO = 0; /* not exported from headers */ 11520ee8c03107e5d5724765da513d595fdaf290dceDaniel Veillardstatic int xmlXPathInitialized = 0; 1163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 1183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathInit: 1193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 1203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Initialize the XPath environment 1213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 1223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 1233473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathInit(void) { 12420ee8c03107e5d5724765da513d595fdaf290dceDaniel Veillard if (xmlXPathInitialized) return; 1253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 126450296070e14629141738fbb34b9a0ad13af1f02Bjorn Reese xmlXPathPINF = trio_pinf(); 127450296070e14629141738fbb34b9a0ad13af1f02Bjorn Reese xmlXPathNINF = trio_ninf(); 128450296070e14629141738fbb34b9a0ad13af1f02Bjorn Reese xmlXPathNAN = trio_nan(); 1295fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard xmlXPathNZERO = trio_nzero(); 1303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 13120ee8c03107e5d5724765da513d595fdaf290dceDaniel Veillard xmlXPathInitialized = 1; 1323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 1333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 134cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard/** 135cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * xmlXPathIsNaN: 136cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * @val: a double value 137cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * 138cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * Provides a portable isnan() function to detect whether a double 139cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * is a NotaNumber. Based on trio code 140cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * http://sourceforge.net/projects/ctrio/ 141cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * 142cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * Returns 1 if the value is a NaN, 0 otherwise 143cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard */ 144cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillardint 145cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel VeillardxmlXPathIsNaN(double val) { 146cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard return(trio_isnan(val)); 147cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard} 148cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard 149cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard/** 150cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * xmlXPathIsInf: 151cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * @val: a double value 152cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * 153cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * Provides a portable isinf() function to detect whether a double 154cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * is a +Infinite or -Infinite. Based on trio code 155cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * http://sourceforge.net/projects/ctrio/ 156cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * 157cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * Returns 1 vi the value is +Infinite, -1 if -Infinite, 0 otherwise 158cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard */ 159cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillardint 160cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel VeillardxmlXPathIsInf(double val) { 161cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard return(trio_isinf(val)); 162cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard} 163cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard 1644432df239b7aba6bff86c838e0be11d08f283b76Daniel Veillard#endif /* SCHEMAS or XPATH */ 1654432df239b7aba6bff86c838e0be11d08f283b76Daniel Veillard#ifdef LIBXML_XPATH_ENABLED 1665fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard/** 1675fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard * xmlXPathGetSign: 1685fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard * @val: a double value 1695fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard * 1705fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard * Provides a portable function to detect the sign of a double 1715fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard * Modified from trio code 1725fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard * http://sourceforge.net/projects/ctrio/ 1735fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard * 1745fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard * Returns 1 if the value is Negative, 0 if positive 1755fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard */ 17621458c85e209cd2621ac3eadfee075ae2dc0121dDaniel Veillardstatic int 1775fc1f0893af6ffe76453ac16817204a866bdeab2Daniel VeillardxmlXPathGetSign(double val) { 17821458c85e209cd2621ac3eadfee075ae2dc0121dDaniel Veillard return(trio_signbit(val)); 1795fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard} 1805fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard 1815fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard 182d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillard/* 183d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillard * TODO: when compatibility allows remove all "fake node libxslt" strings 184d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillard * the test should just be name[0] = ' ' 185d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillard */ 186d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillard/* #define DEBUG */ 187d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillard/* #define DEBUG_STEP */ 188d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillard/* #define DEBUG_STEP_NTH */ 189d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillard/* #define DEBUG_EXPR */ 190d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillard/* #define DEBUG_EVAL_COUNTS */ 191d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillard 192d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillardstatic xmlNs xmlXPathXMLNamespaceStruct = { 193d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillard NULL, 194d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillard XML_NAMESPACE_DECL, 195d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillard XML_XML_NAMESPACE, 196d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillard BAD_CAST "xml", 197d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillard NULL 198d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillard}; 199d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillardstatic xmlNsPtr xmlXPathXMLNamespace = &xmlXPathXMLNamespaceStruct; 200d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillard#ifndef LIBXML_THREAD_ENABLED 201d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillard/* 202d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillard * Optimizer is disabled only when threaded apps are detected while 203d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillard * the library ain't compiled for thread safety. 204d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillard */ 205d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillardstatic int xmlXPathDisableOptimizer = 0; 206d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillard#endif 207d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillard 2083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/************************************************************************ 209d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard * * 210d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard * Error handling routines * 211d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard * * 212d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard ************************************************************************/ 213d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard 21424505b0f5c872c5afb6da5093565e5a6e09ca541Daniel Veillard/** 21524505b0f5c872c5afb6da5093565e5a6e09ca541Daniel Veillard * XP_ERRORNULL: 21624505b0f5c872c5afb6da5093565e5a6e09ca541Daniel Veillard * @X: the error code 21724505b0f5c872c5afb6da5093565e5a6e09ca541Daniel Veillard * 21824505b0f5c872c5afb6da5093565e5a6e09ca541Daniel Veillard * Macro to raise an XPath error and return NULL. 21924505b0f5c872c5afb6da5093565e5a6e09ca541Daniel Veillard */ 22024505b0f5c872c5afb6da5093565e5a6e09ca541Daniel Veillard#define XP_ERRORNULL(X) \ 22124505b0f5c872c5afb6da5093565e5a6e09ca541Daniel Veillard { xmlXPathErr(ctxt, X); return(NULL); } 22224505b0f5c872c5afb6da5093565e5a6e09ca541Daniel Veillard 223081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack/* 224081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack * The array xmlXPathErrorMessages corresponds to the enum xmlXPathError 225081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack */ 226d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillardstatic const char *xmlXPathErrorMessages[] = { 227d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard "Ok\n", 228d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard "Number encoding\n", 229d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard "Unfinished literal\n", 230d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard "Start of literal\n", 231d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard "Expected $ for variable reference\n", 232d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard "Undefined variable\n", 233d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard "Invalid predicate\n", 234d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard "Invalid expression\n", 235d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard "Missing closing curly brace\n", 236d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard "Unregistered function\n", 237d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard "Invalid operand\n", 238d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard "Invalid type\n", 239d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard "Invalid number of arguments\n", 240d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard "Invalid context size\n", 241d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard "Invalid context position\n", 242d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard "Memory allocation error\n", 243d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard "Syntax error\n", 244d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard "Resource error\n", 245d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard "Sub resource error\n", 246d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard "Undefined namespace prefix\n", 247d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard "Encoding error\n", 24857b2516af5e2e06c54750b6549723cf5b8edf8a4Daniel Veillard "Char out of XML range\n", 249cd65bc9a49b406899c78e9e8f6757acca54fc04eWilliam M. Brack "Invalid or incomplete context\n", 250cd65bc9a49b406899c78e9e8f6757acca54fc04eWilliam M. Brack "?? Unknown error ??\n" /* Must be last in the list! */ 251d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard}; 252cd65bc9a49b406899c78e9e8f6757acca54fc04eWilliam M. Brack#define MAXERRNO ((int)(sizeof(xmlXPathErrorMessages) / \ 253cd65bc9a49b406899c78e9e8f6757acca54fc04eWilliam M. Brack sizeof(xmlXPathErrorMessages[0])) - 1) 254d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard/** 255d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard * xmlXPathErrMemory: 256d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard * @ctxt: an XPath context 257d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard * @extra: extra informations 258d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard * 259d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard * Handle a redefinition of attribute error 260d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard */ 261d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillardstatic void 262d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel VeillardxmlXPathErrMemory(xmlXPathContextPtr ctxt, const char *extra) 263d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard{ 264d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard if (ctxt != NULL) { 265d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard if (extra) { 266d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard xmlChar buf[200]; 267d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard 268d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard xmlStrPrintf(buf, 200, 269d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard BAD_CAST "Memory allocation failed : %s\n", 270d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard extra); 271d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard ctxt->lastError.message = (char *) xmlStrdup(buf); 272d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard } else { 273d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard ctxt->lastError.message = (char *) 274d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard xmlStrdup(BAD_CAST "Memory allocation failed\n"); 275d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard } 276d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard ctxt->lastError.domain = XML_FROM_XPATH; 277d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard ctxt->lastError.code = XML_ERR_NO_MEMORY; 278d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard if (ctxt->error != NULL) 279d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard ctxt->error(ctxt->userData, &ctxt->lastError); 280d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard } else { 281d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard if (extra) 282659e71ec2476d24bfca0d6432a69ef9a49a62be4Daniel Veillard __xmlRaiseError(NULL, NULL, NULL, 283d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard NULL, NULL, XML_FROM_XPATH, 284d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard XML_ERR_NO_MEMORY, XML_ERR_FATAL, NULL, 0, 285d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard extra, NULL, NULL, 0, 0, 286d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard "Memory allocation failed : %s\n", extra); 287d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard else 288659e71ec2476d24bfca0d6432a69ef9a49a62be4Daniel Veillard __xmlRaiseError(NULL, NULL, NULL, 289d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard NULL, NULL, XML_FROM_XPATH, 290d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard XML_ERR_NO_MEMORY, XML_ERR_FATAL, NULL, 0, 291d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard NULL, NULL, NULL, 0, 0, 292d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard "Memory allocation failed\n"); 293d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard } 294d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard} 295d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard 296d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard/** 2978de5c0bd79cceeca3d55d6dbf8f0248b7239e050Daniel Veillard * xmlXPathPErrMemory: 298d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard * @ctxt: an XPath parser context 299d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard * @extra: extra informations 300d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard * 301d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard * Handle a redefinition of attribute error 302d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard */ 303d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillardstatic void 304d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel VeillardxmlXPathPErrMemory(xmlXPathParserContextPtr ctxt, const char *extra) 305d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard{ 306d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard if (ctxt == NULL) 307d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard xmlXPathErrMemory(NULL, extra); 30811ce4004d86bb4b317c48b7d5124ba33e40e10f5Daniel Veillard else { 30911ce4004d86bb4b317c48b7d5124ba33e40e10f5Daniel Veillard ctxt->error = XPATH_MEMORY_ERROR; 310d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard xmlXPathErrMemory(ctxt->context, extra); 31111ce4004d86bb4b317c48b7d5124ba33e40e10f5Daniel Veillard } 312d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard} 313d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard 314d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard/** 315d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard * xmlXPathErr: 316d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard * @ctxt: a XPath parser context 317d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard * @error: the error code 318d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard * 319cd65bc9a49b406899c78e9e8f6757acca54fc04eWilliam M. Brack * Handle an XPath error 320d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard */ 321d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillardvoid 322d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel VeillardxmlXPathErr(xmlXPathParserContextPtr ctxt, int error) 323d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard{ 324cd65bc9a49b406899c78e9e8f6757acca54fc04eWilliam M. Brack if ((error < 0) || (error > MAXERRNO)) 325cd65bc9a49b406899c78e9e8f6757acca54fc04eWilliam M. Brack error = MAXERRNO; 326f88d8cf9f1c9538dba187290ad5add003dc22bc7Daniel Veillard if (ctxt == NULL) { 327659e71ec2476d24bfca0d6432a69ef9a49a62be4Daniel Veillard __xmlRaiseError(NULL, NULL, NULL, 328d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard NULL, NULL, XML_FROM_XPATH, 329d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard error + XML_XPATH_EXPRESSION_OK - XPATH_EXPRESSION_OK, 330d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard XML_ERR_ERROR, NULL, 0, 331d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard NULL, NULL, NULL, 0, 0, 332d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard xmlXPathErrorMessages[error]); 333d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard return; 334d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard } 335f88d8cf9f1c9538dba187290ad5add003dc22bc7Daniel Veillard ctxt->error = error; 336f88d8cf9f1c9538dba187290ad5add003dc22bc7Daniel Veillard if (ctxt->context == NULL) { 337f88d8cf9f1c9538dba187290ad5add003dc22bc7Daniel Veillard __xmlRaiseError(NULL, NULL, NULL, 338f88d8cf9f1c9538dba187290ad5add003dc22bc7Daniel Veillard NULL, NULL, XML_FROM_XPATH, 339f88d8cf9f1c9538dba187290ad5add003dc22bc7Daniel Veillard error + XML_XPATH_EXPRESSION_OK - XPATH_EXPRESSION_OK, 340f88d8cf9f1c9538dba187290ad5add003dc22bc7Daniel Veillard XML_ERR_ERROR, NULL, 0, 341f88d8cf9f1c9538dba187290ad5add003dc22bc7Daniel Veillard (const char *) ctxt->base, NULL, NULL, 342f88d8cf9f1c9538dba187290ad5add003dc22bc7Daniel Veillard ctxt->cur - ctxt->base, 0, 343f88d8cf9f1c9538dba187290ad5add003dc22bc7Daniel Veillard xmlXPathErrorMessages[error]); 344f88d8cf9f1c9538dba187290ad5add003dc22bc7Daniel Veillard return; 345f88d8cf9f1c9538dba187290ad5add003dc22bc7Daniel Veillard } 346d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard ctxt->context->lastError.domain = XML_FROM_XPATH; 347d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard ctxt->context->lastError.code = error + XML_XPATH_EXPRESSION_OK - 348d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard XPATH_EXPRESSION_OK; 349fcf719ce0a94f0d438f69b73cd1ca31a7000da81Daniel Veillard ctxt->context->lastError.level = XML_ERR_ERROR; 350d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard ctxt->context->lastError.str1 = (char *) xmlStrdup(ctxt->base); 351d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard ctxt->context->lastError.int1 = ctxt->cur - ctxt->base; 352d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard ctxt->context->lastError.node = ctxt->context->debugNode; 353d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard if (ctxt->context->error != NULL) { 354d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard ctxt->context->error(ctxt->context->userData, 355d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard &ctxt->context->lastError); 356d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard } else { 357659e71ec2476d24bfca0d6432a69ef9a49a62be4Daniel Veillard __xmlRaiseError(NULL, NULL, NULL, 358d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard NULL, ctxt->context->debugNode, XML_FROM_XPATH, 359d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard error + XML_XPATH_EXPRESSION_OK - XPATH_EXPRESSION_OK, 360d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard XML_ERR_ERROR, NULL, 0, 361d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard (const char *) ctxt->base, NULL, NULL, 362d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard ctxt->cur - ctxt->base, 0, 363d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard xmlXPathErrorMessages[error]); 364d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard } 365d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard 366d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard} 367d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard 368d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard/** 369d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard * xmlXPatherror: 370d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard * @ctxt: the XPath Parser context 371d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard * @file: the file name 372d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard * @line: the line number 373d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard * @no: the error number 374d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard * 375d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard * Formats an error message. 376d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard */ 377d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillardvoid 378d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel VeillardxmlXPatherror(xmlXPathParserContextPtr ctxt, const char *file ATTRIBUTE_UNUSED, 379d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard int line ATTRIBUTE_UNUSED, int no) { 380d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard xmlXPathErr(ctxt, no); 381d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard} 382d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard 383d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard 384d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard/************************************************************************ 3859e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * * 3869e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * Parser Types * 3879e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * * 3889e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard ************************************************************************/ 3899e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 3909e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard/* 3919e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * Types are private: 3929e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard */ 3939e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 3949e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillardtypedef enum { 3959e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard XPATH_OP_END=0, 3969e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard XPATH_OP_AND, 3979e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard XPATH_OP_OR, 3989e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard XPATH_OP_EQUAL, 3999e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard XPATH_OP_CMP, 4009e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard XPATH_OP_PLUS, 4019e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard XPATH_OP_MULT, 4029e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard XPATH_OP_UNION, 4039e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard XPATH_OP_ROOT, 4049e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard XPATH_OP_NODE, 4059e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard XPATH_OP_RESET, 4069e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard XPATH_OP_COLLECT, 4079e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard XPATH_OP_VALUE, 4089e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard XPATH_OP_VARIABLE, 4099e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard XPATH_OP_FUNCTION, 4109e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard XPATH_OP_ARG, 4119e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard XPATH_OP_PREDICATE, 412d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard XPATH_OP_FILTER, 4139e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard XPATH_OP_SORT 4149e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard#ifdef LIBXML_XPTR_ENABLED 4159e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard ,XPATH_OP_RANGETO 4169e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard#endif 4179e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard} xmlXPathOp; 4189e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 4199e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillardtypedef enum { 4209e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard AXIS_ANCESTOR = 1, 4219e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard AXIS_ANCESTOR_OR_SELF, 4229e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard AXIS_ATTRIBUTE, 4239e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard AXIS_CHILD, 4249e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard AXIS_DESCENDANT, 4259e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard AXIS_DESCENDANT_OR_SELF, 4269e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard AXIS_FOLLOWING, 4279e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard AXIS_FOLLOWING_SIBLING, 4289e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard AXIS_NAMESPACE, 4299e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard AXIS_PARENT, 4309e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard AXIS_PRECEDING, 4319e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard AXIS_PRECEDING_SIBLING, 4329e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard AXIS_SELF 4339e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard} xmlXPathAxisVal; 4349e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 4359e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillardtypedef enum { 4369e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard NODE_TEST_NONE = 0, 4379e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard NODE_TEST_TYPE = 1, 4389e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard NODE_TEST_PI = 2, 4399e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard NODE_TEST_ALL = 3, 4409e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard NODE_TEST_NS = 4, 4419e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard NODE_TEST_NAME = 5 4429e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard} xmlXPathTestVal; 4439e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 4449e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillardtypedef enum { 4459e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard NODE_TYPE_NODE = 0, 4469e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard NODE_TYPE_COMMENT = XML_COMMENT_NODE, 4479e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard NODE_TYPE_TEXT = XML_TEXT_NODE, 4489e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard NODE_TYPE_PI = XML_PI_NODE 4499e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard} xmlXPathTypeVal; 4509e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 4519e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 4529e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillardtypedef struct _xmlXPathStepOp xmlXPathStepOp; 4539e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillardtypedef xmlXPathStepOp *xmlXPathStepOpPtr; 4549e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillardstruct _xmlXPathStepOp { 455081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack xmlXPathOp op; /* The identifier of the operation */ 456081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack int ch1; /* First child */ 457081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack int ch2; /* Second child */ 4589e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard int value; 4599e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard int value2; 4609e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard int value3; 4619e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard void *value4; 4629e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard void *value5; 463e39a93d0d3df9907cf3538cd3f1fbbe4106e893dDaniel Veillard void *cache; 46442596ad20cdf1925dd79ea801cbe598b6e7b7aecDaniel Veillard void *cacheURI; 4659e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard}; 4669e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 4679e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillardstruct _xmlXPathCompExpr { 468081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack int nbStep; /* Number of steps in this expression */ 469081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack int maxStep; /* Maximum number of steps allocated */ 470081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack xmlXPathStepOp *steps; /* ops for computation of this expression */ 471081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack int last; /* index of last step in expression */ 472081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack xmlChar *expr; /* the expression being computed */ 4734773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard xmlDictPtr dict; /* the dictionnary to use if any */ 474f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#ifdef DEBUG_EVAL_COUNTS 475f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard int nb; 476f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlChar *string; 477f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#endif 47856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard#ifdef XPATH_STREAMING 47956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard xmlPatternPtr stream; 48056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard#endif 4819e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard}; 4829e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 4839e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard/************************************************************************ 4849e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * * 4859e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * Parser Type functions * 4869e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * * 4879e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard ************************************************************************/ 4889e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 4899e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard/** 4909e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * xmlXPathNewCompExpr: 4919e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * 4929e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * Create a new Xpath component 4939e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * 4949e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * Returns the newly allocated xmlXPathCompExprPtr or NULL in case of error 4959e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard */ 49656a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic xmlXPathCompExprPtr 4979e7160d45a18bfa26d708e22ba991f7670d0128bDaniel VeillardxmlXPathNewCompExpr(void) { 4989e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlXPathCompExprPtr cur; 4999e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 5009e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard cur = (xmlXPathCompExprPtr) xmlMalloc(sizeof(xmlXPathCompExpr)); 5019e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (cur == NULL) { 502d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard xmlXPathErrMemory(NULL, "allocating component\n"); 5039e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard return(NULL); 5049e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } 5059e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard memset(cur, 0, sizeof(xmlXPathCompExpr)); 5069e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard cur->maxStep = 10; 5079e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard cur->nbStep = 0; 5089e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard cur->steps = (xmlXPathStepOp *) xmlMalloc(cur->maxStep * 5099e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard sizeof(xmlXPathStepOp)); 5109e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (cur->steps == NULL) { 511d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard xmlXPathErrMemory(NULL, "allocating steps\n"); 5129e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlFree(cur); 5139e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard return(NULL); 5149e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } 5159e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard memset(cur->steps, 0, cur->maxStep * sizeof(xmlXPathStepOp)); 5169e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard cur->last = -1; 517f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#ifdef DEBUG_EVAL_COUNTS 518f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard cur->nb = 0; 519f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#endif 5209e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard return(cur); 5219e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard} 5229e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 5239e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard/** 5249e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * xmlXPathFreeCompExpr: 5259e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * @comp: an XPATH comp 5269e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * 5279e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * Free up the memory allocated by @comp 5289e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard */ 5299e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillardvoid 530f06307e2c172284bb41376c396f757bdac9bdd19Daniel VeillardxmlXPathFreeCompExpr(xmlXPathCompExprPtr comp) 531f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard{ 5329e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlXPathStepOpPtr op; 5339e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard int i; 5349e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 5359e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (comp == NULL) 536f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return; 5374773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard if (comp->dict == NULL) { 5384773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard for (i = 0; i < comp->nbStep; i++) { 5394773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard op = &comp->steps[i]; 5404773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard if (op->value4 != NULL) { 5414773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard if (op->op == XPATH_OP_VALUE) 5424773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard xmlXPathFreeObject(op->value4); 5434773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard else 5444773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard xmlFree(op->value4); 5454773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard } 5464773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard if (op->value5 != NULL) 5474773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard xmlFree(op->value5); 5484773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard } 5494773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard } else { 5504773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard for (i = 0; i < comp->nbStep; i++) { 5514773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard op = &comp->steps[i]; 5524773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard if (op->value4 != NULL) { 5534773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard if (op->op == XPATH_OP_VALUE) 5544773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard xmlXPathFreeObject(op->value4); 5554773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard } 5564773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard } 5574773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard xmlDictFree(comp->dict); 5589e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } 5599e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (comp->steps != NULL) { 560f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlFree(comp->steps); 5619e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } 562f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#ifdef DEBUG_EVAL_COUNTS 563f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (comp->string != NULL) { 564f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlFree(comp->string); 565f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 566f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#endif 56756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard#ifdef XPATH_STREAMING 56856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard if (comp->stream != NULL) { 56956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard xmlFreePatternList(comp->stream); 57056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard } 57156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard#endif 572118aed78f360f51d182770e62b251ef324707aa2Daniel Veillard if (comp->expr != NULL) { 573118aed78f360f51d182770e62b251ef324707aa2Daniel Veillard xmlFree(comp->expr); 574118aed78f360f51d182770e62b251ef324707aa2Daniel Veillard } 575f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 5769e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlFree(comp); 5779e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard} 5789e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 5799e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard/** 5809e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * xmlXPathCompExprAdd: 5819e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * @comp: the compiled expression 5829e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * @ch1: first child index 5839e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * @ch2: second child index 5849e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * @op: an op 5859e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * @value: the first int value 5869e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * @value2: the second int value 5879e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * @value3: the third int value 5889e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * @value4: the first string value 5899e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * @value5: the second string value 5909e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * 591081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack * Add a step to an XPath Compiled Expression 5929e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * 5939e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * Returns -1 in case of failure, the index otherwise 5949e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard */ 59556a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic int 5969e7160d45a18bfa26d708e22ba991f7670d0128bDaniel VeillardxmlXPathCompExprAdd(xmlXPathCompExprPtr comp, int ch1, int ch2, 5979e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlXPathOp op, int value, 5989e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard int value2, int value3, void *value4, void *value5) { 5999e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (comp->nbStep >= comp->maxStep) { 6009e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlXPathStepOp *real; 6019e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 6029e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard comp->maxStep *= 2; 6039e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard real = (xmlXPathStepOp *) xmlRealloc(comp->steps, 6049e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard comp->maxStep * sizeof(xmlXPathStepOp)); 6059e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (real == NULL) { 6069e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard comp->maxStep /= 2; 607d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard xmlXPathErrMemory(NULL, "adding step\n"); 6089e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard return(-1); 6099e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } 6109e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard comp->steps = real; 6119e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } 6129e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard comp->last = comp->nbStep; 6139e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard comp->steps[comp->nbStep].ch1 = ch1; 6149e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard comp->steps[comp->nbStep].ch2 = ch2; 6159e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard comp->steps[comp->nbStep].op = op; 6169e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard comp->steps[comp->nbStep].value = value; 6179e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard comp->steps[comp->nbStep].value2 = value2; 6189e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard comp->steps[comp->nbStep].value3 = value3; 6194773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard if ((comp->dict != NULL) && 6204773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard ((op == XPATH_OP_FUNCTION) || (op == XPATH_OP_VARIABLE) || 6214773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard (op == XPATH_OP_COLLECT))) { 6224773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard if (value4 != NULL) { 623b337795500cbe3fc47ac2b81f3d955126c6fbfdeDaniel Veillard comp->steps[comp->nbStep].value4 = (xmlChar *) 624c07ed5e6a14fb801cfd6bbb2a582caf726e5324eWilliam M. Brack (void *)xmlDictLookup(comp->dict, value4, -1); 6254773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard xmlFree(value4); 6264773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard } else 6274773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard comp->steps[comp->nbStep].value4 = NULL; 6284773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard if (value5 != NULL) { 629b337795500cbe3fc47ac2b81f3d955126c6fbfdeDaniel Veillard comp->steps[comp->nbStep].value5 = (xmlChar *) 630c07ed5e6a14fb801cfd6bbb2a582caf726e5324eWilliam M. Brack (void *)xmlDictLookup(comp->dict, value5, -1); 6314773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard xmlFree(value5); 6324773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard } else 6334773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard comp->steps[comp->nbStep].value5 = NULL; 6344773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard } else { 6354773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard comp->steps[comp->nbStep].value4 = value4; 6364773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard comp->steps[comp->nbStep].value5 = value5; 6374773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard } 638e39a93d0d3df9907cf3538cd3f1fbbe4106e893dDaniel Veillard comp->steps[comp->nbStep].cache = NULL; 6399e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard return(comp->nbStep++); 6409e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard} 6419e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 642f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard/** 643f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * xmlXPathCompSwap: 644f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * @comp: the compiled expression 645f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * @op: operation index 646f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * 647f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Swaps 2 operations in the compiled expression 648f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 649f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillardstatic void 650f06307e2c172284bb41376c396f757bdac9bdd19Daniel VeillardxmlXPathCompSwap(xmlXPathStepOpPtr op) { 651f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard int tmp; 652f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 653bc6f759ac9b41773e3643ad288b5214732051c98Daniel Veillard#ifndef LIBXML_THREAD_ENABLED 6548146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard /* 6558146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard * Since this manipulates possibly shared variables, this is 656081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack * disabled if one detects that the library is used in a multithreaded 6578146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard * application 6588146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard */ 6598146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard if (xmlXPathDisableOptimizer) 6608146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard return; 6618146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard#endif 6628146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard 663f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard tmp = op->ch1; 664f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard op->ch1 = op->ch2; 665f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard op->ch2 = tmp; 666f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard} 667f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 668d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#define PUSH_FULL_EXPR(op, op1, op2, val, val2, val3, val4, val5) \ 669d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard xmlXPathCompExprAdd(ctxt->comp, (op1), (op2), \ 670d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard (op), (val), (val2), (val3), (val4), (val5)) 6719e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard#define PUSH_LONG_EXPR(op, val, val2, val3, val4, val5) \ 6729e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlXPathCompExprAdd(ctxt->comp, ctxt->comp->last, -1, \ 6739e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard (op), (val), (val2), (val3), (val4), (val5)) 6749e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 6759e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard#define PUSH_LEAVE_EXPR(op, val, val2) \ 6769e7160d45a18bfa26d708e22ba991f7670d0128bDaniel VeillardxmlXPathCompExprAdd(ctxt->comp, -1, -1, (op), (val), (val2), 0 ,NULL ,NULL) 6779e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 6789e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard#define PUSH_UNARY_EXPR(op, ch, val, val2) \ 6799e7160d45a18bfa26d708e22ba991f7670d0128bDaniel VeillardxmlXPathCompExprAdd(ctxt->comp, (ch), -1, (op), (val), (val2), 0 ,NULL ,NULL) 6809e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 6819e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard#define PUSH_BINARY_EXPR(op, ch1, ch2, val, val2) \ 682081719182de3d15e6a438f32fdc3d1ca240a08e8William M. BrackxmlXPathCompExprAdd(ctxt->comp, (ch1), (ch2), (op), \ 683081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack (val), (val2), 0 ,NULL ,NULL) 6849e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 6859e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard/************************************************************************ 6863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * * 6873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Debugging related functions * 6883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * * 6893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ************************************************************************/ 6903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 6913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define STRANGE \ 6923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, \ 6933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "Internal error at %s:%d\n", \ 6943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor __FILE__, __LINE__); 6953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 6963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef LIBXML_DEBUG_ENABLED 69756a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic void 69856a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel VeillardxmlXPathDebugDumpNode(FILE *output, xmlNodePtr cur, int depth) { 6993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int i; 7003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor char shift[100]; 7013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 7023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor for (i = 0;((i < depth) && (i < 25));i++) 7033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor shift[2 * i] = shift[2 * i + 1] = ' '; 7043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor shift[2 * i] = shift[2 * i + 1] = 0; 7053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == NULL) { 7063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, shift); 7073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, "Node is NULL !\n"); 7083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return; 7093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 7103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 7113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 7123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((cur->type == XML_DOCUMENT_NODE) || 7133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor (cur->type == XML_HTML_DOCUMENT_NODE)) { 7143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, shift); 7153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, " /\n"); 7163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else if (cur->type == XML_ATTRIBUTE_NODE) 7173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlDebugDumpAttr(output, (xmlAttrPtr)cur, depth); 7183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else 7193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlDebugDumpOneNode(output, cur, depth); 7203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 72156a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic void 72256a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel VeillardxmlXPathDebugDumpNodeList(FILE *output, xmlNodePtr cur, int depth) { 723f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard xmlNodePtr tmp; 724f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard int i; 725f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard char shift[100]; 726f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard 727f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard for (i = 0;((i < depth) && (i < 25));i++) 728f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard shift[2 * i] = shift[2 * i + 1] = ' '; 729f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard shift[2 * i] = shift[2 * i + 1] = 0; 730f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard if (cur == NULL) { 731f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard fprintf(output, shift); 732f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard fprintf(output, "Node is NULL !\n"); 733f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard return; 734f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard 735f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard } 736f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard 737f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard while (cur != NULL) { 738f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard tmp = cur; 739f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard cur = cur->next; 740f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard xmlDebugDumpOneNode(output, tmp, depth); 741f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard } 742f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard} 7433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 74456a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic void 74556a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel VeillardxmlXPathDebugDumpNodeSet(FILE *output, xmlNodeSetPtr cur, int depth) { 7463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int i; 7473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor char shift[100]; 7483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 7493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor for (i = 0;((i < depth) && (i < 25));i++) 7503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor shift[2 * i] = shift[2 * i + 1] = ' '; 7513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor shift[2 * i] = shift[2 * i + 1] = 0; 7523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 7533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == NULL) { 7543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, shift); 7553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, "NodeSet is NULL !\n"); 7563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return; 7573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 7583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 7593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 760911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard if (cur != NULL) { 761911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard fprintf(output, "Set contains %d nodes:\n", cur->nodeNr); 762911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard for (i = 0;i < cur->nodeNr;i++) { 763911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard fprintf(output, shift); 764911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard fprintf(output, "%d", i + 1); 765911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard xmlXPathDebugDumpNode(output, cur->nodeTab[i], depth + 1); 766911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard } 7673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 7683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 7693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 77056a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic void 77156a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel VeillardxmlXPathDebugDumpValueTree(FILE *output, xmlNodeSetPtr cur, int depth) { 772f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard int i; 773f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard char shift[100]; 774f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard 775f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard for (i = 0;((i < depth) && (i < 25));i++) 776f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard shift[2 * i] = shift[2 * i + 1] = ' '; 777f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard shift[2 * i] = shift[2 * i + 1] = 0; 778f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard 779f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard if ((cur == NULL) || (cur->nodeNr == 0) || (cur->nodeTab[0] == NULL)) { 780f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard fprintf(output, shift); 781f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard fprintf(output, "Value Tree is NULL !\n"); 782f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard return; 783f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard 784f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard } 785f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard 786f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard fprintf(output, shift); 787f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard fprintf(output, "%d", i + 1); 788f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard xmlXPathDebugDumpNodeList(output, cur->nodeTab[0]->children, depth + 1); 789f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard} 7903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#if defined(LIBXML_XPTR_ENABLED) 79156a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic void 79256a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel VeillardxmlXPathDebugDumpLocationSet(FILE *output, xmlLocationSetPtr cur, int depth) { 7933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int i; 7943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor char shift[100]; 7953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 7963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor for (i = 0;((i < depth) && (i < 25));i++) 7973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor shift[2 * i] = shift[2 * i + 1] = ' '; 7983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor shift[2 * i] = shift[2 * i + 1] = 0; 7993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 8003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == NULL) { 8013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, shift); 8023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, "LocationSet is NULL !\n"); 8033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return; 8043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 8053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 8063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 8073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor for (i = 0;i < cur->locNr;i++) { 8083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, shift); 8093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, "%d : ", i + 1); 8103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathDebugDumpObject(output, cur->locTab[i], depth + 1); 8113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 8123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 813017b108fcf16dbce05ca7ebd75763f3d888abb5fDaniel Veillard#endif /* LIBXML_XPTR_ENABLED */ 8143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 815afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard/** 816afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathDebugDumpObject: 817afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * @output: the FILE * to dump the output 818afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * @cur: the object to inspect 819afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * @depth: indentation level 820afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * 821afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Dump the content of the object for debugging purposes 822afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard */ 823afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardvoid 824afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathDebugDumpObject(FILE *output, xmlXPathObjectPtr cur, int depth) { 8253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int i; 8263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor char shift[100]; 8273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 828a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard if (output == NULL) return; 829a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard 8303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor for (i = 0;((i < depth) && (i < 25));i++) 8313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor shift[2 * i] = shift[2 * i + 1] = ' '; 8323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor shift[2 * i] = shift[2 * i + 1] = 0; 8333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 83497258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik 83597258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik fprintf(output, shift); 8363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 8373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == NULL) { 8383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, "Object is empty (NULL)\n"); 8393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return; 8403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 8413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor switch(cur->type) { 8423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_UNDEFINED: 8433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, "Object is uninitialized\n"); 8443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 8453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_NODESET: 8463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, "Object is a Node Set :\n"); 8473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathDebugDumpNodeSet(output, cur->nodesetval, depth); 8483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 8493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_XSLT_TREE: 8503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, "Object is an XSLT value tree :\n"); 851f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard xmlXPathDebugDumpValueTree(output, cur->nodesetval, depth); 8523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 8533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_BOOLEAN: 8543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, "Object is a Boolean : "); 8553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur->boolval) fprintf(output, "true\n"); 8563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else fprintf(output, "false\n"); 8573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 8583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_NUMBER: 859cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard switch (xmlXPathIsInf(cur->floatval)) { 860357c960e4035ee2fb40d0072bb7bde4533be76f8Daniel Veillard case 1: 8615fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard fprintf(output, "Object is a number : Infinity\n"); 862357c960e4035ee2fb40d0072bb7bde4533be76f8Daniel Veillard break; 863357c960e4035ee2fb40d0072bb7bde4533be76f8Daniel Veillard case -1: 864357c960e4035ee2fb40d0072bb7bde4533be76f8Daniel Veillard fprintf(output, "Object is a number : -Infinity\n"); 865357c960e4035ee2fb40d0072bb7bde4533be76f8Daniel Veillard break; 866357c960e4035ee2fb40d0072bb7bde4533be76f8Daniel Veillard default: 867cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard if (xmlXPathIsNaN(cur->floatval)) { 868357c960e4035ee2fb40d0072bb7bde4533be76f8Daniel Veillard fprintf(output, "Object is a number : NaN\n"); 869d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard } else if (cur->floatval == 0 && xmlXPathGetSign(cur->floatval) != 0) { 870d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard fprintf(output, "Object is a number : 0\n"); 871357c960e4035ee2fb40d0072bb7bde4533be76f8Daniel Veillard } else { 872357c960e4035ee2fb40d0072bb7bde4533be76f8Daniel Veillard fprintf(output, "Object is a number : %0g\n", cur->floatval); 873357c960e4035ee2fb40d0072bb7bde4533be76f8Daniel Veillard } 874357c960e4035ee2fb40d0072bb7bde4533be76f8Daniel Veillard } 8753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 8763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_STRING: 8773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, "Object is a string : "); 8783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlDebugDumpString(output, cur->stringval); 8793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, "\n"); 8803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 8813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_POINT: 8823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, "Object is a point : index %d in node", cur->index); 8833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathDebugDumpNode(output, (xmlNodePtr) cur->user, depth + 1); 8843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, "\n"); 8853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 8863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_RANGE: 8873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((cur->user2 == NULL) || 8883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ((cur->user2 == cur->user) && (cur->index == cur->index2))) { 8893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, "Object is a collapsed range :\n"); 8903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, shift); 8913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur->index >= 0) 8923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, "index %d in ", cur->index); 8933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, "node\n"); 8943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathDebugDumpNode(output, (xmlNodePtr) cur->user, 8953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor depth + 1); 8963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else { 8973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, "Object is a range :\n"); 8983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, shift); 8993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, "From "); 9003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur->index >= 0) 9013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, "index %d in ", cur->index); 9023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, "node\n"); 9033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathDebugDumpNode(output, (xmlNodePtr) cur->user, 9043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor depth + 1); 9053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, shift); 9063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, "To "); 9073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur->index2 >= 0) 9083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, "index %d in ", cur->index2); 9093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, "node\n"); 9103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathDebugDumpNode(output, (xmlNodePtr) cur->user2, 9113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor depth + 1); 9123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, "\n"); 9133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 9143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 9153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_LOCATIONSET: 9163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#if defined(LIBXML_XPTR_ENABLED) 9173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, "Object is a Location Set:\n"); 9183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathDebugDumpLocationSet(output, 9193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor (xmlLocationSetPtr) cur->user, depth); 9203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 9213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 9223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_USERS: 9233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, "Object is user defined\n"); 9243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 9253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 9263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 9279e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 92856a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic void 92956a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel VeillardxmlXPathDebugDumpStepOp(FILE *output, xmlXPathCompExprPtr comp, 9309e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlXPathStepOpPtr op, int depth) { 9319e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard int i; 9329e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard char shift[100]; 9339e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 9349e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard for (i = 0;((i < depth) && (i < 25));i++) 9359e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard shift[2 * i] = shift[2 * i + 1] = ' '; 9369e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard shift[2 * i] = shift[2 * i + 1] = 0; 9379e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 9389e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, shift); 9399e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (op == NULL) { 9409e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "Step is NULL\n"); 9419e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard return; 9429e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } 9439e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard switch (op->op) { 9449e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case XPATH_OP_END: 9459e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "END"); break; 9469e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case XPATH_OP_AND: 9479e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "AND"); break; 9489e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case XPATH_OP_OR: 9499e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "OR"); break; 9509e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case XPATH_OP_EQUAL: 9519e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (op->value) 9529e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "EQUAL ="); 9539e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard else 9549e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "EQUAL !="); 9559e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard break; 9569e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case XPATH_OP_CMP: 9579e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (op->value) 9589e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "CMP <"); 9599e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard else 9609e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "CMP >"); 9619e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (!op->value2) 9629e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "="); 9639e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard break; 9649e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case XPATH_OP_PLUS: 9659e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (op->value == 0) 9669e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "PLUS -"); 9679e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard else if (op->value == 1) 9689e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "PLUS +"); 9699e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard else if (op->value == 2) 9709e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "PLUS unary -"); 9719e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard else if (op->value == 3) 9729e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "PLUS unary - -"); 9739e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard break; 9749e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case XPATH_OP_MULT: 9759e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (op->value == 0) 9769e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "MULT *"); 9779e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard else if (op->value == 1) 9789e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "MULT div"); 9799e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard else 9809e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "MULT mod"); 9819e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard break; 9829e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case XPATH_OP_UNION: 9839e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "UNION"); break; 9849e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case XPATH_OP_ROOT: 9859e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "ROOT"); break; 9869e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case XPATH_OP_NODE: 9879e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "NODE"); break; 9889e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case XPATH_OP_RESET: 9899e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "RESET"); break; 9909e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case XPATH_OP_SORT: 9919e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "SORT"); break; 9929e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case XPATH_OP_COLLECT: { 99378637da0ea1c833dfdfad87a9aa5bea14510d08aWilliam M. Brack xmlXPathAxisVal axis = (xmlXPathAxisVal)op->value; 99478637da0ea1c833dfdfad87a9aa5bea14510d08aWilliam M. Brack xmlXPathTestVal test = (xmlXPathTestVal)op->value2; 99578637da0ea1c833dfdfad87a9aa5bea14510d08aWilliam M. Brack xmlXPathTypeVal type = (xmlXPathTypeVal)op->value3; 9969e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard const xmlChar *prefix = op->value4; 9979e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard const xmlChar *name = op->value5; 9989e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 9999e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "COLLECT "); 10009e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard switch (axis) { 10019e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case AXIS_ANCESTOR: 10029e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, " 'ancestors' "); break; 10039e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case AXIS_ANCESTOR_OR_SELF: 10049e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, " 'ancestors-or-self' "); break; 10059e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case AXIS_ATTRIBUTE: 10069e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, " 'attributes' "); break; 10079e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case AXIS_CHILD: 10089e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, " 'child' "); break; 10099e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case AXIS_DESCENDANT: 10109e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, " 'descendant' "); break; 10119e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case AXIS_DESCENDANT_OR_SELF: 10129e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, " 'descendant-or-self' "); break; 10139e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case AXIS_FOLLOWING: 10149e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, " 'following' "); break; 10159e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case AXIS_FOLLOWING_SIBLING: 10169e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, " 'following-siblings' "); break; 10179e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case AXIS_NAMESPACE: 10189e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, " 'namespace' "); break; 10199e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case AXIS_PARENT: 10209e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, " 'parent' "); break; 10219e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case AXIS_PRECEDING: 10229e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, " 'preceding' "); break; 10239e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case AXIS_PRECEDING_SIBLING: 10249e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, " 'preceding-sibling' "); break; 10259e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case AXIS_SELF: 10269e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, " 'self' "); break; 10279e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } 10289e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard switch (test) { 10299e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case NODE_TEST_NONE: 10309e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "'none' "); break; 10319e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case NODE_TEST_TYPE: 10329e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "'type' "); break; 10339e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case NODE_TEST_PI: 10349e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "'PI' "); break; 10359e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case NODE_TEST_ALL: 10369e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "'all' "); break; 10379e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case NODE_TEST_NS: 10389e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "'namespace' "); break; 10399e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case NODE_TEST_NAME: 10409e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "'name' "); break; 10419e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } 10429e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard switch (type) { 10439e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case NODE_TYPE_NODE: 10449e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "'node' "); break; 10459e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case NODE_TYPE_COMMENT: 10469e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "'comment' "); break; 10479e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case NODE_TYPE_TEXT: 10489e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "'text' "); break; 10499e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case NODE_TYPE_PI: 10509e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "'PI' "); break; 10519e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } 10529e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (prefix != NULL) 10539e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "%s:", prefix); 10549e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (name != NULL) 1055580ced8ee28ecd99374da9383897678e4ba6c358Daniel Veillard fprintf(output, "%s", (const char *) name); 10569e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard break; 10579e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 10589e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } 10599e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case XPATH_OP_VALUE: { 10609e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlXPathObjectPtr object = (xmlXPathObjectPtr) op->value4; 10619e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 10629e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "ELEM "); 10639e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlXPathDebugDumpObject(output, object, 0); 10649e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard goto finish; 10659e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } 10669e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case XPATH_OP_VARIABLE: { 10679e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard const xmlChar *prefix = op->value5; 10689e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard const xmlChar *name = op->value4; 10699e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 10709e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (prefix != NULL) 10719e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "VARIABLE %s:%s", prefix, name); 10729e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard else 10739e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "VARIABLE %s", name); 10749e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard break; 10759e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } 10769e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case XPATH_OP_FUNCTION: { 10779e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard int nbargs = op->value; 10789e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard const xmlChar *prefix = op->value5; 10799e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard const xmlChar *name = op->value4; 10809e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 10819e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (prefix != NULL) 10829e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "FUNCTION %s:%s(%d args)", 10839e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard prefix, name, nbargs); 10849e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard else 10859e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "FUNCTION %s(%d args)", name, nbargs); 10869e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard break; 10879e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } 10889e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case XPATH_OP_ARG: fprintf(output, "ARG"); break; 10899e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard case XPATH_OP_PREDICATE: fprintf(output, "PREDICATE"); break; 1090d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard case XPATH_OP_FILTER: fprintf(output, "FILTER"); break; 1091fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard#ifdef LIBXML_XPTR_ENABLED 1092fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard case XPATH_OP_RANGETO: fprintf(output, "RANGETO"); break; 1093fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard#endif 10949e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard default: 10959e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "UNKNOWN %d\n", op->op); return; 10969e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } 10979e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "\n"); 10989e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillardfinish: 10999e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (op->ch1 >= 0) 11009e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlXPathDebugDumpStepOp(output, comp, &comp->steps[op->ch1], depth + 1); 11019e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (op->ch2 >= 0) 11029e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlXPathDebugDumpStepOp(output, comp, &comp->steps[op->ch2], depth + 1); 11039e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard} 110456a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillard 11055e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard/** 11065e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard * xmlXPathDebugDumpCompExpr: 11075e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard * @output: the FILE * for the output 11085e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard * @comp: the precompiled XPath expression 11095e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard * @depth: the indentation level. 11105e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard * 11115e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard * Dumps the tree of the compiled XPath expression. 11125e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard */ 111356a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardvoid 111456a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel VeillardxmlXPathDebugDumpCompExpr(FILE *output, xmlXPathCompExprPtr comp, 111556a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillard int depth) { 11169e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard int i; 11179e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard char shift[100]; 11189e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 1119a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard if ((output == NULL) || (comp == NULL)) return; 1120a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard 11219e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard for (i = 0;((i < depth) && (i < 25));i++) 11229e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard shift[2 * i] = shift[2 * i + 1] = ' '; 11239e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard shift[2 * i] = shift[2 * i + 1] = 0; 11249e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 11259e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, shift); 11269e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 11279e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard fprintf(output, "Compiled Expression : %d elements\n", 11289e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard comp->nbStep); 11299e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard i = comp->last; 11309e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlXPathDebugDumpStepOp(output, comp, &comp->steps[i], depth + 1); 11319e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard} 1132017b108fcf16dbce05ca7ebd75763f3d888abb5fDaniel Veillard#endif /* LIBXML_DEBUG_ENABLED */ 11333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 11343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/************************************************************************ 11353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * * 11363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Parser stacks related functions and macros * 11373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * * 11383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ************************************************************************/ 11393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 11405e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard/** 11415e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard * valuePop: 11425e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard * @ctxt: an XPath evaluation context 11435e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard * 11445e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard * Pops the top XPath object from the value stack 11455e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard * 11465e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard * Returns the XPath object just removed 11475e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard */ 114824505b0f5c872c5afb6da5093565e5a6e09ca541Daniel VeillardxmlXPathObjectPtr 11491c732d2e10935529b717864b6fa4296f80edace1Daniel VeillardvaluePop(xmlXPathParserContextPtr ctxt) 11501c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard{ 11511c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard xmlXPathObjectPtr ret; 11521c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard 1153a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard if ((ctxt == NULL) || (ctxt->valueNr <= 0)) 115424505b0f5c872c5afb6da5093565e5a6e09ca541Daniel Veillard return (NULL); 11551c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard ctxt->valueNr--; 11561c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard if (ctxt->valueNr > 0) 11571c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard ctxt->value = ctxt->valueTab[ctxt->valueNr - 1]; 11581c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard else 11591c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard ctxt->value = NULL; 11601c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard ret = ctxt->valueTab[ctxt->valueNr]; 116124505b0f5c872c5afb6da5093565e5a6e09ca541Daniel Veillard ctxt->valueTab[ctxt->valueNr] = NULL; 11621c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard return (ret); 11631c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard} 11645e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard/** 11655e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard * valuePush: 11665e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard * @ctxt: an XPath evaluation context 11675e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard * @value: the XPath object 11685e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard * 11695e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard * Pushes a new XPath object on top of the value stack 1170cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * 1171cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * returns the number of items on the value stack 11725e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard */ 117324505b0f5c872c5afb6da5093565e5a6e09ca541Daniel Veillardint 11741c732d2e10935529b717864b6fa4296f80edace1Daniel VeillardvaluePush(xmlXPathParserContextPtr ctxt, xmlXPathObjectPtr value) 11751c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard{ 1176a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard if ((ctxt == NULL) || (value == NULL)) return(-1); 11771c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard if (ctxt->valueNr >= ctxt->valueMax) { 1178a918b5b08ac20d4e7c765bdce653969ebad6c315Daniel Veillard xmlXPathObjectPtr *tmp; 1179a918b5b08ac20d4e7c765bdce653969ebad6c315Daniel Veillard 1180a918b5b08ac20d4e7c765bdce653969ebad6c315Daniel Veillard tmp = (xmlXPathObjectPtr *) xmlRealloc(ctxt->valueTab, 1181a918b5b08ac20d4e7c765bdce653969ebad6c315Daniel Veillard 2 * ctxt->valueMax * 11821c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard sizeof(ctxt->valueTab[0])); 1183a918b5b08ac20d4e7c765bdce653969ebad6c315Daniel Veillard if (tmp == NULL) { 11841c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard xmlGenericError(xmlGenericErrorContext, "realloc failed !\n"); 11851c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard return (0); 11861c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard } 1187a918b5b08ac20d4e7c765bdce653969ebad6c315Daniel Veillard ctxt->valueMax *= 2; 1188a918b5b08ac20d4e7c765bdce653969ebad6c315Daniel Veillard ctxt->valueTab = tmp; 11891c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard } 11901c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard ctxt->valueTab[ctxt->valueNr] = value; 11911c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard ctxt->value = value; 11921c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard return (ctxt->valueNr++); 11931c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard} 11943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1195f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/** 1196f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathPopBoolean: 1197f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @ctxt: an XPath parser context 1198f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 1199f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Pops a boolean from the stack, handling conversion if needed. 1200f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Check error with #xmlXPathCheckError. 1201f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 1202f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns the boolean 1203f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */ 1204f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyerint 1205f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathPopBoolean (xmlXPathParserContextPtr ctxt) { 1206f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathObjectPtr obj; 1207f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer int ret; 1208f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 1209f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer obj = valuePop(ctxt); 1210f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (obj == NULL) { 1211f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathSetError(ctxt, XPATH_INVALID_OPERAND); 1212f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(0); 1213f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer } 1214081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack if (obj->type != XPATH_BOOLEAN) 1215081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack ret = xmlXPathCastToBoolean(obj); 1216081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack else 1217081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack ret = obj->boolval; 1218f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathFreeObject(obj); 1219f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(ret); 1220f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer} 1221f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 1222f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/** 1223f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathPopNumber: 1224f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @ctxt: an XPath parser context 1225f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 1226f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Pops a number from the stack, handling conversion if needed. 1227f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Check error with #xmlXPathCheckError. 1228f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 1229f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns the number 1230f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */ 1231f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyerdouble 1232f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathPopNumber (xmlXPathParserContextPtr ctxt) { 1233f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathObjectPtr obj; 1234f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer double ret; 1235f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 1236f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer obj = valuePop(ctxt); 1237f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (obj == NULL) { 1238f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathSetError(ctxt, XPATH_INVALID_OPERAND); 1239f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(0); 1240f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer } 1241081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack if (obj->type != XPATH_NUMBER) 1242081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack ret = xmlXPathCastToNumber(obj); 1243081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack else 1244081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack ret = obj->floatval; 1245f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathFreeObject(obj); 1246f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(ret); 1247f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer} 1248f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 1249f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/** 1250f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathPopString: 1251f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @ctxt: an XPath parser context 1252f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 1253f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Pops a string from the stack, handling conversion if needed. 1254f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Check error with #xmlXPathCheckError. 1255f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 1256f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns the string 1257f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */ 1258f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlChar * 1259f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathPopString (xmlXPathParserContextPtr ctxt) { 1260f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathObjectPtr obj; 1261f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlChar * ret; 1262f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 1263f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer obj = valuePop(ctxt); 1264f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (obj == NULL) { 1265f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathSetError(ctxt, XPATH_INVALID_OPERAND); 1266f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(NULL); 1267f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer } 1268081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack ret = xmlXPathCastToString(obj); /* this does required strdup */ 1269f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer /* TODO: needs refactoring somewhere else */ 1270f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (obj->stringval == ret) 1271f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer obj->stringval = NULL; 1272f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathFreeObject(obj); 1273f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(ret); 1274f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer} 1275f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 1276f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/** 1277f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathPopNodeSet: 1278f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @ctxt: an XPath parser context 1279f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 1280f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Pops a node-set from the stack, handling conversion if needed. 1281f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Check error with #xmlXPathCheckError. 1282f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 1283f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns the node-set 1284f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */ 1285f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlNodeSetPtr 1286f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathPopNodeSet (xmlXPathParserContextPtr ctxt) { 1287f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathObjectPtr obj; 1288f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlNodeSetPtr ret; 1289f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 1290f2a36f98e16efa8a89d9bed359d59be10e5d33cdDaniel Veillard if (ctxt == NULL) return(NULL); 1291f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (ctxt->value == NULL) { 1292f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathSetError(ctxt, XPATH_INVALID_OPERAND); 1293f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(NULL); 1294f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer } 1295f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (!xmlXPathStackIsNodeSet(ctxt)) { 1296f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathSetTypeError(ctxt); 1297f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(NULL); 1298f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer } 1299f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer obj = valuePop(ctxt); 1300f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer ret = obj->nodesetval; 1301e9449c5d29d87b1dc51de7784ed947ae1e3da831William M. Brack#if 0 13029deb242b558cbcff45165866e0634a1962404885Daniel Veillard /* to fix memory leak of not clearing obj->user */ 13039deb242b558cbcff45165866e0634a1962404885Daniel Veillard if (obj->boolval && obj->user != NULL) 13049deb242b558cbcff45165866e0634a1962404885Daniel Veillard xmlFreeNodeList((xmlNodePtr) obj->user); 1305e9449c5d29d87b1dc51de7784ed947ae1e3da831William M. Brack#endif 1306f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathFreeNodeSetList(obj); 1307f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(ret); 1308f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer} 1309f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 1310f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/** 1311f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathPopExternal: 1312f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @ctxt: an XPath parser context 1313f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 1314cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * Pops an external object from the stack, handling conversion if needed. 1315f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Check error with #xmlXPathCheckError. 1316f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 1317f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns the object 1318f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */ 1319f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyervoid * 1320f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathPopExternal (xmlXPathParserContextPtr ctxt) { 1321f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathObjectPtr obj; 1322f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer void * ret; 1323f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 1324a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard if ((ctxt == NULL) || (ctxt->value == NULL)) { 1325f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathSetError(ctxt, XPATH_INVALID_OPERAND); 1326f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(NULL); 1327f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer } 1328f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (ctxt->value->type != XPATH_USERS) { 1329f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathSetTypeError(ctxt); 1330f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(NULL); 1331f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer } 1332f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer obj = valuePop(ctxt); 1333f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer ret = obj->user; 1334f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathFreeObject(obj); 1335f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(ret); 1336f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer} 1337f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 13383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/* 13393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Macros for accessing the content. Those should be used only by the parser, 13403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * and not exported. 13413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 13423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Dirty macros, i.e. one need to make assumption on the context to use them 13433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 13443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * CUR_PTR return the current pointer to the xmlChar to be parsed. 13453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * CUR returns the current xmlChar value, i.e. a 8 bit value 13463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * in ISO-Latin or UTF-8. 13473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * This should be used internally by the parser 13483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * only to compare to ASCII values otherwise it would break when 13493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * running with UTF-8 encoding. 13503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * NXT(n) returns the n'th next xmlChar. Same as CUR is should be used only 13513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * to compare on ASCII based substring. 13523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * SKIP(n) Skip n xmlChar, and must also be used only to skip ASCII defined 13533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * strings within the parser. 13543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * CURRENT Returns the current char value, with the full decoding of 13553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * UTF-8 if we are using this mode. It returns an int. 13563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * NEXT Skip to the next character, this does the proper decoding 13573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * in UTF-8 mode. It also pop-up unfinished entities on the fly. 13583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * It returns the pointer to the current xmlChar. 13593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 13603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 13613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define CUR (*ctxt->cur) 13623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define SKIP(val) ctxt->cur += (val) 13633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define NXT(val) ctxt->cur[(val)] 13643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define CUR_PTR ctxt->cur 136561d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard#define CUR_CHAR(l) xmlXPathCurrentChar(ctxt, &l) 136661d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard 136761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard#define COPY_BUF(l,b,i,v) \ 136861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard if (l == 1) b[i++] = (xmlChar) v; \ 136961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard else i += xmlCopyChar(l,&b[i],v) 137061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard 137161d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard#define NEXTL(l) ctxt->cur += l 13723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 13733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define SKIP_BLANKS \ 137476e95df05556c9610b564b14cf578c8f9e34c9c1William M. Brack while (IS_BLANK_CH(*(ctxt->cur))) NEXT 13753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 13763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define CURRENT (*ctxt->cur) 13773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define NEXT ((*ctxt->cur) ? ctxt->cur++: ctxt->cur) 13783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1379e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese 1380e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese#ifndef DBL_DIG 1381e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese#define DBL_DIG 16 1382e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese#endif 1383e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese#ifndef DBL_EPSILON 1384e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese#define DBL_EPSILON 1E-9 1385e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese#endif 1386e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese 1387e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese#define UPPER_DOUBLE 1E9 1388e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese#define LOWER_DOUBLE 1E-5 1389e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese 1390e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese#define INTEGER_DIGITS DBL_DIG 1391e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese#define FRACTION_DIGITS (DBL_DIG + 1) 1392e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese#define EXPONENT_DIGITS (3 + 2) 1393e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese 1394e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese/** 1395e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese * xmlXPathFormatNumber: 1396e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese * @number: number to format 1397e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese * @buffer: output buffer 1398e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese * @buffersize: size of output buffer 1399e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese * 1400e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese * Convert the number into a string representation. 1401e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese */ 1402e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reesestatic void 1403e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn ReesexmlXPathFormatNumber(double number, char buffer[], int buffersize) 1404e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese{ 1405cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard switch (xmlXPathIsInf(number)) { 1406e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese case 1: 14075fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard if (buffersize > (int)sizeof("Infinity")) 140849cc97565fbe2928388a1e437c44429097a504aeAleksey Sanin snprintf(buffer, buffersize, "Infinity"); 1409e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese break; 1410e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese case -1: 1411e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese if (buffersize > (int)sizeof("-Infinity")) 141249cc97565fbe2928388a1e437c44429097a504aeAleksey Sanin snprintf(buffer, buffersize, "-Infinity"); 1413e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese break; 1414e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese default: 1415cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard if (xmlXPathIsNaN(number)) { 1416e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese if (buffersize > (int)sizeof("NaN")) 141749cc97565fbe2928388a1e437c44429097a504aeAleksey Sanin snprintf(buffer, buffersize, "NaN"); 1418d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard } else if (number == 0 && xmlXPathGetSign(number) != 0) { 141949cc97565fbe2928388a1e437c44429097a504aeAleksey Sanin snprintf(buffer, buffersize, "0"); 142028cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard } else if (number == ((int) number)) { 142128cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard char work[30]; 142228cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard char *ptr, *cur; 1423b3d1491b69060f8a67516b9a3ef12617adf88954Daniel Veillard int value = (int) number; 142428cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard 142528cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard ptr = &buffer[0]; 142628cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard if (value == 0) { 142728cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard *ptr++ = '0'; 142828cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard } else { 1429b3d1491b69060f8a67516b9a3ef12617adf88954Daniel Veillard snprintf(work, 29, "%d", value); 143028cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard cur = &work[0]; 1431b3d1491b69060f8a67516b9a3ef12617adf88954Daniel Veillard while ((*cur) && (ptr - buffer < buffersize)) { 1432b3d1491b69060f8a67516b9a3ef12617adf88954Daniel Veillard *ptr++ = *cur++; 143328cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard } 143428cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard } 143528cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard if (ptr - buffer < buffersize) { 143628cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard *ptr = 0; 143728cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard } else if (buffersize > 0) { 143828cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard ptr--; 143928cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard *ptr = 0; 144028cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard } 1441e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese } else { 144270a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese /* 3 is sign, decimal point, and terminating zero */ 144370a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese char work[DBL_DIG + EXPONENT_DIGITS + 3]; 144470a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese int integer_place, fraction_place; 144570a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese char *ptr; 144670a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese char *after_fraction; 144770a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese double absolute_value; 144870a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese int size; 144970a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese 145070a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese absolute_value = fabs(number); 145170a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese 145270a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese /* 145370a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese * First choose format - scientific or regular floating point. 145470a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese * In either case, result is in work, and after_fraction points 145570a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese * just past the fractional part. 145670a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese */ 145770a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese if ( ((absolute_value > UPPER_DOUBLE) || 145870a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese (absolute_value < LOWER_DOUBLE)) && 145970a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese (absolute_value != 0.0) ) { 146070a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese /* Use scientific notation */ 146170a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese integer_place = DBL_DIG + EXPONENT_DIGITS + 1; 146270a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese fraction_place = DBL_DIG - 1; 146311ce4004d86bb4b317c48b7d5124ba33e40e10f5Daniel Veillard size = snprintf(work, sizeof(work),"%*.*e", 146470a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese integer_place, fraction_place, number); 146511ce4004d86bb4b317c48b7d5124ba33e40e10f5Daniel Veillard while ((size > 0) && (work[size] != 'e')) size--; 146611ce4004d86bb4b317c48b7d5124ba33e40e10f5Daniel Veillard after_fraction = work + size; 146711ce4004d86bb4b317c48b7d5124ba33e40e10f5Daniel Veillard 1468e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese } 146970a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese else { 147070a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese /* Use regular notation */ 147156f0646e734ffbdd6945d86cc28b69b6569a82fcDaniel Veillard if (absolute_value > 0.0) 147256f0646e734ffbdd6945d86cc28b69b6569a82fcDaniel Veillard integer_place = 1 + (int)log10(absolute_value); 147356f0646e734ffbdd6945d86cc28b69b6569a82fcDaniel Veillard else 1474a3067d19ec3a96fd6e7997753e27a5422a2856f7Daniel Veillard integer_place = 0; 147570a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese fraction_place = (integer_place > 0) 147670a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese ? DBL_DIG - integer_place 147770a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese : DBL_DIG; 147870a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese size = snprintf(work, sizeof(work), "%0.*f", 147970a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese fraction_place, number); 148070a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese after_fraction = work + size; 1481e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese } 1482e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese 148370a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese /* Remove fractional trailing zeroes */ 148470a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese ptr = after_fraction; 148570a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese while (*(--ptr) == '0') 148670a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese ; 148770a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese if (*ptr != '.') 148870a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese ptr++; 14895dd3c9622ab6a8e75870bc5351499155e7963abcDaniel Veillard while ((*ptr++ = *after_fraction++) != 0); 149070a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese 149170a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese /* Finally copy result back to caller */ 149270a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese size = strlen(work) + 1; 149370a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese if (size > buffersize) { 149470a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese work[buffersize - 1] = 0; 149570a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese size = buffersize; 149670a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese } 14975dd3c9622ab6a8e75870bc5351499155e7963abcDaniel Veillard memmove(buffer, work, size); 1498e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese } 1499e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese break; 1500e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese } 1501e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese} 1502e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese 15033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 15043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/************************************************************************ 15053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * * 15063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Routines to handle NodeSets * 15073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * * 15083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ************************************************************************/ 15093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 15103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 1511e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard * xmlXPathOrderDocElems: 1512e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard * @doc: an input document 1513e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard * 1514e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard * Call this routine to speed up XPath computation on static documents. 1515e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard * This stamps all the element nodes with the document order 1516e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard * Like for line information, the order is kept in the element->content 1517081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack * field, the value stored is actually - the node number (starting at -1) 1518081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack * to be able to differentiate from line numbers. 1519e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard * 1520081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack * Returns the number of elements found in the document or -1 in case 1521e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard * of error. 1522e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard */ 1523e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillardlong 1524e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel VeillardxmlXPathOrderDocElems(xmlDocPtr doc) { 1525e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard long count = 0; 1526e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard xmlNodePtr cur; 1527e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard 1528e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard if (doc == NULL) 1529e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard return(-1); 1530e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard cur = doc->children; 1531e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard while (cur != NULL) { 1532e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard if (cur->type == XML_ELEMENT_NODE) { 1533e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard cur->content = (void *) (-(++count)); 1534e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard if (cur->children != NULL) { 1535e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard cur = cur->children; 1536e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard continue; 1537e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard } 1538e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard } 1539e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard if (cur->next != NULL) { 1540e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard cur = cur->next; 1541e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard continue; 1542e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard } 1543e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard do { 1544e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard cur = cur->parent; 1545e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard if (cur == NULL) 1546e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard break; 1547e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard if (cur == (xmlNodePtr) doc) { 1548e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard cur = NULL; 1549e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard break; 1550e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard } 1551e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard if (cur->next != NULL) { 1552e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard cur = cur->next; 1553e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard break; 1554e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard } 1555e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard } while (cur != NULL); 1556e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard } 1557e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard return(count); 1558e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard} 1559e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard 1560e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard/** 15613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathCmpNodes: 15623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @node1: the first node 15633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @node2: the second node 15643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 15653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Compare two nodes w.r.t document order 15663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 15673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns -2 in case of error 1 if first point < second point, 0 if 1568081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack * it's the same node, -1 otherwise 15693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 15703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorint 15713473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathCmpNodes(xmlNodePtr node1, xmlNodePtr node2) { 15723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int depth1, depth2; 1573edfd588e95d7c4690b5e85880521a32c20ed4fdeDaniel Veillard int attr1 = 0, attr2 = 0; 1574e8d1bd9daa881b01259e83eab60df8cbb56785c6William M. Brack xmlNodePtr attrNode1 = NULL, attrNode2 = NULL; 15753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlNodePtr cur, root; 15763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 15773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((node1 == NULL) || (node2 == NULL)) 15783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(-2); 15793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 15803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * a couple of optimizations which will avoid computations in most cases 15813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 1582edfd588e95d7c4690b5e85880521a32c20ed4fdeDaniel Veillard if (node1->type == XML_ATTRIBUTE_NODE) { 1583edfd588e95d7c4690b5e85880521a32c20ed4fdeDaniel Veillard attr1 = 1; 1584e8d1bd9daa881b01259e83eab60df8cbb56785c6William M. Brack attrNode1 = node1; 1585edfd588e95d7c4690b5e85880521a32c20ed4fdeDaniel Veillard node1 = node1->parent; 1586edfd588e95d7c4690b5e85880521a32c20ed4fdeDaniel Veillard } 1587edfd588e95d7c4690b5e85880521a32c20ed4fdeDaniel Veillard if (node2->type == XML_ATTRIBUTE_NODE) { 1588edfd588e95d7c4690b5e85880521a32c20ed4fdeDaniel Veillard attr2 = 1; 1589e8d1bd9daa881b01259e83eab60df8cbb56785c6William M. Brack attrNode2 = node2; 1590edfd588e95d7c4690b5e85880521a32c20ed4fdeDaniel Veillard node2 = node2->parent; 1591edfd588e95d7c4690b5e85880521a32c20ed4fdeDaniel Veillard } 1592edfd588e95d7c4690b5e85880521a32c20ed4fdeDaniel Veillard if (node1 == node2) { 1593e8d1bd9daa881b01259e83eab60df8cbb56785c6William M. Brack if (attr1 == attr2) { 1594e8d1bd9daa881b01259e83eab60df8cbb56785c6William M. Brack /* not required, but we keep attributes in order */ 1595e8d1bd9daa881b01259e83eab60df8cbb56785c6William M. Brack if (attr1 != 0) { 1596e8d1bd9daa881b01259e83eab60df8cbb56785c6William M. Brack cur = attrNode2->prev; 1597e8d1bd9daa881b01259e83eab60df8cbb56785c6William M. Brack while (cur != NULL) { 1598e8d1bd9daa881b01259e83eab60df8cbb56785c6William M. Brack if (cur == attrNode1) 1599e8d1bd9daa881b01259e83eab60df8cbb56785c6William M. Brack return (1); 1600e8d1bd9daa881b01259e83eab60df8cbb56785c6William M. Brack cur = cur->prev; 1601e8d1bd9daa881b01259e83eab60df8cbb56785c6William M. Brack } 1602e8d1bd9daa881b01259e83eab60df8cbb56785c6William M. Brack return (-1); 1603e8d1bd9daa881b01259e83eab60df8cbb56785c6William M. Brack } 1604edfd588e95d7c4690b5e85880521a32c20ed4fdeDaniel Veillard return(0); 1605e8d1bd9daa881b01259e83eab60df8cbb56785c6William M. Brack } 1606edfd588e95d7c4690b5e85880521a32c20ed4fdeDaniel Veillard if (attr2 == 1) 1607edfd588e95d7c4690b5e85880521a32c20ed4fdeDaniel Veillard return(1); 1608edfd588e95d7c4690b5e85880521a32c20ed4fdeDaniel Veillard return(-1); 1609edfd588e95d7c4690b5e85880521a32c20ed4fdeDaniel Veillard } 1610b33c201978ed1c434877cdc6e2000b7012cc26f9Daniel Veillard if ((node1->type == XML_NAMESPACE_DECL) || 1611b33c201978ed1c434877cdc6e2000b7012cc26f9Daniel Veillard (node2->type == XML_NAMESPACE_DECL)) 1612b33c201978ed1c434877cdc6e2000b7012cc26f9Daniel Veillard return(1); 16133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (node1 == node2->prev) 16143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(1); 16153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (node1 == node2->next) 16163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(-1); 16173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 16183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 1619e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard * Speedup using document order if availble. 16207216cfd6622d947695c67b7b430edef8cc0af967Daniel Veillard */ 16217216cfd6622d947695c67b7b430edef8cc0af967Daniel Veillard if ((node1->type == XML_ELEMENT_NODE) && 16227216cfd6622d947695c67b7b430edef8cc0af967Daniel Veillard (node2->type == XML_ELEMENT_NODE) && 1623e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard (0 > (long) node1->content) && 1624e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard (0 > (long) node2->content) && 1625e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard (node1->doc == node2->doc)) { 1626e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard long l1, l2; 1627e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard 1628e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard l1 = -((long) node1->content); 1629e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard l2 = -((long) node2->content); 16307216cfd6622d947695c67b7b430edef8cc0af967Daniel Veillard if (l1 < l2) 16317216cfd6622d947695c67b7b430edef8cc0af967Daniel Veillard return(1); 16327216cfd6622d947695c67b7b430edef8cc0af967Daniel Veillard if (l1 > l2) 16337216cfd6622d947695c67b7b430edef8cc0af967Daniel Veillard return(-1); 16347216cfd6622d947695c67b7b430edef8cc0af967Daniel Veillard } 1635e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard 16367216cfd6622d947695c67b7b430edef8cc0af967Daniel Veillard /* 16373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * compute depth to root 16383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 16393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor for (depth2 = 0, cur = node2;cur->parent != NULL;cur = cur->parent) { 16403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == node1) 16413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(1); 16423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor depth2++; 16433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 16443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor root = cur; 16453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor for (depth1 = 0, cur = node1;cur->parent != NULL;cur = cur->parent) { 16463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == node2) 16473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(-1); 16483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor depth1++; 16493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 16503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 16513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Distinct document (or distinct entities :-( ) case. 16523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 16533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (root != cur) { 16543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(-2); 16553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 16563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 16573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * get the nearest common ancestor. 16583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 16593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while (depth1 > depth2) { 16603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor depth1--; 16613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor node1 = node1->parent; 16623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 16633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while (depth2 > depth1) { 16643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor depth2--; 16653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor node2 = node2->parent; 16663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 16673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while (node1->parent != node2->parent) { 16683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor node1 = node1->parent; 16693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor node2 = node2->parent; 16703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* should not happen but just in case ... */ 16713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((node1 == NULL) || (node2 == NULL)) 16723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(-2); 16733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 16743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 16753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Find who's first. 16763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 1677f49be4778db34e8bbcfabc5d5f1ad33c594b7387Daniel Veillard if (node1 == node2->prev) 1678f49be4778db34e8bbcfabc5d5f1ad33c594b7387Daniel Veillard return(1); 16793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (node1 == node2->next) 16803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(-1); 1681f49be4778db34e8bbcfabc5d5f1ad33c594b7387Daniel Veillard /* 1682f49be4778db34e8bbcfabc5d5f1ad33c594b7387Daniel Veillard * Speedup using document order if availble. 1683f49be4778db34e8bbcfabc5d5f1ad33c594b7387Daniel Veillard */ 1684f49be4778db34e8bbcfabc5d5f1ad33c594b7387Daniel Veillard if ((node1->type == XML_ELEMENT_NODE) && 1685f49be4778db34e8bbcfabc5d5f1ad33c594b7387Daniel Veillard (node2->type == XML_ELEMENT_NODE) && 1686f49be4778db34e8bbcfabc5d5f1ad33c594b7387Daniel Veillard (0 > (long) node1->content) && 1687f49be4778db34e8bbcfabc5d5f1ad33c594b7387Daniel Veillard (0 > (long) node2->content) && 1688f49be4778db34e8bbcfabc5d5f1ad33c594b7387Daniel Veillard (node1->doc == node2->doc)) { 1689f49be4778db34e8bbcfabc5d5f1ad33c594b7387Daniel Veillard long l1, l2; 1690f49be4778db34e8bbcfabc5d5f1ad33c594b7387Daniel Veillard 1691f49be4778db34e8bbcfabc5d5f1ad33c594b7387Daniel Veillard l1 = -((long) node1->content); 1692f49be4778db34e8bbcfabc5d5f1ad33c594b7387Daniel Veillard l2 = -((long) node2->content); 1693f49be4778db34e8bbcfabc5d5f1ad33c594b7387Daniel Veillard if (l1 < l2) 1694f49be4778db34e8bbcfabc5d5f1ad33c594b7387Daniel Veillard return(1); 1695f49be4778db34e8bbcfabc5d5f1ad33c594b7387Daniel Veillard if (l1 > l2) 1696f49be4778db34e8bbcfabc5d5f1ad33c594b7387Daniel Veillard return(-1); 1697f49be4778db34e8bbcfabc5d5f1ad33c594b7387Daniel Veillard } 1698f49be4778db34e8bbcfabc5d5f1ad33c594b7387Daniel Veillard 16993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor for (cur = node1->next;cur != NULL;cur = cur->next) 17003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == node2) 17013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(1); 17023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(-1); /* assume there is no sibling list corruption */ 17033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 17043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 17052bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik#ifdef XP_FAST_NON_ELEM_COMPARISON 17062bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik/** 17072bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik * xmlXPathCmpNodesExt: 17082bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik * @node1: the first node 17092bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik * @node2: the second node 17102bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik * 17112bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik * Compare two nodes w.r.t document order. 17122bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik * This one is optimized for handling of non-element nodes. 17132bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik * 17142bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik * Returns -2 in case of error 1 if first point < second point, 0 if 17152bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik * it's the same node, -1 otherwise 17162bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik */ 17172bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcikstatic int 17182bdabbd711356e534940431053523f1538d1a93eKasimier T. BuchcikxmlXPathCmpNodesExt(xmlNodePtr node1, xmlNodePtr node2) { 17192bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik int depth1, depth2; 17202bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik int misc = 0, precedence1 = 0, precedence2 = 0; 17212bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik xmlNodePtr miscNode1 = NULL, miscNode2 = NULL; 17222bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik xmlNodePtr cur, root; 17232bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik 17242bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik if ((node1 == NULL) || (node2 == NULL)) 17252bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik return(-2); 17262bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik 17272bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik if (node1 == node2) 17282bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik return(0); 17292bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik 17302bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik /* 17312bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik * a couple of optimizations which will avoid computations in most cases 17322bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik */ 17332bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik 17342bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik switch (node1->type) { 17352bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik case XML_ELEMENT_NODE: 17362bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik break; 17372bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik case XML_ATTRIBUTE_NODE: 17382bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik precedence1 = 1; /* element is owner */ 17392bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik miscNode1 = node1; 17402bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik node1 = node1->parent; 17412bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik misc = 1; 17422bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik break; 17432bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik case XML_TEXT_NODE: 17442bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik case XML_CDATA_SECTION_NODE: 17452bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik case XML_COMMENT_NODE: 17462bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik case XML_PI_NODE: { 17472bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik miscNode1 = node1; 17482bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik /* 17492bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik * Find nearest element node. 17502bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik */ 17512bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik if (node1->prev != NULL) { 17522bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik do { 17532bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik node1 = node1->prev; 17542bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik if (node1->type == XML_ELEMENT_NODE) { 17552bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik precedence1 = 3; /* element in prev-sibl axis */ 17562bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik break; 17572bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik } 17582bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik if (node1->prev == NULL) { 17592bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik precedence1 = 2; /* element is parent */ 17602bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik /* 17612bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik * URGENT TODO: Are there any cases, where the 17622bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik * parent of such a node is not an element node? 17632bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik */ 17642bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik node1 = node1->parent; 17652bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik break; 17662bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik } 17672bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik } while (1); 17682bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik } else { 17692bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik precedence1 = 2; /* element is parent */ 17702bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik node1 = node1->parent; 17712bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik } 17722bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik if ((node1 == NULL) || (node1->type != XML_ELEMENT_NODE)) { 17732bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik /* 17742bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik * Fallback for whatever case. 17752bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik */ 17762bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik node1 = miscNode1; 17772bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik precedence1 = 0; 17782bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik } else 17792bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik misc = 1; 17802bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik } 17812bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik break; 17822bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik case XML_NAMESPACE_DECL: 17832bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik /* 17842bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik * TODO: why do we return 1 for namespace nodes? 17852bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik */ 17862bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik return(1); 17872bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik default: 17882bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik break; 17892bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik } 17902bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik switch (node2->type) { 17912bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik case XML_ELEMENT_NODE: 17922bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik break; 17932bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik case XML_ATTRIBUTE_NODE: 17942bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik precedence2 = 1; /* element is owner */ 17952bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik miscNode2 = node2; 17962bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik node2 = node2->parent; 17972bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik misc = 1; 17982bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik break; 17992bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik case XML_TEXT_NODE: 18002bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik case XML_CDATA_SECTION_NODE: 18012bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik case XML_COMMENT_NODE: 18022bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik case XML_PI_NODE: { 18032bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik miscNode2 = node2; 18042bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik if (node2->prev != NULL) { 18052bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik do { 18062bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik node2 = node2->prev; 18072bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik if (node2->type == XML_ELEMENT_NODE) { 18082bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik precedence2 = 3; /* element in prev-sibl axis */ 18092bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik break; 18102bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik } 18112bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik if (node2->prev == NULL) { 18122bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik precedence2 = 2; /* element is parent */ 18132bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik node2 = node2->parent; 18142bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik break; 18152bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik } 18162bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik } while (1); 18172bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik } else { 18182bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik precedence2 = 2; /* element is parent */ 18192bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik node2 = node2->parent; 18202bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik } 18212bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik if ((node2 == NULL) || (node2->type != XML_ELEMENT_NODE) || 18222bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik (0 <= (long) node1->content)) 18232bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik { 18242bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik node2 = miscNode2; 18252bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik precedence2 = 0; 18262bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik } else 18272bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik misc = 1; 18282bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik } 18292bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik break; 18302bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik case XML_NAMESPACE_DECL: 18312bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik return(1); 18322bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik default: 18332bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik break; 18342bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik } 18352bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik if (misc) { 18362bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik if (node1 == node2) { 18372bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik if (precedence1 == precedence2) { 18382bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik /* 18392bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik * The ugly case; but normally there aren't many 18402bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik * adjacent non-element nodes around. 18412bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik */ 18422bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik cur = miscNode2->prev; 18432bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik while (cur != NULL) { 18442bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik if (cur == miscNode1) 18452bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik return(1); 18462bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik if (cur->type == XML_ELEMENT_NODE) 18472bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik return(-1); 18482bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik cur = cur->prev; 18492bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik } 18502bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik return (-1); 18512bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik } else { 18522bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik /* 18532bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik * Evaluate based on higher precedence wrt to the element. 18542bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik * TODO: This assumes attributes are sorted before content. 18552bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik * Is this 100% correct? 18562bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik */ 18572bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik if (precedence1 < precedence2) 18582bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik return(1); 18592bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik else 18602bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik return(-1); 18612bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik } 18622bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik } 18632bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik /* 18642bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik * Special case: One of the helper-elements is contained by the other. 18652bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik * <foo> 18662bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik * <node2> 18672bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik * <node1>Text-1(precedence1 == 2)</node1> 18682bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik * </node2> 18692bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik * Text-6(precedence2 == 3) 18702bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik * </foo> 18712bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik */ 18722bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik if ((precedence2 == 3) && (precedence1 > 1)) { 18732bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik cur = node1->parent; 18742bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik while (cur) { 18752bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik if (cur == node2) 18762bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik return(1); 18772bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik cur = cur->parent; 18782bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik } 18792bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik } 18802bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik if ((precedence1 == 3) && (precedence2 > 1)) { 18812bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik cur = node2->parent; 18822bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik while (cur) { 18832bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik if (cur == node1) 18842bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik return(-1); 18852bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik cur = cur->parent; 18862bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik } 18872bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik } 18882bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik } 18892bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik 18902bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik if (node1 == node2->prev) 18912bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik return(1); 18922bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik if (node1 == node2->next) 18932bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik return(-1); 18942bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik 18952bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik /* 18962bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik * Speedup using document order if availble. 18972bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik */ 18982bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik if ((node1->type == XML_ELEMENT_NODE) && 18992bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik (node2->type == XML_ELEMENT_NODE) && 19002bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik (0 > (long) node1->content) && 19012bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik (0 > (long) node2->content) && 19022bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik (node1->doc == node2->doc)) { 19032bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik long l1, l2; 19042bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik 19052bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik l1 = -((long) node1->content); 19062bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik l2 = -((long) node2->content); 19072bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik if (l1 < l2) 19082bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik return(1); 19092bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik if (l1 > l2) 19102bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik return(-1); 19112bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik } 19122bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik 19132bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik /* 19142bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik * compute depth to root 19152bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik */ 19162bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik for (depth2 = 0, cur = node2;cur->parent != NULL;cur = cur->parent) { 19172bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik if (cur == node1) 19182bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik return(1); 19192bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik depth2++; 19202bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik } 19212bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik root = cur; 19222bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik for (depth1 = 0, cur = node1;cur->parent != NULL;cur = cur->parent) { 19232bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik if (cur == node2) 19242bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik return(-1); 19252bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik depth1++; 19262bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik } 19272bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik /* 19282bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik * Distinct document (or distinct entities :-( ) case. 19292bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik */ 19302bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik if (root != cur) { 19312bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik return(-2); 19322bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik } 19332bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik /* 19342bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik * get the nearest common ancestor. 19352bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik */ 19362bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik while (depth1 > depth2) { 19372bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik depth1--; 19382bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik node1 = node1->parent; 19392bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik } 19402bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik while (depth2 > depth1) { 19412bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik depth2--; 19422bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik node2 = node2->parent; 19432bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik } 19442bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik while (node1->parent != node2->parent) { 19452bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik node1 = node1->parent; 19462bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik node2 = node2->parent; 19472bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik /* should not happen but just in case ... */ 19482bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik if ((node1 == NULL) || (node2 == NULL)) 19492bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik return(-2); 19502bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik } 19512bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik /* 19522bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik * Find who's first. 19532bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik */ 19542bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik if (node1 == node2->prev) 19552bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik return(1); 19562bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik if (node1 == node2->next) 19572bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik return(-1); 19582bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik /* 19592bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik * Speedup using document order if availble. 19602bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik */ 19612bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik if ((node1->type == XML_ELEMENT_NODE) && 19622bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik (node2->type == XML_ELEMENT_NODE) && 19632bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik (0 > (long) node1->content) && 19642bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik (0 > (long) node2->content) && 19652bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik (node1->doc == node2->doc)) { 19662bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik long l1, l2; 19672bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik 19682bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik l1 = -((long) node1->content); 19692bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik l2 = -((long) node2->content); 19702bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik if (l1 < l2) 19712bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik return(1); 19722bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik if (l1 > l2) 19732bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik return(-1); 19742bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik } 19752bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik 19762bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik for (cur = node1->next;cur != NULL;cur = cur->next) 19772bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik if (cur == node2) 19782bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik return(1); 19792bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik return(-1); /* assume there is no sibling list corruption */ 19802bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik} 19812bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik#endif /* XP_FAST_NON_ELEM_COMPARISON */ 19822bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik 19833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 19843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNodeSetSort: 19853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @set: the node set 19863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 19873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Sort the node set in document order 19883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 19893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 19903473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNodeSetSort(xmlNodeSetPtr set) { 1991e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese int i, j, incr, len; 19923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlNodePtr tmp; 19933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 19943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (set == NULL) 19953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return; 19963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 19973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* Use Shell's sort to sort the node-set */ 19983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor len = set->nodeNr; 19993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor for (incr = len / 2; incr > 0; incr /= 2) { 20003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor for (i = incr; i < len; i++) { 20013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor j = i - incr; 20023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while (j >= 0) { 20032bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik#ifdef XP_FAST_NON_ELEM_COMPARISON 20042bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik if (xmlXPathCmpNodesExt(set->nodeTab[j], 20052bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik set->nodeTab[j + incr]) == -1) 20062bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik#else 2007e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese if (xmlXPathCmpNodes(set->nodeTab[j], 20082bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik set->nodeTab[j + incr]) == -1) 20092bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik#endif 20102bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik { 20113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor tmp = set->nodeTab[j]; 20123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor set->nodeTab[j] = set->nodeTab[j + incr]; 20133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor set->nodeTab[j + incr] = tmp; 20143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor j -= incr; 20153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else 20163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 20173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 20183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 20193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 20203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 20213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 20223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define XML_NODESET_DEFAULT 10 20233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 2024044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * xmlXPathNodeSetDupNs: 2025044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * @node: the parent node of the namespace XPath node 2026044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * @ns: the libxml namespace declaration node. 2027044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * 2028044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * Namespace node in libxml don't match the XPath semantic. In a node set 2029044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * the namespace nodes are duplicated and the next pointer is set to the 2030044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * parent node in the XPath semantic. 2031044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * 2032044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * Returns the newly created object. 2033044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard */ 2034044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillardstatic xmlNodePtr 2035044fc6b7476798cbb95277b4905e5111d7c2775dDaniel VeillardxmlXPathNodeSetDupNs(xmlNodePtr node, xmlNsPtr ns) { 2036044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlNsPtr cur; 2037044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard 2038044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if ((ns == NULL) || (ns->type != XML_NAMESPACE_DECL)) 2039044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard return(NULL); 2040044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if ((node == NULL) || (node->type == XML_NAMESPACE_DECL)) 2041044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard return((xmlNodePtr) ns); 2042044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard 2043044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard /* 2044044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * Allocate a new Namespace and fill the fields. 2045044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard */ 2046044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard cur = (xmlNsPtr) xmlMalloc(sizeof(xmlNs)); 2047044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if (cur == NULL) { 2048d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard xmlXPathErrMemory(NULL, "duplicating namespace\n"); 2049044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard return(NULL); 2050044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } 2051044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard memset(cur, 0, sizeof(xmlNs)); 2052044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard cur->type = XML_NAMESPACE_DECL; 2053044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if (ns->href != NULL) 2054044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard cur->href = xmlStrdup(ns->href); 2055044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if (ns->prefix != NULL) 2056044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard cur->prefix = xmlStrdup(ns->prefix); 2057044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard cur->next = (xmlNsPtr) node; 2058044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard return((xmlNodePtr) cur); 2059044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard} 2060044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard 2061044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard/** 2062044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * xmlXPathNodeSetFreeNs: 2063044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * @ns: the XPath namespace node found in a nodeset. 2064044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * 2065081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack * Namespace nodes in libxml don't match the XPath semantic. In a node set 2066044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * the namespace nodes are duplicated and the next pointer is set to the 2067081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack * parent node in the XPath semantic. Check if such a node needs to be freed 2068044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard */ 2069f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Saninvoid 2070044fc6b7476798cbb95277b4905e5111d7c2775dDaniel VeillardxmlXPathNodeSetFreeNs(xmlNsPtr ns) { 2071044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if ((ns == NULL) || (ns->type != XML_NAMESPACE_DECL)) 2072044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard return; 2073044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard 2074044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if ((ns->next != NULL) && (ns->next->type != XML_NAMESPACE_DECL)) { 2075044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if (ns->href != NULL) 2076044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlFree((xmlChar *)ns->href); 2077044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if (ns->prefix != NULL) 2078044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlFree((xmlChar *)ns->prefix); 2079044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlFree(ns); 2080044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } 2081044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard} 2082044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard 2083044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard/** 20843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNodeSetCreate: 20853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val: an initial xmlNodePtr, or NULL 20863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 20873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Create a new xmlNodeSetPtr of type double and of value @val 20883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 20893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the newly created object. 20903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 20913473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNodeSetPtr 20923473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNodeSetCreate(xmlNodePtr val) { 20933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlNodeSetPtr ret; 20943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 20953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = (xmlNodeSetPtr) xmlMalloc(sizeof(xmlNodeSet)); 20963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ret == NULL) { 2097d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard xmlXPathErrMemory(NULL, "creating nodeset\n"); 20983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 20993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 21003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor memset(ret, 0 , (size_t) sizeof(xmlNodeSet)); 21013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (val != NULL) { 21023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->nodeTab = (xmlNodePtr *) xmlMalloc(XML_NODESET_DEFAULT * 21033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor sizeof(xmlNodePtr)); 21043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ret->nodeTab == NULL) { 2105d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard xmlXPathErrMemory(NULL, "creating nodeset\n"); 2106d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard xmlFree(ret); 21073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 21083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 21093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor memset(ret->nodeTab, 0 , 21103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XML_NODESET_DEFAULT * (size_t) sizeof(xmlNodePtr)); 21113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->nodeMax = XML_NODESET_DEFAULT; 2112044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if (val->type == XML_NAMESPACE_DECL) { 2113044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlNsPtr ns = (xmlNsPtr) val; 2114044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard 2115044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard ret->nodeTab[ret->nodeNr++] = 2116044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlXPathNodeSetDupNs((xmlNodePtr) ns->next, ns); 2117044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } else 2118044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard ret->nodeTab[ret->nodeNr++] = val; 21193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 21203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ret); 21213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 21223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 21233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 2124f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathNodeSetContains: 2125f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @cur: the node-set 2126f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @val: the node 2127f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 2128f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * checks whether @cur contains @val 2129f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 2130f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns true (1) if @cur contains @val, false (0) otherwise 2131f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */ 2132f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyerint 2133f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathNodeSetContains (xmlNodeSetPtr cur, xmlNodePtr val) { 2134f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer int i; 2135f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 2136a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard if ((cur == NULL) || (val == NULL)) return(0); 2137044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if (val->type == XML_NAMESPACE_DECL) { 2138044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard for (i = 0; i < cur->nodeNr; i++) { 2139044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if (cur->nodeTab[i]->type == XML_NAMESPACE_DECL) { 2140044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlNsPtr ns1, ns2; 2141044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard 2142044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard ns1 = (xmlNsPtr) val; 2143044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard ns2 = (xmlNsPtr) cur->nodeTab[i]; 2144044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if (ns1 == ns2) 2145044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard return(1); 2146044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if ((ns1->next != NULL) && (ns2->next == ns1->next) && 2147044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard (xmlStrEqual(ns1->prefix, ns2->prefix))) 2148044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard return(1); 2149044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } 2150044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } 2151044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } else { 2152044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard for (i = 0; i < cur->nodeNr; i++) { 2153044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if (cur->nodeTab[i] == val) 2154044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard return(1); 2155044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } 2156f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer } 2157f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(0); 2158f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer} 2159f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 2160f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/** 2161044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * xmlXPathNodeSetAddNs: 2162044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * @cur: the initial node set 2163044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * @node: the hosting node 2164044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * @ns: a the namespace node 2165044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * 2166044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * add a new namespace node to an existing NodeSet 2167044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard */ 216879376ba94845db7096c3917f4f40baeb450eb0e9Aleksey Saninvoid 2169044fc6b7476798cbb95277b4905e5111d7c2775dDaniel VeillardxmlXPathNodeSetAddNs(xmlNodeSetPtr cur, xmlNodePtr node, xmlNsPtr ns) { 2170044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard int i; 2171044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard 2172a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard 2173a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard if ((cur == NULL) || (ns == NULL) || (node == NULL) || 2174a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard (ns->type != XML_NAMESPACE_DECL) || 2175044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard (node->type != XML_ELEMENT_NODE)) 2176044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard return; 2177044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard 2178081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack /* @@ with_ns to check whether namespace nodes should be looked at @@ */ 2179044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard /* 2180081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack * prevent duplicates 2181044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard */ 2182044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard for (i = 0;i < cur->nodeNr;i++) { 2183044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if ((cur->nodeTab[i] != NULL) && 2184044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard (cur->nodeTab[i]->type == XML_NAMESPACE_DECL) && 2185c62a147963b5839fc815267706eaec381f90ca16Daniel Veillard (((xmlNsPtr)cur->nodeTab[i])->next == (xmlNsPtr) node) && 2186044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard (xmlStrEqual(ns->prefix, ((xmlNsPtr)cur->nodeTab[i])->prefix))) 2187044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard return; 2188044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } 2189044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard 2190044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard /* 2191044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * grow the nodeTab if needed 2192044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard */ 2193044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if (cur->nodeMax == 0) { 2194044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard cur->nodeTab = (xmlNodePtr *) xmlMalloc(XML_NODESET_DEFAULT * 2195044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard sizeof(xmlNodePtr)); 2196044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if (cur->nodeTab == NULL) { 2197d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard xmlXPathErrMemory(NULL, "growing nodeset\n"); 2198044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard return; 2199044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } 2200044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard memset(cur->nodeTab, 0 , 2201044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard XML_NODESET_DEFAULT * (size_t) sizeof(xmlNodePtr)); 2202044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard cur->nodeMax = XML_NODESET_DEFAULT; 2203044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } else if (cur->nodeNr == cur->nodeMax) { 2204044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlNodePtr *temp; 2205044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard 2206044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard cur->nodeMax *= 2; 2207044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard temp = (xmlNodePtr *) xmlRealloc(cur->nodeTab, cur->nodeMax * 2208044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard sizeof(xmlNodePtr)); 2209044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if (temp == NULL) { 2210d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard xmlXPathErrMemory(NULL, "growing nodeset\n"); 2211044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard return; 2212044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } 2213044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard cur->nodeTab = temp; 2214044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } 2215044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard cur->nodeTab[cur->nodeNr++] = xmlXPathNodeSetDupNs(node, ns); 2216044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard} 2217044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard 2218044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard/** 22193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNodeSetAdd: 22203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur: the initial node set 22213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val: a new xmlNodePtr 22223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 2223cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * add a new xmlNodePtr to an existing NodeSet 22243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 22253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 22263473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNodeSetAdd(xmlNodeSetPtr cur, xmlNodePtr val) { 22273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int i; 22283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 2229a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard if ((cur == NULL) || (val == NULL)) return; 22303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 2231ef0b45016373d65700ef6f7d494a200758b2e4c5Daniel Veillard#if 0 2232652d8a949447833405cc0805f4b7ff1179e59ed2Daniel Veillard if ((val->type == XML_ELEMENT_NODE) && (val->name[0] == ' ')) 2233652d8a949447833405cc0805f4b7ff1179e59ed2Daniel Veillard return; /* an XSLT fake node */ 2234ef0b45016373d65700ef6f7d494a200758b2e4c5Daniel Veillard#endif 2235652d8a949447833405cc0805f4b7ff1179e59ed2Daniel Veillard 2236081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack /* @@ with_ns to check whether namespace nodes should be looked at @@ */ 22373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 2238081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack * prevent duplcates 22393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 22403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor for (i = 0;i < cur->nodeNr;i++) 22413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur->nodeTab[i] == val) return; 22423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 22433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 22443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * grow the nodeTab if needed 22453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 22463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur->nodeMax == 0) { 22473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur->nodeTab = (xmlNodePtr *) xmlMalloc(XML_NODESET_DEFAULT * 22483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor sizeof(xmlNodePtr)); 22493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur->nodeTab == NULL) { 2250d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard xmlXPathErrMemory(NULL, "growing nodeset\n"); 22513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return; 22523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 22533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor memset(cur->nodeTab, 0 , 22543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XML_NODESET_DEFAULT * (size_t) sizeof(xmlNodePtr)); 22553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur->nodeMax = XML_NODESET_DEFAULT; 22563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else if (cur->nodeNr == cur->nodeMax) { 22573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlNodePtr *temp; 22583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 22593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur->nodeMax *= 2; 22603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor temp = (xmlNodePtr *) xmlRealloc(cur->nodeTab, cur->nodeMax * 22613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor sizeof(xmlNodePtr)); 22623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (temp == NULL) { 2263d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard xmlXPathErrMemory(NULL, "growing nodeset\n"); 22643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return; 22653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 22663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur->nodeTab = temp; 22673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 2268044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if (val->type == XML_NAMESPACE_DECL) { 2269044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlNsPtr ns = (xmlNsPtr) val; 2270044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard 2271044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard cur->nodeTab[cur->nodeNr++] = 2272044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlXPathNodeSetDupNs((xmlNodePtr) ns->next, ns); 2273044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } else 2274044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard cur->nodeTab[cur->nodeNr++] = val; 22753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 22763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 22773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 22783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNodeSetAddUnique: 22793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur: the initial node set 22803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val: a new xmlNodePtr 22813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 2282cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * add a new xmlNodePtr to an existing NodeSet, optimized version 22833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * when we are sure the node is not already in the set. 22843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 22853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 22863473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNodeSetAddUnique(xmlNodeSetPtr cur, xmlNodePtr val) { 2287a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard if ((cur == NULL) || (val == NULL)) return; 22883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 2289ef0b45016373d65700ef6f7d494a200758b2e4c5Daniel Veillard#if 0 2290652d8a949447833405cc0805f4b7ff1179e59ed2Daniel Veillard if ((val->type == XML_ELEMENT_NODE) && (val->name[0] == ' ')) 2291652d8a949447833405cc0805f4b7ff1179e59ed2Daniel Veillard return; /* an XSLT fake node */ 2292ef0b45016373d65700ef6f7d494a200758b2e4c5Daniel Veillard#endif 2293652d8a949447833405cc0805f4b7ff1179e59ed2Daniel Veillard 2294081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack /* @@ with_ns to check whether namespace nodes should be looked at @@ */ 22953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 22963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * grow the nodeTab if needed 22973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 22983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur->nodeMax == 0) { 22993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur->nodeTab = (xmlNodePtr *) xmlMalloc(XML_NODESET_DEFAULT * 23003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor sizeof(xmlNodePtr)); 23013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur->nodeTab == NULL) { 2302d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard xmlXPathErrMemory(NULL, "growing nodeset\n"); 23033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return; 23043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 23053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor memset(cur->nodeTab, 0 , 23063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XML_NODESET_DEFAULT * (size_t) sizeof(xmlNodePtr)); 23073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur->nodeMax = XML_NODESET_DEFAULT; 23083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else if (cur->nodeNr == cur->nodeMax) { 23093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlNodePtr *temp; 23103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 23113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur->nodeMax *= 2; 23123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor temp = (xmlNodePtr *) xmlRealloc(cur->nodeTab, cur->nodeMax * 23133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor sizeof(xmlNodePtr)); 23143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (temp == NULL) { 2315d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard xmlXPathErrMemory(NULL, "growing nodeset\n"); 23163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return; 23173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 23183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur->nodeTab = temp; 23193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 2320044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if (val->type == XML_NAMESPACE_DECL) { 2321044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlNsPtr ns = (xmlNsPtr) val; 2322044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard 2323044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard cur->nodeTab[cur->nodeNr++] = 2324044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlXPathNodeSetDupNs((xmlNodePtr) ns->next, ns); 2325044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } else 2326044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard cur->nodeTab[cur->nodeNr++] = val; 23273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 23283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 23293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 23303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNodeSetMerge: 23313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val1: the first NodeSet or NULL 23323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val2: the second NodeSet 23333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 23343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Merges two nodesets, all nodes from @val2 are added to @val1 23353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * if @val1 is NULL, a new set is created and copied from @val2 23363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 2337cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * Returns @val1 once extended or NULL in case of error. 23383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 23393473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNodeSetPtr 23403473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNodeSetMerge(xmlNodeSetPtr val1, xmlNodeSetPtr val2) { 2341d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard int i, j, initNr, skip; 23423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 23433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (val2 == NULL) return(val1); 23443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (val1 == NULL) { 23453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor val1 = xmlXPathNodeSetCreate(NULL); 23463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 23473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 2348081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack /* @@ with_ns to check whether namespace nodes should be looked at @@ */ 23493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor initNr = val1->nodeNr; 23503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 23513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor for (i = 0;i < val2->nodeNr;i++) { 23523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 2353081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack * check against duplicates 23543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 2355d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard skip = 0; 2356d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard for (j = 0; j < initNr; j++) { 2357d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard if (val1->nodeTab[j] == val2->nodeTab[i]) { 2358d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard skip = 1; 2359d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard break; 2360044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } else if ((val1->nodeTab[j]->type == XML_NAMESPACE_DECL) && 2361044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard (val2->nodeTab[i]->type == XML_NAMESPACE_DECL)) { 2362044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlNsPtr ns1, ns2; 2363044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard ns1 = (xmlNsPtr) val1->nodeTab[j]; 2364044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard ns2 = (xmlNsPtr) val2->nodeTab[i]; 2365044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if ((ns1->next == ns2->next) && 2366044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard (xmlStrEqual(ns1->prefix, ns2->prefix))) { 2367044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard skip = 1; 2368044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard break; 2369044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } 2370d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard } 2371d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard } 2372d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard if (skip) 2373d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard continue; 23743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 23753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 23763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * grow the nodeTab if needed 23773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 23783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (val1->nodeMax == 0) { 23793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor val1->nodeTab = (xmlNodePtr *) xmlMalloc(XML_NODESET_DEFAULT * 23803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor sizeof(xmlNodePtr)); 23813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (val1->nodeTab == NULL) { 2382d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard xmlXPathErrMemory(NULL, "merging nodeset\n"); 23833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 23843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 23853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor memset(val1->nodeTab, 0 , 23863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XML_NODESET_DEFAULT * (size_t) sizeof(xmlNodePtr)); 23873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor val1->nodeMax = XML_NODESET_DEFAULT; 23883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else if (val1->nodeNr == val1->nodeMax) { 23893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlNodePtr *temp; 23903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 23913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor val1->nodeMax *= 2; 23923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor temp = (xmlNodePtr *) xmlRealloc(val1->nodeTab, val1->nodeMax * 23933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor sizeof(xmlNodePtr)); 23943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (temp == NULL) { 2395d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard xmlXPathErrMemory(NULL, "merging nodeset\n"); 23963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 23973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 23983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor val1->nodeTab = temp; 23993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 2400044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if (val2->nodeTab[i]->type == XML_NAMESPACE_DECL) { 2401044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlNsPtr ns = (xmlNsPtr) val2->nodeTab[i]; 2402044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard 2403044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard val1->nodeTab[val1->nodeNr++] = 2404044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlXPathNodeSetDupNs((xmlNodePtr) ns->next, ns); 2405044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } else 2406044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard val1->nodeTab[val1->nodeNr++] = val2->nodeTab[i]; 24073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 24083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 24093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(val1); 24103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 24113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 24123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 241375be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard * xmlXPathNodeSetMergeUnique: 241475be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard * @val1: the first NodeSet or NULL 241575be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard * @val2: the second NodeSet 241675be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard * 241775be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard * Merges two nodesets, all nodes from @val2 are added to @val1 241875be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard * if @val1 is NULL, a new set is created and copied from @val2 241975be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard * 242075be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard * Returns @val1 once extended or NULL in case of error. 242175be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard */ 242275be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillardstatic xmlNodeSetPtr 242375be0130855fe02d238bbbf19a04d3c5eb45f494Daniel VeillardxmlXPathNodeSetMergeUnique(xmlNodeSetPtr val1, xmlNodeSetPtr val2) { 242478637da0ea1c833dfdfad87a9aa5bea14510d08aWilliam M. Brack int i; 242575be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard 242675be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard if (val2 == NULL) return(val1); 242775be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard if (val1 == NULL) { 242875be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard val1 = xmlXPathNodeSetCreate(NULL); 242975be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard } 243075be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard 2431081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack /* @@ with_ns to check whether namespace nodes should be looked at @@ */ 243275be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard 243375be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard for (i = 0;i < val2->nodeNr;i++) { 243475be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard /* 243575be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard * grow the nodeTab if needed 243675be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard */ 243775be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard if (val1->nodeMax == 0) { 243875be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard val1->nodeTab = (xmlNodePtr *) xmlMalloc(XML_NODESET_DEFAULT * 243975be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard sizeof(xmlNodePtr)); 244075be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard if (val1->nodeTab == NULL) { 2441d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard xmlXPathErrMemory(NULL, "merging nodeset\n"); 244275be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard return(NULL); 244375be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard } 244475be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard memset(val1->nodeTab, 0 , 244575be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard XML_NODESET_DEFAULT * (size_t) sizeof(xmlNodePtr)); 244675be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard val1->nodeMax = XML_NODESET_DEFAULT; 244775be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard } else if (val1->nodeNr == val1->nodeMax) { 244875be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard xmlNodePtr *temp; 244975be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard 245075be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard val1->nodeMax *= 2; 245175be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard temp = (xmlNodePtr *) xmlRealloc(val1->nodeTab, val1->nodeMax * 245275be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard sizeof(xmlNodePtr)); 245375be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard if (temp == NULL) { 2454d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard xmlXPathErrMemory(NULL, "merging nodeset\n"); 245575be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard return(NULL); 245675be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard } 245775be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard val1->nodeTab = temp; 245875be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard } 245975be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard if (val2->nodeTab[i]->type == XML_NAMESPACE_DECL) { 246075be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard xmlNsPtr ns = (xmlNsPtr) val2->nodeTab[i]; 246175be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard 246275be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard val1->nodeTab[val1->nodeNr++] = 246375be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard xmlXPathNodeSetDupNs((xmlNodePtr) ns->next, ns); 246475be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard } else 246575be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard val1->nodeTab[val1->nodeNr++] = val2->nodeTab[i]; 246675be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard } 246775be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard 246875be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard return(val1); 246975be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard} 247075be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard 247175be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard/** 24723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNodeSetDel: 24733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur: the initial node set 24743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val: an xmlNodePtr 24753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 24763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Removes an xmlNodePtr from an existing NodeSet 24773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 24783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 24793473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNodeSetDel(xmlNodeSetPtr cur, xmlNodePtr val) { 24803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int i; 24813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 24823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == NULL) return; 24833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (val == NULL) return; 24843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 24853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 2486081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack * find node in nodeTab 24873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 24883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor for (i = 0;i < cur->nodeNr;i++) 24893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur->nodeTab[i] == val) break; 24903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 2491081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack if (i >= cur->nodeNr) { /* not found */ 24923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG 24933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 24943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "xmlXPathNodeSetDel: Node %s wasn't found in NodeList\n", 24953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor val->name); 24963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 24973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return; 24983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 2499044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if ((cur->nodeTab[i] != NULL) && 2500044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard (cur->nodeTab[i]->type == XML_NAMESPACE_DECL)) 2501044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlXPathNodeSetFreeNs((xmlNsPtr) cur->nodeTab[i]); 25023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur->nodeNr--; 25033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor for (;i < cur->nodeNr;i++) 25043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur->nodeTab[i] = cur->nodeTab[i + 1]; 25053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur->nodeTab[cur->nodeNr] = NULL; 25063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 25073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 25083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 25093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNodeSetRemove: 25103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur: the initial node set 25113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val: the index to remove 25123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 25133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Removes an entry from an existing NodeSet list. 25143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 25153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 25163473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNodeSetRemove(xmlNodeSetPtr cur, int val) { 25173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == NULL) return; 25183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (val >= cur->nodeNr) return; 2519044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if ((cur->nodeTab[val] != NULL) && 2520044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard (cur->nodeTab[val]->type == XML_NAMESPACE_DECL)) 2521044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlXPathNodeSetFreeNs((xmlNsPtr) cur->nodeTab[val]); 25223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur->nodeNr--; 25233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor for (;val < cur->nodeNr;val++) 25243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur->nodeTab[val] = cur->nodeTab[val + 1]; 25253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur->nodeTab[cur->nodeNr] = NULL; 25263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 25273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 25283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 25293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathFreeNodeSet: 25303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @obj: the xmlNodeSetPtr to free 25313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 25323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Free the NodeSet compound (not the actual nodes !). 25333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 25343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 25353473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathFreeNodeSet(xmlNodeSetPtr obj) { 25363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (obj == NULL) return; 25373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (obj->nodeTab != NULL) { 2538044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard int i; 2539044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard 2540081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack /* @@ with_ns to check whether namespace nodes should be looked at @@ */ 2541044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard for (i = 0;i < obj->nodeNr;i++) 2542044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if ((obj->nodeTab[i] != NULL) && 2543044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard (obj->nodeTab[i]->type == XML_NAMESPACE_DECL)) 2544044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlXPathNodeSetFreeNs((xmlNsPtr) obj->nodeTab[i]); 25453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(obj->nodeTab); 25463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 25473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(obj); 25483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 25493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 25503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 25513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathFreeValueTree: 25523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @obj: the xmlNodeSetPtr to free 25533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 25543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Free the NodeSet compound and the actual tree, this is different 25553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * from xmlXPathFreeNodeSet() 25563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 255756a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic void 25583473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathFreeValueTree(xmlNodeSetPtr obj) { 25593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int i; 25603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 25613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (obj == NULL) return; 25623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 25633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (obj->nodeTab != NULL) { 2564044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard for (i = 0;i < obj->nodeNr;i++) { 2565044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if (obj->nodeTab[i] != NULL) { 2566044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if (obj->nodeTab[i]->type == XML_NAMESPACE_DECL) { 2567044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlXPathNodeSetFreeNs((xmlNsPtr) obj->nodeTab[i]); 2568044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } else { 2569044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlFreeNodeList(obj->nodeTab[i]); 2570044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } 2571044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } 2572044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } 25733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(obj->nodeTab); 25743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 25753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(obj); 25763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 25773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 25783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#if defined(DEBUG) || defined(DEBUG_STEP) 25793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 25803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlGenericErrorContextNodeSet: 25813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @output: a FILE * for the output 2582081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack * @obj: the xmlNodeSetPtr to display 25833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 25843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Quick display of a NodeSet 25853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 25863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 25873473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlGenericErrorContextNodeSet(FILE *output, xmlNodeSetPtr obj) { 25883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int i; 25893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 25903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (output == NULL) output = xmlGenericErrorContext; 25913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (obj == NULL) { 25923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, "NodeSet == NULL !\n"); 25933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return; 25943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 25953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (obj->nodeNr == 0) { 25963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, "NodeSet is empty\n"); 25973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return; 25983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 25993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (obj->nodeTab == NULL) { 26003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, " nodeTab == NULL !\n"); 26013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return; 26023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 26033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor for (i = 0; i < obj->nodeNr; i++) { 26043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (obj->nodeTab[i] == NULL) { 26053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, " NULL !\n"); 26063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return; 26073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 26083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((obj->nodeTab[i]->type == XML_DOCUMENT_NODE) || 26093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor (obj->nodeTab[i]->type == XML_HTML_DOCUMENT_NODE)) 26103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, " /"); 26113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else if (obj->nodeTab[i]->name == NULL) 26123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, " noname!"); 26133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else fprintf(output, " %s", obj->nodeTab[i]->name); 26143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 26153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fprintf(output, "\n"); 26163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 26173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 26183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 26193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 26203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNewNodeSet: 26213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val: the NodePtr value 26223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 26233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Create a new xmlXPathObjectPtr of type NodeSet and initialize 26243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * it with the single Node @val 26253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 26263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the newly created object. 26273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 26283473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathObjectPtr 26293473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNewNodeSet(xmlNodePtr val) { 26303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr ret; 26313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 26323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject)); 26333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ret == NULL) { 2634d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard xmlXPathErrMemory(NULL, "creating nodeset\n"); 26353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 26363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 26373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor memset(ret, 0 , (size_t) sizeof(xmlXPathObject)); 26383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->type = XPATH_NODESET; 263977851710aba3a0effdc6af67ea4caf212307420cDaniel Veillard ret->boolval = 0; 26403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->nodesetval = xmlXPathNodeSetCreate(val); 2641081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack /* @@ with_ns to check whether namespace nodes should be looked at @@ */ 26423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ret); 26433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 26443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 26453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 26463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNewValueTree: 26473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val: the NodePtr value 26483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 26493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Create a new xmlXPathObjectPtr of type Value Tree (XSLT) and initialize 26503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * it with the tree root @val 26513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 26523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the newly created object. 26533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 26543473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathObjectPtr 26553473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNewValueTree(xmlNodePtr val) { 26563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr ret; 26573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 26583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject)); 26593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ret == NULL) { 2660d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard xmlXPathErrMemory(NULL, "creating result value tree\n"); 26613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 26623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 26633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor memset(ret, 0 , (size_t) sizeof(xmlXPathObject)); 26643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->type = XPATH_XSLT_TREE; 26650ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard ret->boolval = 1; 26660ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard ret->user = (void *) val; 26673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->nodesetval = xmlXPathNodeSetCreate(val); 26683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ret); 26693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 26703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 26713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 26723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNewNodeSetList: 26733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val: an existing NodeSet 26743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 26753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Create a new xmlXPathObjectPtr of type NodeSet and initialize 26763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * it with the Nodeset @val 26773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 26783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the newly created object. 26793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 26803473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathObjectPtr 2681044fc6b7476798cbb95277b4905e5111d7c2775dDaniel VeillardxmlXPathNewNodeSetList(xmlNodeSetPtr val) 2682044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard{ 26833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr ret; 26843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int i; 26853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 26863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (val == NULL) 2687044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard ret = NULL; 26883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else if (val->nodeTab == NULL) 2689044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard ret = xmlXPathNewNodeSet(NULL); 2690044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard else { 2691044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard ret = xmlXPathNewNodeSet(val->nodeTab[0]); 2692044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard for (i = 1; i < val->nodeNr; ++i) 2693044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlXPathNodeSetAddUnique(ret->nodesetval, val->nodeTab[i]); 2694044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } 26953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 2696044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard return (ret); 26973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 26983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 26993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 27003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathWrapNodeSet: 27013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val: the NodePtr value 27023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 27033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Wrap the Nodeset @val in a new xmlXPathObjectPtr 27043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 27053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the newly created object. 27063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 27073473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathObjectPtr 27083473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathWrapNodeSet(xmlNodeSetPtr val) { 27093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr ret; 27103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 27113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject)); 27123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ret == NULL) { 2713d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard xmlXPathErrMemory(NULL, "creating node set object\n"); 27143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 27153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 27163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor memset(ret, 0 , (size_t) sizeof(xmlXPathObject)); 27173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->type = XPATH_NODESET; 27183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->nodesetval = val; 27193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ret); 27203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 27213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 27223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 27233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathFreeNodeSetList: 27243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @obj: an existing NodeSetList object 27253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 27263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Free up the xmlXPathObjectPtr @obj but don't deallocate the objects in 27273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the list contrary to xmlXPathFreeObject(). 27283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 27293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 27303473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathFreeNodeSetList(xmlXPathObjectPtr obj) { 27313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (obj == NULL) return; 27323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(obj); 27333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 27343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 2735f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/** 2736f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathDifference: 2737f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes1: a node-set 2738f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes2: a node-set 2739f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 2740f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Implements the EXSLT - Sets difference() function: 2741f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * node-set set:difference (node-set, node-set) 2742f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 2743f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns the difference between the two node sets, or nodes1 if 2744f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * nodes2 is empty 2745f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */ 2746f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlNodeSetPtr 2747f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathDifference (xmlNodeSetPtr nodes1, xmlNodeSetPtr nodes2) { 2748f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlNodeSetPtr ret; 2749f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer int i, l1; 2750f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlNodePtr cur; 2751f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 2752f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (xmlXPathNodeSetIsEmpty(nodes2)) 2753f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(nodes1); 2754f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 2755f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer ret = xmlXPathNodeSetCreate(NULL); 2756f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (xmlXPathNodeSetIsEmpty(nodes1)) 2757f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(ret); 2758f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 2759f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer l1 = xmlXPathNodeSetGetLength(nodes1); 2760f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 2761f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer for (i = 0; i < l1; i++) { 2762f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer cur = xmlXPathNodeSetItem(nodes1, i); 2763f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (!xmlXPathNodeSetContains(nodes2, cur)) 2764f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathNodeSetAddUnique(ret, cur); 2765f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer } 2766f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(ret); 2767f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer} 2768f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 2769f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/** 2770f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathIntersection: 2771f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes1: a node-set 2772f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes2: a node-set 2773f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 2774f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Implements the EXSLT - Sets intersection() function: 2775f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * node-set set:intersection (node-set, node-set) 2776f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 2777f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns a node set comprising the nodes that are within both the 2778f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * node sets passed as arguments 2779f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */ 2780f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlNodeSetPtr 2781f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathIntersection (xmlNodeSetPtr nodes1, xmlNodeSetPtr nodes2) { 2782f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlNodeSetPtr ret = xmlXPathNodeSetCreate(NULL); 2783f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer int i, l1; 2784f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlNodePtr cur; 2785f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 2786f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (xmlXPathNodeSetIsEmpty(nodes1)) 2787f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(ret); 2788f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (xmlXPathNodeSetIsEmpty(nodes2)) 2789f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(ret); 2790f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 2791f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer l1 = xmlXPathNodeSetGetLength(nodes1); 2792f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 2793f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer for (i = 0; i < l1; i++) { 2794f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer cur = xmlXPathNodeSetItem(nodes1, i); 2795f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (xmlXPathNodeSetContains(nodes2, cur)) 2796f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathNodeSetAddUnique(ret, cur); 2797f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer } 2798f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(ret); 2799f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer} 2800f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 2801f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/** 2802f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathDistinctSorted: 2803f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes: a node-set, sorted by document order 2804f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 2805f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Implements the EXSLT - Sets distinct() function: 2806f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * node-set set:distinct (node-set) 2807f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 2808f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns a subset of the nodes contained in @nodes, or @nodes if 2809f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * it is empty 2810f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */ 2811f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlNodeSetPtr 2812f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathDistinctSorted (xmlNodeSetPtr nodes) { 2813f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlNodeSetPtr ret; 2814f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlHashTablePtr hash; 2815f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer int i, l; 2816f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlChar * strval; 2817f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlNodePtr cur; 2818f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 2819f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (xmlXPathNodeSetIsEmpty(nodes)) 2820f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(nodes); 2821f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 2822f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer ret = xmlXPathNodeSetCreate(NULL); 2823f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer l = xmlXPathNodeSetGetLength(nodes); 2824f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer hash = xmlHashCreate (l); 2825f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer for (i = 0; i < l; i++) { 2826f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer cur = xmlXPathNodeSetItem(nodes, i); 2827f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer strval = xmlXPathCastNodeToString(cur); 2828f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (xmlHashLookup(hash, strval) == NULL) { 2829f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlHashAddEntry(hash, strval, strval); 2830f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathNodeSetAddUnique(ret, cur); 2831f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer } else { 2832f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlFree(strval); 2833f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer } 2834f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer } 2835f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlHashFree(hash, (xmlHashDeallocator) xmlFree); 2836f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(ret); 2837f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer} 2838f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 2839f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/** 2840f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathDistinct: 2841f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes: a node-set 2842f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 2843f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Implements the EXSLT - Sets distinct() function: 2844f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * node-set set:distinct (node-set) 2845f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes is sorted by document order, then #exslSetsDistinctSorted 2846f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * is called with the sorted node-set 2847f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 2848f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns a subset of the nodes contained in @nodes, or @nodes if 2849f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * it is empty 2850f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */ 2851f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlNodeSetPtr 2852f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathDistinct (xmlNodeSetPtr nodes) { 2853f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (xmlXPathNodeSetIsEmpty(nodes)) 2854f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(nodes); 2855f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 2856f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathNodeSetSort(nodes); 2857f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(xmlXPathDistinctSorted(nodes)); 2858f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer} 2859f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 2860f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/** 2861f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathHasSameNodes: 2862f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes1: a node-set 2863f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes2: a node-set 2864f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 2865f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Implements the EXSLT - Sets has-same-nodes function: 2866f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * boolean set:has-same-node(node-set, node-set) 2867f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 2868f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns true (1) if @nodes1 shares any node with @nodes2, false (0) 2869f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * otherwise 2870f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */ 2871f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyerint 2872f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathHasSameNodes (xmlNodeSetPtr nodes1, xmlNodeSetPtr nodes2) { 2873f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer int i, l; 2874f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlNodePtr cur; 2875f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 2876f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (xmlXPathNodeSetIsEmpty(nodes1) || 2877f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathNodeSetIsEmpty(nodes2)) 2878f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(0); 2879f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 2880f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer l = xmlXPathNodeSetGetLength(nodes1); 2881f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer for (i = 0; i < l; i++) { 2882f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer cur = xmlXPathNodeSetItem(nodes1, i); 2883f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (xmlXPathNodeSetContains(nodes2, cur)) 2884f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(1); 2885f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer } 2886f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(0); 2887f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer} 2888f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 2889f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/** 2890f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathNodeLeadingSorted: 2891f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes: a node-set, sorted by document order 2892f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @node: a node 2893f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 2894f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Implements the EXSLT - Sets leading() function: 2895f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * node-set set:leading (node-set, node-set) 2896f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 2897f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns the nodes in @nodes that precede @node in document order, 2898f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes if @node is NULL or an empty node-set if @nodes 2899f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * doesn't contain @node 2900f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */ 2901f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlNodeSetPtr 2902f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathNodeLeadingSorted (xmlNodeSetPtr nodes, xmlNodePtr node) { 2903f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer int i, l; 2904f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlNodePtr cur; 2905f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlNodeSetPtr ret; 2906f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 2907f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (node == NULL) 2908f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(nodes); 2909f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 2910f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer ret = xmlXPathNodeSetCreate(NULL); 2911f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (xmlXPathNodeSetIsEmpty(nodes) || 2912f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer (!xmlXPathNodeSetContains(nodes, node))) 2913f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(ret); 2914f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 2915f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer l = xmlXPathNodeSetGetLength(nodes); 2916f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer for (i = 0; i < l; i++) { 2917f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer cur = xmlXPathNodeSetItem(nodes, i); 2918f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (cur == node) 2919f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer break; 2920f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathNodeSetAddUnique(ret, cur); 2921f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer } 2922f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(ret); 2923f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer} 2924f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 2925f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/** 2926f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathNodeLeading: 2927f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes: a node-set 2928f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @node: a node 2929f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 2930f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Implements the EXSLT - Sets leading() function: 2931f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * node-set set:leading (node-set, node-set) 2932f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes is sorted by document order, then #exslSetsNodeLeadingSorted 2933f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * is called. 2934f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 2935f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns the nodes in @nodes that precede @node in document order, 2936f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes if @node is NULL or an empty node-set if @nodes 2937f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * doesn't contain @node 2938f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */ 2939f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlNodeSetPtr 2940f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathNodeLeading (xmlNodeSetPtr nodes, xmlNodePtr node) { 2941f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathNodeSetSort(nodes); 2942f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(xmlXPathNodeLeadingSorted(nodes, node)); 2943f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer} 2944f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 2945f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/** 2946f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathLeadingSorted: 2947f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes1: a node-set, sorted by document order 2948f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes2: a node-set, sorted by document order 2949f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 2950f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Implements the EXSLT - Sets leading() function: 2951f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * node-set set:leading (node-set, node-set) 2952f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 2953f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns the nodes in @nodes1 that precede the first node in @nodes2 2954f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * in document order, @nodes1 if @nodes2 is NULL or empty or 2955f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * an empty node-set if @nodes1 doesn't contain @nodes2 2956f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */ 2957f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlNodeSetPtr 2958f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathLeadingSorted (xmlNodeSetPtr nodes1, xmlNodeSetPtr nodes2) { 2959f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (xmlXPathNodeSetIsEmpty(nodes2)) 2960f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(nodes1); 2961f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(xmlXPathNodeLeadingSorted(nodes1, 2962f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathNodeSetItem(nodes2, 1))); 2963f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer} 2964f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 2965f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/** 2966f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathLeading: 2967f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes1: a node-set 2968f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes2: a node-set 2969f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 2970f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Implements the EXSLT - Sets leading() function: 2971f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * node-set set:leading (node-set, node-set) 2972f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes1 and @nodes2 are sorted by document order, then 2973f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * #exslSetsLeadingSorted is called. 2974f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 2975f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns the nodes in @nodes1 that precede the first node in @nodes2 2976f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * in document order, @nodes1 if @nodes2 is NULL or empty or 2977f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * an empty node-set if @nodes1 doesn't contain @nodes2 2978f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */ 2979f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlNodeSetPtr 2980f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathLeading (xmlNodeSetPtr nodes1, xmlNodeSetPtr nodes2) { 2981f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (xmlXPathNodeSetIsEmpty(nodes2)) 2982f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(nodes1); 2983f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (xmlXPathNodeSetIsEmpty(nodes1)) 2984f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(xmlXPathNodeSetCreate(NULL)); 2985f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathNodeSetSort(nodes1); 2986f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathNodeSetSort(nodes2); 2987f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(xmlXPathNodeLeadingSorted(nodes1, 2988f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathNodeSetItem(nodes2, 1))); 2989f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer} 2990f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 2991f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/** 2992f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathNodeTrailingSorted: 2993f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes: a node-set, sorted by document order 2994f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @node: a node 2995f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 2996f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Implements the EXSLT - Sets trailing() function: 2997f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * node-set set:trailing (node-set, node-set) 2998f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 2999f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns the nodes in @nodes that follow @node in document order, 3000f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes if @node is NULL or an empty node-set if @nodes 3001f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * doesn't contain @node 3002f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */ 3003f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlNodeSetPtr 3004f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathNodeTrailingSorted (xmlNodeSetPtr nodes, xmlNodePtr node) { 3005f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer int i, l; 3006f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlNodePtr cur; 3007f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlNodeSetPtr ret; 3008f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 3009f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (node == NULL) 3010f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(nodes); 3011f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 3012f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer ret = xmlXPathNodeSetCreate(NULL); 3013f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (xmlXPathNodeSetIsEmpty(nodes) || 3014f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer (!xmlXPathNodeSetContains(nodes, node))) 3015f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(ret); 3016f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 3017f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer l = xmlXPathNodeSetGetLength(nodes); 3018f186c8259ae985cd56b3e14c1def484ab127fd14Thomas Broyer for (i = l; i > 0; i--) { 3019f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer cur = xmlXPathNodeSetItem(nodes, i); 3020f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (cur == node) 3021f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer break; 3022f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathNodeSetAddUnique(ret, cur); 3023f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer } 3024f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(ret); 3025f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer} 3026f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 3027f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/** 3028f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathNodeTrailing: 3029f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes: a node-set 3030f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @node: a node 3031f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 3032f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Implements the EXSLT - Sets trailing() function: 3033f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * node-set set:trailing (node-set, node-set) 3034f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes is sorted by document order, then #xmlXPathNodeTrailingSorted 3035f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * is called. 3036f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 3037f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns the nodes in @nodes that follow @node in document order, 3038f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes if @node is NULL or an empty node-set if @nodes 3039f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * doesn't contain @node 3040f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */ 3041f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlNodeSetPtr 3042f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathNodeTrailing (xmlNodeSetPtr nodes, xmlNodePtr node) { 3043f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathNodeSetSort(nodes); 3044f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(xmlXPathNodeTrailingSorted(nodes, node)); 3045f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer} 3046f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 3047f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/** 3048f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathTrailingSorted: 3049f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes1: a node-set, sorted by document order 3050f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes2: a node-set, sorted by document order 3051f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 3052f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Implements the EXSLT - Sets trailing() function: 3053f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * node-set set:trailing (node-set, node-set) 3054f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 3055f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns the nodes in @nodes1 that follow the first node in @nodes2 3056f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * in document order, @nodes1 if @nodes2 is NULL or empty or 3057f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * an empty node-set if @nodes1 doesn't contain @nodes2 3058f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */ 3059f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlNodeSetPtr 3060f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathTrailingSorted (xmlNodeSetPtr nodes1, xmlNodeSetPtr nodes2) { 3061f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (xmlXPathNodeSetIsEmpty(nodes2)) 3062f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(nodes1); 3063f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(xmlXPathNodeTrailingSorted(nodes1, 3064f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathNodeSetItem(nodes2, 0))); 3065f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer} 3066f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 3067f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/** 3068f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathTrailing: 3069f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes1: a node-set 3070f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes2: a node-set 3071f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 3072f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Implements the EXSLT - Sets trailing() function: 3073f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * node-set set:trailing (node-set, node-set) 3074f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes1 and @nodes2 are sorted by document order, then 3075f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * #xmlXPathTrailingSorted is called. 3076f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 3077f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns the nodes in @nodes1 that follow the first node in @nodes2 3078f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * in document order, @nodes1 if @nodes2 is NULL or empty or 3079f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * an empty node-set if @nodes1 doesn't contain @nodes2 3080f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */ 3081f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlNodeSetPtr 3082f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathTrailing (xmlNodeSetPtr nodes1, xmlNodeSetPtr nodes2) { 3083f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (xmlXPathNodeSetIsEmpty(nodes2)) 3084f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(nodes1); 3085f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (xmlXPathNodeSetIsEmpty(nodes1)) 3086f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(xmlXPathNodeSetCreate(NULL)); 3087f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathNodeSetSort(nodes1); 3088f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathNodeSetSort(nodes2); 3089f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(xmlXPathNodeTrailingSorted(nodes1, 3090f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathNodeSetItem(nodes2, 0))); 3091f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer} 3092f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 30933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/************************************************************************ 30943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * * 30953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Routines to handle extra functions * 30963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * * 30973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ************************************************************************/ 30983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 30993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 31003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathRegisterFunc: 31013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath context 31023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @name: the function name 31033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @f: the function implementation or NULL 31043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 31053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Register a new function. If @f is NULL it unregisters the function 31063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 31073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns 0 in case of success, -1 in case of error 31083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 31093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorint 31103473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathRegisterFunc(xmlXPathContextPtr ctxt, const xmlChar *name, 31113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFunction f) { 31123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(xmlXPathRegisterFuncNS(ctxt, name, NULL, f)); 31133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 31143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 31153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 31163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathRegisterFuncNS: 31173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath context 31183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @name: the function name 31193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ns_uri: the function namespace URI 31203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @f: the function implementation or NULL 31213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 31223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Register a new function. If @f is NULL it unregisters the function 31233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 31243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns 0 in case of success, -1 in case of error 31253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 31263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorint 31273473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathRegisterFuncNS(xmlXPathContextPtr ctxt, const xmlChar *name, 31283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor const xmlChar *ns_uri, xmlXPathFunction f) { 31293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt == NULL) 31303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(-1); 31313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (name == NULL) 31323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(-1); 31333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 31343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->funcHash == NULL) 31353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ctxt->funcHash = xmlHashCreate(0); 31363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->funcHash == NULL) 31373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(-1); 313894394cd1e494f8d669b310748f54192268185c8dDaniel Veillard if (f == NULL) 313994394cd1e494f8d669b310748f54192268185c8dDaniel Veillard return(xmlHashRemoveEntry2(ctxt->funcHash, name, ns_uri, NULL)); 3140ad0e67c57f26f691fc120d5c5336cee9885cf324William M. Brack return(xmlHashAddEntry2(ctxt->funcHash, name, ns_uri, XML_CAST_FPTR(f))); 31413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 31423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 31433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 3144ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer * xmlXPathRegisterFuncLookup: 3145ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer * @ctxt: the XPath context 3146ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer * @f: the lookup function 3147cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * @funcCtxt: the lookup data 3148ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer * 3149cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * Registers an external mechanism to do function lookup. 3150ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer */ 3151ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyervoid 3152ba4ad3263bf7f5625329f115367e0c7018521a16Thomas BroyerxmlXPathRegisterFuncLookup (xmlXPathContextPtr ctxt, 3153ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer xmlXPathFuncLookupFunc f, 3154ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer void *funcCtxt) { 3155ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer if (ctxt == NULL) 3156ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer return; 31576ebf3c4c1a78406d15e8629b4a7b3d52549f0c8bDaniel Veillard ctxt->funcLookupFunc = f; 3158ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer ctxt->funcLookupData = funcCtxt; 3159ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer} 3160ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer 3161ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer/** 31623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathFunctionLookup: 31633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath context 31643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @name: the function name 31653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 31663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Search in the Function array of the context for the given 31673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * function. 31683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 31693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the xmlXPathFunction or NULL if not found 31703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 31713473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathFunction 31723473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathFunctionLookup(xmlXPathContextPtr ctxt, const xmlChar *name) { 3173ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer if (ctxt == NULL) 3174ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer return (NULL); 3175ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer 3176ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer if (ctxt->funcLookupFunc != NULL) { 3177ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer xmlXPathFunction ret; 317899e55ebe945f6f4de33e8454f2770e02295a3a00Daniel Veillard xmlXPathFuncLookupFunc f; 3179ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer 31806ebf3c4c1a78406d15e8629b4a7b3d52549f0c8bDaniel Veillard f = ctxt->funcLookupFunc; 3181963d2ae41574066f9b44bcae610dd280c1e57dd8Daniel Veillard ret = f(ctxt->funcLookupData, name, NULL); 3182ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer if (ret != NULL) 3183ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer return(ret); 3184ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer } 31853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(xmlXPathFunctionLookupNS(ctxt, name, NULL)); 31863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 31873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 31883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 31893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathFunctionLookupNS: 31903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath context 31913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @name: the function name 31923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ns_uri: the function namespace URI 31933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 31943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Search in the Function array of the context for the given 31953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * function. 31963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 31973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the xmlXPathFunction or NULL if not found 31983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 31993473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathFunction 32003473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathFunctionLookupNS(xmlXPathContextPtr ctxt, const xmlChar *name, 32013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor const xmlChar *ns_uri) { 3202ad0e67c57f26f691fc120d5c5336cee9885cf324William M. Brack xmlXPathFunction ret; 3203ad0e67c57f26f691fc120d5c5336cee9885cf324William M. Brack 32043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt == NULL) 32053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 32063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (name == NULL) 32073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 32083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 3209ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer if (ctxt->funcLookupFunc != NULL) { 321099e55ebe945f6f4de33e8454f2770e02295a3a00Daniel Veillard xmlXPathFuncLookupFunc f; 3211ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer 32126ebf3c4c1a78406d15e8629b4a7b3d52549f0c8bDaniel Veillard f = ctxt->funcLookupFunc; 3213963d2ae41574066f9b44bcae610dd280c1e57dd8Daniel Veillard ret = f(ctxt->funcLookupData, name, ns_uri); 3214ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer if (ret != NULL) 3215ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer return(ret); 3216ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer } 3217ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer 3218ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer if (ctxt->funcHash == NULL) 3219ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer return(NULL); 3220ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer 3221ad0e67c57f26f691fc120d5c5336cee9885cf324William M. Brack XML_CAST_FPTR(ret) = xmlHashLookup2(ctxt->funcHash, name, ns_uri); 3222ad0e67c57f26f691fc120d5c5336cee9885cf324William M. Brack return(ret); 32233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 32243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 32253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 32263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathRegisteredFuncsCleanup: 32273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath context 32283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 32293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Cleanup the XPath context data associated to registered functions 32303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 32313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 32323473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathRegisteredFuncsCleanup(xmlXPathContextPtr ctxt) { 32333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt == NULL) 32343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return; 32353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 32363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlHashFree(ctxt->funcHash, NULL); 32373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ctxt->funcHash = NULL; 32383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 32393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 32403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/************************************************************************ 32413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * * 3242081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack * Routines to handle Variables * 32433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * * 32443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ************************************************************************/ 32453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 32463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 32473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathRegisterVariable: 32483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath context 32493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @name: the variable name 32503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @value: the variable value or NULL 32513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 32523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Register a new variable value. If @value is NULL it unregisters 32533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the variable 32543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 32553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns 0 in case of success, -1 in case of error 32563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 32573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorint 32583473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathRegisterVariable(xmlXPathContextPtr ctxt, const xmlChar *name, 32593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr value) { 32603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(xmlXPathRegisterVariableNS(ctxt, name, NULL, value)); 32613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 32623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 32633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 32643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathRegisterVariableNS: 32653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath context 32663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @name: the variable name 32673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ns_uri: the variable namespace URI 32683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @value: the variable value or NULL 32693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 32703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Register a new variable value. If @value is NULL it unregisters 32713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the variable 32723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 32733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns 0 in case of success, -1 in case of error 32743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 32753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorint 32763473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathRegisterVariableNS(xmlXPathContextPtr ctxt, const xmlChar *name, 32773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor const xmlChar *ns_uri, 32783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr value) { 32793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt == NULL) 32803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(-1); 32813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (name == NULL) 32823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(-1); 32833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 32843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->varHash == NULL) 32853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ctxt->varHash = xmlHashCreate(0); 32863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->varHash == NULL) 32873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(-1); 328894394cd1e494f8d669b310748f54192268185c8dDaniel Veillard if (value == NULL) 328994394cd1e494f8d669b310748f54192268185c8dDaniel Veillard return(xmlHashRemoveEntry2(ctxt->varHash, name, ns_uri, 329094394cd1e494f8d669b310748f54192268185c8dDaniel Veillard (xmlHashDeallocator)xmlXPathFreeObject)); 32913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(xmlHashUpdateEntry2(ctxt->varHash, name, ns_uri, 32923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor (void *) value, 32933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor (xmlHashDeallocator)xmlXPathFreeObject)); 32943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 32953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 32963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 32973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathRegisterVariableLookup: 32983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath context 32993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @f: the lookup function 33003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @data: the lookup data 33013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 33023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * register an external mechanism to do variable lookup 33033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 33043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 33053473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathRegisterVariableLookup(xmlXPathContextPtr ctxt, 33063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathVariableLookupFunc f, void *data) { 33073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt == NULL) 33083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return; 33096ebf3c4c1a78406d15e8629b4a7b3d52549f0c8bDaniel Veillard ctxt->varLookupFunc = f; 33103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ctxt->varLookupData = data; 33113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 33123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 33133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 33143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathVariableLookup: 33153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath context 33163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @name: the variable name 33173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 33183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Search in the Variable array of the context for the given 33193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * variable value. 33203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 332173c9c049195bf897dbcb6308a1ab9d16b3fe6b2cDaniel Veillard * Returns a copy of the value or NULL if not found 33223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 33233473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathObjectPtr 33243473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathVariableLookup(xmlXPathContextPtr ctxt, const xmlChar *name) { 33253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt == NULL) 33263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 33273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 33283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->varLookupFunc != NULL) { 33293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr ret; 33303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 33313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = ((xmlXPathVariableLookupFunc)ctxt->varLookupFunc) 33323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor (ctxt->varLookupData, name, NULL); 3333556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard return(ret); 33343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 33353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(xmlXPathVariableLookupNS(ctxt, name, NULL)); 33363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 33373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 33383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 33393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathVariableLookupNS: 33403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath context 33413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @name: the variable name 33423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ns_uri: the variable namespace URI 33433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 33443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Search in the Variable array of the context for the given 334573c9c049195bf897dbcb6308a1ab9d16b3fe6b2cDaniel Veillard * variable value. 33463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 334773c9c049195bf897dbcb6308a1ab9d16b3fe6b2cDaniel Veillard * Returns the a copy of the value or NULL if not found 33483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 33493473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathObjectPtr 33503473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathVariableLookupNS(xmlXPathContextPtr ctxt, const xmlChar *name, 33513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor const xmlChar *ns_uri) { 33523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt == NULL) 33533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 33543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 33553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->varLookupFunc != NULL) { 33563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr ret; 33573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 33583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = ((xmlXPathVariableLookupFunc)ctxt->varLookupFunc) 33593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor (ctxt->varLookupData, name, ns_uri); 33603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ret != NULL) return(ret); 33613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 33623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 33633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->varHash == NULL) 33643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 33653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (name == NULL) 33663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 33673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 33688c357d58c2d1dde022b67393a47dcb52100ce129Daniel Veillard return(xmlXPathObjectCopy((xmlXPathObjectPtr) 33698c357d58c2d1dde022b67393a47dcb52100ce129Daniel Veillard xmlHashLookup2(ctxt->varHash, name, ns_uri))); 33703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 33713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 33723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 33733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathRegisteredVariablesCleanup: 33743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath context 33753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 33763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Cleanup the XPath context data associated to registered variables 33773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 33783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 33793473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathRegisteredVariablesCleanup(xmlXPathContextPtr ctxt) { 33803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt == NULL) 33813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return; 33823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 338376d66f416d2d0d5db4a09d212b4e43087e9cdae7Daniel Veillard xmlHashFree(ctxt->varHash, (xmlHashDeallocator)xmlXPathFreeObject); 33843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ctxt->varHash = NULL; 33853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 33863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 33873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 33883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathRegisterNs: 33893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath context 33903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @prefix: the namespace prefix 33913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ns_uri: the namespace name 33923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 33933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Register a new namespace. If @ns_uri is NULL it unregisters 33943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the namespace 33953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 33963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns 0 in case of success, -1 in case of error 33973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 33983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorint 33993473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathRegisterNs(xmlXPathContextPtr ctxt, const xmlChar *prefix, 34003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor const xmlChar *ns_uri) { 34013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt == NULL) 34023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(-1); 34033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (prefix == NULL) 34043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(-1); 34053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 34063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->nsHash == NULL) 34073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ctxt->nsHash = xmlHashCreate(10); 34083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->nsHash == NULL) 34093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(-1); 3410e991fe958f5269a459262bcff802a3d26167edb8Daniel Veillard if (ns_uri == NULL) 341194394cd1e494f8d669b310748f54192268185c8dDaniel Veillard return(xmlHashRemoveEntry(ctxt->nsHash, prefix, 3412e991fe958f5269a459262bcff802a3d26167edb8Daniel Veillard (xmlHashDeallocator)xmlFree)); 341342766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard return(xmlHashUpdateEntry(ctxt->nsHash, prefix, (void *) xmlStrdup(ns_uri), 34143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor (xmlHashDeallocator)xmlFree)); 34153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 34163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 34173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 34183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNsLookup: 34193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath context 34203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @prefix: the namespace prefix value 34213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 34223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Search in the namespace declaration array of the context for the given 34233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * namespace name associated to the given prefix 34243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 34253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the value or NULL if not found 34263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 34273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorconst xmlChar * 34283473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNsLookup(xmlXPathContextPtr ctxt, const xmlChar *prefix) { 34293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt == NULL) 34303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 34313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (prefix == NULL) 34323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 34333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 34343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef XML_XML_NAMESPACE 34353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (xmlStrEqual(prefix, (const xmlChar *) "xml")) 34363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(XML_XML_NAMESPACE); 34373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 34383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 3439c8f620ba7f95b3ceb687699e140eeaa33343e41aDaniel Veillard if (ctxt->namespaces != NULL) { 3440c8f620ba7f95b3ceb687699e140eeaa33343e41aDaniel Veillard int i; 3441c8f620ba7f95b3ceb687699e140eeaa33343e41aDaniel Veillard 3442c8f620ba7f95b3ceb687699e140eeaa33343e41aDaniel Veillard for (i = 0;i < ctxt->nsNr;i++) { 3443c8f620ba7f95b3ceb687699e140eeaa33343e41aDaniel Veillard if ((ctxt->namespaces[i] != NULL) && 3444c8f620ba7f95b3ceb687699e140eeaa33343e41aDaniel Veillard (xmlStrEqual(ctxt->namespaces[i]->prefix, prefix))) 3445c8f620ba7f95b3ceb687699e140eeaa33343e41aDaniel Veillard return(ctxt->namespaces[i]->href); 3446c8f620ba7f95b3ceb687699e140eeaa33343e41aDaniel Veillard } 3447c8f620ba7f95b3ceb687699e140eeaa33343e41aDaniel Veillard } 34483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 34493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return((const xmlChar *) xmlHashLookup(ctxt->nsHash, prefix)); 34503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 34513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 34523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 34535e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard * xmlXPathRegisteredNsCleanup: 34543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath context 34553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 34563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Cleanup the XPath context data associated to registered variables 34573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 34583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 34593473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathRegisteredNsCleanup(xmlXPathContextPtr ctxt) { 34603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt == NULL) 34613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return; 34623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 346342766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard xmlHashFree(ctxt->nsHash, (xmlHashDeallocator)xmlFree); 34643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ctxt->nsHash = NULL; 34653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 34663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 34673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/************************************************************************ 34683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * * 34693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Routines to handle Values * 34703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * * 34713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ************************************************************************/ 34723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 3473081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack/* Allocations are terrible, one needs to optimize all this !!! */ 34743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 34753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 34763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNewFloat: 34773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val: the double value 34783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 34793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Create a new xmlXPathObjectPtr of type double and of value @val 34803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 34813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the newly created object. 34823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 34833473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathObjectPtr 34843473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNewFloat(double val) { 34853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr ret; 34863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 34873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject)); 34883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ret == NULL) { 3489d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard xmlXPathErrMemory(NULL, "creating float object\n"); 34903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 34913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 34923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor memset(ret, 0 , (size_t) sizeof(xmlXPathObject)); 34933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->type = XPATH_NUMBER; 34943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->floatval = val; 34953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ret); 34963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 34973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 34983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 34993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNewBoolean: 35003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val: the boolean value 35013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 35023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Create a new xmlXPathObjectPtr of type boolean and of value @val 35033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 35043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the newly created object. 35053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 35063473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathObjectPtr 35073473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNewBoolean(int val) { 35083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr ret; 35093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 35103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject)); 35113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ret == NULL) { 3512d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard xmlXPathErrMemory(NULL, "creating boolean object\n"); 35133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 35143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 35153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor memset(ret, 0 , (size_t) sizeof(xmlXPathObject)); 35163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->type = XPATH_BOOLEAN; 35173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->boolval = (val != 0); 35183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ret); 35193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 35203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 35213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 35223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNewString: 35233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val: the xmlChar * value 35243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 35253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Create a new xmlXPathObjectPtr of type string and of value @val 35263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 35273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the newly created object. 35283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 35293473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathObjectPtr 35303473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNewString(const xmlChar *val) { 35313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr ret; 35323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 35333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject)); 35343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ret == NULL) { 3535d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard xmlXPathErrMemory(NULL, "creating string object\n"); 35363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 35373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 35383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor memset(ret, 0 , (size_t) sizeof(xmlXPathObject)); 35393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->type = XPATH_STRING; 35403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (val != NULL) 35413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->stringval = xmlStrdup(val); 35423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else 35433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->stringval = xmlStrdup((const xmlChar *)""); 35443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ret); 35453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 35463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 35473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 3548ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathWrapString: 3549ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @val: the xmlChar * value 3550ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3551ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Wraps the @val string into an XPath object. 3552ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3553ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns the newly created object. 3554ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */ 3555ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathObjectPtr 3556ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathWrapString (xmlChar *val) { 3557ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlXPathObjectPtr ret; 3558ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 3559ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject)); 3560ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard if (ret == NULL) { 3561d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard xmlXPathErrMemory(NULL, "creating string object\n"); 3562ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(NULL); 3563ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard } 3564ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard memset(ret, 0 , (size_t) sizeof(xmlXPathObject)); 3565ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret->type = XPATH_STRING; 3566ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret->stringval = val; 3567ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(ret); 3568ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard} 3569ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 3570ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/** 35713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNewCString: 35723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val: the char * value 35733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 35743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Create a new xmlXPathObjectPtr of type string and of value @val 35753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 35763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the newly created object. 35773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 35783473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathObjectPtr 35793473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNewCString(const char *val) { 35803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr ret; 35813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 35823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject)); 35833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ret == NULL) { 3584d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard xmlXPathErrMemory(NULL, "creating string object\n"); 35853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 35863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 35873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor memset(ret, 0 , (size_t) sizeof(xmlXPathObject)); 35883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->type = XPATH_STRING; 35893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->stringval = xmlStrdup(BAD_CAST val); 35903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ret); 35913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 35923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 35933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 3594ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathWrapCString: 3595ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @val: the char * value 3596ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3597ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Wraps a string into an XPath object. 3598ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3599ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns the newly created object. 3600ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */ 3601ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathObjectPtr 3602ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathWrapCString (char * val) { 3603ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(xmlXPathWrapString((xmlChar *)(val))); 3604ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard} 3605ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 3606ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/** 3607f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathWrapExternal: 3608f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @val: the user data 3609f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 3610f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Wraps the @val data into an XPath object. 3611f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * 3612f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns the newly created object. 3613f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */ 3614f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathObjectPtr 3615f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathWrapExternal (void *val) { 3616f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer xmlXPathObjectPtr ret; 3617f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 3618f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject)); 3619f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer if (ret == NULL) { 3620d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard xmlXPathErrMemory(NULL, "creating user object\n"); 3621f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(NULL); 3622f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer } 3623f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer memset(ret, 0 , (size_t) sizeof(xmlXPathObject)); 3624f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer ret->type = XPATH_USERS; 3625f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer ret->user = val; 3626f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer return(ret); 3627f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer} 3628f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer 3629f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/** 36303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathObjectCopy: 36313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val: the original object 36323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 36333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * allocate a new copy of a given object 36343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 36353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the newly created object. 36363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 36373473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathObjectPtr 36383473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathObjectCopy(xmlXPathObjectPtr val) { 36393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr ret; 36403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 36413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (val == NULL) 36423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 36433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 36443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject)); 36453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ret == NULL) { 3646d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard xmlXPathErrMemory(NULL, "copying object\n"); 36473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 36483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 36493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor memcpy(ret, val , (size_t) sizeof(xmlXPathObject)); 36503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor switch (val->type) { 36513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_BOOLEAN: 36523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_NUMBER: 36533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_POINT: 36543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_RANGE: 36553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 36563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_STRING: 36573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->stringval = xmlStrdup(val->stringval); 36583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 36593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_XSLT_TREE: 3660e9449c5d29d87b1dc51de7784ed947ae1e3da831William M. Brack#if 0 3661e9449c5d29d87b1dc51de7784ed947ae1e3da831William M. Brack/* 3662e9449c5d29d87b1dc51de7784ed947ae1e3da831William M. Brack Removed 11 July 2004 - the current handling of xslt tmpRVT nodes means that 3663e9449c5d29d87b1dc51de7784ed947ae1e3da831William M. Brack this previous handling is no longer correct, and can cause some serious 3664e9449c5d29d87b1dc51de7784ed947ae1e3da831William M. Brack problems (ref. bug 145547) 3665e9449c5d29d87b1dc51de7784ed947ae1e3da831William M. Brack*/ 36663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((val->nodesetval != NULL) && 36670ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard (val->nodesetval->nodeTab != NULL)) { 36689adc0469d4691e798ea4ad59b84c874cdea8b38dDaniel Veillard xmlNodePtr cur, tmp; 36699adc0469d4691e798ea4ad59b84c874cdea8b38dDaniel Veillard xmlDocPtr top; 3670ef0b45016373d65700ef6f7d494a200758b2e4c5Daniel Veillard 36710ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard ret->boolval = 1; 36729adc0469d4691e798ea4ad59b84c874cdea8b38dDaniel Veillard top = xmlNewDoc(NULL); 36739adc0469d4691e798ea4ad59b84c874cdea8b38dDaniel Veillard top->name = (char *) 36749adc0469d4691e798ea4ad59b84c874cdea8b38dDaniel Veillard xmlStrdup(val->nodesetval->nodeTab[0]->name); 3675ef0b45016373d65700ef6f7d494a200758b2e4c5Daniel Veillard ret->user = top; 3676ef0b45016373d65700ef6f7d494a200758b2e4c5Daniel Veillard if (top != NULL) { 36779adc0469d4691e798ea4ad59b84c874cdea8b38dDaniel Veillard top->doc = top; 3678ef0b45016373d65700ef6f7d494a200758b2e4c5Daniel Veillard cur = val->nodesetval->nodeTab[0]->children; 3679ef0b45016373d65700ef6f7d494a200758b2e4c5Daniel Veillard while (cur != NULL) { 36809adc0469d4691e798ea4ad59b84c874cdea8b38dDaniel Veillard tmp = xmlDocCopyNode(cur, top, 1); 36819adc0469d4691e798ea4ad59b84c874cdea8b38dDaniel Veillard xmlAddChild((xmlNodePtr) top, tmp); 3682ef0b45016373d65700ef6f7d494a200758b2e4c5Daniel Veillard cur = cur->next; 3683ef0b45016373d65700ef6f7d494a200758b2e4c5Daniel Veillard } 3684ef0b45016373d65700ef6f7d494a200758b2e4c5Daniel Veillard } 3685e9449c5d29d87b1dc51de7784ed947ae1e3da831William M. Brack 36869adc0469d4691e798ea4ad59b84c874cdea8b38dDaniel Veillard ret->nodesetval = xmlXPathNodeSetCreate((xmlNodePtr) top); 36870ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard } else 36883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->nodesetval = xmlXPathNodeSetCreate(NULL); 36890ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard /* Deallocate the copied tree value */ 36903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 3691e9449c5d29d87b1dc51de7784ed947ae1e3da831William M. Brack#endif 36923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_NODESET: 36933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->nodesetval = xmlXPathNodeSetMerge(NULL, val->nodesetval); 36940ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard /* Do not deallocate the copied tree value */ 36950ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard ret->boolval = 0; 36963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 36973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_LOCATIONSET: 36983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef LIBXML_XPTR_ENABLED 36993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor { 37003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlLocationSetPtr loc = val->user; 37013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->user = (void *) xmlXPtrLocationSetMerge(NULL, loc); 37023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 37033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 37043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 370547334c09f4373e4cff71334e60a623fee73a525fThomas Broyer case XPATH_USERS: 370647334c09f4373e4cff71334e60a623fee73a525fThomas Broyer ret->user = val->user; 370747334c09f4373e4cff71334e60a623fee73a525fThomas Broyer break; 370847334c09f4373e4cff71334e60a623fee73a525fThomas Broyer case XPATH_UNDEFINED: 37093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 37103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "xmlXPathObjectCopy: unsupported type %d\n", 37113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor val->type); 37123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 37133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 37143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ret); 37153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 37163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 37173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 37183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathFreeObject: 37193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @obj: the object to free 37203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 37213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Free up an xmlXPathObjectPtr object. 37223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 37233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 37243473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathFreeObject(xmlXPathObjectPtr obj) { 37253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (obj == NULL) return; 37260ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard if ((obj->type == XPATH_NODESET) || (obj->type == XPATH_XSLT_TREE)) { 372777851710aba3a0effdc6af67ea4caf212307420cDaniel Veillard if (obj->boolval) { 3728e9449c5d29d87b1dc51de7784ed947ae1e3da831William M. Brack#if 0 37290ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard if (obj->user != NULL) { 37300ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard xmlXPathFreeNodeSet(obj->nodesetval); 373138bf6f042507c6051bfa2db5cc9b6666cfc35c2aDaniel Veillard xmlFreeNodeList((xmlNodePtr) obj->user); 3732e9449c5d29d87b1dc51de7784ed947ae1e3da831William M. Brack } else 3733e9449c5d29d87b1dc51de7784ed947ae1e3da831William M. Brack#endif 3734e9449c5d29d87b1dc51de7784ed947ae1e3da831William M. Brack if (obj->nodesetval != NULL) 373577851710aba3a0effdc6af67ea4caf212307420cDaniel Veillard xmlXPathFreeValueTree(obj->nodesetval); 373677851710aba3a0effdc6af67ea4caf212307420cDaniel Veillard } else { 373777851710aba3a0effdc6af67ea4caf212307420cDaniel Veillard if (obj->nodesetval != NULL) 373877851710aba3a0effdc6af67ea4caf212307420cDaniel Veillard xmlXPathFreeNodeSet(obj->nodesetval); 373977851710aba3a0effdc6af67ea4caf212307420cDaniel Veillard } 37403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef LIBXML_XPTR_ENABLED 37413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else if (obj->type == XPATH_LOCATIONSET) { 37423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (obj->user != NULL) 37433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPtrFreeLocationSet(obj->user); 37443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 37453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else if (obj->type == XPATH_STRING) { 37463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (obj->stringval != NULL) 37473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(obj->stringval); 37483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 37493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 37503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(obj); 37513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 37523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 3753ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 3754ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/************************************************************************ 3755ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * * 3756ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Type Casting Routines * 3757ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * * 3758ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ************************************************************************/ 3759ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 3760ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/** 3761ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathCastBooleanToString: 3762ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @val: a boolean 3763ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3764ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts a boolean to its string value. 3765ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3766ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns a newly allocated string. 3767ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */ 3768ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlChar * 3769ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathCastBooleanToString (int val) { 3770ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlChar *ret; 3771ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard if (val) 3772ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = xmlStrdup((const xmlChar *) "true"); 3773ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard else 3774ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = xmlStrdup((const xmlChar *) "false"); 3775ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(ret); 3776ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard} 3777ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 3778ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/** 3779ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathCastNumberToString: 3780ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @val: a number 3781ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3782ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts a number to its string value. 3783ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3784ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns a newly allocated string. 3785ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */ 3786ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlChar * 3787ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathCastNumberToString (double val) { 3788ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlChar *ret; 3789cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard switch (xmlXPathIsInf(val)) { 3790ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case 1: 37915fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard ret = xmlStrdup((const xmlChar *) "Infinity"); 3792ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard break; 3793ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case -1: 3794ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = xmlStrdup((const xmlChar *) "-Infinity"); 3795ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard break; 3796ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard default: 3797cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard if (xmlXPathIsNaN(val)) { 3798ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = xmlStrdup((const xmlChar *) "NaN"); 3799d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard } else if (val == 0 && xmlXPathGetSign(val) != 0) { 3800d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret = xmlStrdup((const xmlChar *) "0"); 3801ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard } else { 3802ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard /* could be improved */ 3803ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard char buf[100]; 380411ce4004d86bb4b317c48b7d5124ba33e40e10f5Daniel Veillard xmlXPathFormatNumber(val, buf, 99); 380511ce4004d86bb4b317c48b7d5124ba33e40e10f5Daniel Veillard buf[99] = 0; 3806ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = xmlStrdup((const xmlChar *) buf); 3807ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard } 3808ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard } 3809ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(ret); 3810ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard} 3811ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 3812ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/** 3813ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathCastNodeToString: 3814ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @node: a node 3815ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3816ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts a node to its string value. 3817ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3818ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns a newly allocated string. 3819ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */ 3820ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlChar * 3821ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathCastNodeToString (xmlNodePtr node) { 3822ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(xmlNodeGetContent(node)); 3823ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard} 3824ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 3825ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/** 3826ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathCastNodeSetToString: 3827ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @ns: a node-set 3828ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3829ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts a node-set to its string value. 3830ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3831ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns a newly allocated string. 3832ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */ 3833ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlChar * 3834ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathCastNodeSetToString (xmlNodeSetPtr ns) { 3835ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard if ((ns == NULL) || (ns->nodeNr == 0) || (ns->nodeTab == NULL)) 3836ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(xmlStrdup((const xmlChar *) "")); 3837ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 3838ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlXPathNodeSetSort(ns); 3839ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(xmlXPathCastNodeToString(ns->nodeTab[0])); 3840ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard} 3841ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 3842ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/** 3843ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathCastToString: 3844ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @val: an XPath object 3845ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3846ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts an existing object to its string() equivalent 3847ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3848ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns the string value of the object, NULL in case of error. 3849cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * A new string is allocated only if needed (@val isn't a 3850ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * string object). 3851ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */ 3852ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlChar * 3853ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathCastToString(xmlXPathObjectPtr val) { 3854ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlChar *ret = NULL; 3855ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 3856ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard if (val == NULL) 3857ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(xmlStrdup((const xmlChar *) "")); 3858ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard switch (val->type) { 3859ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_UNDEFINED: 3860ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard#ifdef DEBUG_EXPR 3861ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlGenericError(xmlGenericErrorContext, "String: undefined\n"); 3862ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard#endif 3863ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = xmlStrdup((const xmlChar *) ""); 3864ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard break; 3865ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_NODESET: 38660c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack case XPATH_XSLT_TREE: 3867ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = xmlXPathCastNodeSetToString(val->nodesetval); 3868ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard break; 3869ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_STRING: 38704e2df54bb17645ef0d3f28b9665b2d2dde4b47a3Daniel Veillard return(xmlStrdup(val->stringval)); 3871ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_BOOLEAN: 3872ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = xmlXPathCastBooleanToString(val->boolval); 3873ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard break; 3874ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_NUMBER: { 3875ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = xmlXPathCastNumberToString(val->floatval); 3876ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard break; 3877ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard } 3878ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_USERS: 3879ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_POINT: 3880ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_RANGE: 3881ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_LOCATIONSET: 3882ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard TODO 3883ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = xmlStrdup((const xmlChar *) ""); 3884ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard break; 3885ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard } 3886ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(ret); 3887ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard} 3888ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 3889ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/** 3890ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathConvertString: 3891ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @val: an XPath object 3892ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3893ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts an existing object to its string() equivalent 3894ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3895ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns the new object, the old one is freed (or the operation 3896ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * is done directly on @val) 3897ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */ 3898ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathObjectPtr 3899ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathConvertString(xmlXPathObjectPtr val) { 3900ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlChar *res = NULL; 3901ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 3902ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard if (val == NULL) 3903ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(xmlXPathNewCString("")); 3904ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 3905ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard switch (val->type) { 3906ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_UNDEFINED: 3907ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard#ifdef DEBUG_EXPR 3908ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlGenericError(xmlGenericErrorContext, "STRING: undefined\n"); 3909ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard#endif 3910ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard break; 3911ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_NODESET: 39120c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack case XPATH_XSLT_TREE: 3913ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard res = xmlXPathCastNodeSetToString(val->nodesetval); 3914ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard break; 3915ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_STRING: 3916ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(val); 3917ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_BOOLEAN: 3918ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard res = xmlXPathCastBooleanToString(val->boolval); 3919ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard break; 3920ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_NUMBER: 3921ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard res = xmlXPathCastNumberToString(val->floatval); 3922ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard break; 3923ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_USERS: 3924ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_POINT: 3925ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_RANGE: 3926ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_LOCATIONSET: 3927ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard TODO; 3928ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard break; 3929ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard } 3930ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlXPathFreeObject(val); 3931ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard if (res == NULL) 3932ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(xmlXPathNewCString("")); 3933ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(xmlXPathWrapString(res)); 3934ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard} 3935ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 3936ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/** 3937ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathCastBooleanToNumber: 3938ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @val: a boolean 3939ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3940ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts a boolean to its number value 3941ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3942ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns the number value 3943ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */ 3944ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillarddouble 3945ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathCastBooleanToNumber(int val) { 3946ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard if (val) 3947ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(1.0); 3948ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(0.0); 3949ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard} 3950ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 3951ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/** 3952ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathCastStringToNumber: 3953ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @val: a string 3954ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3955ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts a string to its number value 3956ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3957ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns the number value 3958ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */ 3959ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillarddouble 3960ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathCastStringToNumber(const xmlChar * val) { 3961ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(xmlXPathStringEvalNumber(val)); 3962ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard} 3963ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 3964ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/** 3965ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathCastNodeToNumber: 3966ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @node: a node 3967ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3968ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts a node to its number value 3969ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3970ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns the number value 3971ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */ 3972ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillarddouble 3973ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathCastNodeToNumber (xmlNodePtr node) { 3974ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlChar *strval; 3975ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard double ret; 3976ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 3977ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard if (node == NULL) 3978ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(xmlXPathNAN); 3979ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard strval = xmlXPathCastNodeToString(node); 3980ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard if (strval == NULL) 3981ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(xmlXPathNAN); 3982ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = xmlXPathCastStringToNumber(strval); 3983ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlFree(strval); 3984ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 3985ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(ret); 3986ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard} 3987ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 3988ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/** 3989ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathCastNodeSetToNumber: 3990ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @ns: a node-set 3991ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3992ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts a node-set to its number value 3993ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 3994ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns the number value 3995ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */ 3996ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillarddouble 3997ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathCastNodeSetToNumber (xmlNodeSetPtr ns) { 3998ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlChar *str; 3999ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard double ret; 4000ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 4001ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard if (ns == NULL) 4002ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(xmlXPathNAN); 4003ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard str = xmlXPathCastNodeSetToString(ns); 4004ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = xmlXPathCastStringToNumber(str); 4005ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlFree(str); 4006ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(ret); 4007ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard} 4008ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 4009ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/** 4010ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathCastToNumber: 4011ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @val: an XPath object 4012ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 4013ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts an XPath object to its number value 4014ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 4015ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns the number value 4016ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */ 4017ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillarddouble 4018ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathCastToNumber(xmlXPathObjectPtr val) { 4019ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard double ret = 0.0; 4020ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 4021ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard if (val == NULL) 4022ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(xmlXPathNAN); 4023ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard switch (val->type) { 4024ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_UNDEFINED: 4025ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard#ifdef DEGUB_EXPR 4026ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlGenericError(xmlGenericErrorContext, "NUMBER: undefined\n"); 4027ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard#endif 4028ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = xmlXPathNAN; 4029ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard break; 4030ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_NODESET: 40310c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack case XPATH_XSLT_TREE: 4032ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = xmlXPathCastNodeSetToNumber(val->nodesetval); 4033ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard break; 4034ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_STRING: 4035ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = xmlXPathCastStringToNumber(val->stringval); 4036ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard break; 4037ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_NUMBER: 4038ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = val->floatval; 4039ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard break; 4040ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_BOOLEAN: 4041ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = xmlXPathCastBooleanToNumber(val->boolval); 4042ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard break; 4043ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_USERS: 4044ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_POINT: 4045ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_RANGE: 4046ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_LOCATIONSET: 4047ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard TODO; 4048ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = xmlXPathNAN; 4049ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard break; 4050ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard } 4051ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(ret); 4052ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard} 4053ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 4054ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/** 4055ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathConvertNumber: 4056ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @val: an XPath object 4057ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 4058ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts an existing object to its number() equivalent 4059ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 4060ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns the new object, the old one is freed (or the operation 4061ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * is done directly on @val) 4062ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */ 4063ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathObjectPtr 4064ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathConvertNumber(xmlXPathObjectPtr val) { 4065ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlXPathObjectPtr ret; 4066ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 4067ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard if (val == NULL) 4068ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(xmlXPathNewFloat(0.0)); 4069ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard if (val->type == XPATH_NUMBER) 4070ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(val); 4071ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = xmlXPathNewFloat(xmlXPathCastToNumber(val)); 4072ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlXPathFreeObject(val); 4073ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(ret); 4074ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard} 4075ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 4076ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/** 4077ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathCastNumberToBoolean: 4078ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @val: a number 4079ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 4080ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts a number to its boolean value 4081ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 4082ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns the boolean value 4083ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */ 4084ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillardint 4085ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathCastNumberToBoolean (double val) { 4086cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard if (xmlXPathIsNaN(val) || (val == 0.0)) 4087ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(0); 4088ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(1); 4089ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard} 4090ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 4091ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/** 4092ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathCastStringToBoolean: 4093ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @val: a string 4094ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 4095ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts a string to its boolean value 4096ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 4097ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns the boolean value 4098ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */ 4099ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillardint 4100ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathCastStringToBoolean (const xmlChar *val) { 4101ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard if ((val == NULL) || (xmlStrlen(val) == 0)) 4102ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(0); 4103ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(1); 4104ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard} 4105ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 4106ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/** 4107ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathCastNodeSetToBoolean: 4108ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @ns: a node-set 4109ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 4110ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts a node-set to its boolean value 4111ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 4112ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns the boolean value 4113ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */ 4114ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillardint 4115ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathCastNodeSetToBoolean (xmlNodeSetPtr ns) { 4116ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard if ((ns == NULL) || (ns->nodeNr == 0)) 4117ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(0); 4118ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(1); 4119ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard} 4120ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 4121ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/** 41225e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard * xmlXPathCastToBoolean: 4123ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @val: an XPath object 4124ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 4125ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts an XPath object to its boolean value 4126ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 4127ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns the boolean value 4128ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */ 4129ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillardint 4130ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathCastToBoolean (xmlXPathObjectPtr val) { 4131ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard int ret = 0; 4132ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 4133ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard if (val == NULL) 4134ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(0); 4135ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard switch (val->type) { 4136ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_UNDEFINED: 4137ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard#ifdef DEBUG_EXPR 4138ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlGenericError(xmlGenericErrorContext, "BOOLEAN: undefined\n"); 4139ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard#endif 4140ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = 0; 4141ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard break; 4142ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_NODESET: 41430c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack case XPATH_XSLT_TREE: 4144ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = xmlXPathCastNodeSetToBoolean(val->nodesetval); 4145ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard break; 4146ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_STRING: 4147ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = xmlXPathCastStringToBoolean(val->stringval); 4148ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard break; 4149ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_NUMBER: 4150ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = xmlXPathCastNumberToBoolean(val->floatval); 4151ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard break; 4152ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_BOOLEAN: 4153ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = val->boolval; 4154ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard break; 4155ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_USERS: 4156ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_POINT: 4157ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_RANGE: 4158ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard case XPATH_LOCATIONSET: 4159ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard TODO; 4160ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = 0; 4161ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard break; 4162ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard } 4163ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(ret); 4164ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard} 4165ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 4166ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 4167ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/** 4168ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathConvertBoolean: 4169ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @val: an XPath object 4170ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 4171ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts an existing object to its boolean() equivalent 4172ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 4173ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns the new object, the old one is freed (or the operation 4174ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * is done directly on @val) 4175ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */ 4176ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathObjectPtr 4177ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathConvertBoolean(xmlXPathObjectPtr val) { 4178ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlXPathObjectPtr ret; 4179ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 4180ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard if (val == NULL) 4181ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(xmlXPathNewBoolean(0)); 4182ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard if (val->type == XPATH_BOOLEAN) 4183ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(val); 4184ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = xmlXPathNewBoolean(xmlXPathCastToBoolean(val)); 4185ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlXPathFreeObject(val); 4186ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(ret); 4187ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard} 4188ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 41893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/************************************************************************ 41903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * * 41913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Routines to handle XPath contexts * 41923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * * 41933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ************************************************************************/ 41943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 41953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 41963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNewContext: 41973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @doc: the XML document 41983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 41993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Create a new xmlXPathContext 42003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 4201af43f63aaabf0dc4b4a070773875d0927da3d8a2Daniel Veillard * Returns the xmlXPathContext just allocated. The caller will need to free it. 42023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 42033473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathContextPtr 42043473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNewContext(xmlDocPtr doc) { 42053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathContextPtr ret; 42063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 42073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = (xmlXPathContextPtr) xmlMalloc(sizeof(xmlXPathContext)); 42083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ret == NULL) { 4209d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard xmlXPathErrMemory(NULL, "creating context\n"); 42103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 42113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 42123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor memset(ret, 0 , (size_t) sizeof(xmlXPathContext)); 42133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->doc = doc; 42143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->node = NULL; 42153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 42163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->varHash = NULL; 42173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 42183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->nb_types = 0; 42193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->max_types = 0; 42203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->types = NULL; 42213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 42223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->funcHash = xmlHashCreate(0); 42233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 42243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->nb_axis = 0; 42253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->max_axis = 0; 42263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->axis = NULL; 42273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 42283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->nsHash = NULL; 42293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->user = NULL; 42303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 42313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->contextSize = -1; 42323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->proximityPosition = -1; 42333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 42343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisterAllFunctions(ret); 42353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 42363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ret); 42373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 42383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 42393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 42403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathFreeContext: 42413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the context to free 42423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 42433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Free up an xmlXPathContext 42443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 42453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 42463473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathFreeContext(xmlXPathContextPtr ctxt) { 42477eca35fbaef6bd06074c4b978d381303609fcb0bDaniel Veillard if (ctxt == NULL) return; 42487eca35fbaef6bd06074c4b978d381303609fcb0bDaniel Veillard 42493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisteredNsCleanup(ctxt); 42503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisteredFuncsCleanup(ctxt); 42513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisteredVariablesCleanup(ctxt); 42527eca35fbaef6bd06074c4b978d381303609fcb0bDaniel Veillard xmlResetError(&ctxt->lastError); 42533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(ctxt); 42543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 42553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 42563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/************************************************************************ 42573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * * 42583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Routines to handle XPath parser contexts * 42593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * * 42603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ************************************************************************/ 42613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 42623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define CHECK_CTXT(ctxt) \ 42633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt == NULL) { \ 4264f13f77f0e6a7876063d5fba15c096befb0827cedWilliam M. Brack __xmlRaiseError(NULL, NULL, NULL, \ 4265f13f77f0e6a7876063d5fba15c096befb0827cedWilliam M. Brack NULL, NULL, XML_FROM_XPATH, \ 4266f13f77f0e6a7876063d5fba15c096befb0827cedWilliam M. Brack XML_ERR_INTERNAL_ERROR, XML_ERR_FATAL, \ 4267f13f77f0e6a7876063d5fba15c096befb0827cedWilliam M. Brack __FILE__, __LINE__, \ 4268f13f77f0e6a7876063d5fba15c096befb0827cedWilliam M. Brack NULL, NULL, NULL, 0, 0, \ 4269f13f77f0e6a7876063d5fba15c096befb0827cedWilliam M. Brack "NULL context pointer\n"); \ 4270f13f77f0e6a7876063d5fba15c096befb0827cedWilliam M. Brack return(NULL); \ 42713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } \ 42723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 42733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 42743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define CHECK_CONTEXT(ctxt) \ 427557b2516af5e2e06c54750b6549723cf5b8edf8a4Daniel Veillard if ((ctxt == NULL) || (ctxt->doc == NULL) || \ 427657b2516af5e2e06c54750b6549723cf5b8edf8a4Daniel Veillard (ctxt->doc->children == NULL)) { \ 427757b2516af5e2e06c54750b6549723cf5b8edf8a4Daniel Veillard xmlXPatherror(ctxt, __FILE__, __LINE__, XPATH_INVALID_CTXT); \ 4278ce682bc24b79f1dd29b781d4c17f9bf169ce7e32Daniel Veillard return(NULL); \ 427957b2516af5e2e06c54750b6549723cf5b8edf8a4Daniel Veillard } 42803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 42813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 42823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 42833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNewParserContext: 42843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @str: the XPath expression 42853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath context 42863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 42873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Create a new xmlXPathParserContext 42883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 42893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the xmlXPathParserContext just allocated. 42903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 42913473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathParserContextPtr 42923473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNewParserContext(const xmlChar *str, xmlXPathContextPtr ctxt) { 42933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathParserContextPtr ret; 42943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 42953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = (xmlXPathParserContextPtr) xmlMalloc(sizeof(xmlXPathParserContext)); 42963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ret == NULL) { 4297d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard xmlXPathErrMemory(ctxt, "creating parser context\n"); 42983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 42993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 43003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor memset(ret, 0 , (size_t) sizeof(xmlXPathParserContext)); 43013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->cur = ret->base = str; 43023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->context = ctxt; 43033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 43049e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard ret->comp = xmlXPathNewCompExpr(); 43059e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (ret->comp == NULL) { 43069e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlFree(ret->valueTab); 43079e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlFree(ret); 43089e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard return(NULL); 43099e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } 43104773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard if ((ctxt != NULL) && (ctxt->dict != NULL)) { 43114773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard ret->comp->dict = ctxt->dict; 43124773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard xmlDictReference(ret->comp->dict); 43134773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard } 43149e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 43159e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard return(ret); 43169e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard} 43179e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 43189e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard/** 43199e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * xmlXPathCompParserContext: 43209e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * @comp: the XPath compiled expression 43219e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * @ctxt: the XPath context 43229e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * 43239e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * Create a new xmlXPathParserContext when processing a compiled expression 43249e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * 43259e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * Returns the xmlXPathParserContext just allocated. 43269e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard */ 432756a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic xmlXPathParserContextPtr 43289e7160d45a18bfa26d708e22ba991f7670d0128bDaniel VeillardxmlXPathCompParserContext(xmlXPathCompExprPtr comp, xmlXPathContextPtr ctxt) { 43299e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlXPathParserContextPtr ret; 43309e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 43319e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard ret = (xmlXPathParserContextPtr) xmlMalloc(sizeof(xmlXPathParserContext)); 43329e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (ret == NULL) { 4333d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard xmlXPathErrMemory(ctxt, "creating evaluation context\n"); 43349e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard return(NULL); 43359e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } 43369e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard memset(ret, 0 , (size_t) sizeof(xmlXPathParserContext)); 43379e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 43383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* Allocate the value stack */ 43393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->valueTab = (xmlXPathObjectPtr *) 43403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlMalloc(10 * sizeof(xmlXPathObjectPtr)); 43419e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (ret->valueTab == NULL) { 43429e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlFree(ret); 4343d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard xmlXPathErrMemory(ctxt, "creating evaluation context\n"); 43449e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard return(NULL); 43459e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } 43463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->valueNr = 0; 43473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->valueMax = 10; 43483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->value = NULL; 43499e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 4350fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard ret->context = ctxt; 43519e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard ret->comp = comp; 43529e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 43533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ret); 43543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 43553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 43563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 43573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathFreeParserContext: 43583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the context to free 43593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 43603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Free up an xmlXPathParserContext 43613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 43623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 43633473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathFreeParserContext(xmlXPathParserContextPtr ctxt) { 43643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->valueTab != NULL) { 43653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(ctxt->valueTab); 43663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 436756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard if (ctxt->comp != NULL) { 436856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard#ifdef XPATH_STREAMING 436956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard if (ctxt->comp->stream != NULL) { 437056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard xmlFreePatternList(ctxt->comp->stream); 437156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard ctxt->comp->stream = NULL; 437256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard } 437356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard#endif 43749e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlXPathFreeCompExpr(ctxt->comp); 437556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard } 43763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(ctxt); 43773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 43783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 43793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/************************************************************************ 43803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * * 43813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The implicit core function library * 43823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * * 43833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ************************************************************************/ 43843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 43853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 438601c13b5be2d249ef66d86585adee87901bb8efa2Daniel Veillard * xmlXPathNodeValHash: 4387f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * @node: a node pointer 4388f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * 4389f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Function computing the beginning of the string value of the node, 4390f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * used to speed up comparisons 4391f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * 4392f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Returns an int usable as a hash 4393f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 4394f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillardstatic unsigned int 4395f06307e2c172284bb41376c396f757bdac9bdd19Daniel VeillardxmlXPathNodeValHash(xmlNodePtr node) { 4396f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard int len = 2; 4397f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard const xmlChar * string = NULL; 4398f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlNodePtr tmp = NULL; 4399f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard unsigned int ret = 0; 4400f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 4401f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (node == NULL) 4402f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return(0); 4403f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 44049adc0469d4691e798ea4ad59b84c874cdea8b38dDaniel Veillard if (node->type == XML_DOCUMENT_NODE) { 44059adc0469d4691e798ea4ad59b84c874cdea8b38dDaniel Veillard tmp = xmlDocGetRootElement((xmlDocPtr) node); 44069adc0469d4691e798ea4ad59b84c874cdea8b38dDaniel Veillard if (tmp == NULL) 44079adc0469d4691e798ea4ad59b84c874cdea8b38dDaniel Veillard node = node->children; 44089adc0469d4691e798ea4ad59b84c874cdea8b38dDaniel Veillard else 44099adc0469d4691e798ea4ad59b84c874cdea8b38dDaniel Veillard node = tmp; 44109adc0469d4691e798ea4ad59b84c874cdea8b38dDaniel Veillard 44119adc0469d4691e798ea4ad59b84c874cdea8b38dDaniel Veillard if (node == NULL) 44129adc0469d4691e798ea4ad59b84c874cdea8b38dDaniel Veillard return(0); 44139adc0469d4691e798ea4ad59b84c874cdea8b38dDaniel Veillard } 4414f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 4415f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard switch (node->type) { 4416f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XML_COMMENT_NODE: 4417f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XML_PI_NODE: 4418f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XML_CDATA_SECTION_NODE: 4419f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XML_TEXT_NODE: 4420f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard string = node->content; 4421f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (string == NULL) 4422f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return(0); 4423f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (string[0] == 0) 4424f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return(0); 4425f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return(((unsigned int) string[0]) + 4426f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (((unsigned int) string[1]) << 8)); 4427f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XML_NAMESPACE_DECL: 4428f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard string = ((xmlNsPtr)node)->href; 4429f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (string == NULL) 4430f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return(0); 4431f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (string[0] == 0) 4432f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return(0); 4433f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return(((unsigned int) string[0]) + 4434f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (((unsigned int) string[1]) << 8)); 4435f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XML_ATTRIBUTE_NODE: 4436f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard tmp = ((xmlAttrPtr) node)->children; 4437f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 4438f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XML_ELEMENT_NODE: 4439f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard tmp = node->children; 4440f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 4441f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard default: 4442f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return(0); 4443f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 4444f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard while (tmp != NULL) { 4445f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard switch (tmp->type) { 4446f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XML_COMMENT_NODE: 4447f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XML_PI_NODE: 4448f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XML_CDATA_SECTION_NODE: 4449f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XML_TEXT_NODE: 4450f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard string = tmp->content; 4451f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 4452f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XML_NAMESPACE_DECL: 4453f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard string = ((xmlNsPtr)tmp)->href; 4454f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 4455f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard default: 4456f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 4457f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 4458f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((string != NULL) && (string[0] != 0)) { 4459f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (len == 1) { 4460f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return(ret + (((unsigned int) string[0]) << 8)); 4461f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 4462f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (string[1] == 0) { 4463f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard len = 1; 4464f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ret = (unsigned int) string[0]; 4465f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } else { 4466f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return(((unsigned int) string[0]) + 4467f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (((unsigned int) string[1]) << 8)); 4468f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 4469f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 4470f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* 4471f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Skip to next node 4472f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 4473f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((tmp->children != NULL) && (tmp->type != XML_DTD_NODE)) { 4474f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (tmp->children->type != XML_ENTITY_DECL) { 4475f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard tmp = tmp->children; 4476f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard continue; 4477f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 4478f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 4479f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (tmp == node) 4480f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 4481f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 4482f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (tmp->next != NULL) { 4483f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard tmp = tmp->next; 4484f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard continue; 4485f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 4486f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 4487f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard do { 4488f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard tmp = tmp->parent; 4489f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (tmp == NULL) 4490f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 4491f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (tmp == node) { 4492f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard tmp = NULL; 4493f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 4494f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 4495f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (tmp->next != NULL) { 4496f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard tmp = tmp->next; 4497f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 4498f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 4499f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } while (tmp != NULL); 4500f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 4501f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return(ret); 4502f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard} 4503f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 4504f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard/** 4505f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * xmlXPathStringHash: 4506f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * @string: a string 4507f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * 4508f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Function computing the beginning of the string value of the node, 4509f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * used to speed up comparisons 4510f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * 4511f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Returns an int usable as a hash 4512f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 4513f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillardstatic unsigned int 4514f06307e2c172284bb41376c396f757bdac9bdd19Daniel VeillardxmlXPathStringHash(const xmlChar * string) { 4515f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (string == NULL) 4516f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return((unsigned int) 0); 4517f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (string[0] == 0) 4518f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return(0); 4519f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return(((unsigned int) string[0]) + 4520f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (((unsigned int) string[1]) << 8)); 4521f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard} 4522f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 4523f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard/** 45243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathCompareNodeSetFloat: 45253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 45263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @inf: less than (1) or greater than (0) 45273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @strict: is the comparison strict 45283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @arg: the node set 45293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @f: the value 45303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 45313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the compare operation between a nodeset and a number 45323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ns < @val (1, 1, ... 45333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ns <= @val (1, 0, ... 45343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ns > @val (0, 1, ... 45353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ns >= @val (0, 0, ... 45363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 45373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * If one object to be compared is a node-set and the other is a number, 45383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * then the comparison will be true if and only if there is a node in the 45393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * node-set such that the result of performing the comparison on the number 45403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * to be compared and on the result of converting the string-value of that 45413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * node to a number using the number function is true. 45423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 45433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns 0 or 1 depending on the results of the test. 45443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 454556a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic int 45463473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathCompareNodeSetFloat(xmlXPathParserContextPtr ctxt, int inf, int strict, 45473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr arg, xmlXPathObjectPtr f) { 45483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int i, ret = 0; 45493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlNodeSetPtr ns; 45503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlChar *str2; 45513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 45523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((f == NULL) || (arg == NULL) || 45533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ((arg->type != XPATH_NODESET) && (arg->type != XPATH_XSLT_TREE))) { 45543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(arg); 45553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(f); 45563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(0); 45573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 45583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ns = arg->nodesetval; 4559911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard if (ns != NULL) { 4560911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard for (i = 0;i < ns->nodeNr;i++) { 4561ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard str2 = xmlXPathCastNodeToString(ns->nodeTab[i]); 4562911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard if (str2 != NULL) { 4563911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard valuePush(ctxt, 4564911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard xmlXPathNewString(str2)); 4565911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard xmlFree(str2); 4566911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard xmlXPathNumberFunction(ctxt, 1); 4567911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard valuePush(ctxt, xmlXPathObjectCopy(f)); 4568911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard ret = xmlXPathCompareValues(ctxt, inf, strict); 4569911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard if (ret) 4570911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard break; 4571911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard } 4572911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard } 45733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 45743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(arg); 45753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(f); 45763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ret); 45773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 45783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 45793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 45803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathCompareNodeSetString: 45813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 45823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @inf: less than (1) or greater than (0) 45833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @strict: is the comparison strict 45843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @arg: the node set 45853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @s: the value 45863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 45873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the compare operation between a nodeset and a string 45883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ns < @val (1, 1, ... 45893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ns <= @val (1, 0, ... 45903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ns > @val (0, 1, ... 45913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ns >= @val (0, 0, ... 45923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 45933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * If one object to be compared is a node-set and the other is a string, 45943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * then the comparison will be true if and only if there is a node in 45953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the node-set such that the result of performing the comparison on the 45963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * string-value of the node and the other string is true. 45973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 45983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns 0 or 1 depending on the results of the test. 45993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 460056a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic int 46013473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathCompareNodeSetString(xmlXPathParserContextPtr ctxt, int inf, int strict, 46023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr arg, xmlXPathObjectPtr s) { 46033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int i, ret = 0; 46043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlNodeSetPtr ns; 46053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlChar *str2; 46063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 46073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((s == NULL) || (arg == NULL) || 46083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ((arg->type != XPATH_NODESET) && (arg->type != XPATH_XSLT_TREE))) { 46093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(arg); 46103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(s); 46113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(0); 46123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 46133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ns = arg->nodesetval; 4614911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard if (ns != NULL) { 4615911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard for (i = 0;i < ns->nodeNr;i++) { 4616ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard str2 = xmlXPathCastNodeToString(ns->nodeTab[i]); 4617911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard if (str2 != NULL) { 4618911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard valuePush(ctxt, 4619911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard xmlXPathNewString(str2)); 4620911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard xmlFree(str2); 4621911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard valuePush(ctxt, xmlXPathObjectCopy(s)); 4622911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard ret = xmlXPathCompareValues(ctxt, inf, strict); 4623911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard if (ret) 4624911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard break; 4625911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard } 4626911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard } 46273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 46283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(arg); 46293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(s); 46303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ret); 46313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 46323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 46333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 46343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathCompareNodeSets: 4635ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @inf: less than (1) or greater than (0) 46363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @strict: is the comparison strict 4637cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * @arg1: the first node set object 46383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @arg2: the second node set object 46393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 46403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the compare operation on nodesets: 46413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 46423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * If both objects to be compared are node-sets, then the comparison 46433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * will be true if and only if there is a node in the first node-set 46443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * and a node in the second node-set such that the result of performing 46453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the comparison on the string-values of the two nodes is true. 46463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * .... 46473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * When neither object to be compared is a node-set and the operator 46483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * is <=, <, >= or >, then the objects are compared by converting both 46493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * objects to numbers and comparing the numbers according to IEEE 754. 46503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * .... 46513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The number function converts its argument to a number as follows: 46523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * - a string that consists of optional whitespace followed by an 46533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * optional minus sign followed by a Number followed by whitespace 46543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * is converted to the IEEE 754 number that is nearest (according 46553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * to the IEEE 754 round-to-nearest rule) to the mathematical value 46563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * represented by the string; any other string is converted to NaN 46573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 46583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Conclusion all nodes need to be converted first to their string value 46593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * and then the comparison must be done when possible 46603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 466156a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic int 466256a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel VeillardxmlXPathCompareNodeSets(int inf, int strict, 46633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr arg1, xmlXPathObjectPtr arg2) { 46643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int i, j, init = 0; 46653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor double val1; 46663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor double *values2; 46673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int ret = 0; 46683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlNodeSetPtr ns1; 46693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlNodeSetPtr ns2; 46703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 46713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((arg1 == NULL) || 46724dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard ((arg1->type != XPATH_NODESET) && (arg1->type != XPATH_XSLT_TREE))) { 46734dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard xmlXPathFreeObject(arg2); 46743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(0); 46754dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard } 46763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((arg2 == NULL) || 46774dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard ((arg2->type != XPATH_NODESET) && (arg2->type != XPATH_XSLT_TREE))) { 46784dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard xmlXPathFreeObject(arg1); 46794dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard xmlXPathFreeObject(arg2); 46803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(0); 46814dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard } 46823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 46833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ns1 = arg1->nodesetval; 46843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ns2 = arg2->nodesetval; 46853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 4686d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard if ((ns1 == NULL) || (ns1->nodeNr <= 0)) { 46874dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard xmlXPathFreeObject(arg1); 46884dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard xmlXPathFreeObject(arg2); 46893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(0); 46904dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard } 4691d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard if ((ns2 == NULL) || (ns2->nodeNr <= 0)) { 46924dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard xmlXPathFreeObject(arg1); 46934dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard xmlXPathFreeObject(arg2); 46943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(0); 46954dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard } 46963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 46973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor values2 = (double *) xmlMalloc(ns2->nodeNr * sizeof(double)); 46983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (values2 == NULL) { 4699d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard xmlXPathErrMemory(NULL, "comparing nodesets\n"); 47004dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard xmlXPathFreeObject(arg1); 47014dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard xmlXPathFreeObject(arg2); 47023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(0); 47033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 47043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor for (i = 0;i < ns1->nodeNr;i++) { 4705ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard val1 = xmlXPathCastNodeToNumber(ns1->nodeTab[i]); 4706cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard if (xmlXPathIsNaN(val1)) 47073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor continue; 47083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor for (j = 0;j < ns2->nodeNr;j++) { 47093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (init == 0) { 4710ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard values2[j] = xmlXPathCastNodeToNumber(ns2->nodeTab[j]); 47113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 4712cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard if (xmlXPathIsNaN(values2[j])) 47133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor continue; 47143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (inf && strict) 47153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = (val1 < values2[j]); 47163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else if (inf && !strict) 47173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = (val1 <= values2[j]); 47183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else if (!inf && strict) 47193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = (val1 > values2[j]); 47203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else if (!inf && !strict) 47213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = (val1 >= values2[j]); 47223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ret) 47233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 47243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 47253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ret) 47263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 47273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor init = 1; 47283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 47293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(values2); 47304dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard xmlXPathFreeObject(arg1); 47314dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard xmlXPathFreeObject(arg2); 47323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ret); 47333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 47343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 47353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 47363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathCompareNodeSetValue: 47373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 47383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @inf: less than (1) or greater than (0) 47393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @strict: is the comparison strict 47403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @arg: the node set 47413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val: the value 47423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 47433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the compare operation between a nodeset and a value 47443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ns < @val (1, 1, ... 47453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ns <= @val (1, 0, ... 47463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ns > @val (0, 1, ... 47473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ns >= @val (0, 0, ... 47483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 47493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * If one object to be compared is a node-set and the other is a boolean, 47503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * then the comparison will be true if and only if the result of performing 47513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the comparison on the boolean and on the result of converting 47523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the node-set to a boolean using the boolean function is true. 47533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 47543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns 0 or 1 depending on the results of the test. 47553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 475656a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic int 47573473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathCompareNodeSetValue(xmlXPathParserContextPtr ctxt, int inf, int strict, 47583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr arg, xmlXPathObjectPtr val) { 47593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((val == NULL) || (arg == NULL) || 47603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ((arg->type != XPATH_NODESET) && (arg->type != XPATH_XSLT_TREE))) 47613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(0); 47623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 47633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor switch(val->type) { 47643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_NUMBER: 47653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(xmlXPathCompareNodeSetFloat(ctxt, inf, strict, arg, val)); 47663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_NODESET: 47673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_XSLT_TREE: 476856a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillard return(xmlXPathCompareNodeSets(inf, strict, arg, val)); 47693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_STRING: 47703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(xmlXPathCompareNodeSetString(ctxt, inf, strict, arg, val)); 47713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_BOOLEAN: 47723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, arg); 47733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathBooleanFunction(ctxt, 1); 47743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, val); 47753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(xmlXPathCompareValues(ctxt, inf, strict)); 47763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor default: 47773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor TODO 47783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 47793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(0); 47803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 47813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 47823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 478301c13b5be2d249ef66d86585adee87901bb8efa2Daniel Veillard * xmlXPathEqualNodeSetString: 47843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @arg: the nodeset object argument 47853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @str: the string to compare to. 47860c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack * @neq: flag to show whether for '=' (0) or '!=' (1) 47873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 47883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the equal operation on XPath objects content: @arg1 == @arg2 47893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * If one object to be compared is a node-set and the other is a string, 47903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * then the comparison will be true if and only if there is a node in 47913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the node-set such that the result of performing the comparison on the 47923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * string-value of the node and the other string is true. 47933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 47943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns 0 or 1 depending on the results of the test. 47953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 479656a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic int 47970c022ad8234a9228288c651f5e6a9bce7efcd789William M. BrackxmlXPathEqualNodeSetString(xmlXPathObjectPtr arg, const xmlChar * str, int neq) 4798f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard{ 47993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int i; 48003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlNodeSetPtr ns; 48013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlChar *str2; 4802f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard unsigned int hash; 48033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 48043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((str == NULL) || (arg == NULL) || 4805f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ((arg->type != XPATH_NODESET) && (arg->type != XPATH_XSLT_TREE))) 4806f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (0); 48073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ns = arg->nodesetval; 4808c125a721a4b7856f5356334137d467f95e6bf4b2William M. Brack /* 4809c125a721a4b7856f5356334137d467f95e6bf4b2William M. Brack * A NULL nodeset compared with a string is always false 4810c125a721a4b7856f5356334137d467f95e6bf4b2William M. Brack * (since there is no node equal, and no node not equal) 4811c125a721a4b7856f5356334137d467f95e6bf4b2William M. Brack */ 4812c125a721a4b7856f5356334137d467f95e6bf4b2William M. Brack if ((ns == NULL) || (ns->nodeNr <= 0) ) 4813f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (0); 4814c125a721a4b7856f5356334137d467f95e6bf4b2William M. Brack hash = xmlXPathStringHash(str); 4815f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard for (i = 0; i < ns->nodeNr; i++) { 4816f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (xmlXPathNodeValHash(ns->nodeTab[i]) == hash) { 4817f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard str2 = xmlNodeGetContent(ns->nodeTab[i]); 4818f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((str2 != NULL) && (xmlStrEqual(str, str2))) { 4819f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlFree(str2); 48200c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack if (neq) 48210c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack continue; 4822f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (1); 48239adc0469d4691e798ea4ad59b84c874cdea8b38dDaniel Veillard } else if ((str2 == NULL) && (xmlStrEqual(str, BAD_CAST ""))) { 48249adc0469d4691e798ea4ad59b84c874cdea8b38dDaniel Veillard if (neq) 48259adc0469d4691e798ea4ad59b84c874cdea8b38dDaniel Veillard continue; 48269adc0469d4691e798ea4ad59b84c874cdea8b38dDaniel Veillard return (1); 48270c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack } else if (neq) { 48280c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack if (str2 != NULL) 48290c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack xmlFree(str2); 48300c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack return (1); 48310c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack } 4832f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (str2 != NULL) 4833f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlFree(str2); 48340c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack } else if (neq) 48350c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack return (1); 48363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 4837f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (0); 48383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 48393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 48403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 484101c13b5be2d249ef66d86585adee87901bb8efa2Daniel Veillard * xmlXPathEqualNodeSetFloat: 48423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @arg: the nodeset object argument 48433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @f: the float to compare to 48440c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack * @neq: flag to show whether to compare '=' (0) or '!=' (1) 48453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 48463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the equal operation on XPath objects content: @arg1 == @arg2 48473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * If one object to be compared is a node-set and the other is a number, 48483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * then the comparison will be true if and only if there is a node in 48493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the node-set such that the result of performing the comparison on the 48503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * number to be compared and on the result of converting the string-value 48513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * of that node to a number using the number function is true. 48523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 48533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns 0 or 1 depending on the results of the test. 48543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 485556a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic int 48560c022ad8234a9228288c651f5e6a9bce7efcd789William M. BrackxmlXPathEqualNodeSetFloat(xmlXPathParserContextPtr ctxt, 48570c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack xmlXPathObjectPtr arg, double f, int neq) { 48580c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack int i, ret=0; 48590c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack xmlNodeSetPtr ns; 48600c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack xmlChar *str2; 48610c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack xmlXPathObjectPtr val; 48620c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack double v; 48633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 48643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((arg == NULL) || 48653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ((arg->type != XPATH_NODESET) && (arg->type != XPATH_XSLT_TREE))) 48663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(0); 48673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 48680c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack ns = arg->nodesetval; 48690c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack if (ns != NULL) { 48700c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack for (i=0;i<ns->nodeNr;i++) { 48710c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack str2 = xmlXPathCastNodeToString(ns->nodeTab[i]); 48720c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack if (str2 != NULL) { 48730c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack valuePush(ctxt, xmlXPathNewString(str2)); 48740c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack xmlFree(str2); 48750c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack xmlXPathNumberFunction(ctxt, 1); 48760c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack val = valuePop(ctxt); 48770c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack v = val->floatval; 48780c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack xmlXPathFreeObject(val); 48790c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack if (!xmlXPathIsNaN(v)) { 48800c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack if ((!neq) && (v==f)) { 48810c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack ret = 1; 48820c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack break; 48830c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack } else if ((neq) && (v!=f)) { 48840c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack ret = 1; 48850c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack break; 48860c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack } 488732f0f717d1e7854d87e03b659e772fa48ec9f91aWilliam M. Brack } else { /* NaN is unequal to any value */ 488832f0f717d1e7854d87e03b659e772fa48ec9f91aWilliam M. Brack if (neq) 488932f0f717d1e7854d87e03b659e772fa48ec9f91aWilliam M. Brack ret = 1; 48900c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack } 48910c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack } 48920c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack } 48930c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack } 48940c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack 48950c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack return(ret); 48963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 48973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 48983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 48993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 490001c13b5be2d249ef66d86585adee87901bb8efa2Daniel Veillard * xmlXPathEqualNodeSets: 49013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @arg1: first nodeset object argument 49023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @arg2: second nodeset object argument 49030c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack * @neq: flag to show whether to test '=' (0) or '!=' (1) 49043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 49050c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack * Implement the equal / not equal operation on XPath nodesets: 49060c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack * @arg1 == @arg2 or @arg1 != @arg2 49073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * If both objects to be compared are node-sets, then the comparison 49083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * will be true if and only if there is a node in the first node-set and 49093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * a node in the second node-set such that the result of performing the 49103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * comparison on the string-values of the two nodes is true. 49113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 49123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * (needless to say, this is a costly operation) 49133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 49143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns 0 or 1 depending on the results of the test. 49153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 491656a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic int 49170c022ad8234a9228288c651f5e6a9bce7efcd789William M. BrackxmlXPathEqualNodeSets(xmlXPathObjectPtr arg1, xmlXPathObjectPtr arg2, int neq) { 49183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int i, j; 4919f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard unsigned int *hashs1; 4920f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard unsigned int *hashs2; 49213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlChar **values1; 49223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlChar **values2; 49233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int ret = 0; 49243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlNodeSetPtr ns1; 49253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlNodeSetPtr ns2; 49263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 49273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((arg1 == NULL) || 49283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ((arg1->type != XPATH_NODESET) && (arg1->type != XPATH_XSLT_TREE))) 49293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(0); 49303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((arg2 == NULL) || 49313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ((arg2->type != XPATH_NODESET) && (arg2->type != XPATH_XSLT_TREE))) 49323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(0); 49333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 49343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ns1 = arg1->nodesetval; 49353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ns2 = arg2->nodesetval; 49363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 4937911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard if ((ns1 == NULL) || (ns1->nodeNr <= 0)) 49383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(0); 4939911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard if ((ns2 == NULL) || (ns2->nodeNr <= 0)) 49403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(0); 49413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 49423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 49430c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack * for equal, check if there is a node pertaining to both sets 49443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 49450c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack if (neq == 0) 49460c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack for (i = 0;i < ns1->nodeNr;i++) 49470c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack for (j = 0;j < ns2->nodeNr;j++) 49480c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack if (ns1->nodeTab[i] == ns2->nodeTab[j]) 49490c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack return(1); 49503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 49513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor values1 = (xmlChar **) xmlMalloc(ns1->nodeNr * sizeof(xmlChar *)); 4952d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard if (values1 == NULL) { 4953d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard xmlXPathErrMemory(NULL, "comparing nodesets\n"); 49543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(0); 4955d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard } 4956f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard hashs1 = (unsigned int *) xmlMalloc(ns1->nodeNr * sizeof(unsigned int)); 4957f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (hashs1 == NULL) { 4958d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard xmlXPathErrMemory(NULL, "comparing nodesets\n"); 4959f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlFree(values1); 4960f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return(0); 4961f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 49623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor memset(values1, 0, ns1->nodeNr * sizeof(xmlChar *)); 49633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor values2 = (xmlChar **) xmlMalloc(ns2->nodeNr * sizeof(xmlChar *)); 49643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (values2 == NULL) { 4965d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard xmlXPathErrMemory(NULL, "comparing nodesets\n"); 4966f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlFree(hashs1); 49673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(values1); 49683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(0); 49693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 4970f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard hashs2 = (unsigned int *) xmlMalloc(ns2->nodeNr * sizeof(unsigned int)); 4971f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (hashs2 == NULL) { 4972d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard xmlXPathErrMemory(NULL, "comparing nodesets\n"); 4973f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlFree(hashs1); 4974f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlFree(values1); 4975f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlFree(values2); 4976f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return(0); 4977f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 49783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor memset(values2, 0, ns2->nodeNr * sizeof(xmlChar *)); 49793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor for (i = 0;i < ns1->nodeNr;i++) { 4980f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard hashs1[i] = xmlXPathNodeValHash(ns1->nodeTab[i]); 49813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor for (j = 0;j < ns2->nodeNr;j++) { 49823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (i == 0) 4983f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard hashs2[j] = xmlXPathNodeValHash(ns2->nodeTab[j]); 49840c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack if (hashs1[i] != hashs2[j]) { 49850c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack if (neq) { 49860c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack ret = 1; 49870c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack break; 49880c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack } 49890c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack } 49900c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack else { 4991f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (values1[i] == NULL) 4992f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard values1[i] = xmlNodeGetContent(ns1->nodeTab[i]); 4993f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (values2[j] == NULL) 4994f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard values2[j] = xmlNodeGetContent(ns2->nodeTab[j]); 49950c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack ret = xmlStrEqual(values1[i], values2[j]) ^ neq; 4996f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (ret) 4997f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 4998f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 49993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 50003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ret) 50013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 50023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 50033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor for (i = 0;i < ns1->nodeNr;i++) 50043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (values1[i] != NULL) 50053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(values1[i]); 50063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor for (j = 0;j < ns2->nodeNr;j++) 50073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (values2[j] != NULL) 50083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(values2[j]); 50093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(values1); 50103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(values2); 5011f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlFree(hashs1); 5012f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlFree(hashs2); 50133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ret); 50143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 50153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 50160c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brackstatic int 50170c022ad8234a9228288c651f5e6a9bce7efcd789William M. BrackxmlXPathEqualValuesCommon(xmlXPathParserContextPtr ctxt, 50180c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack xmlXPathObjectPtr arg1, xmlXPathObjectPtr arg2) { 50193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int ret = 0; 50200c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack /* 50210c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack *At this point we are assured neither arg1 nor arg2 50220c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack *is a nodeset, so we can just pick the appropriate routine. 50230c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack */ 50243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor switch (arg1->type) { 50253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_UNDEFINED: 50263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_EXPR 50273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 50283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "Equal: undefined\n"); 50293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 50303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 50313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_BOOLEAN: 50323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor switch (arg2->type) { 50333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_UNDEFINED: 50343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_EXPR 50353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 50363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "Equal: undefined\n"); 50373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 50383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 50393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_BOOLEAN: 50403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_EXPR 50413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 50423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "Equal: %d boolean %d \n", 50433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor arg1->boolval, arg2->boolval); 50443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 50453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = (arg1->boolval == arg2->boolval); 50463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 50473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_NUMBER: 5048ef61d208503e41688f4bf86f6e9023c70e65829bWilliam M. Brack ret = (arg1->boolval == 5049ef61d208503e41688f4bf86f6e9023c70e65829bWilliam M. Brack xmlXPathCastNumberToBoolean(arg2->floatval)); 50503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 50513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_STRING: 50523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((arg2->stringval == NULL) || 50533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor (arg2->stringval[0] == 0)) ret = 0; 50543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else 50553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = 1; 50563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = (arg1->boolval == ret); 50573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 50583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_USERS: 50593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_POINT: 50603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_RANGE: 50613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_LOCATIONSET: 50623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor TODO 50633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 50640c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack case XPATH_NODESET: 50650c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack case XPATH_XSLT_TREE: 50660c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack break; 50673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 50683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 50693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_NUMBER: 50703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor switch (arg2->type) { 50713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_UNDEFINED: 50723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_EXPR 50733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 50743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "Equal: undefined\n"); 50753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 50763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 50773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_BOOLEAN: 5078ef61d208503e41688f4bf86f6e9023c70e65829bWilliam M. Brack ret = (arg2->boolval== 5079ef61d208503e41688f4bf86f6e9023c70e65829bWilliam M. Brack xmlXPathCastNumberToBoolean(arg1->floatval)); 50803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 50813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_STRING: 50823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, arg2); 50833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathNumberFunction(ctxt, 1); 50843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor arg2 = valuePop(ctxt); 50853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* no break on purpose */ 50863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_NUMBER: 5087d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard /* Hand check NaN and Infinity equalities */ 5088081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack if (xmlXPathIsNaN(arg1->floatval) || 5089081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack xmlXPathIsNaN(arg2->floatval)) { 509021458c85e209cd2621ac3eadfee075ae2dc0121dDaniel Veillard ret = 0; 5091d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard } else if (xmlXPathIsInf(arg1->floatval) == 1) { 5092d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard if (xmlXPathIsInf(arg2->floatval) == 1) 5093d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret = 1; 5094d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard else 5095d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret = 0; 5096d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard } else if (xmlXPathIsInf(arg1->floatval) == -1) { 5097d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard if (xmlXPathIsInf(arg2->floatval) == -1) 5098d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret = 1; 5099d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard else 5100d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret = 0; 5101d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard } else if (xmlXPathIsInf(arg2->floatval) == 1) { 5102d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard if (xmlXPathIsInf(arg1->floatval) == 1) 5103d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret = 1; 5104d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard else 5105d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret = 0; 5106d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard } else if (xmlXPathIsInf(arg2->floatval) == -1) { 5107d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard if (xmlXPathIsInf(arg1->floatval) == -1) 5108d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret = 1; 5109d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard else 5110d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret = 0; 511121458c85e209cd2621ac3eadfee075ae2dc0121dDaniel Veillard } else { 511221458c85e209cd2621ac3eadfee075ae2dc0121dDaniel Veillard ret = (arg1->floatval == arg2->floatval); 511321458c85e209cd2621ac3eadfee075ae2dc0121dDaniel Veillard } 51143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 51153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_USERS: 51163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_POINT: 51173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_RANGE: 51183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_LOCATIONSET: 51193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor TODO 51203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 51210c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack case XPATH_NODESET: 51220c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack case XPATH_XSLT_TREE: 51230c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack break; 51243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 51253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 51263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_STRING: 51273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor switch (arg2->type) { 51283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_UNDEFINED: 51293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_EXPR 51303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 51313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "Equal: undefined\n"); 51323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 51333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 51343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_BOOLEAN: 51353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((arg1->stringval == NULL) || 51363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor (arg1->stringval[0] == 0)) ret = 0; 51373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else 51383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = 1; 51393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = (arg2->boolval == ret); 51403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 51413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_STRING: 51423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = xmlStrEqual(arg1->stringval, arg2->stringval); 51433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 51443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_NUMBER: 51453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, arg1); 51463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathNumberFunction(ctxt, 1); 51473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor arg1 = valuePop(ctxt); 5148d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard /* Hand check NaN and Infinity equalities */ 5149081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack if (xmlXPathIsNaN(arg1->floatval) || 5150081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack xmlXPathIsNaN(arg2->floatval)) { 515121458c85e209cd2621ac3eadfee075ae2dc0121dDaniel Veillard ret = 0; 5152d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard } else if (xmlXPathIsInf(arg1->floatval) == 1) { 5153d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard if (xmlXPathIsInf(arg2->floatval) == 1) 5154d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret = 1; 5155d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard else 5156d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret = 0; 5157d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard } else if (xmlXPathIsInf(arg1->floatval) == -1) { 5158d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard if (xmlXPathIsInf(arg2->floatval) == -1) 5159d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret = 1; 5160d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard else 5161d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret = 0; 5162d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard } else if (xmlXPathIsInf(arg2->floatval) == 1) { 5163d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard if (xmlXPathIsInf(arg1->floatval) == 1) 5164d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret = 1; 5165d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard else 5166d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret = 0; 5167d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard } else if (xmlXPathIsInf(arg2->floatval) == -1) { 5168d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard if (xmlXPathIsInf(arg1->floatval) == -1) 5169d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret = 1; 5170d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard else 5171d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret = 0; 517221458c85e209cd2621ac3eadfee075ae2dc0121dDaniel Veillard } else { 517321458c85e209cd2621ac3eadfee075ae2dc0121dDaniel Veillard ret = (arg1->floatval == arg2->floatval); 517421458c85e209cd2621ac3eadfee075ae2dc0121dDaniel Veillard } 51753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 51763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_USERS: 51773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_POINT: 51783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_RANGE: 51793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_LOCATIONSET: 51803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor TODO 51813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 51820c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack case XPATH_NODESET: 51830c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack case XPATH_XSLT_TREE: 51840c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack break; 51853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 51863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 51873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_USERS: 51883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_POINT: 51893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_RANGE: 51903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XPATH_LOCATIONSET: 51913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor TODO 51923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 51930c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack case XPATH_NODESET: 51940c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack case XPATH_XSLT_TREE: 51950c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack break; 51963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 51973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(arg1); 51983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(arg2); 51993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ret); 52003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 52013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 52020c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack/** 52030c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack * xmlXPathEqualValues: 52040c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack * @ctxt: the XPath Parser context 52050c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack * 52060c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack * Implement the equal operation on XPath objects content: @arg1 == @arg2 52070c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack * 52080c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack * Returns 0 or 1 depending on the results of the test. 52090c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack */ 52100c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brackint 52110c022ad8234a9228288c651f5e6a9bce7efcd789William M. BrackxmlXPathEqualValues(xmlXPathParserContextPtr ctxt) { 52120c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack xmlXPathObjectPtr arg1, arg2, argtmp; 52130c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack int ret = 0; 52140c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack 52156128c01ca6a5c1d67970b44cd11aa95a392d8a2dDaniel Veillard if ((ctxt == NULL) || (ctxt->context == NULL)) return(0); 52160c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack arg2 = valuePop(ctxt); 52170c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack arg1 = valuePop(ctxt); 52180c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack if ((arg1 == NULL) || (arg2 == NULL)) { 52190c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack if (arg1 != NULL) 52200c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack xmlXPathFreeObject(arg1); 52210c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack else 52220c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack xmlXPathFreeObject(arg2); 52230c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack XP_ERROR0(XPATH_INVALID_OPERAND); 52240c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack } 52250c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack 52260c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack if (arg1 == arg2) { 52270c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack#ifdef DEBUG_EXPR 52280c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack xmlGenericError(xmlGenericErrorContext, 52290c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack "Equal: by pointer\n"); 52300c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack#endif 52312c19a7bf2ee0f78485840cac50f2a989f5efe476William M. Brack xmlXPathFreeObject(arg1); 52320c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack return(1); 52330c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack } 52340c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack 52350c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack /* 52360c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack *If either argument is a nodeset, it's a 'special case' 52370c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack */ 52380c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack if ((arg2->type == XPATH_NODESET) || (arg2->type == XPATH_XSLT_TREE) || 52390c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack (arg1->type == XPATH_NODESET) || (arg1->type == XPATH_XSLT_TREE)) { 52400c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack /* 52410c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack *Hack it to assure arg1 is the nodeset 52420c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack */ 52430c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack if ((arg1->type != XPATH_NODESET) && (arg1->type != XPATH_XSLT_TREE)) { 52440c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack argtmp = arg2; 52450c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack arg2 = arg1; 52460c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack arg1 = argtmp; 52470c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack } 52480c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack switch (arg2->type) { 52490c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack case XPATH_UNDEFINED: 52500c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack#ifdef DEBUG_EXPR 52510c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack xmlGenericError(xmlGenericErrorContext, 52520c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack "Equal: undefined\n"); 52530c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack#endif 52540c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack break; 52550c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack case XPATH_NODESET: 52560c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack case XPATH_XSLT_TREE: 52570c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack ret = xmlXPathEqualNodeSets(arg1, arg2, 0); 52580c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack break; 52590c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack case XPATH_BOOLEAN: 52600c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack if ((arg1->nodesetval == NULL) || 52610c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack (arg1->nodesetval->nodeNr == 0)) ret = 0; 52620c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack else 52630c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack ret = 1; 52640c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack ret = (ret == arg2->boolval); 52650c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack break; 52660c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack case XPATH_NUMBER: 52670c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack ret = xmlXPathEqualNodeSetFloat(ctxt, arg1, arg2->floatval, 0); 52680c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack break; 52690c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack case XPATH_STRING: 52700c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack ret = xmlXPathEqualNodeSetString(arg1, arg2->stringval, 0); 52710c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack break; 52720c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack case XPATH_USERS: 52730c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack case XPATH_POINT: 52740c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack case XPATH_RANGE: 52750c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack case XPATH_LOCATIONSET: 52760c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack TODO 52770c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack break; 52780c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack } 52790c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack xmlXPathFreeObject(arg1); 52800c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack xmlXPathFreeObject(arg2); 52810c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack return(ret); 52820c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack } 52830c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack 52840c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack return (xmlXPathEqualValuesCommon(ctxt, arg1, arg2)); 52850c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack} 52860c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack 52870c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack/** 52880c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack * xmlXPathNotEqualValues: 52890c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack * @ctxt: the XPath Parser context 52900c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack * 52910c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack * Implement the equal operation on XPath objects content: @arg1 == @arg2 52920c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack * 52930c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack * Returns 0 or 1 depending on the results of the test. 52940c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack */ 52950c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brackint 52960c022ad8234a9228288c651f5e6a9bce7efcd789William M. BrackxmlXPathNotEqualValues(xmlXPathParserContextPtr ctxt) { 52970c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack xmlXPathObjectPtr arg1, arg2, argtmp; 52980c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack int ret = 0; 52990c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack 53006128c01ca6a5c1d67970b44cd11aa95a392d8a2dDaniel Veillard if ((ctxt == NULL) || (ctxt->context == NULL)) return(0); 53010c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack arg2 = valuePop(ctxt); 53020c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack arg1 = valuePop(ctxt); 53030c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack if ((arg1 == NULL) || (arg2 == NULL)) { 53040c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack if (arg1 != NULL) 53050c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack xmlXPathFreeObject(arg1); 53060c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack else 53070c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack xmlXPathFreeObject(arg2); 53080c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack XP_ERROR0(XPATH_INVALID_OPERAND); 53090c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack } 53100c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack 53110c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack if (arg1 == arg2) { 53120c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack#ifdef DEBUG_EXPR 53130c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack xmlGenericError(xmlGenericErrorContext, 53140c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack "NotEqual: by pointer\n"); 53150c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack#endif 53162c19a7bf2ee0f78485840cac50f2a989f5efe476William M. Brack xmlXPathFreeObject(arg1); 53170c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack return(0); 53180c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack } 53190c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack 53200c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack /* 53210c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack *If either argument is a nodeset, it's a 'special case' 53220c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack */ 53230c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack if ((arg2->type == XPATH_NODESET) || (arg2->type == XPATH_XSLT_TREE) || 53240c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack (arg1->type == XPATH_NODESET) || (arg1->type == XPATH_XSLT_TREE)) { 53250c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack /* 53260c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack *Hack it to assure arg1 is the nodeset 53270c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack */ 53280c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack if ((arg1->type != XPATH_NODESET) && (arg1->type != XPATH_XSLT_TREE)) { 53290c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack argtmp = arg2; 53300c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack arg2 = arg1; 53310c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack arg1 = argtmp; 53320c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack } 53330c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack switch (arg2->type) { 53340c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack case XPATH_UNDEFINED: 53350c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack#ifdef DEBUG_EXPR 53360c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack xmlGenericError(xmlGenericErrorContext, 53370c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack "NotEqual: undefined\n"); 53380c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack#endif 53390c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack break; 53400c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack case XPATH_NODESET: 53410c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack case XPATH_XSLT_TREE: 53420c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack ret = xmlXPathEqualNodeSets(arg1, arg2, 1); 53430c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack break; 53440c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack case XPATH_BOOLEAN: 53450c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack if ((arg1->nodesetval == NULL) || 53460c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack (arg1->nodesetval->nodeNr == 0)) ret = 0; 53470c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack else 53480c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack ret = 1; 5349ef61d208503e41688f4bf86f6e9023c70e65829bWilliam M. Brack ret = (ret != arg2->boolval); 53500c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack break; 53510c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack case XPATH_NUMBER: 53520c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack ret = xmlXPathEqualNodeSetFloat(ctxt, arg1, arg2->floatval, 1); 53530c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack break; 53540c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack case XPATH_STRING: 53550c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack ret = xmlXPathEqualNodeSetString(arg1, arg2->stringval,1); 53560c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack break; 53570c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack case XPATH_USERS: 53580c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack case XPATH_POINT: 53590c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack case XPATH_RANGE: 53600c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack case XPATH_LOCATIONSET: 53610c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack TODO 53620c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack break; 53630c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack } 53640c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack xmlXPathFreeObject(arg1); 53650c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack xmlXPathFreeObject(arg2); 53660c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack return(ret); 53670c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack } 53680c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack 53690c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack return (!xmlXPathEqualValuesCommon(ctxt, arg1, arg2)); 53700c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack} 53713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 53723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 53733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathCompareValues: 53743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 53753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @inf: less than (1) or greater than (0) 53763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @strict: is the comparison strict 53773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 53783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the compare operation on XPath objects: 53793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @arg1 < @arg2 (1, 1, ... 53803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @arg1 <= @arg2 (1, 0, ... 53813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @arg1 > @arg2 (0, 1, ... 53823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @arg1 >= @arg2 (0, 0, ... 53833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 53843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * When neither object to be compared is a node-set and the operator is 53853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * <=, <, >=, >, then the objects are compared by converted both objects 53863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * to numbers and comparing the numbers according to IEEE 754. The < 53873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * comparison will be true if and only if the first number is less than the 53883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * second number. The <= comparison will be true if and only if the first 53893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * number is less than or equal to the second number. The > comparison 53903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * will be true if and only if the first number is greater than the second 53913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * number. The >= comparison will be true if and only if the first number 53923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * is greater than or equal to the second number. 53933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 5394cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * Returns 1 if the comparison succeeded, 0 if it failed 53953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 53963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorint 53973473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathCompareValues(xmlXPathParserContextPtr ctxt, int inf, int strict) { 5398d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard int ret = 0, arg1i = 0, arg2i = 0; 53993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr arg1, arg2; 54003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 54016128c01ca6a5c1d67970b44cd11aa95a392d8a2dDaniel Veillard if ((ctxt == NULL) || (ctxt->context == NULL)) return(0); 54020c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack arg2 = valuePop(ctxt); 54033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor arg1 = valuePop(ctxt); 54040c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack if ((arg1 == NULL) || (arg2 == NULL)) { 54050c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack if (arg1 != NULL) 54060c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack xmlXPathFreeObject(arg1); 54070c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack else 54080c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack xmlXPathFreeObject(arg2); 54093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XP_ERROR0(XPATH_INVALID_OPERAND); 54103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 54113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 54120c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack if ((arg2->type == XPATH_NODESET) || (arg2->type == XPATH_XSLT_TREE) || 54130c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack (arg1->type == XPATH_NODESET) || (arg1->type == XPATH_XSLT_TREE)) { 5414d6e347e865b473f06fd431be926183c77596194aWilliam M. Brack /* 5415d6e347e865b473f06fd431be926183c77596194aWilliam M. Brack * If either argument is a XPATH_NODESET or XPATH_XSLT_TREE the two arguments 5416d6e347e865b473f06fd431be926183c77596194aWilliam M. Brack * are not freed from within this routine; they will be freed from the 5417d6e347e865b473f06fd431be926183c77596194aWilliam M. Brack * called routine, e.g. xmlXPathCompareNodeSets or xmlXPathCompareNodeSetValue 5418d6e347e865b473f06fd431be926183c77596194aWilliam M. Brack */ 54190c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack if (((arg2->type == XPATH_NODESET) || (arg2->type == XPATH_XSLT_TREE)) && 54200c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack ((arg1->type == XPATH_NODESET) || (arg1->type == XPATH_XSLT_TREE))){ 542156a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillard ret = xmlXPathCompareNodeSets(inf, strict, arg1, arg2); 54223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else { 54230c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack if ((arg1->type == XPATH_NODESET) || (arg1->type == XPATH_XSLT_TREE)) { 54244af6b6e801346d1c832cf19b7c3833a831871db2Daniel Veillard ret = xmlXPathCompareNodeSetValue(ctxt, inf, strict, 54254af6b6e801346d1c832cf19b7c3833a831871db2Daniel Veillard arg1, arg2); 54263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else { 54274af6b6e801346d1c832cf19b7c3833a831871db2Daniel Veillard ret = xmlXPathCompareNodeSetValue(ctxt, !inf, strict, 54284af6b6e801346d1c832cf19b7c3833a831871db2Daniel Veillard arg2, arg1); 54293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 54303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 54313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ret); 54323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 54333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 54343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (arg1->type != XPATH_NUMBER) { 54353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, arg1); 54363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathNumberFunction(ctxt, 1); 54373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor arg1 = valuePop(ctxt); 54383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 54393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (arg1->type != XPATH_NUMBER) { 54403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(arg1); 54413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(arg2); 54423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XP_ERROR0(XPATH_INVALID_OPERAND); 54433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 54443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (arg2->type != XPATH_NUMBER) { 54453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, arg2); 54463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathNumberFunction(ctxt, 1); 54473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor arg2 = valuePop(ctxt); 54483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 54493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (arg2->type != XPATH_NUMBER) { 54503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(arg1); 54513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(arg2); 54523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XP_ERROR0(XPATH_INVALID_OPERAND); 54533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 54543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 54553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Add tests for infinity and nan 54563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * => feedback on 3.4 for Inf and NaN 54573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 5458d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard /* Hand check NaN and Infinity comparisons */ 545921458c85e209cd2621ac3eadfee075ae2dc0121dDaniel Veillard if (xmlXPathIsNaN(arg1->floatval) || xmlXPathIsNaN(arg2->floatval)) { 5460d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret=0; 546121458c85e209cd2621ac3eadfee075ae2dc0121dDaniel Veillard } else { 5462d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard arg1i=xmlXPathIsInf(arg1->floatval); 5463d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard arg2i=xmlXPathIsInf(arg2->floatval); 5464d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard if (inf && strict) { 5465d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard if ((arg1i == -1 && arg2i != -1) || 5466d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard (arg2i == 1 && arg1i != 1)) { 5467d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret = 1; 5468d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard } else if (arg1i == 0 && arg2i == 0) { 5469d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret = (arg1->floatval < arg2->floatval); 5470d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard } else { 5471d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret = 0; 5472d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard } 5473d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard } 5474d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard else if (inf && !strict) { 5475d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard if (arg1i == -1 || arg2i == 1) { 5476d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret = 1; 5477d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard } else if (arg1i == 0 && arg2i == 0) { 5478d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret = (arg1->floatval <= arg2->floatval); 5479d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard } else { 5480d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret = 0; 5481d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard } 5482d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard } 5483d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard else if (!inf && strict) { 5484d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard if ((arg1i == 1 && arg2i != 1) || 5485d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard (arg2i == -1 && arg1i != -1)) { 5486d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret = 1; 5487d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard } else if (arg1i == 0 && arg2i == 0) { 5488d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret = (arg1->floatval > arg2->floatval); 5489d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard } else { 5490d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret = 0; 5491d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard } 5492d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard } 5493d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard else if (!inf && !strict) { 5494d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard if (arg1i == 1 || arg2i == -1) { 5495d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret = 1; 5496d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard } else if (arg1i == 0 && arg2i == 0) { 5497d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret = (arg1->floatval >= arg2->floatval); 5498d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard } else { 5499d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard ret = 0; 5500d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard } 5501d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard } 550221458c85e209cd2621ac3eadfee075ae2dc0121dDaniel Veillard } 55033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(arg1); 55043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(arg2); 55053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ret); 55063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 55073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 55083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 55093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathValueFlipSign: 55103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 55113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 55123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the unary - operation on an XPath object 55133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The numeric operators convert their operands to numbers as if 55143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * by calling the number function. 55153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 55163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 55173473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathValueFlipSign(xmlXPathParserContextPtr ctxt) { 5518a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard if ((ctxt == NULL) || (ctxt->context == NULL)) return; 5519ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard CAST_TO_NUMBER; 5520ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard CHECK_TYPE(XPATH_NUMBER); 5521eca82810f0fb81f3e9936d2018347e1e19de513aDaniel Veillard if (xmlXPathIsNaN(ctxt->value->floatval)) 5522eca82810f0fb81f3e9936d2018347e1e19de513aDaniel Veillard ctxt->value->floatval=xmlXPathNAN; 5523eca82810f0fb81f3e9936d2018347e1e19de513aDaniel Veillard else if (xmlXPathIsInf(ctxt->value->floatval) == 1) 5524eca82810f0fb81f3e9936d2018347e1e19de513aDaniel Veillard ctxt->value->floatval=xmlXPathNINF; 5525eca82810f0fb81f3e9936d2018347e1e19de513aDaniel Veillard else if (xmlXPathIsInf(ctxt->value->floatval) == -1) 5526eca82810f0fb81f3e9936d2018347e1e19de513aDaniel Veillard ctxt->value->floatval=xmlXPathPINF; 5527eca82810f0fb81f3e9936d2018347e1e19de513aDaniel Veillard else if (ctxt->value->floatval == 0) { 55285fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard if (xmlXPathGetSign(ctxt->value->floatval) == 0) 55295fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard ctxt->value->floatval = xmlXPathNZERO; 55305fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard else 55315fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard ctxt->value->floatval = 0; 55325fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard } 55335fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard else 55345fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard ctxt->value->floatval = - ctxt->value->floatval; 55353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 55363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 55373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 55383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathAddValues: 55393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 55403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 55413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the add operation on XPath objects: 55423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The numeric operators convert their operands to numbers as if 55433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * by calling the number function. 55443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 55453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 55463473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathAddValues(xmlXPathParserContextPtr ctxt) { 55473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr arg; 55483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor double val; 55493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 5550ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard arg = valuePop(ctxt); 5551ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard if (arg == NULL) 5552ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard XP_ERROR(XPATH_INVALID_OPERAND); 5553ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard val = xmlXPathCastToNumber(arg); 55543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(arg); 55553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 5556ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard CAST_TO_NUMBER; 5557ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard CHECK_TYPE(XPATH_NUMBER); 5558ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ctxt->value->floatval += val; 55593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 55603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 55613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 55623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathSubValues: 55633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 55643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 5565cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * Implement the subtraction operation on XPath objects: 55663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The numeric operators convert their operands to numbers as if 55673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * by calling the number function. 55683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 55693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 55703473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathSubValues(xmlXPathParserContextPtr ctxt) { 55713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr arg; 55723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor double val; 55733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 5574ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard arg = valuePop(ctxt); 5575ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard if (arg == NULL) 5576ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard XP_ERROR(XPATH_INVALID_OPERAND); 5577ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard val = xmlXPathCastToNumber(arg); 55783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(arg); 55793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 5580ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard CAST_TO_NUMBER; 5581ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard CHECK_TYPE(XPATH_NUMBER); 5582ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ctxt->value->floatval -= val; 55833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 55843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 55853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 55863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathMultValues: 55873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 55883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 55893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the multiply operation on XPath objects: 55903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The numeric operators convert their operands to numbers as if 55913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * by calling the number function. 55923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 55933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 55943473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathMultValues(xmlXPathParserContextPtr ctxt) { 55953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr arg; 55963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor double val; 55973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 5598ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard arg = valuePop(ctxt); 5599ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard if (arg == NULL) 5600ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard XP_ERROR(XPATH_INVALID_OPERAND); 5601ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard val = xmlXPathCastToNumber(arg); 56023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(arg); 56033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 5604ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard CAST_TO_NUMBER; 5605ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard CHECK_TYPE(XPATH_NUMBER); 5606ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ctxt->value->floatval *= val; 56073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 56083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 56093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 56103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathDivValues: 56113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 56123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 56133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the div operation on XPath objects @arg1 / @arg2: 56143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The numeric operators convert their operands to numbers as if 56153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * by calling the number function. 56163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 56173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 56183473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathDivValues(xmlXPathParserContextPtr ctxt) { 56193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr arg; 56203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor double val; 56213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 5622ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard arg = valuePop(ctxt); 5623ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard if (arg == NULL) 5624ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard XP_ERROR(XPATH_INVALID_OPERAND); 5625ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard val = xmlXPathCastToNumber(arg); 56263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(arg); 56273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 5628ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard CAST_TO_NUMBER; 5629ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard CHECK_TYPE(XPATH_NUMBER); 5630eca82810f0fb81f3e9936d2018347e1e19de513aDaniel Veillard if (xmlXPathIsNaN(val) || xmlXPathIsNaN(ctxt->value->floatval)) 5631eca82810f0fb81f3e9936d2018347e1e19de513aDaniel Veillard ctxt->value->floatval = xmlXPathNAN; 5632eca82810f0fb81f3e9936d2018347e1e19de513aDaniel Veillard else if (val == 0 && xmlXPathGetSign(val) != 0) { 56335fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard if (ctxt->value->floatval == 0) 56345fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard ctxt->value->floatval = xmlXPathNAN; 56355fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard else if (ctxt->value->floatval > 0) 56365fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard ctxt->value->floatval = xmlXPathNINF; 56375fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard else if (ctxt->value->floatval < 0) 56385fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard ctxt->value->floatval = xmlXPathPINF; 56395fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard } 56405fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard else if (val == 0) { 56415f4b5999b4eeda2ca68e6d9f54a3c534a8474b38Daniel Veillard if (ctxt->value->floatval == 0) 56425f4b5999b4eeda2ca68e6d9f54a3c534a8474b38Daniel Veillard ctxt->value->floatval = xmlXPathNAN; 56435f4b5999b4eeda2ca68e6d9f54a3c534a8474b38Daniel Veillard else if (ctxt->value->floatval > 0) 56445f4b5999b4eeda2ca68e6d9f54a3c534a8474b38Daniel Veillard ctxt->value->floatval = xmlXPathPINF; 56455f4b5999b4eeda2ca68e6d9f54a3c534a8474b38Daniel Veillard else if (ctxt->value->floatval < 0) 56465f4b5999b4eeda2ca68e6d9f54a3c534a8474b38Daniel Veillard ctxt->value->floatval = xmlXPathNINF; 56475f4b5999b4eeda2ca68e6d9f54a3c534a8474b38Daniel Veillard } else 56485f4b5999b4eeda2ca68e6d9f54a3c534a8474b38Daniel Veillard ctxt->value->floatval /= val; 56493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 56503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 56513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 56523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathModValues: 56533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 56543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 56553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the mod operation on XPath objects: @arg1 / @arg2 56563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The numeric operators convert their operands to numbers as if 56573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * by calling the number function. 56583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 56593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 56603473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathModValues(xmlXPathParserContextPtr ctxt) { 56613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr arg; 5662fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard double arg1, arg2; 56633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 5664ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard arg = valuePop(ctxt); 5665ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard if (arg == NULL) 5666ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard XP_ERROR(XPATH_INVALID_OPERAND); 56675fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard arg2 = xmlXPathCastToNumber(arg); 56683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(arg); 56693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 5670ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard CAST_TO_NUMBER; 5671ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard CHECK_TYPE(XPATH_NUMBER); 56725fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard arg1 = ctxt->value->floatval; 5673268fd1bc97f79b43290041cfda2287fb0b0ef2d6Daniel Veillard if (arg2 == 0) 5674268fd1bc97f79b43290041cfda2287fb0b0ef2d6Daniel Veillard ctxt->value->floatval = xmlXPathNAN; 56755fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard else { 5676fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard ctxt->value->floatval = fmod(arg1, arg2); 56775fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard } 56783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 56793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 56803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/************************************************************************ 56813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * * 56823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The traversal functions * 56833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * * 56843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ************************************************************************/ 56853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 56863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/* 56873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * A traversal function enumerates nodes along an axis. 56883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Initially it must be called with NULL, and it indicates 56893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * termination on the axis by returning NULL. 56903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 56913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylortypedef xmlNodePtr (*xmlXPathTraversalFunction) 56923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor (xmlXPathParserContextPtr ctxt, xmlNodePtr cur); 56933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 56943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 56953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNextSelf: 56963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 56973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur: the current node in the traversal 56983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 56993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Traversal function for the "self" direction 57003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The self axis contains just the context node itself 57013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 57023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the next element following that axis 57033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 57043473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNodePtr 57053473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNextSelf(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) { 5706a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard if ((ctxt == NULL) || (ctxt->context == NULL)) return(NULL); 57073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == NULL) 57083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ctxt->context->node); 57093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 57103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 57113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 57123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 57133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNextChild: 57143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 57153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur: the current node in the traversal 57163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 57173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Traversal function for the "child" direction 57183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The child axis contains the children of the context node in document order. 57193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 57203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the next element following that axis 57213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 57223473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNodePtr 57233473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNextChild(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) { 5724a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard if ((ctxt == NULL) || (ctxt->context == NULL)) return(NULL); 57253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == NULL) { 57263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->context->node == NULL) return(NULL); 57273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor switch (ctxt->context->node->type) { 57283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ELEMENT_NODE: 57293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_TEXT_NODE: 57303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_CDATA_SECTION_NODE: 57313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ENTITY_REF_NODE: 57323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ENTITY_NODE: 57333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_PI_NODE: 57343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_COMMENT_NODE: 57353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_NOTATION_NODE: 57363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_DTD_NODE: 57373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ctxt->context->node->children); 57383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_DOCUMENT_NODE: 57393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_DOCUMENT_TYPE_NODE: 57403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_DOCUMENT_FRAG_NODE: 57413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_HTML_DOCUMENT_NODE: 5742eae522a0d8aa9f830d2e447f29b504030dbb6bbdDaniel Veillard#ifdef LIBXML_DOCB_ENABLED 5743eae522a0d8aa9f830d2e447f29b504030dbb6bbdDaniel Veillard case XML_DOCB_DOCUMENT_NODE: 57443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 57453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(((xmlDocPtr) ctxt->context->node)->children); 57463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ELEMENT_DECL: 57473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ATTRIBUTE_DECL: 57483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ENTITY_DECL: 57493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ATTRIBUTE_NODE: 57503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_NAMESPACE_DECL: 57513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_XINCLUDE_START: 57523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_XINCLUDE_END: 57533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 57543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 57553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 57563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 57573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((cur->type == XML_DOCUMENT_NODE) || 57583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor (cur->type == XML_HTML_DOCUMENT_NODE)) 57593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 57603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(cur->next); 57613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 57623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 57633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 57643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNextDescendant: 57653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 57663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur: the current node in the traversal 57673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 57683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Traversal function for the "descendant" direction 57693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the descendant axis contains the descendants of the context node in document 57703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * order; a descendant is a child or a child of a child and so on. 57713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 57723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the next element following that axis 57733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 57743473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNodePtr 57753473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNextDescendant(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) { 5776a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard if ((ctxt == NULL) || (ctxt->context == NULL)) return(NULL); 57773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == NULL) { 57783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->context->node == NULL) 57793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 57803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((ctxt->context->node->type == XML_ATTRIBUTE_NODE) || 57813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor (ctxt->context->node->type == XML_NAMESPACE_DECL)) 57823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 57833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 57843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->context->node == (xmlNodePtr) ctxt->context->doc) 57853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ctxt->context->doc->children); 57863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ctxt->context->node->children); 57873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 57883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 5789567e1b48e8664163894742d5674c24baa4282f9eDaniel Veillard if (cur->children != NULL) { 579068e9e74af85ebbc30781787f247c361bc85adfa0Daniel Veillard /* 579168e9e74af85ebbc30781787f247c361bc85adfa0Daniel Veillard * Do not descend on entities declarations 579268e9e74af85ebbc30781787f247c361bc85adfa0Daniel Veillard */ 579368e9e74af85ebbc30781787f247c361bc85adfa0Daniel Veillard if (cur->children->type != XML_ENTITY_DECL) { 579468e9e74af85ebbc30781787f247c361bc85adfa0Daniel Veillard cur = cur->children; 579568e9e74af85ebbc30781787f247c361bc85adfa0Daniel Veillard /* 579668e9e74af85ebbc30781787f247c361bc85adfa0Daniel Veillard * Skip DTDs 579768e9e74af85ebbc30781787f247c361bc85adfa0Daniel Veillard */ 579868e9e74af85ebbc30781787f247c361bc85adfa0Daniel Veillard if (cur->type != XML_DTD_NODE) 579968e9e74af85ebbc30781787f247c361bc85adfa0Daniel Veillard return(cur); 580068e9e74af85ebbc30781787f247c361bc85adfa0Daniel Veillard } 5801567e1b48e8664163894742d5674c24baa4282f9eDaniel Veillard } 5802567e1b48e8664163894742d5674c24baa4282f9eDaniel Veillard 5803567e1b48e8664163894742d5674c24baa4282f9eDaniel Veillard if (cur == ctxt->context->node) return(NULL); 5804567e1b48e8664163894742d5674c24baa4282f9eDaniel Veillard 580568e9e74af85ebbc30781787f247c361bc85adfa0Daniel Veillard while (cur->next != NULL) { 580668e9e74af85ebbc30781787f247c361bc85adfa0Daniel Veillard cur = cur->next; 580768e9e74af85ebbc30781787f247c361bc85adfa0Daniel Veillard if ((cur->type != XML_ENTITY_DECL) && 580868e9e74af85ebbc30781787f247c361bc85adfa0Daniel Veillard (cur->type != XML_DTD_NODE)) 580968e9e74af85ebbc30781787f247c361bc85adfa0Daniel Veillard return(cur); 581068e9e74af85ebbc30781787f247c361bc85adfa0Daniel Veillard } 58113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 58123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor do { 58133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur = cur->parent; 581411ce4004d86bb4b317c48b7d5124ba33e40e10f5Daniel Veillard if (cur == NULL) break; 58153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == ctxt->context->node) return(NULL); 58163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur->next != NULL) { 58173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur = cur->next; 58183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(cur); 58193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 58203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } while (cur != NULL); 58213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(cur); 58223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 58233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 58243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 58253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNextDescendantOrSelf: 58263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 58273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur: the current node in the traversal 58283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 58293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Traversal function for the "descendant-or-self" direction 58303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the descendant-or-self axis contains the context node and the descendants 58313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * of the context node in document order; thus the context node is the first 58323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * node on the axis, and the first child of the context node is the second node 58333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * on the axis 58343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 58353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the next element following that axis 58363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 58373473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNodePtr 58383473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNextDescendantOrSelf(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) { 5839a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard if ((ctxt == NULL) || (ctxt->context == NULL)) return(NULL); 58403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == NULL) { 58413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->context->node == NULL) 58423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 58433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((ctxt->context->node->type == XML_ATTRIBUTE_NODE) || 58443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor (ctxt->context->node->type == XML_NAMESPACE_DECL)) 58453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 58463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ctxt->context->node); 58473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 58483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 58493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(xmlXPathNextDescendant(ctxt, cur)); 58503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 58513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 58523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 58533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNextParent: 58543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 58553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur: the current node in the traversal 58563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 58573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Traversal function for the "parent" direction 58583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The parent axis contains the parent of the context node, if there is one. 58593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 58603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the next element following that axis 58613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 58623473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNodePtr 58633473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNextParent(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) { 5864a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard if ((ctxt == NULL) || (ctxt->context == NULL)) return(NULL); 58653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 58663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the parent of an attribute or namespace node is the element 58673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * to which the attribute or namespace node is attached 58683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Namespace handling !!! 58693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 58703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == NULL) { 58713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->context->node == NULL) return(NULL); 58723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor switch (ctxt->context->node->type) { 58733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ELEMENT_NODE: 58743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_TEXT_NODE: 58753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_CDATA_SECTION_NODE: 58763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ENTITY_REF_NODE: 58773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ENTITY_NODE: 58783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_PI_NODE: 58793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_COMMENT_NODE: 58803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_NOTATION_NODE: 58813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_DTD_NODE: 58823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ELEMENT_DECL: 58833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ATTRIBUTE_DECL: 58843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_XINCLUDE_START: 58853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_XINCLUDE_END: 58863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ENTITY_DECL: 58873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->context->node->parent == NULL) 58883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return((xmlNodePtr) ctxt->context->doc); 58898e7e1c00ce5cc3ce959833b888c50ed9fd9d5aaeDaniel Veillard if ((ctxt->context->node->parent->type == XML_ELEMENT_NODE) && 5890652d8a949447833405cc0805f4b7ff1179e59ed2Daniel Veillard ((ctxt->context->node->parent->name[0] == ' ') || 5891652d8a949447833405cc0805f4b7ff1179e59ed2Daniel Veillard (xmlStrEqual(ctxt->context->node->parent->name, 5892652d8a949447833405cc0805f4b7ff1179e59ed2Daniel Veillard BAD_CAST "fake node libxslt")))) 58938e7e1c00ce5cc3ce959833b888c50ed9fd9d5aaeDaniel Veillard return(NULL); 58943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ctxt->context->node->parent); 58953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ATTRIBUTE_NODE: { 58963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlAttrPtr att = (xmlAttrPtr) ctxt->context->node; 58973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 58983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(att->parent); 58993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 59003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_DOCUMENT_NODE: 59013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_DOCUMENT_TYPE_NODE: 59023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_DOCUMENT_FRAG_NODE: 59033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_HTML_DOCUMENT_NODE: 5904eae522a0d8aa9f830d2e447f29b504030dbb6bbdDaniel Veillard#ifdef LIBXML_DOCB_ENABLED 5905eae522a0d8aa9f830d2e447f29b504030dbb6bbdDaniel Veillard case XML_DOCB_DOCUMENT_NODE: 59063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 59073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 5908044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard case XML_NAMESPACE_DECL: { 5909044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlNsPtr ns = (xmlNsPtr) ctxt->context->node; 5910044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard 5911044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if ((ns->next != NULL) && 5912044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard (ns->next->type != XML_NAMESPACE_DECL)) 5913044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard return((xmlNodePtr) ns->next); 59143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 5915044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } 59163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 59173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 59183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 59193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 59203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 59213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 59223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNextAncestor: 59233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 59243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur: the current node in the traversal 59253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 59263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Traversal function for the "ancestor" direction 59273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the ancestor axis contains the ancestors of the context node; the ancestors 59283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * of the context node consist of the parent of context node and the parent's 59293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * parent and so on; the nodes are ordered in reverse document order; thus the 59303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * parent is the first node on the axis, and the parent's parent is the second 59313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * node on the axis 59323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 59333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the next element following that axis 59343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 59353473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNodePtr 59363473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNextAncestor(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) { 5937a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard if ((ctxt == NULL) || (ctxt->context == NULL)) return(NULL); 59383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 59393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the parent of an attribute or namespace node is the element 59403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * to which the attribute or namespace node is attached 59413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * !!!!!!!!!!!!! 59423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 59433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == NULL) { 59443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->context->node == NULL) return(NULL); 59453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor switch (ctxt->context->node->type) { 59463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ELEMENT_NODE: 59473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_TEXT_NODE: 59483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_CDATA_SECTION_NODE: 59493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ENTITY_REF_NODE: 59503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ENTITY_NODE: 59513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_PI_NODE: 59523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_COMMENT_NODE: 59533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_DTD_NODE: 59543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ELEMENT_DECL: 59553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ATTRIBUTE_DECL: 59563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ENTITY_DECL: 59573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_NOTATION_NODE: 59583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_XINCLUDE_START: 59593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_XINCLUDE_END: 59603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->context->node->parent == NULL) 59613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return((xmlNodePtr) ctxt->context->doc); 59628e7e1c00ce5cc3ce959833b888c50ed9fd9d5aaeDaniel Veillard if ((ctxt->context->node->parent->type == XML_ELEMENT_NODE) && 5963652d8a949447833405cc0805f4b7ff1179e59ed2Daniel Veillard ((ctxt->context->node->parent->name[0] == ' ') || 5964652d8a949447833405cc0805f4b7ff1179e59ed2Daniel Veillard (xmlStrEqual(ctxt->context->node->parent->name, 5965652d8a949447833405cc0805f4b7ff1179e59ed2Daniel Veillard BAD_CAST "fake node libxslt")))) 59668e7e1c00ce5cc3ce959833b888c50ed9fd9d5aaeDaniel Veillard return(NULL); 59673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ctxt->context->node->parent); 59683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ATTRIBUTE_NODE: { 596956a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillard xmlAttrPtr tmp = (xmlAttrPtr) ctxt->context->node; 59703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 597156a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillard return(tmp->parent); 59723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 59733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_DOCUMENT_NODE: 59743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_DOCUMENT_TYPE_NODE: 59753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_DOCUMENT_FRAG_NODE: 59763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_HTML_DOCUMENT_NODE: 5977eae522a0d8aa9f830d2e447f29b504030dbb6bbdDaniel Veillard#ifdef LIBXML_DOCB_ENABLED 5978eae522a0d8aa9f830d2e447f29b504030dbb6bbdDaniel Veillard case XML_DOCB_DOCUMENT_NODE: 59793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 59803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 5981044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard case XML_NAMESPACE_DECL: { 5982044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlNsPtr ns = (xmlNsPtr) ctxt->context->node; 5983044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard 5984044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if ((ns->next != NULL) && 5985044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard (ns->next->type != XML_NAMESPACE_DECL)) 5986044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard return((xmlNodePtr) ns->next); 5987081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack /* Bad, how did that namespace end up here ? */ 59883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 5989044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } 59903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 59913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 59923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 59933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == ctxt->context->doc->children) 59943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return((xmlNodePtr) ctxt->context->doc); 59953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == (xmlNodePtr) ctxt->context->doc) 59963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 59973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor switch (cur->type) { 59983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ELEMENT_NODE: 59993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_TEXT_NODE: 60003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_CDATA_SECTION_NODE: 60013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ENTITY_REF_NODE: 60023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ENTITY_NODE: 60033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_PI_NODE: 60043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_COMMENT_NODE: 60053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_NOTATION_NODE: 60063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_DTD_NODE: 60073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ELEMENT_DECL: 60083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ATTRIBUTE_DECL: 60093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ENTITY_DECL: 60103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_XINCLUDE_START: 60113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_XINCLUDE_END: 60128e7e1c00ce5cc3ce959833b888c50ed9fd9d5aaeDaniel Veillard if (cur->parent == NULL) 60138e7e1c00ce5cc3ce959833b888c50ed9fd9d5aaeDaniel Veillard return(NULL); 60148e7e1c00ce5cc3ce959833b888c50ed9fd9d5aaeDaniel Veillard if ((cur->parent->type == XML_ELEMENT_NODE) && 6015652d8a949447833405cc0805f4b7ff1179e59ed2Daniel Veillard ((cur->parent->name[0] == ' ') || 6016652d8a949447833405cc0805f4b7ff1179e59ed2Daniel Veillard (xmlStrEqual(cur->parent->name, 6017652d8a949447833405cc0805f4b7ff1179e59ed2Daniel Veillard BAD_CAST "fake node libxslt")))) 60188e7e1c00ce5cc3ce959833b888c50ed9fd9d5aaeDaniel Veillard return(NULL); 60193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(cur->parent); 60203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ATTRIBUTE_NODE: { 60213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlAttrPtr att = (xmlAttrPtr) ctxt->context->node; 60223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 60233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(att->parent); 60243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 6025dffd5c8dbc7b9052db7ae69dce419a96e22acc68Aleksey Sanin case XML_NAMESPACE_DECL: { 6026dffd5c8dbc7b9052db7ae69dce419a96e22acc68Aleksey Sanin xmlNsPtr ns = (xmlNsPtr) ctxt->context->node; 6027dffd5c8dbc7b9052db7ae69dce419a96e22acc68Aleksey Sanin 6028dffd5c8dbc7b9052db7ae69dce419a96e22acc68Aleksey Sanin if ((ns->next != NULL) && 6029dffd5c8dbc7b9052db7ae69dce419a96e22acc68Aleksey Sanin (ns->next->type != XML_NAMESPACE_DECL)) 6030dffd5c8dbc7b9052db7ae69dce419a96e22acc68Aleksey Sanin return((xmlNodePtr) ns->next); 6031081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack /* Bad, how did that namespace end up here ? */ 6032dffd5c8dbc7b9052db7ae69dce419a96e22acc68Aleksey Sanin return(NULL); 6033dffd5c8dbc7b9052db7ae69dce419a96e22acc68Aleksey Sanin } 60343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_DOCUMENT_NODE: 60353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_DOCUMENT_TYPE_NODE: 60363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_DOCUMENT_FRAG_NODE: 60373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_HTML_DOCUMENT_NODE: 6038eae522a0d8aa9f830d2e447f29b504030dbb6bbdDaniel Veillard#ifdef LIBXML_DOCB_ENABLED 6039eae522a0d8aa9f830d2e447f29b504030dbb6bbdDaniel Veillard case XML_DOCB_DOCUMENT_NODE: 60403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 60413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 60423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 60433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 60443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 60453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 60463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 60473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNextAncestorOrSelf: 60483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 60493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur: the current node in the traversal 60503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 60513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Traversal function for the "ancestor-or-self" direction 60523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * he ancestor-or-self axis contains the context node and ancestors of 60533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the context node in reverse document order; thus the context node is 60543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the first node on the axis, and the context node's parent the second; 60553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * parent here is defined the same as with the parent axis. 60563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 60573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the next element following that axis 60583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 60593473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNodePtr 60603473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNextAncestorOrSelf(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) { 6061a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard if ((ctxt == NULL) || (ctxt->context == NULL)) return(NULL); 60623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == NULL) 60633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ctxt->context->node); 60643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(xmlXPathNextAncestor(ctxt, cur)); 60653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 60663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 60673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 60683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNextFollowingSibling: 60693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 60703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur: the current node in the traversal 60713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 60723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Traversal function for the "following-sibling" direction 60733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The following-sibling axis contains the following siblings of the context 60743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * node in document order. 60753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 60763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the next element following that axis 60773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 60783473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNodePtr 60793473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNextFollowingSibling(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) { 6080a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard if ((ctxt == NULL) || (ctxt->context == NULL)) return(NULL); 60813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((ctxt->context->node->type == XML_ATTRIBUTE_NODE) || 60823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor (ctxt->context->node->type == XML_NAMESPACE_DECL)) 60833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 60843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == (xmlNodePtr) ctxt->context->doc) 60853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 60863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == NULL) 60873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ctxt->context->node->next); 60883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(cur->next); 60893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 60903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 60913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 60923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNextPrecedingSibling: 60933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 60943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur: the current node in the traversal 60953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 60963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Traversal function for the "preceding-sibling" direction 60973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The preceding-sibling axis contains the preceding siblings of the context 60983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * node in reverse document order; the first preceding sibling is first on the 60993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * axis; the sibling preceding that node is the second on the axis and so on. 61003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 61013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the next element following that axis 61023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 61033473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNodePtr 61043473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNextPrecedingSibling(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) { 6105a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard if ((ctxt == NULL) || (ctxt->context == NULL)) return(NULL); 61063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((ctxt->context->node->type == XML_ATTRIBUTE_NODE) || 61073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor (ctxt->context->node->type == XML_NAMESPACE_DECL)) 61083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 61093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == (xmlNodePtr) ctxt->context->doc) 61103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 61113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == NULL) 61123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ctxt->context->node->prev); 6113f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((cur->prev != NULL) && (cur->prev->type == XML_DTD_NODE)) { 6114f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard cur = cur->prev; 6115f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (cur == NULL) 6116f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return(ctxt->context->node->prev); 6117f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 61183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(cur->prev); 61193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 61203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 61213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 61223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNextFollowing: 61233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 61243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur: the current node in the traversal 61253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 61263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Traversal function for the "following" direction 61273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The following axis contains all nodes in the same document as the context 61283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * node that are after the context node in document order, excluding any 61293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * descendants and excluding attribute nodes and namespace nodes; the nodes 61303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * are ordered in document order 61313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 61323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the next element following that axis 61333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 61343473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNodePtr 61353473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNextFollowing(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) { 6136a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard if ((ctxt == NULL) || (ctxt->context == NULL)) return(NULL); 61373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur != NULL && cur->children != NULL) 61383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return cur->children ; 61393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == NULL) cur = ctxt->context->node; 61403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == NULL) return(NULL) ; /* ERROR */ 61413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur->next != NULL) return(cur->next) ; 61423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor do { 61433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur = cur->parent; 614411ce4004d86bb4b317c48b7d5124ba33e40e10f5Daniel Veillard if (cur == NULL) break; 61453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == (xmlNodePtr) ctxt->context->doc) return(NULL); 61463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur->next != NULL) return(cur->next); 61473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } while (cur != NULL); 61483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(cur); 61493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 61503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 61513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/* 61523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathIsAncestor: 61533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ancestor: the ancestor node 61543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @node: the current node 61553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 61563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Check that @ancestor is a @node's ancestor 61573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 61583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * returns 1 if @ancestor is a @node's ancestor, 0 otherwise. 61593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 61603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorstatic int 61613473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathIsAncestor(xmlNodePtr ancestor, xmlNodePtr node) { 61623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((ancestor == NULL) || (node == NULL)) return(0); 61633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* nodes need to be in the same document */ 61643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ancestor->doc != node->doc) return(0); 61653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* avoid searching if ancestor or node is the root node */ 61663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ancestor == (xmlNodePtr) node->doc) return(1); 61673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (node == (xmlNodePtr) ancestor->doc) return(0); 61683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while (node->parent != NULL) { 61693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (node->parent == ancestor) 61703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(1); 61713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor node = node->parent; 61723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 61733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(0); 61743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 61753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 61763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 61773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNextPreceding: 61783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 61793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur: the current node in the traversal 61803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 61813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Traversal function for the "preceding" direction 61823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the preceding axis contains all nodes in the same document as the context 61833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * node that are before the context node in document order, excluding any 61843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * ancestors and excluding attribute nodes and namespace nodes; the nodes are 61853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * ordered in reverse document order 61863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 61873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the next element following that axis 61883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 61893473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNodePtr 6190f06307e2c172284bb41376c396f757bdac9bdd19Daniel VeillardxmlXPathNextPreceding(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) 6191f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard{ 6192a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard if ((ctxt == NULL) || (ctxt->context == NULL)) return(NULL); 6193f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (cur == NULL) 6194f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard cur = ctxt->context->node; 61953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == NULL) 6196f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (NULL); 6197f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((cur->prev != NULL) && (cur->prev->type == XML_DTD_NODE)) 6198f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard cur = cur->prev; 61993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor do { 62003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur->prev != NULL) { 6201f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard for (cur = cur->prev; cur->last != NULL; cur = cur->last) ; 6202f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (cur); 62033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 62043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 62053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur = cur->parent; 6206f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (cur == NULL) 6207f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (NULL); 6208f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (cur == ctxt->context->doc->children) 6209f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (NULL); 62103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } while (xmlXPathIsAncestor(cur, ctxt->context->node)); 6211f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (cur); 6212f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard} 6213f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 6214f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard/** 6215f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * xmlXPathNextPrecedingInternal: 6216f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * @ctxt: the XPath Parser context 6217f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * @cur: the current node in the traversal 6218f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * 6219f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Traversal function for the "preceding" direction 6220f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * the preceding axis contains all nodes in the same document as the context 6221f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * node that are before the context node in document order, excluding any 6222f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * ancestors and excluding attribute nodes and namespace nodes; the nodes are 6223f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * ordered in reverse document order 6224f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * This is a faster implementation but internal only since it requires a 6225f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * state kept in the parser context: ctxt->ancestor. 6226f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * 6227f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Returns the next element following that axis 6228f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 6229f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillardstatic xmlNodePtr 6230f06307e2c172284bb41376c396f757bdac9bdd19Daniel VeillardxmlXPathNextPrecedingInternal(xmlXPathParserContextPtr ctxt, 6231f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlNodePtr cur) 6232f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard{ 6233a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard if ((ctxt == NULL) || (ctxt->context == NULL)) return(NULL); 6234f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (cur == NULL) { 6235f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard cur = ctxt->context->node; 6236f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (cur == NULL) 6237f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (NULL); 623840c22b472b3d24ecc2f5b843aa3fffad6ed5cf5eWilliam M. Brack if (cur->type == XML_NAMESPACE_DECL) 623940c22b472b3d24ecc2f5b843aa3fffad6ed5cf5eWilliam M. Brack cur = (xmlNodePtr)((xmlNsPtr)cur)->next; 6240f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->ancestor = cur->parent; 6241f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 6242f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((cur->prev != NULL) && (cur->prev->type == XML_DTD_NODE)) 6243f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard cur = cur->prev; 6244f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard while (cur->prev == NULL) { 6245f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard cur = cur->parent; 6246f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (cur == NULL) 6247f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (NULL); 6248f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (cur == ctxt->context->doc->children) 6249f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (NULL); 6250f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (cur != ctxt->ancestor) 6251f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (cur); 6252f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->ancestor = cur->parent; 6253f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 6254f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard cur = cur->prev; 6255f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard while (cur->last != NULL) 6256f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard cur = cur->last; 6257f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (cur); 62583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 62593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 62603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 62613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNextNamespace: 62623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 62633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur: the current attribute in the traversal 62643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 62653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Traversal function for the "namespace" direction 62663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the namespace axis contains the namespace nodes of the context node; 62673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the order of nodes on this axis is implementation-defined; the axis will 62683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * be empty unless the context node is an element 62693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 627020ee8c03107e5d5724765da513d595fdaf290dceDaniel Veillard * We keep the XML namespace node at the end of the list. 627120ee8c03107e5d5724765da513d595fdaf290dceDaniel Veillard * 62723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the next element following that axis 62733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 62743473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNodePtr 62753473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNextNamespace(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) { 6276a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard if ((ctxt == NULL) || (ctxt->context == NULL)) return(NULL); 62773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->context->node->type != XML_ELEMENT_NODE) return(NULL); 6278fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard if (ctxt->context->tmpNsList == NULL && cur != (xmlNodePtr) xmlXPathXMLNamespace) { 62797d7e37919fc6c7f257769c867122d885d2aae26fDaniel Veillard if (ctxt->context->tmpNsList != NULL) 62807d7e37919fc6c7f257769c867122d885d2aae26fDaniel Veillard xmlFree(ctxt->context->tmpNsList); 62817d7e37919fc6c7f257769c867122d885d2aae26fDaniel Veillard ctxt->context->tmpNsList = 62823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGetNsList(ctxt->context->doc, ctxt->context->node); 62837d7e37919fc6c7f257769c867122d885d2aae26fDaniel Veillard ctxt->context->tmpNsNr = 0; 6284fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard if (ctxt->context->tmpNsList != NULL) { 6285fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard while (ctxt->context->tmpNsList[ctxt->context->tmpNsNr] != NULL) { 6286fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard ctxt->context->tmpNsNr++; 6287fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard } 6288fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard } 6289fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard return((xmlNodePtr) xmlXPathXMLNamespace); 62907d7e37919fc6c7f257769c867122d885d2aae26fDaniel Veillard } 6291fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard if (ctxt->context->tmpNsNr > 0) { 6292fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard return (xmlNodePtr)ctxt->context->tmpNsList[--ctxt->context->tmpNsNr]; 6293fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard } else { 6294fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard if (ctxt->context->tmpNsList != NULL) 6295fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard xmlFree(ctxt->context->tmpNsList); 62967d7e37919fc6c7f257769c867122d885d2aae26fDaniel Veillard ctxt->context->tmpNsList = NULL; 6297fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard return(NULL); 62983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 62993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 63003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 63013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 63023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNextAttribute: 63033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 63043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur: the current attribute in the traversal 63053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 63063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Traversal function for the "attribute" direction 63073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * TODO: support DTD inherited default attributes 63083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 63093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the next element following that axis 63103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 63113473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNodePtr 63123473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNextAttribute(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) { 6313a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard if ((ctxt == NULL) || (ctxt->context == NULL)) return(NULL); 6314e470df7fdd3505c6232d6498f3b8834ebfce522dDaniel Veillard if (ctxt->context->node == NULL) 6315e470df7fdd3505c6232d6498f3b8834ebfce522dDaniel Veillard return(NULL); 6316e470df7fdd3505c6232d6498f3b8834ebfce522dDaniel Veillard if (ctxt->context->node->type != XML_ELEMENT_NODE) 6317e470df7fdd3505c6232d6498f3b8834ebfce522dDaniel Veillard return(NULL); 63183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == NULL) { 63193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->context->node == (xmlNodePtr) ctxt->context->doc) 63203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 63213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return((xmlNodePtr)ctxt->context->node->properties); 63223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 63233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return((xmlNodePtr)cur->next); 63243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 63253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 63263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/************************************************************************ 63273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * * 63283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * NodeTest Functions * 63293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * * 63303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ************************************************************************/ 63313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 63323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define IS_FUNCTION 200 63333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 6334d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard 6335d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard/************************************************************************ 6336d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * * 6337d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * Implicit tree core function library * 6338d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * * 6339d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard ************************************************************************/ 6340d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard 63413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 6342d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * xmlXPathRoot: 63433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 63443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 6345d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * Initialize the context to the root of the document 63463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 6347d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillardvoid 6348d8df6c0e8c883e1d618388d266015dda36731440Daniel VeillardxmlXPathRoot(xmlXPathParserContextPtr ctxt) { 6349a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard if ((ctxt == NULL) || (ctxt->context == NULL)) return; 6350d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard ctxt->context->node = (xmlNodePtr) ctxt->context->doc; 6351d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard valuePush(ctxt, xmlXPathNewNodeSet(ctxt->context->node)); 6352d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard} 63533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 6354d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard/************************************************************************ 6355d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * * 6356d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * The explicit core function library * 6357d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard *http://www.w3.org/Style/XSL/Group/1999/07/xpath-19990705.html#corelib * 6358d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * * 6359d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard ************************************************************************/ 63603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 6361d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard 6362d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard/** 6363d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * xmlXPathLastFunction: 6364d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * @ctxt: the XPath Parser context 6365d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * @nargs: the number of arguments 6366d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * 6367d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * Implement the last() XPath function 6368d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * number last() 6369d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * The last function returns the number of nodes in the context node list. 6370d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard */ 6371d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillardvoid 6372d8df6c0e8c883e1d618388d266015dda36731440Daniel VeillardxmlXPathLastFunction(xmlXPathParserContextPtr ctxt, int nargs) { 6373d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard CHECK_ARITY(0); 6374d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard if (ctxt->context->contextSize >= 0) { 6375d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard valuePush(ctxt, xmlXPathNewFloat((double) ctxt->context->contextSize)); 6376d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_EXPR 6377d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard xmlGenericError(xmlGenericErrorContext, 6378d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard "last() : %d\n", ctxt->context->contextSize); 63793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 6380d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard } else { 6381d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard XP_ERROR(XPATH_INVALID_CTXT_SIZE); 63823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 6383d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard} 63843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 6385d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard/** 6386d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * xmlXPathPositionFunction: 6387d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * @ctxt: the XPath Parser context 6388d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * @nargs: the number of arguments 6389d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * 6390d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * Implement the position() XPath function 6391d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * number position() 6392d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * The position function returns the position of the context node in the 6393cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * context node list. The first position is 1, and so the last position 6394d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * will be equal to last(). 6395d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard */ 6396d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillardvoid 6397d8df6c0e8c883e1d618388d266015dda36731440Daniel VeillardxmlXPathPositionFunction(xmlXPathParserContextPtr ctxt, int nargs) { 6398d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard CHECK_ARITY(0); 6399d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard if (ctxt->context->proximityPosition >= 0) { 6400d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard valuePush(ctxt, 6401d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard xmlXPathNewFloat((double) ctxt->context->proximityPosition)); 6402d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_EXPR 6403d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard xmlGenericError(xmlGenericErrorContext, "position() : %d\n", 6404d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard ctxt->context->proximityPosition); 64053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 6406d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard } else { 6407d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard XP_ERROR(XPATH_INVALID_CTXT_POSITION); 6408d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard } 6409d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard} 64103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 64113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 64123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathCountFunction: 64133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 64143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs: the number of arguments 64153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 64163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the count() XPath function 64173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * number count(node-set) 64183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 64193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 64203473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathCountFunction(xmlXPathParserContextPtr ctxt, int nargs) { 64213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr cur; 64223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 64233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ARITY(1); 64243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((ctxt->value == NULL) || 64253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ((ctxt->value->type != XPATH_NODESET) && 64263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor (ctxt->value->type != XPATH_XSLT_TREE))) 64273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XP_ERROR(XPATH_INVALID_TYPE); 64283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur = valuePop(ctxt); 64293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 6430911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard if ((cur == NULL) || (cur->nodesetval == NULL)) 6431911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard valuePush(ctxt, xmlXPathNewFloat((double) 0)); 64320c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack else if ((cur->type == XPATH_NODESET) || (cur->type == XPATH_XSLT_TREE)) { 6433911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard valuePush(ctxt, xmlXPathNewFloat((double) cur->nodesetval->nodeNr)); 6434fe70332f7f29f146a364c73450729a8b3274daeeDaniel Veillard } else { 6435fe70332f7f29f146a364c73450729a8b3274daeeDaniel Veillard if ((cur->nodesetval->nodeNr != 1) || 6436fe70332f7f29f146a364c73450729a8b3274daeeDaniel Veillard (cur->nodesetval->nodeTab == NULL)) { 6437fe70332f7f29f146a364c73450729a8b3274daeeDaniel Veillard valuePush(ctxt, xmlXPathNewFloat((double) 0)); 6438fe70332f7f29f146a364c73450729a8b3274daeeDaniel Veillard } else { 6439fe70332f7f29f146a364c73450729a8b3274daeeDaniel Veillard xmlNodePtr tmp; 6440fe70332f7f29f146a364c73450729a8b3274daeeDaniel Veillard int i = 0; 6441fe70332f7f29f146a364c73450729a8b3274daeeDaniel Veillard 6442fe70332f7f29f146a364c73450729a8b3274daeeDaniel Veillard tmp = cur->nodesetval->nodeTab[0]; 6443fe70332f7f29f146a364c73450729a8b3274daeeDaniel Veillard if (tmp != NULL) { 6444fe70332f7f29f146a364c73450729a8b3274daeeDaniel Veillard tmp = tmp->children; 6445fe70332f7f29f146a364c73450729a8b3274daeeDaniel Veillard while (tmp != NULL) { 6446fe70332f7f29f146a364c73450729a8b3274daeeDaniel Veillard tmp = tmp->next; 6447fe70332f7f29f146a364c73450729a8b3274daeeDaniel Veillard i++; 6448fe70332f7f29f146a364c73450729a8b3274daeeDaniel Veillard } 6449fe70332f7f29f146a364c73450729a8b3274daeeDaniel Veillard } 6450fe70332f7f29f146a364c73450729a8b3274daeeDaniel Veillard valuePush(ctxt, xmlXPathNewFloat((double) i)); 6451fe70332f7f29f146a364c73450729a8b3274daeeDaniel Veillard } 6452fe70332f7f29f146a364c73450729a8b3274daeeDaniel Veillard } 64533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(cur); 64543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 64553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 64563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 6457ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathGetElementsByIds: 6458ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @doc: the document 6459ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @ids: a whitespace separated list of IDs 6460ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 6461ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Selects elements by their unique ID. 6462ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * 6463ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns a node-set of selected elements. 6464ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */ 6465ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillardstatic xmlNodeSetPtr 6466ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathGetElementsByIds (xmlDocPtr doc, const xmlChar *ids) { 6467ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlNodeSetPtr ret; 6468ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard const xmlChar *cur = ids; 6469ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlChar *ID; 6470ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlAttrPtr attr; 6471ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlNodePtr elem = NULL; 6472ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 64737a985a18c2fee0aa9b490792dd990b75506e3740Daniel Veillard if (ids == NULL) return(NULL); 64747a985a18c2fee0aa9b490792dd990b75506e3740Daniel Veillard 6475ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = xmlXPathNodeSetCreate(NULL); 6476ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 647776e95df05556c9610b564b14cf578c8f9e34c9c1William M. Brack while (IS_BLANK_CH(*cur)) cur++; 6478ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard while (*cur != 0) { 647976e95df05556c9610b564b14cf578c8f9e34c9c1William M. Brack while ((!IS_BLANK_CH(*cur)) && (*cur != 0)) 6480e209b330558d170da195acb3a7618b0048d22c9eDaniel Veillard cur++; 6481ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 6482ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ID = xmlStrndup(ids, cur - ids); 6483e209b330558d170da195acb3a7618b0048d22c9eDaniel Veillard if (ID != NULL) { 648468cb4b2498088cf920ed6c9490b134ce7f38909fDaniel Veillard /* 648568cb4b2498088cf920ed6c9490b134ce7f38909fDaniel Veillard * We used to check the fact that the value passed 648668cb4b2498088cf920ed6c9490b134ce7f38909fDaniel Veillard * was an NCName, but this generated much troubles for 648768cb4b2498088cf920ed6c9490b134ce7f38909fDaniel Veillard * me and Aleksey Sanin, people blatantly violated that 648868cb4b2498088cf920ed6c9490b134ce7f38909fDaniel Veillard * constaint, like Visa3D spec. 648968cb4b2498088cf920ed6c9490b134ce7f38909fDaniel Veillard * if (xmlValidateNCName(ID, 1) == 0) 649068cb4b2498088cf920ed6c9490b134ce7f38909fDaniel Veillard */ 649168cb4b2498088cf920ed6c9490b134ce7f38909fDaniel Veillard attr = xmlGetID(doc, ID); 649268cb4b2498088cf920ed6c9490b134ce7f38909fDaniel Veillard if (attr != NULL) { 649368cb4b2498088cf920ed6c9490b134ce7f38909fDaniel Veillard if (attr->type == XML_ATTRIBUTE_NODE) 649468cb4b2498088cf920ed6c9490b134ce7f38909fDaniel Veillard elem = attr->parent; 649568cb4b2498088cf920ed6c9490b134ce7f38909fDaniel Veillard else if (attr->type == XML_ELEMENT_NODE) 649668cb4b2498088cf920ed6c9490b134ce7f38909fDaniel Veillard elem = (xmlNodePtr) attr; 649768cb4b2498088cf920ed6c9490b134ce7f38909fDaniel Veillard else 649868cb4b2498088cf920ed6c9490b134ce7f38909fDaniel Veillard elem = NULL; 649968cb4b2498088cf920ed6c9490b134ce7f38909fDaniel Veillard if (elem != NULL) 650068cb4b2498088cf920ed6c9490b134ce7f38909fDaniel Veillard xmlXPathNodeSetAdd(ret, elem); 6501e209b330558d170da195acb3a7618b0048d22c9eDaniel Veillard } 6502ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlFree(ID); 6503e209b330558d170da195acb3a7618b0048d22c9eDaniel Veillard } 6504ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 650576e95df05556c9610b564b14cf578c8f9e34c9c1William M. Brack while (IS_BLANK_CH(*cur)) cur++; 6506ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ids = cur; 6507ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard } 6508ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return(ret); 6509ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard} 6510ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard 6511ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/** 65123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathIdFunction: 65133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 65143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs: the number of arguments 65153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 65163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the id() XPath function 65173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * node-set id(object) 65183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The id function selects elements by their unique ID 65193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * (see [5.2.1 Unique IDs]). When the argument to id is of type node-set, 65203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * then the result is the union of the result of applying id to the 65213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * string value of each of the nodes in the argument node-set. When the 65223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * argument to id is of any other type, the argument is converted to a 65233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * string as if by a call to the string function; the string is split 65243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * into a whitespace-separated list of tokens (whitespace is any sequence 65253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * of characters matching the production S); the result is a node-set 65263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * containing the elements in the same document as the context node that 65273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * have a unique ID equal to any of the tokens in the list. 65283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 65293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 65303473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathIdFunction(xmlXPathParserContextPtr ctxt, int nargs) { 6531ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlChar *tokens; 6532ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlNodeSetPtr ret; 6533ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlXPathObjectPtr obj; 65343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 65353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ARITY(1); 65363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor obj = valuePop(ctxt); 65373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (obj == NULL) XP_ERROR(XPATH_INVALID_OPERAND); 65380c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack if ((obj->type == XPATH_NODESET) || (obj->type == XPATH_XSLT_TREE)) { 6539ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlNodeSetPtr ns; 65403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int i; 65413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 6542ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = xmlXPathNodeSetCreate(NULL); 65433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 6544911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard if (obj->nodesetval != NULL) { 6545911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard for (i = 0; i < obj->nodesetval->nodeNr; i++) { 6546ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard tokens = 6547ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlXPathCastNodeToString(obj->nodesetval->nodeTab[i]); 6548ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ns = xmlXPathGetElementsByIds(ctxt->context->doc, tokens); 6549ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = xmlXPathNodeSetMerge(ret, ns); 6550ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlXPathFreeNodeSet(ns); 6551ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard if (tokens != NULL) 6552ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlFree(tokens); 6553911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard } 65543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 65553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 65563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(obj); 6557ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard valuePush(ctxt, xmlXPathWrapNodeSet(ret)); 65583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return; 65593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 6560ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard obj = xmlXPathConvertString(obj); 65613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 6562ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ret = xmlXPathGetElementsByIds(ctxt->context->doc, obj->stringval); 6563ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard valuePush(ctxt, xmlXPathWrapNodeSet(ret)); 65643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 65653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(obj); 65663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return; 65673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 65683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 65693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 65703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathLocalNameFunction: 65713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 65723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs: the number of arguments 65733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 65743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the local-name() XPath function 65753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * string local-name(node-set?) 65763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The local-name function returns a string containing the local part 65773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * of the name of the node in the argument node-set that is first in 65783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * document order. If the node-set is empty or the first node has no 65793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * name, an empty string is returned. If the argument is omitted it 65803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * defaults to the context node. 65813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 65823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 65833473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathLocalNameFunction(xmlXPathParserContextPtr ctxt, int nargs) { 65843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr cur; 65853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 6586a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard if (ctxt == NULL) return; 6587a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard 65883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (nargs == 0) { 65893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, xmlXPathNewNodeSet(ctxt->context->node)); 65903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor nargs = 1; 65913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 65923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 65933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ARITY(1); 65943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((ctxt->value == NULL) || 65953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ((ctxt->value->type != XPATH_NODESET) && 65963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor (ctxt->value->type != XPATH_XSLT_TREE))) 65973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XP_ERROR(XPATH_INVALID_TYPE); 65983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur = valuePop(ctxt); 65993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 6600911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard if ((cur->nodesetval == NULL) || (cur->nodesetval->nodeNr == 0)) { 66013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, xmlXPathNewCString("")); 66023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else { 66033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int i = 0; /* Should be first in document order !!!!! */ 66043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor switch (cur->nodesetval->nodeTab[i]->type) { 66053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ELEMENT_NODE: 66063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ATTRIBUTE_NODE: 66073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_PI_NODE: 6608652d8a949447833405cc0805f4b7ff1179e59ed2Daniel Veillard if (cur->nodesetval->nodeTab[i]->name[0] == ' ') 6609652d8a949447833405cc0805f4b7ff1179e59ed2Daniel Veillard valuePush(ctxt, xmlXPathNewCString("")); 6610652d8a949447833405cc0805f4b7ff1179e59ed2Daniel Veillard else 6611652d8a949447833405cc0805f4b7ff1179e59ed2Daniel Veillard valuePush(ctxt, 66123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathNewString(cur->nodesetval->nodeTab[i]->name)); 66133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 66143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_NAMESPACE_DECL: 66153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, xmlXPathNewString( 66163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ((xmlNsPtr)cur->nodesetval->nodeTab[i])->prefix)); 66173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 66183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor default: 66193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, xmlXPathNewCString("")); 66203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 66213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 66223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(cur); 66233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 66243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 66253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 66263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNamespaceURIFunction: 66273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 66283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs: the number of arguments 66293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 66303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the namespace-uri() XPath function 66313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * string namespace-uri(node-set?) 66323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The namespace-uri function returns a string containing the 66333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * namespace URI of the expanded name of the node in the argument 66343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * node-set that is first in document order. If the node-set is empty, 66353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the first node has no name, or the expanded name has no namespace 66363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * URI, an empty string is returned. If the argument is omitted it 66373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * defaults to the context node. 66383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 66393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 66403473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNamespaceURIFunction(xmlXPathParserContextPtr ctxt, int nargs) { 66413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr cur; 66423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 6643a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard if (ctxt == NULL) return; 6644a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard 66453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (nargs == 0) { 66463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, xmlXPathNewNodeSet(ctxt->context->node)); 66473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor nargs = 1; 66483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 66493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ARITY(1); 66503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((ctxt->value == NULL) || 66513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ((ctxt->value->type != XPATH_NODESET) && 66523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor (ctxt->value->type != XPATH_XSLT_TREE))) 66533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XP_ERROR(XPATH_INVALID_TYPE); 66543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur = valuePop(ctxt); 66553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 6656911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard if ((cur->nodesetval == NULL) || (cur->nodesetval->nodeNr == 0)) { 66573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, xmlXPathNewCString("")); 66583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else { 66593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int i = 0; /* Should be first in document order !!!!! */ 66603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor switch (cur->nodesetval->nodeTab[i]->type) { 66613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ELEMENT_NODE: 66623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case XML_ATTRIBUTE_NODE: 66633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur->nodesetval->nodeTab[i]->ns == NULL) 66643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, xmlXPathNewCString("")); 66653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else 66663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, xmlXPathNewString( 66673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur->nodesetval->nodeTab[i]->ns->href)); 66683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 66693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor default: 66703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, xmlXPathNewCString("")); 66713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 66723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 66733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(cur); 66743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 66753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 66763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 66773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNameFunction: 66783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 66793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs: the number of arguments 66803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 66813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the name() XPath function 66823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * string name(node-set?) 66833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The name function returns a string containing a QName representing 6684cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * the name of the node in the argument node-set that is first in document 66853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * order. The QName must represent the name with respect to the namespace 66863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * declarations in effect on the node whose name is being represented. 66873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Typically, this will be the form in which the name occurred in the XML 66883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * source. This need not be the case if there are namespace declarations 66893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * in effect on the node that associate multiple prefixes with the same 66903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * namespace. However, an implementation may include information about 66913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the original prefix in its representation of nodes; in this case, an 66923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * implementation can ensure that the returned string is always the same 66933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * as the QName used in the XML source. If the argument it omitted it 66943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * defaults to the context node. 66953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Libxml keep the original prefix so the "real qualified name" used is 66963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * returned. 66973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 669856a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic void 66990438375d2e6be47d0179826271081ae64df94f8bDaniel VeillardxmlXPathNameFunction(xmlXPathParserContextPtr ctxt, int nargs) 67000438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard{ 67013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr cur; 67023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 67033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (nargs == 0) { 67040438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard valuePush(ctxt, xmlXPathNewNodeSet(ctxt->context->node)); 67050438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard nargs = 1; 67063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 67073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 67083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ARITY(1); 67090438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard if ((ctxt->value == NULL) || 67100438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard ((ctxt->value->type != XPATH_NODESET) && 67110438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard (ctxt->value->type != XPATH_XSLT_TREE))) 67120438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard XP_ERROR(XPATH_INVALID_TYPE); 67133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur = valuePop(ctxt); 67143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 6715911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard if ((cur->nodesetval == NULL) || (cur->nodesetval->nodeNr == 0)) { 67160438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard valuePush(ctxt, xmlXPathNewCString("")); 67173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else { 67180438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard int i = 0; /* Should be first in document order !!!!! */ 67193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 67200438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard switch (cur->nodesetval->nodeTab[i]->type) { 67210438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard case XML_ELEMENT_NODE: 67220438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard case XML_ATTRIBUTE_NODE: 6723652d8a949447833405cc0805f4b7ff1179e59ed2Daniel Veillard if (cur->nodesetval->nodeTab[i]->name[0] == ' ') 6724652d8a949447833405cc0805f4b7ff1179e59ed2Daniel Veillard valuePush(ctxt, xmlXPathNewCString("")); 6725652d8a949447833405cc0805f4b7ff1179e59ed2Daniel Veillard else if ((cur->nodesetval->nodeTab[i]->ns == NULL) || 6726652d8a949447833405cc0805f4b7ff1179e59ed2Daniel Veillard (cur->nodesetval->nodeTab[i]->ns->prefix == NULL)) { 67270438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard valuePush(ctxt, 6728c00cda8c065beba24706c9e8719f08e9de420274Daniel Veillard xmlXPathNewString(cur->nodesetval->nodeTab[i]->name)); 67290438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard 6730652d8a949447833405cc0805f4b7ff1179e59ed2Daniel Veillard } else { 6731c00cda8c065beba24706c9e8719f08e9de420274Daniel Veillard xmlChar *fullname; 6732c00cda8c065beba24706c9e8719f08e9de420274Daniel Veillard 6733c00cda8c065beba24706c9e8719f08e9de420274Daniel Veillard fullname = xmlBuildQName(cur->nodesetval->nodeTab[i]->name, 6734c00cda8c065beba24706c9e8719f08e9de420274Daniel Veillard cur->nodesetval->nodeTab[i]->ns->prefix, 6735c00cda8c065beba24706c9e8719f08e9de420274Daniel Veillard NULL, 0); 6736c00cda8c065beba24706c9e8719f08e9de420274Daniel Veillard if (fullname == cur->nodesetval->nodeTab[i]->name) 6737c00cda8c065beba24706c9e8719f08e9de420274Daniel Veillard fullname = xmlStrdup(cur->nodesetval->nodeTab[i]->name); 6738c00cda8c065beba24706c9e8719f08e9de420274Daniel Veillard if (fullname == NULL) { 6739c00cda8c065beba24706c9e8719f08e9de420274Daniel Veillard XP_ERROR(XPATH_MEMORY_ERROR); 6740c00cda8c065beba24706c9e8719f08e9de420274Daniel Veillard } 6741c00cda8c065beba24706c9e8719f08e9de420274Daniel Veillard valuePush(ctxt, xmlXPathWrapString(fullname)); 67420438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard } 67430438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard break; 67440438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard default: 67450438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard valuePush(ctxt, 67460438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard xmlXPathNewNodeSet(cur->nodesetval->nodeTab[i])); 67470438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard xmlXPathLocalNameFunction(ctxt, 1); 67480438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard } 67493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 67503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(cur); 67513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 67523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 6753fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard 6754fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard/** 67553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathStringFunction: 67563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 67573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs: the number of arguments 67583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 67593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the string() XPath function 67603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * string string(object?) 6761081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack * The string function converts an object to a string as follows: 67623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * - A node-set is converted to a string by returning the value of 67633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the node in the node-set that is first in document order. 67643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * If the node-set is empty, an empty string is returned. 67653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * - A number is converted to a string as follows 67663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * + NaN is converted to the string NaN 67673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * + positive zero is converted to the string 0 67683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * + negative zero is converted to the string 0 67693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * + positive infinity is converted to the string Infinity 67703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * + negative infinity is converted to the string -Infinity 67713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * + if the number is an integer, the number is represented in 67723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * decimal form as a Number with no decimal point and no leading 67733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * zeros, preceded by a minus sign (-) if the number is negative 67743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * + otherwise, the number is represented in decimal form as a 67753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Number including a decimal point with at least one digit 67763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * before the decimal point and at least one digit after the 67773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * decimal point, preceded by a minus sign (-) if the number 67783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * is negative; there must be no leading zeros before the decimal 6779cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * point apart possibly from the one required digit immediately 67803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * before the decimal point; beyond the one required digit 67813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * after the decimal point there must be as many, but only as 67823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * many, more digits as are needed to uniquely distinguish the 67833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * number from all other IEEE 754 numeric values. 67843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * - The boolean false value is converted to the string false. 67853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The boolean true value is converted to the string true. 67863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 67873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * If the argument is omitted, it defaults to a node-set with the 67883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * context node as its only member. 67893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 67903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 67913473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathStringFunction(xmlXPathParserContextPtr ctxt, int nargs) { 67923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr cur; 67933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 6794a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard if (ctxt == NULL) return; 67953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (nargs == 0) { 6796ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard valuePush(ctxt, 6797ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlXPathWrapString( 6798ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlXPathCastNodeToString(ctxt->context->node))); 6799ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard return; 68003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 68013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 68023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ARITY(1); 68033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur = valuePop(ctxt); 68043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur == NULL) XP_ERROR(XPATH_INVALID_OPERAND); 6805fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard cur = xmlXPathConvertString(cur); 6806fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard valuePush(ctxt, cur); 68073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 68083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 68093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 68103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathStringLengthFunction: 68113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 68123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs: the number of arguments 68133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 68143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the string-length() XPath function 68153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * number string-length(string?) 68163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The string-length returns the number of characters in the string 68173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * (see [3.6 Strings]). If the argument is omitted, it defaults to 68183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the context node converted to a string, in other words the value 68193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * of the context node. 68203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 68213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 68223473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathStringLengthFunction(xmlXPathParserContextPtr ctxt, int nargs) { 68233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr cur; 68243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 68253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (nargs == 0) { 6826a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard if ((ctxt == NULL) || (ctxt->context == NULL)) 6827a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard return; 68283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->context->node == NULL) { 68293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, xmlXPathNewFloat(0)); 68303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else { 68313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlChar *content; 68323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 6833ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard content = xmlXPathCastNodeToString(ctxt->context->node); 6834e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard valuePush(ctxt, xmlXPathNewFloat(xmlUTF8Strlen(content))); 68353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(content); 68363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 68373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return; 68383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 68393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ARITY(1); 68403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CAST_TO_STRING; 68413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_TYPE(XPATH_STRING); 68423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur = valuePop(ctxt); 6843e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard valuePush(ctxt, xmlXPathNewFloat(xmlUTF8Strlen(cur->stringval))); 68443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(cur); 68453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 68463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 68473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 68483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathConcatFunction: 68493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 68503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs: the number of arguments 68513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 68523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the concat() XPath function 68533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * string concat(string, string, string*) 68543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The concat function returns the concatenation of its arguments. 68553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 68563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 68573473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathConcatFunction(xmlXPathParserContextPtr ctxt, int nargs) { 68583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr cur, newobj; 68593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlChar *tmp; 68603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 6861a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard if (ctxt == NULL) return; 68623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (nargs < 2) { 68633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ARITY(2); 68643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 68653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 68663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CAST_TO_STRING; 68673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur = valuePop(ctxt); 68683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((cur == NULL) || (cur->type != XPATH_STRING)) { 68693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(cur); 68703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return; 68713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 68723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor nargs--; 68733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 68743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while (nargs > 0) { 68753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CAST_TO_STRING; 68763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor newobj = valuePop(ctxt); 68773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((newobj == NULL) || (newobj->type != XPATH_STRING)) { 68783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(newobj); 68793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(cur); 68803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XP_ERROR(XPATH_INVALID_TYPE); 68813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 68823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor tmp = xmlStrcat(newobj->stringval, cur->stringval); 68833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor newobj->stringval = cur->stringval; 68843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur->stringval = tmp; 68853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 68863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(newobj); 68873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor nargs--; 68883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 68893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, cur); 68903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 68913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 68923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 68933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathContainsFunction: 68943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 68953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs: the number of arguments 68963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 68973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the contains() XPath function 68983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * boolean contains(string, string) 68993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The contains function returns true if the first argument string 69003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * contains the second argument string, and otherwise returns false. 69013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 69023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 69033473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathContainsFunction(xmlXPathParserContextPtr ctxt, int nargs) { 69043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr hay, needle; 69053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 69063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ARITY(2); 69073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CAST_TO_STRING; 69083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_TYPE(XPATH_STRING); 69093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor needle = valuePop(ctxt); 69103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CAST_TO_STRING; 69113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor hay = valuePop(ctxt); 69123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((hay == NULL) || (hay->type != XPATH_STRING)) { 69133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(hay); 69143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(needle); 69153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XP_ERROR(XPATH_INVALID_TYPE); 69163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 69173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (xmlStrstr(hay->stringval, needle->stringval)) 69183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, xmlXPathNewBoolean(1)); 69193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else 69203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, xmlXPathNewBoolean(0)); 69213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(hay); 69223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(needle); 69233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 69243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 69253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 69263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathStartsWithFunction: 69273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 69283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs: the number of arguments 69293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 69303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the starts-with() XPath function 69313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * boolean starts-with(string, string) 69323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The starts-with function returns true if the first argument string 69333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * starts with the second argument string, and otherwise returns false. 69343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 69353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 69363473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathStartsWithFunction(xmlXPathParserContextPtr ctxt, int nargs) { 69373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr hay, needle; 69383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int n; 69393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 69403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ARITY(2); 69413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CAST_TO_STRING; 69423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_TYPE(XPATH_STRING); 69433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor needle = valuePop(ctxt); 69443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CAST_TO_STRING; 69453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor hay = valuePop(ctxt); 69463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((hay == NULL) || (hay->type != XPATH_STRING)) { 69473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(hay); 69483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(needle); 69493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XP_ERROR(XPATH_INVALID_TYPE); 69503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 69513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor n = xmlStrlen(needle->stringval); 69523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (xmlStrncmp(hay->stringval, needle->stringval, n)) 69533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, xmlXPathNewBoolean(0)); 69543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else 69553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, xmlXPathNewBoolean(1)); 69563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(hay); 69573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(needle); 69583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 69593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 69603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 69613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathSubstringFunction: 69623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 69633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs: the number of arguments 69643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 69653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the substring() XPath function 69663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * string substring(string, number, number?) 69673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The substring function returns the substring of the first argument 69683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * starting at the position specified in the second argument with 69693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * length specified in the third argument. For example, 69703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * substring("12345",2,3) returns "234". If the third argument is not 69713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * specified, it returns the substring starting at the position specified 69723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * in the second argument and continuing to the end of the string. For 69733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * example, substring("12345",2) returns "2345". More precisely, each 69743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * character in the string (see [3.6 Strings]) is considered to have a 69753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * numeric position: the position of the first character is 1, the position 69763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * of the second character is 2 and so on. The returned substring contains 69773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * those characters for which the position of the character is greater than 69783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * or equal to the second argument and, if the third argument is specified, 69793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * less than the sum of the second and third arguments; the comparisons 69803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * and addition used for the above follow the standard IEEE 754 rules. Thus: 69813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * - substring("12345", 1.5, 2.6) returns "234" 69823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * - substring("12345", 0, 3) returns "12" 69833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * - substring("12345", 0 div 0, 3) returns "" 69843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * - substring("12345", 1, 0 div 0) returns "" 69853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * - substring("12345", -42, 1 div 0) returns "12345" 69863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * - substring("12345", -1 div 0, 1 div 0) returns "" 69873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 69883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 69893473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathSubstringFunction(xmlXPathParserContextPtr ctxt, int nargs) { 69903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr str, start, len; 699197ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard double le=0, in; 699297ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard int i, l, m; 69933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlChar *ret; 69943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 69953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (nargs < 2) { 69963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ARITY(2); 69973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 69983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (nargs > 3) { 69993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ARITY(3); 70003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 700197ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard /* 700297ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard * take care of possible last (position) argument 700397ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard */ 70043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (nargs == 3) { 70053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CAST_TO_NUMBER; 70063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_TYPE(XPATH_NUMBER); 70073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor len = valuePop(ctxt); 70083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor le = len->floatval; 70093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(len); 70103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 701197ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard 70123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CAST_TO_NUMBER; 70133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_TYPE(XPATH_NUMBER); 70143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor start = valuePop(ctxt); 70153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor in = start->floatval; 70163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(start); 70173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CAST_TO_STRING; 70183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_TYPE(XPATH_STRING); 70193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor str = valuePop(ctxt); 702097ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard m = xmlUTF8Strlen((const unsigned char *)str->stringval); 702197ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard 702297ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard /* 702397ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard * If last pos not present, calculate last position 702497ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard */ 70259e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard if (nargs != 3) { 70269e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard le = (double)m; 70279e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard if (in < 1.0) 70289e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard in = 1.0; 70299e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard } 703097ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard 70310eafdef9881c396ce4c014359d8f497cc088cfabDaniel Veillard /* Need to check for the special cases where either 70320eafdef9881c396ce4c014359d8f497cc088cfabDaniel Veillard * the index is NaN, the length is NaN, or both 70330eafdef9881c396ce4c014359d8f497cc088cfabDaniel Veillard * arguments are infinity (relying on Inf + -Inf = NaN) 703497ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard */ 70359e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard if (!xmlXPathIsNaN(in + le) && !xmlXPathIsInf(in)) { 70360eafdef9881c396ce4c014359d8f497cc088cfabDaniel Veillard /* 70379e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard * To meet the requirements of the spec, the arguments 70389e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard * must be converted to integer format before 70399e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard * initial index calculations are done 70400eafdef9881c396ce4c014359d8f497cc088cfabDaniel Veillard * 70419e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard * First we go to integer form, rounding up 70429e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard * and checking for special cases 70430eafdef9881c396ce4c014359d8f497cc088cfabDaniel Veillard */ 70440eafdef9881c396ce4c014359d8f497cc088cfabDaniel Veillard i = (int) in; 70459e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard if (((double)i)+0.5 <= in) i++; 70469e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard 70479e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard if (xmlXPathIsInf(le) == 1) { 70489e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard l = m; 70499e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard if (i < 1) 70509e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard i = 1; 70519e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard } 70529e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard else if (xmlXPathIsInf(le) == -1 || le < 0.0) 70539e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard l = 0; 70549e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard else { 70559e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard l = (int) le; 70569e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard if (((double)l)+0.5 <= le) l++; 70579e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard } 70580eafdef9881c396ce4c014359d8f497cc088cfabDaniel Veillard 70599e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard /* Now we normalize inidices */ 70609e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard i -= 1; 70619e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard l += i; 70629e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard if (i < 0) 70639e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard i = 0; 70649e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard if (l > m) 70659e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard l = m; 70663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 70670eafdef9881c396ce4c014359d8f497cc088cfabDaniel Veillard /* number of chars to copy */ 70680eafdef9881c396ce4c014359d8f497cc088cfabDaniel Veillard l -= i; 70693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 70700eafdef9881c396ce4c014359d8f497cc088cfabDaniel Veillard ret = xmlUTF8Strsub(str->stringval, i, l); 70710eafdef9881c396ce4c014359d8f497cc088cfabDaniel Veillard } 70720eafdef9881c396ce4c014359d8f497cc088cfabDaniel Veillard else { 70730eafdef9881c396ce4c014359d8f497cc088cfabDaniel Veillard ret = NULL; 70740eafdef9881c396ce4c014359d8f497cc088cfabDaniel Veillard } 70753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 70763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ret == NULL) 70773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, xmlXPathNewCString("")); 70783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else { 70793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, xmlXPathNewString(ret)); 70803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(ret); 70813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 708297ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard 70833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(str); 70843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 70853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 70863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 70873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathSubstringBeforeFunction: 70883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 70893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs: the number of arguments 70903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 70913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the substring-before() XPath function 70923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * string substring-before(string, string) 70933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The substring-before function returns the substring of the first 70943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * argument string that precedes the first occurrence of the second 70953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * argument string in the first argument string, or the empty string 70963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * if the first argument string does not contain the second argument 70973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * string. For example, substring-before("1999/04/01","/") returns 1999. 70983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 70993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 71003473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathSubstringBeforeFunction(xmlXPathParserContextPtr ctxt, int nargs) { 71013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr str; 71023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr find; 71033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlBufferPtr target; 71043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor const xmlChar *point; 71053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int offset; 71063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 71073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ARITY(2); 71083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CAST_TO_STRING; 71093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor find = valuePop(ctxt); 71103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CAST_TO_STRING; 71113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor str = valuePop(ctxt); 71123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 71133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor target = xmlBufferCreate(); 71143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (target) { 71153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor point = xmlStrstr(str->stringval, find->stringval); 71163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (point) { 71173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor offset = (int)(point - str->stringval); 71183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlBufferAdd(target, str->stringval, offset); 71193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 71203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, xmlXPathNewString(xmlBufferContent(target))); 71213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlBufferFree(target); 71223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 71233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 71243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(str); 71253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(find); 71263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 71273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 71283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 71293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathSubstringAfterFunction: 71303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 71313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs: the number of arguments 71323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 71333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the substring-after() XPath function 71343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * string substring-after(string, string) 71353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The substring-after function returns the substring of the first 71363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * argument string that follows the first occurrence of the second 71373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * argument string in the first argument string, or the empty stringi 71383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * if the first argument string does not contain the second argument 71393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * string. For example, substring-after("1999/04/01","/") returns 04/01, 71403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * and substring-after("1999/04/01","19") returns 99/04/01. 71413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 71423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 71433473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathSubstringAfterFunction(xmlXPathParserContextPtr ctxt, int nargs) { 71443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr str; 71453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr find; 71463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlBufferPtr target; 71473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor const xmlChar *point; 71483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int offset; 71493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 71503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ARITY(2); 71513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CAST_TO_STRING; 71523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor find = valuePop(ctxt); 71533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CAST_TO_STRING; 71543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor str = valuePop(ctxt); 71553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 71563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor target = xmlBufferCreate(); 71573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (target) { 71583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor point = xmlStrstr(str->stringval, find->stringval); 71593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (point) { 71603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor offset = (int)(point - str->stringval) + xmlStrlen(find->stringval); 71613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlBufferAdd(target, &str->stringval[offset], 71623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlStrlen(str->stringval) - offset); 71633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 71643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, xmlXPathNewString(xmlBufferContent(target))); 71653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlBufferFree(target); 71663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 71673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 71683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(str); 71693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(find); 71703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 71713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 71723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 71733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNormalizeFunction: 71743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 71753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs: the number of arguments 71763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 71773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the normalize-space() XPath function 71783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * string normalize-space(string?) 71793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The normalize-space function returns the argument string with white 71803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * space normalized by stripping leading and trailing whitespace 71813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * and replacing sequences of whitespace characters by a single 71823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * space. Whitespace characters are the same allowed by the S production 71833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * in XML. If the argument is omitted, it defaults to the context 71843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * node converted to a string, in other words the value of the context node. 71853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 71863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 71873473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNormalizeFunction(xmlXPathParserContextPtr ctxt, int nargs) { 71883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr obj = NULL; 71893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlChar *source = NULL; 71903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlBufferPtr target; 71913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlChar blank; 71923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 7193a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard if (ctxt == NULL) return; 71943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (nargs == 0) { 71953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* Use current context node */ 7196ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard valuePush(ctxt, 7197ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlXPathWrapString( 7198ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard xmlXPathCastNodeToString(ctxt->context->node))); 71993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor nargs = 1; 72003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 72013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 72023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ARITY(1); 72033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CAST_TO_STRING; 72043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_TYPE(XPATH_STRING); 72053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor obj = valuePop(ctxt); 72063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor source = obj->stringval; 72073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 72083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor target = xmlBufferCreate(); 72093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (target && source) { 72103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 72113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* Skip leading whitespaces */ 721276e95df05556c9610b564b14cf578c8f9e34c9c1William M. Brack while (IS_BLANK_CH(*source)) 72133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor source++; 72143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 72153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* Collapse intermediate whitespaces, and skip trailing whitespaces */ 72163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor blank = 0; 72173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while (*source) { 721876e95df05556c9610b564b14cf578c8f9e34c9c1William M. Brack if (IS_BLANK_CH(*source)) { 721997ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard blank = 0x20; 72203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else { 72213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (blank) { 72223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlBufferAdd(target, &blank, 1); 72233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor blank = 0; 72243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 72253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlBufferAdd(target, source, 1); 72263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 72273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor source++; 72283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 72293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 72303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, xmlXPathNewString(xmlBufferContent(target))); 72313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlBufferFree(target); 72323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 72333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(obj); 72343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 72353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 72363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 72373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathTranslateFunction: 72383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 72393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs: the number of arguments 72403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 72413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the translate() XPath function 72423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * string translate(string, string, string) 72433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The translate function returns the first argument string with 72443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * occurrences of characters in the second argument string replaced 72453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * by the character at the corresponding position in the third argument 72463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * string. For example, translate("bar","abc","ABC") returns the string 72473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * BAr. If there is a character in the second argument string with no 72483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * character at a corresponding position in the third argument string 72493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * (because the second argument string is longer than the third argument 72503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * string), then occurrences of that character in the first argument 72513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * string are removed. For example, translate("--aaa--","abc-","ABC") 72523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * returns "AAA". If a character occurs more than once in second 72533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * argument string, then the first occurrence determines the replacement 72543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * character. If the third argument string is longer than the second 72553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * argument string, then excess characters are ignored. 72563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 72573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 72583473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathTranslateFunction(xmlXPathParserContextPtr ctxt, int nargs) { 7259e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard xmlXPathObjectPtr str; 7260e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard xmlXPathObjectPtr from; 7261e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard xmlXPathObjectPtr to; 7262e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard xmlBufferPtr target; 726397ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard int offset, max; 7264e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard xmlChar ch; 7265b031cef5b537d8eda30f508627f08bc642bbd31dWilliam M. Brack const xmlChar *point; 726697ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard xmlChar *cptr; 72673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 7268e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard CHECK_ARITY(3); 72693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 7270e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard CAST_TO_STRING; 7271e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard to = valuePop(ctxt); 7272e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard CAST_TO_STRING; 7273e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard from = valuePop(ctxt); 7274e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard CAST_TO_STRING; 7275e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard str = valuePop(ctxt); 72763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 7277e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard target = xmlBufferCreate(); 7278e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard if (target) { 727997ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard max = xmlUTF8Strlen(to->stringval); 728097ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard for (cptr = str->stringval; (ch=*cptr); ) { 728197ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard offset = xmlUTF8Strloc(from->stringval, cptr); 728297ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard if (offset >= 0) { 728397ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard if (offset < max) { 728497ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard point = xmlUTF8Strpos(to->stringval, offset); 728597ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard if (point) 728697ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard xmlBufferAdd(target, point, xmlUTF8Strsize(point, 1)); 728797ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard } 728897ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard } else 728997ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard xmlBufferAdd(target, cptr, xmlUTF8Strsize(cptr, 1)); 729097ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard 729197ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard /* Step to next character in input */ 729297ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard cptr++; 729397ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard if ( ch & 0x80 ) { 729497ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard /* if not simple ascii, verify proper format */ 729597ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard if ( (ch & 0xc0) != 0xc0 ) { 729697ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard xmlGenericError(xmlGenericErrorContext, 729797ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard "xmlXPathTranslateFunction: Invalid UTF8 string\n"); 729897ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard break; 729997ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard } 730097ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard /* then skip over remaining bytes for this char */ 730197ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard while ( (ch <<= 1) & 0x80 ) 730297ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard if ( (*cptr++ & 0xc0) != 0x80 ) { 730397ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard xmlGenericError(xmlGenericErrorContext, 730497ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard "xmlXPathTranslateFunction: Invalid UTF8 string\n"); 730597ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard break; 730697ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard } 730797ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard if (ch & 0x80) /* must have had error encountered */ 730897ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard break; 730997ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard } 7310e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard } 73113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 7312e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard valuePush(ctxt, xmlXPathNewString(xmlBufferContent(target))); 7313e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard xmlBufferFree(target); 7314e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard xmlXPathFreeObject(str); 7315e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard xmlXPathFreeObject(from); 7316e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard xmlXPathFreeObject(to); 73173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 73183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 73193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 7320fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * xmlXPathBooleanFunction: 7321fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * @ctxt: the XPath Parser context 7322fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * @nargs: the number of arguments 7323fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * 7324fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * Implement the boolean() XPath function 7325fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * boolean boolean(object) 7326081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack * The boolean function converts its argument to a boolean as follows: 7327fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * - a number is true if and only if it is neither positive or 7328fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * negative zero nor NaN 7329fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * - a node-set is true if and only if it is non-empty 7330fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * - a string is true if and only if its length is non-zero 7331fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard */ 7332fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillardvoid 7333fbf8a2d0c8145b713099df63d174154a8442e60dDaniel VeillardxmlXPathBooleanFunction(xmlXPathParserContextPtr ctxt, int nargs) { 7334fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard xmlXPathObjectPtr cur; 7335fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard 7336fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard CHECK_ARITY(1); 7337fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard cur = valuePop(ctxt); 7338fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard if (cur == NULL) XP_ERROR(XPATH_INVALID_OPERAND); 7339fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard cur = xmlXPathConvertBoolean(cur); 7340fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard valuePush(ctxt, cur); 73413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 73423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 73433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 73443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNotFunction: 73453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 73463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs: the number of arguments 73473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 73483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the not() XPath function 73493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * boolean not(boolean) 73503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The not function returns true if its argument is false, 73513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * and false otherwise. 73523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 73533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 73543473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNotFunction(xmlXPathParserContextPtr ctxt, int nargs) { 73553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ARITY(1); 73563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CAST_TO_BOOLEAN; 73573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_TYPE(XPATH_BOOLEAN); 73583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ctxt->value->boolval = ! ctxt->value->boolval; 73593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 73603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 73613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 73623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathTrueFunction: 73633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 73643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs: the number of arguments 73653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 73663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the true() XPath function 73673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * boolean true() 73683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 73693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 73703473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathTrueFunction(xmlXPathParserContextPtr ctxt, int nargs) { 73713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ARITY(0); 73723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, xmlXPathNewBoolean(1)); 73733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 73743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 73753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 73763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathFalseFunction: 73773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 73783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs: the number of arguments 73793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 73803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the false() XPath function 73813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * boolean false() 73823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 73833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 73843473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathFalseFunction(xmlXPathParserContextPtr ctxt, int nargs) { 73853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ARITY(0); 73863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, xmlXPathNewBoolean(0)); 73873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 73883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 73893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 73903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathLangFunction: 73913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 73923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs: the number of arguments 73933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 73943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the lang() XPath function 73953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * boolean lang(string) 73963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The lang function returns true or false depending on whether the 73973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * language of the context node as specified by xml:lang attributes 73983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * is the same as or is a sublanguage of the language specified by 73993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the argument string. The language of the context node is determined 74003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * by the value of the xml:lang attribute on the context node, or, if 74013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the context node has no xml:lang attribute, by the value of the 74023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xml:lang attribute on the nearest ancestor of the context node that 74033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * has an xml:lang attribute. If there is no such attribute, then lang 74043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * returns false. If there is such an attribute, then lang returns 74053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * true if the attribute value is equal to the argument ignoring case, 74063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * or if there is some suffix starting with - such that the attribute 74073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * value is equal to the argument ignoring that suffix of the attribute 74083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * value and ignoring case. 74093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 74103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 74113473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathLangFunction(xmlXPathParserContextPtr ctxt, int nargs) { 74124ddaa56d7af6638c20a4446c47b02b299987be65Daniel Veillard xmlXPathObjectPtr val = NULL; 74134ddaa56d7af6638c20a4446c47b02b299987be65Daniel Veillard const xmlChar *theLang = NULL; 74143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor const xmlChar *lang; 74153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int ret = 0; 74163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int i; 74173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 74183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ARITY(1); 74193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CAST_TO_STRING; 74203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_TYPE(XPATH_STRING); 74213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor val = valuePop(ctxt); 74223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor lang = val->stringval; 74233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor theLang = xmlNodeGetLang(ctxt->context->node); 74243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((theLang != NULL) && (lang != NULL)) { 74253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor for (i = 0;lang[i] != 0;i++) 74263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (toupper(lang[i]) != toupper(theLang[i])) 74273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor goto not_equal; 74284ddaa56d7af6638c20a4446c47b02b299987be65Daniel Veillard if ((theLang[i] == 0) || (theLang[i] == '-')) 74294ddaa56d7af6638c20a4446c47b02b299987be65Daniel Veillard ret = 1; 74303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 74313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylornot_equal: 74324ddaa56d7af6638c20a4446c47b02b299987be65Daniel Veillard if (theLang != NULL) 74334ddaa56d7af6638c20a4446c47b02b299987be65Daniel Veillard xmlFree((void *)theLang); 74343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(val); 74353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, xmlXPathNewBoolean(ret)); 74363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 74373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 74383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 74393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNumberFunction: 74403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 74413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs: the number of arguments 74423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 74433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the number() XPath function 74443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * number number(object?) 74453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 74463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 74473473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNumberFunction(xmlXPathParserContextPtr ctxt, int nargs) { 74483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr cur; 74493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor double res; 74503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 7451a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard if (ctxt == NULL) return; 74523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (nargs == 0) { 74533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->context->node == NULL) { 74543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, xmlXPathNewFloat(0.0)); 74553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else { 74563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlChar* content = xmlNodeGetContent(ctxt->context->node); 74573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 74583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor res = xmlXPathStringEvalNumber(content); 74593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor valuePush(ctxt, xmlXPathNewFloat(res)); 74603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(content); 74613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 74623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return; 74633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 74643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 74653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ARITY(1); 74663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur = valuePop(ctxt); 7467fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard cur = xmlXPathConvertNumber(cur); 7468fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard valuePush(ctxt, cur); 74693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 74703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 74713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 74723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathSumFunction: 74733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 74743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs: the number of arguments 74753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 74763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the sum() XPath function 74773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * number sum(node-set) 74783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The sum function returns the sum of the values of the nodes in 74793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the argument node-set. 74803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 74813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 74823473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathSumFunction(xmlXPathParserContextPtr ctxt, int nargs) { 74833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr cur; 74843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int i; 7485ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard double res = 0.0; 74863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 74873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ARITY(1); 74883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((ctxt->value == NULL) || 74893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ((ctxt->value->type != XPATH_NODESET) && 74903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor (ctxt->value->type != XPATH_XSLT_TREE))) 74913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XP_ERROR(XPATH_INVALID_TYPE); 74923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur = valuePop(ctxt); 74933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 7494081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack if ((cur->nodesetval != NULL) && (cur->nodesetval->nodeNr != 0)) { 7495ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard for (i = 0; i < cur->nodesetval->nodeNr; i++) { 7496ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard res += xmlXPathCastNodeToNumber(cur->nodesetval->nodeTab[i]); 74973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 74983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 7499081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack valuePush(ctxt, xmlXPathNewFloat(res)); 75003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(cur); 75013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 75023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 75033d426663629a53180f3f54282ba27f3d070eef24William M. Brack/* 75043d426663629a53180f3f54282ba27f3d070eef24William M. Brack * To assure working code on multiple platforms, we want to only depend 75053d426663629a53180f3f54282ba27f3d070eef24William M. Brack * upon the characteristic truncation of converting a floating point value 75063d426663629a53180f3f54282ba27f3d070eef24William M. Brack * to an integer. Unfortunately, because of the different storage sizes 75073d426663629a53180f3f54282ba27f3d070eef24William M. Brack * of our internal floating point value (double) and integer (int), we 75083d426663629a53180f3f54282ba27f3d070eef24William M. Brack * can't directly convert (see bug 301162). This macro is a messy 75093d426663629a53180f3f54282ba27f3d070eef24William M. Brack * 'workaround' 75103d426663629a53180f3f54282ba27f3d070eef24William M. Brack */ 75113d426663629a53180f3f54282ba27f3d070eef24William M. Brack#define XTRUNC(f, v) \ 75123d426663629a53180f3f54282ba27f3d070eef24William M. Brack f = fmod((v), INT_MAX); \ 75133d426663629a53180f3f54282ba27f3d070eef24William M. Brack f = (v) - (f) + (double)((int)(f)); 75143d426663629a53180f3f54282ba27f3d070eef24William M. Brack 75153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 75163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathFloorFunction: 75173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 75183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs: the number of arguments 75193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 75203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the floor() XPath function 75213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * number floor(number) 75223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The floor function returns the largest (closest to positive infinity) 75233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * number that is not greater than the argument and that is an integer. 75243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 75253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 75263473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathFloorFunction(xmlXPathParserContextPtr ctxt, int nargs) { 752756cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard double f; 752856cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard 75293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ARITY(1); 75303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CAST_TO_NUMBER; 75313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_TYPE(XPATH_NUMBER); 753256cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard 75333d426663629a53180f3f54282ba27f3d070eef24William M. Brack XTRUNC(f, ctxt->value->floatval); 753456cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard if (f != ctxt->value->floatval) { 753556cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard if (ctxt->value->floatval > 0) 753656cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard ctxt->value->floatval = f; 753756cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard else 753856cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard ctxt->value->floatval = f - 1; 753956cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard } 75403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 75413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 75423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 75433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathCeilingFunction: 75443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 75453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs: the number of arguments 75463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 75473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the ceiling() XPath function 75483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * number ceiling(number) 75493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The ceiling function returns the smallest (closest to negative infinity) 75503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * number that is not less than the argument and that is an integer. 75513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 75523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 75533473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathCeilingFunction(xmlXPathParserContextPtr ctxt, int nargs) { 75543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor double f; 75553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 75563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ARITY(1); 75573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CAST_TO_NUMBER; 75583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_TYPE(XPATH_NUMBER); 75593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 75603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#if 0 75613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ctxt->value->floatval = ceil(ctxt->value->floatval); 75623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#else 75633d426663629a53180f3f54282ba27f3d070eef24William M. Brack XTRUNC(f, ctxt->value->floatval); 756456cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard if (f != ctxt->value->floatval) { 756556cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard if (ctxt->value->floatval > 0) 756656cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard ctxt->value->floatval = f + 1; 75675fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard else { 75685fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard if (ctxt->value->floatval < 0 && f == 0) 75695fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard ctxt->value->floatval = xmlXPathNZERO; 75705fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard else 75715fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard ctxt->value->floatval = f; 75725fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard } 75735fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard 757456cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard } 75753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 75763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 75773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 75783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 75793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathRoundFunction: 75803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 75813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs: the number of arguments 75823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 75833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the round() XPath function 75843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * number round(number) 75853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The round function returns the number that is closest to the 75863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * argument and that is an integer. If there are two such numbers, 75873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * then the one that is even is returned. 75883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 75893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 75903473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathRoundFunction(xmlXPathParserContextPtr ctxt, int nargs) { 75913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor double f; 75923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 75933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ARITY(1); 75943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CAST_TO_NUMBER; 75953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_TYPE(XPATH_NUMBER); 75963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 7597cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard if ((xmlXPathIsNaN(ctxt->value->floatval)) || 7598cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard (xmlXPathIsInf(ctxt->value->floatval) == 1) || 7599cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard (xmlXPathIsInf(ctxt->value->floatval) == -1) || 76003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor (ctxt->value->floatval == 0.0)) 76013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return; 76023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 76033d426663629a53180f3f54282ba27f3d070eef24William M. Brack XTRUNC(f, ctxt->value->floatval); 760456cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard if (ctxt->value->floatval < 0) { 760556cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard if (ctxt->value->floatval < f - 0.5) 760656cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard ctxt->value->floatval = f - 1; 760756cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard else 760856cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard ctxt->value->floatval = f; 76095fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard if (ctxt->value->floatval == 0) 76105fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard ctxt->value->floatval = xmlXPathNZERO; 761156cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard } else { 761256cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard if (ctxt->value->floatval < f + 0.5) 761356cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard ctxt->value->floatval = f; 761456cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard else 761556cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard ctxt->value->floatval = f + 1; 761656cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard } 76173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 76183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 76193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/************************************************************************ 76203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * * 76213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The Parser * 76223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * * 76233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ************************************************************************/ 76243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 76253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/* 7626081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack * a few forward declarations since we use a recursive call based 76273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * implementation. 76283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 7629afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void xmlXPathCompileExpr(xmlXPathParserContextPtr ctxt); 7630d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillardstatic void xmlXPathCompPredicate(xmlXPathParserContextPtr ctxt, int filter); 7631afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void xmlXPathCompLocationPath(xmlXPathParserContextPtr ctxt); 7632afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void xmlXPathCompRelativeLocationPath(xmlXPathParserContextPtr ctxt); 76332156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillardstatic xmlChar * xmlXPathParseNameComplex(xmlXPathParserContextPtr ctxt, 76342156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard int qualified); 76353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 76363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 763761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard * xmlXPathCurrentChar: 763861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard * @ctxt: the XPath parser context 763961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard * @cur: pointer to the beginning of the char 764061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard * @len: pointer to the length of the char read 764161d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard * 7642cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * The current char value, if using UTF-8 this may actually span multiple 764361d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard * bytes in the input buffer. 764461d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard * 764560087f30f3b4cf21de48f39181736e7d71e7a661Daniel Veillard * Returns the current char value and its length 764661d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard */ 764761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard 764861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillardstatic int 764961d80a2822b2678dee885ac2850295cc96277c63Daniel VeillardxmlXPathCurrentChar(xmlXPathParserContextPtr ctxt, int *len) { 765061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard unsigned char c; 765161d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard unsigned int val; 765261d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard const xmlChar *cur; 765361d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard 765461d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard if (ctxt == NULL) 765561d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard return(0); 765661d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard cur = ctxt->cur; 765761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard 765861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard /* 765961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard * We are supposed to handle UTF8, check it's valid 766061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard * From rfc2044: encoding of the Unicode values on UTF-8: 766161d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard * 766261d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard * UCS-4 range (hex.) UTF-8 octet sequence (binary) 766361d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard * 0000 0000-0000 007F 0xxxxxxx 766461d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard * 0000 0080-0000 07FF 110xxxxx 10xxxxxx 766561d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard * 0000 0800-0000 FFFF 1110xxxx 10xxxxxx 10xxxxxx 766661d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard * 766761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard * Check for the 0x110000 limit too 766861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard */ 766961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard c = *cur; 767061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard if (c & 0x80) { 767161d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard if ((cur[1] & 0xc0) != 0x80) 767261d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard goto encoding_error; 767361d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard if ((c & 0xe0) == 0xe0) { 767461d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard 767561d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard if ((cur[2] & 0xc0) != 0x80) 767661d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard goto encoding_error; 767761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard if ((c & 0xf0) == 0xf0) { 767861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard if (((c & 0xf8) != 0xf0) || 767961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard ((cur[3] & 0xc0) != 0x80)) 768061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard goto encoding_error; 768161d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard /* 4-byte code */ 768261d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard *len = 4; 768361d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard val = (cur[0] & 0x7) << 18; 768461d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard val |= (cur[1] & 0x3f) << 12; 768561d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard val |= (cur[2] & 0x3f) << 6; 768661d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard val |= cur[3] & 0x3f; 768761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard } else { 768861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard /* 3-byte code */ 768961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard *len = 3; 769061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard val = (cur[0] & 0xf) << 12; 769161d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard val |= (cur[1] & 0x3f) << 6; 769261d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard val |= cur[2] & 0x3f; 769361d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard } 769461d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard } else { 769561d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard /* 2-byte code */ 769661d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard *len = 2; 769761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard val = (cur[0] & 0x1f) << 6; 769861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard val |= cur[1] & 0x3f; 769961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard } 770061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard if (!IS_CHAR(val)) { 770161d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard XP_ERROR0(XPATH_INVALID_CHAR_ERROR); 770261d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard } 770361d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard return(val); 770461d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard } else { 770561d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard /* 1-byte code */ 770661d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard *len = 1; 770761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard return((int) *cur); 770861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard } 770961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillardencoding_error: 771061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard /* 7711081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack * If we detect an UTF8 error that probably means that the 7712081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack * input encoding didn't get properly advertised in the 771361d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard * declaration header. Report the error and switch the encoding 771461d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard * to ISO-Latin-1 (if you don't like this policy, just declare the 771561d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard * encoding !) 771661d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard */ 771742596ad20cdf1925dd79ea801cbe598b6e7b7aecDaniel Veillard *len = 0; 771861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard XP_ERROR0(XPATH_ENCODING_ERROR); 771961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard} 772061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard 772161d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard/** 77223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathParseNCName: 77233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 77243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 77253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * parse an XML namespace non qualified name. 77263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 77273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [NS 3] NCName ::= (Letter | '_') (NCNameChar)* 77283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 77293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [NS 4] NCNameChar ::= Letter | Digit | '.' | '-' | '_' | 77303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * CombiningChar | Extender 77313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 77323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the namespace name or NULL 77333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 77343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 77353473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlChar * 77363473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathParseNCName(xmlXPathParserContextPtr ctxt) { 77372156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard const xmlChar *in; 77382156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard xmlChar *ret; 77392156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard int count = 0; 77403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 7741a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard if ((ctxt == NULL) || (ctxt->cur == NULL)) return(NULL); 77422156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard /* 77432156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard * Accelerator for simple ASCII names 77442156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard */ 77452156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard in = ctxt->cur; 77462156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard if (((*in >= 0x61) && (*in <= 0x7A)) || 77472156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard ((*in >= 0x41) && (*in <= 0x5A)) || 77482156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard (*in == '_')) { 77492156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard in++; 77502156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard while (((*in >= 0x61) && (*in <= 0x7A)) || 77512156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard ((*in >= 0x41) && (*in <= 0x5A)) || 77522156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard ((*in >= 0x30) && (*in <= 0x39)) || 77539a89a8ab80bc021deec9da7d79bda20995c4e78dDaniel Veillard (*in == '_') || (*in == '.') || 77549a89a8ab80bc021deec9da7d79bda20995c4e78dDaniel Veillard (*in == '-')) 77552156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard in++; 77562156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard if ((*in == ' ') || (*in == '>') || (*in == '/') || 77572156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard (*in == '[') || (*in == ']') || (*in == ':') || 77582156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard (*in == '@') || (*in == '*')) { 77592156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard count = in - ctxt->cur; 77602156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard if (count == 0) 77612156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard return(NULL); 77622156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard ret = xmlStrndup(ctxt->cur, count); 77632156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard ctxt->cur = in; 77642156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard return(ret); 77652156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard } 77662156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard } 77672156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard return(xmlXPathParseNameComplex(ctxt, 0)); 77683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 77693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 77702156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard 77713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 77723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathParseQName: 77733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 77743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @prefix: a xmlChar ** 77753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 77763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * parse an XML qualified name 77773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 77783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [NS 5] QName ::= (Prefix ':')? LocalPart 77793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 77803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [NS 6] Prefix ::= NCName 77813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 77823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [NS 7] LocalPart ::= NCName 77833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 77843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the function returns the local part, and prefix is updated 77853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * to get the Prefix if any. 77863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 77873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 778856a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic xmlChar * 77893473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathParseQName(xmlXPathParserContextPtr ctxt, xmlChar **prefix) { 77903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlChar *ret = NULL; 77913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 77923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *prefix = NULL; 77933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = xmlXPathParseNCName(ctxt); 77943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (CUR == ':') { 77953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *prefix = ret; 77963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 77973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = xmlXPathParseNCName(ctxt); 77983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 77993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ret); 78003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 78013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 78023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 78033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathParseName: 78043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 78053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 78063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * parse an XML name 78073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 78083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [4] NameChar ::= Letter | Digit | '.' | '-' | '_' | ':' | 78093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * CombiningChar | Extender 78103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 78113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [5] Name ::= (Letter | '_' | ':') (NameChar)* 78123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 78133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the namespace name or NULL 78143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 78153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 78163473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlChar * 78173473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathParseName(xmlXPathParserContextPtr ctxt) { 781861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard const xmlChar *in; 781961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard xmlChar *ret; 782061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard int count = 0; 78213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 7822a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard if ((ctxt == NULL) || (ctxt->cur == NULL)) return(NULL); 782361d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard /* 782461d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard * Accelerator for simple ASCII names 782561d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard */ 782661d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard in = ctxt->cur; 782761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard if (((*in >= 0x61) && (*in <= 0x7A)) || 782861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard ((*in >= 0x41) && (*in <= 0x5A)) || 782961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard (*in == '_') || (*in == ':')) { 783061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard in++; 783161d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard while (((*in >= 0x61) && (*in <= 0x7A)) || 783261d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard ((*in >= 0x41) && (*in <= 0x5A)) || 783361d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard ((*in >= 0x30) && (*in <= 0x39)) || 783476d66f416d2d0d5db4a09d212b4e43087e9cdae7Daniel Veillard (*in == '_') || (*in == '-') || 783576d66f416d2d0d5db4a09d212b4e43087e9cdae7Daniel Veillard (*in == ':') || (*in == '.')) 783661d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard in++; 783776d66f416d2d0d5db4a09d212b4e43087e9cdae7Daniel Veillard if ((*in > 0) && (*in < 0x80)) { 783861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard count = in - ctxt->cur; 783961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard ret = xmlStrndup(ctxt->cur, count); 784061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard ctxt->cur = in; 784161d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard return(ret); 784261d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard } 784361d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard } 78442156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard return(xmlXPathParseNameComplex(ctxt, 1)); 784561d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard} 78463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 784761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillardstatic xmlChar * 78482156a56bcbf5d83fb3d694123be01beebf84d273Daniel VeillardxmlXPathParseNameComplex(xmlXPathParserContextPtr ctxt, int qualified) { 784961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard xmlChar buf[XML_MAX_NAMELEN + 5]; 785061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard int len = 0, l; 785161d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard int c; 78523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 785361d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard /* 785461d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard * Handler for more complex cases 785561d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard */ 785661d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard c = CUR_CHAR(l); 785761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard if ((c == ' ') || (c == '>') || (c == '/') || /* accelerators */ 78582156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard (c == '[') || (c == ']') || (c == '@') || /* accelerators */ 78592156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard (c == '*') || /* accelerators */ 786061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard (!IS_LETTER(c) && (c != '_') && 78612156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard ((qualified) && (c != ':')))) { 786261d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard return(NULL); 786361d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard } 78643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 786561d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard while ((c != ' ') && (c != '>') && (c != '/') && /* test bigname.xml */ 786661d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard ((IS_LETTER(c)) || (IS_DIGIT(c)) || 786761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard (c == '.') || (c == '-') || 78682156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard (c == '_') || ((qualified) && (c == ':')) || 786961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard (IS_COMBINING(c)) || 787061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard (IS_EXTENDER(c)))) { 787161d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard COPY_BUF(l,buf,len,c); 787261d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard NEXTL(l); 787361d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard c = CUR_CHAR(l); 787461d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard if (len >= XML_MAX_NAMELEN) { 787561d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard /* 787661d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard * Okay someone managed to make a huge name, so he's ready to pay 787761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard * for the processing speed. 787861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard */ 787961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard xmlChar *buffer; 788061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard int max = len * 2; 788161d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard 78823c908dca479ed50dca24b8593bca90e40dbde6b8Daniel Veillard buffer = (xmlChar *) xmlMallocAtomic(max * sizeof(xmlChar)); 788361d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard if (buffer == NULL) { 788424505b0f5c872c5afb6da5093565e5a6e09ca541Daniel Veillard XP_ERRORNULL(XPATH_MEMORY_ERROR); 788561d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard } 788661d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard memcpy(buffer, buf, len); 788761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard while ((IS_LETTER(c)) || (IS_DIGIT(c)) || /* test bigname.xml */ 788861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard (c == '.') || (c == '-') || 78892156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard (c == '_') || ((qualified) && (c == ':')) || 789061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard (IS_COMBINING(c)) || 789161d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard (IS_EXTENDER(c))) { 789261d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard if (len + 10 > max) { 789361d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard max *= 2; 789461d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard buffer = (xmlChar *) xmlRealloc(buffer, 789561d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard max * sizeof(xmlChar)); 789661d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard if (buffer == NULL) { 789724505b0f5c872c5afb6da5093565e5a6e09ca541Daniel Veillard XP_ERRORNULL(XPATH_MEMORY_ERROR); 789861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard } 789961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard } 790061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard COPY_BUF(l,buffer,len,c); 790161d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard NEXTL(l); 790261d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard c = CUR_CHAR(l); 790361d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard } 790461d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard buffer[len] = 0; 790561d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard return(buffer); 790661d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard } 790761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard } 79082156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard if (len == 0) 79092156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard return(NULL); 791061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard return(xmlStrndup(buf, len)); 791161d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard} 79123cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard 79133cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard#define MAX_FRAC 20 79143cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard 7915372a445479b859bd0fe24df54e9b3db34d113d5aWilliam M. Brack/* 7916372a445479b859bd0fe24df54e9b3db34d113d5aWilliam M. Brack * These are used as divisors for the fractional part of a number. 7917372a445479b859bd0fe24df54e9b3db34d113d5aWilliam M. Brack * Since the table includes 1.0 (representing '0' fractional digits), 7918372a445479b859bd0fe24df54e9b3db34d113d5aWilliam M. Brack * it must be dimensioned at MAX_FRAC+1 (bug 133921) 7919372a445479b859bd0fe24df54e9b3db34d113d5aWilliam M. Brack */ 7920372a445479b859bd0fe24df54e9b3db34d113d5aWilliam M. Brackstatic double my_pow10[MAX_FRAC+1] = { 79213cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard 1.0, 10.0, 100.0, 1000.0, 10000.0, 79223cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard 100000.0, 1000000.0, 10000000.0, 100000000.0, 1000000000.0, 79233cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard 10000000000.0, 100000000000.0, 1000000000000.0, 10000000000000.0, 79243cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard 100000000000000.0, 79253cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard 1000000000000000.0, 10000000000000000.0, 100000000000000000.0, 7926372a445479b859bd0fe24df54e9b3db34d113d5aWilliam M. Brack 1000000000000000000.0, 10000000000000000000.0, 100000000000000000000.0 79273cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard}; 79283cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard 79293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 79303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathStringEvalNumber: 79313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @str: A string to scan 79323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 793370a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese * [30a] Float ::= Number ('e' Digits?)? 793470a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese * 79353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [30] Number ::= Digits ('.' Digits?)? 79363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | '.' Digits 79373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [31] Digits ::= [0-9]+ 79383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 7939afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile a Number in the string 79403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * In complement of the Number expression, this function also handles 79413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * negative values : '-' Number. 79423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 79433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the double value. 79443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 79453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylordouble 79463473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathStringEvalNumber(const xmlChar *str) { 79473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor const xmlChar *cur = str; 79487b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard double ret; 7949b06c61455f86758511aa050a06ff1bbd33f8c3c3Daniel Veillard int ok = 0; 79503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int isneg = 0; 795170a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese int exponent = 0; 795270a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese int is_exponent_negative = 0; 7953b06c61455f86758511aa050a06ff1bbd33f8c3c3Daniel Veillard#ifdef __GNUC__ 7954b06c61455f86758511aa050a06ff1bbd33f8c3c3Daniel Veillard unsigned long tmp = 0; 79557b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard double temp; 7956b06c61455f86758511aa050a06ff1bbd33f8c3c3Daniel Veillard#endif 7957eca82810f0fb81f3e9936d2018347e1e19de513aDaniel Veillard if (cur == NULL) return(0); 795876e95df05556c9610b564b14cf578c8f9e34c9c1William M. Brack while (IS_BLANK_CH(*cur)) cur++; 79593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((*cur != '.') && ((*cur < '0') || (*cur > '9')) && (*cur != '-')) { 79603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(xmlXPathNAN); 79613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 79623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (*cur == '-') { 79633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor isneg = 1; 79643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur++; 79653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 7966b06c61455f86758511aa050a06ff1bbd33f8c3c3Daniel Veillard 7967b06c61455f86758511aa050a06ff1bbd33f8c3c3Daniel Veillard#ifdef __GNUC__ 7968d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard /* 79697b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard * tmp/temp is a workaround against a gcc compiler bug 79707b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard * http://veillard.com/gcc.bug 7971d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard */ 79727b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard ret = 0; 79733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while ((*cur >= '0') && (*cur <= '9')) { 79747b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard ret = ret * 10; 79757b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard tmp = (*cur - '0'); 79763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ok = 1; 79773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur++; 79787b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard temp = (double) tmp; 79797b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard ret = ret + temp; 79803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 7981b06c61455f86758511aa050a06ff1bbd33f8c3c3Daniel Veillard#else 79827b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard ret = 0; 7983b06c61455f86758511aa050a06ff1bbd33f8c3c3Daniel Veillard while ((*cur >= '0') && (*cur <= '9')) { 7984b06c61455f86758511aa050a06ff1bbd33f8c3c3Daniel Veillard ret = ret * 10 + (*cur - '0'); 7985b06c61455f86758511aa050a06ff1bbd33f8c3c3Daniel Veillard ok = 1; 7986b06c61455f86758511aa050a06ff1bbd33f8c3c3Daniel Veillard cur++; 7987b06c61455f86758511aa050a06ff1bbd33f8c3c3Daniel Veillard } 7988b06c61455f86758511aa050a06ff1bbd33f8c3c3Daniel Veillard#endif 7989d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard 79903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (*cur == '.') { 79913cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard int v, frac = 0; 79923cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard double fraction = 0; 79933cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard 79943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur++; 79953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (((*cur < '0') || (*cur > '9')) && (!ok)) { 79963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(xmlXPathNAN); 79973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 79983cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard while (((*cur >= '0') && (*cur <= '9')) && (frac < MAX_FRAC)) { 79993cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard v = (*cur - '0'); 80003cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard fraction = fraction * 10 + v; 80013cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard frac = frac + 1; 80023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur++; 80033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 80043cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard fraction /= my_pow10[frac]; 80053cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard ret = ret + fraction; 80063cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard while ((*cur >= '0') && (*cur <= '9')) 80073cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard cur++; 80083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 800970a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese if ((*cur == 'e') || (*cur == 'E')) { 801070a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese cur++; 801170a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese if (*cur == '-') { 801270a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese is_exponent_negative = 1; 801370a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese cur++; 80149912705b82cbf3fbff43e19dd95dd0a6ec494d2dWilliam M. Brack } else if (*cur == '+') { 80159912705b82cbf3fbff43e19dd95dd0a6ec494d2dWilliam M. Brack cur++; 801670a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese } 801770a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese while ((*cur >= '0') && (*cur <= '9')) { 801870a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese exponent = exponent * 10 + (*cur - '0'); 801970a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese cur++; 802070a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese } 802170a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese } 802276e95df05556c9610b564b14cf578c8f9e34c9c1William M. Brack while (IS_BLANK_CH(*cur)) cur++; 80233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (*cur != 0) return(xmlXPathNAN); 80243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (isneg) ret = -ret; 802570a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese if (is_exponent_negative) exponent = -exponent; 802670a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese ret *= pow(10.0, (double)exponent); 80273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ret); 80283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 80293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 80303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 8031afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompNumber: 80323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 80333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 80343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [30] Number ::= Digits ('.' Digits?)? 80353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | '.' Digits 80363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [31] Digits ::= [0-9]+ 80373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 8038afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile a Number, then push it on the stack 80393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 80403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 8041afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void 8042d79bcd1b36412a7996ace1900ab613e38a609b60Daniel VeillardxmlXPathCompNumber(xmlXPathParserContextPtr ctxt) 8043d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard{ 80443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor double ret = 0.0; 80453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor double mult = 1; 80467b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard int ok = 0; 804770a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese int exponent = 0; 804870a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese int is_exponent_negative = 0; 80497b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard#ifdef __GNUC__ 80507b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard unsigned long tmp = 0; 80517b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard double temp; 80527b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard#endif 80533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 80543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ERROR; 80553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((CUR != '.') && ((CUR < '0') || (CUR > '9'))) { 80563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XP_ERROR(XPATH_NUMBER_ERROR); 80573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 80587b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard#ifdef __GNUC__ 8059d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard /* 80607b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard * tmp/temp is a workaround against a gcc compiler bug 80617b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard * http://veillard.com/gcc.bug 8062d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard */ 80637b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard ret = 0; 80643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while ((CUR >= '0') && (CUR <= '9')) { 80657b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard ret = ret * 10; 80667b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard tmp = (CUR - '0'); 8067d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard ok = 1; 8068d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard NEXT; 80697b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard temp = (double) tmp; 80707b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard ret = ret + temp; 80713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 80727b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard#else 80737b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard ret = 0; 80747b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard while ((CUR >= '0') && (CUR <= '9')) { 80757b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard ret = ret * 10 + (CUR - '0'); 80767b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard ok = 1; 80777b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard NEXT; 80787b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard } 80797b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard#endif 80803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (CUR == '.') { 80813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 8082d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard if (((CUR < '0') || (CUR > '9')) && (!ok)) { 8083d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard XP_ERROR(XPATH_NUMBER_ERROR); 8084d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard } 8085d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard while ((CUR >= '0') && (CUR <= '9')) { 8086d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard mult /= 10; 8087d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard ret = ret + (CUR - '0') * mult; 8088d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard NEXT; 8089d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard } 80903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 809170a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese if ((CUR == 'e') || (CUR == 'E')) { 8092d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard NEXT; 8093d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard if (CUR == '-') { 8094d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard is_exponent_negative = 1; 8095d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard NEXT; 80969912705b82cbf3fbff43e19dd95dd0a6ec494d2dWilliam M. Brack } else if (CUR == '+') { 80979912705b82cbf3fbff43e19dd95dd0a6ec494d2dWilliam M. Brack NEXT; 80989912705b82cbf3fbff43e19dd95dd0a6ec494d2dWilliam M. Brack } 8099d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard while ((CUR >= '0') && (CUR <= '9')) { 8100d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard exponent = exponent * 10 + (CUR - '0'); 8101d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard NEXT; 8102d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard } 8103d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard if (is_exponent_negative) 8104d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard exponent = -exponent; 8105d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard ret *= pow(10.0, (double) exponent); 810670a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese } 81079e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard PUSH_LONG_EXPR(XPATH_OP_VALUE, XPATH_NUMBER, 0, 0, 8108d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard xmlXPathNewFloat(ret), NULL); 81093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 81103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 81113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 8112fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * xmlXPathParseLiteral: 8113fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * @ctxt: the XPath Parser context 8114fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * 8115fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * Parse a Literal 8116fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * 8117fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * [29] Literal ::= '"' [^"]* '"' 8118fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * | "'" [^']* "'" 8119fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * 8120fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * Returns the value found or NULL in case of error 8121fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard */ 8122fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillardstatic xmlChar * 8123fbf8a2d0c8145b713099df63d174154a8442e60dDaniel VeillardxmlXPathParseLiteral(xmlXPathParserContextPtr ctxt) { 8124fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard const xmlChar *q; 8125fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard xmlChar *ret = NULL; 8126fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard 8127fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard if (CUR == '"') { 8128fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard NEXT; 8129fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard q = CUR_PTR; 813076e95df05556c9610b564b14cf578c8f9e34c9c1William M. Brack while ((IS_CHAR_CH(CUR)) && (CUR != '"')) 8131fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard NEXT; 813276e95df05556c9610b564b14cf578c8f9e34c9c1William M. Brack if (!IS_CHAR_CH(CUR)) { 813324505b0f5c872c5afb6da5093565e5a6e09ca541Daniel Veillard XP_ERRORNULL(XPATH_UNFINISHED_LITERAL_ERROR); 8134fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard } else { 8135fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard ret = xmlStrndup(q, CUR_PTR - q); 8136fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard NEXT; 8137fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard } 8138fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard } else if (CUR == '\'') { 8139fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard NEXT; 8140fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard q = CUR_PTR; 814176e95df05556c9610b564b14cf578c8f9e34c9c1William M. Brack while ((IS_CHAR_CH(CUR)) && (CUR != '\'')) 8142fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard NEXT; 814376e95df05556c9610b564b14cf578c8f9e34c9c1William M. Brack if (!IS_CHAR_CH(CUR)) { 814424505b0f5c872c5afb6da5093565e5a6e09ca541Daniel Veillard XP_ERRORNULL(XPATH_UNFINISHED_LITERAL_ERROR); 8145fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard } else { 8146fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard ret = xmlStrndup(q, CUR_PTR - q); 8147fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard NEXT; 8148fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard } 8149fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard } else { 815024505b0f5c872c5afb6da5093565e5a6e09ca541Daniel Veillard XP_ERRORNULL(XPATH_START_LITERAL_ERROR); 8151fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard } 8152fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard return(ret); 8153fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard} 8154fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard 8155fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard/** 8156afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompLiteral: 81573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 81583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 81593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Parse a Literal and push it on the stack. 81603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 81613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [29] Literal ::= '"' [^"]* '"' 81623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | "'" [^']* "'" 81633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 8164afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * TODO: xmlXPathCompLiteral memory allocation could be improved. 81653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 8166afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void 8167afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompLiteral(xmlXPathParserContextPtr ctxt) { 81683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor const xmlChar *q; 81693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlChar *ret = NULL; 81703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 81713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (CUR == '"') { 81723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 81733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor q = CUR_PTR; 817476e95df05556c9610b564b14cf578c8f9e34c9c1William M. Brack while ((IS_CHAR_CH(CUR)) && (CUR != '"')) 81753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 817676e95df05556c9610b564b14cf578c8f9e34c9c1William M. Brack if (!IS_CHAR_CH(CUR)) { 81773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XP_ERROR(XPATH_UNFINISHED_LITERAL_ERROR); 81783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else { 81793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = xmlStrndup(q, CUR_PTR - q); 81803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 81813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 81823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else if (CUR == '\'') { 81833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 81843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor q = CUR_PTR; 818576e95df05556c9610b564b14cf578c8f9e34c9c1William M. Brack while ((IS_CHAR_CH(CUR)) && (CUR != '\'')) 81863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 818776e95df05556c9610b564b14cf578c8f9e34c9c1William M. Brack if (!IS_CHAR_CH(CUR)) { 81883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XP_ERROR(XPATH_UNFINISHED_LITERAL_ERROR); 81893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else { 81903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = xmlStrndup(q, CUR_PTR - q); 81913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 81923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 81933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else { 81943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XP_ERROR(XPATH_START_LITERAL_ERROR); 81953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 81963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ret == NULL) return; 81979e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard PUSH_LONG_EXPR(XPATH_OP_VALUE, XPATH_STRING, 0, 0, 81989e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlXPathNewString(ret), NULL); 81993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(ret); 82003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 82013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 82023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 8203afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompVariableReference: 82043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 82053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 82063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Parse a VariableReference, evaluate it and push it on the stack. 82073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 82083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The variable bindings consist of a mapping from variable names 8209081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack * to variable values. The value of a variable is an object, which can be 82103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * of any of the types that are possible for the value of an expression, 82113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * and may also be of additional types not specified here. 82123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 82133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Early evaluation is possible since: 82143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The variable bindings [...] used to evaluate a subexpression are 82153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * always the same as those used to evaluate the containing expression. 82163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 82173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [36] VariableReference ::= '$' QName 82183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 8219afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void 8220afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompVariableReference(xmlXPathParserContextPtr ctxt) { 82213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlChar *name; 82223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlChar *prefix; 82233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 82243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 82253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (CUR != '$') { 82263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XP_ERROR(XPATH_VARIABLE_REF_ERROR); 82273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 82283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 82293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor name = xmlXPathParseQName(ctxt, &prefix); 82303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (name == NULL) { 82313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XP_ERROR(XPATH_VARIABLE_REF_ERROR); 82323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 8233fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard ctxt->comp->last = -1; 82349e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard PUSH_LONG_EXPR(XPATH_OP_VARIABLE, 0, 0, 0, 82359e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard name, prefix); 82363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 8237b3d1491b69060f8a67516b9a3ef12617adf88954Daniel Veillard if ((ctxt->context != NULL) && (ctxt->context->flags & XML_XPATH_NOVAR)) { 8238b3d1491b69060f8a67516b9a3ef12617adf88954Daniel Veillard XP_ERROR(XPATH_UNDEF_VARIABLE_ERROR); 8239b3d1491b69060f8a67516b9a3ef12617adf88954Daniel Veillard } 82403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 82413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 82423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 82433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathIsNodeType: 82443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @name: a name string 82453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 82463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Is the name given a NodeType one. 82473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 82483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [38] NodeType ::= 'comment' 82493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | 'text' 82503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | 'processing-instruction' 82513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | 'node' 82523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 82533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns 1 if true 0 otherwise 82543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 82553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorint 82563473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathIsNodeType(const xmlChar *name) { 82573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (name == NULL) 82583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(0); 82593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 82601971ee2698cb84c7699c96d3302f00e20d42c0d3Daniel Veillard if (xmlStrEqual(name, BAD_CAST "node")) 82613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(1); 82623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (xmlStrEqual(name, BAD_CAST "text")) 82633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(1); 82641971ee2698cb84c7699c96d3302f00e20d42c0d3Daniel Veillard if (xmlStrEqual(name, BAD_CAST "comment")) 82653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(1); 82661971ee2698cb84c7699c96d3302f00e20d42c0d3Daniel Veillard if (xmlStrEqual(name, BAD_CAST "processing-instruction")) 82673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(1); 82683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(0); 82693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 82703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 82713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 8272afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompFunctionCall: 82733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 82743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 82753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [16] FunctionCall ::= FunctionName '(' ( Argument ( ',' Argument)*)? ')' 82763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [17] Argument ::= Expr 82773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 8278afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile a function call, the evaluation of all arguments are 82793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * pushed on the stack 82803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 8281afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void 8282afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompFunctionCall(xmlXPathParserContextPtr ctxt) { 82833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlChar *name; 82843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlChar *prefix; 82853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int nbargs = 0; 82863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 82873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor name = xmlXPathParseQName(ctxt, &prefix); 82883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (name == NULL) { 82893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XP_ERROR(XPATH_EXPR_ERROR); 82903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 82913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 82923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_EXPR 82933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (prefix == NULL) 82943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, "Calling function %s\n", 82953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor name); 82963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else 82973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, "Calling function %s:%s\n", 82983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor prefix, name); 82993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 83003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 83013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (CUR != '(') { 83023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XP_ERROR(XPATH_EXPR_ERROR); 83033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 83043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 83053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 83063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 83079e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard ctxt->comp->last = -1; 830871f9d7310c1f8c587f518ec685b1448160df7336Daniel Veillard if (CUR != ')') { 830971f9d7310c1f8c587f518ec685b1448160df7336Daniel Veillard while (CUR != 0) { 831071f9d7310c1f8c587f518ec685b1448160df7336Daniel Veillard int op1 = ctxt->comp->last; 831171f9d7310c1f8c587f518ec685b1448160df7336Daniel Veillard ctxt->comp->last = -1; 831271f9d7310c1f8c587f518ec685b1448160df7336Daniel Veillard xmlXPathCompileExpr(ctxt); 831371f9d7310c1f8c587f518ec685b1448160df7336Daniel Veillard CHECK_ERROR; 831471f9d7310c1f8c587f518ec685b1448160df7336Daniel Veillard PUSH_BINARY_EXPR(XPATH_OP_ARG, op1, ctxt->comp->last, 0, 0); 831571f9d7310c1f8c587f518ec685b1448160df7336Daniel Veillard nbargs++; 831671f9d7310c1f8c587f518ec685b1448160df7336Daniel Veillard if (CUR == ')') break; 831771f9d7310c1f8c587f518ec685b1448160df7336Daniel Veillard if (CUR != ',') { 831871f9d7310c1f8c587f518ec685b1448160df7336Daniel Veillard XP_ERROR(XPATH_EXPR_ERROR); 831971f9d7310c1f8c587f518ec685b1448160df7336Daniel Veillard } 832071f9d7310c1f8c587f518ec685b1448160df7336Daniel Veillard NEXT; 832171f9d7310c1f8c587f518ec685b1448160df7336Daniel Veillard SKIP_BLANKS; 83223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 83233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 83249e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard PUSH_LONG_EXPR(XPATH_OP_FUNCTION, nbargs, 0, 0, 83259e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard name, prefix); 83263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 83273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 83283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 83293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 83303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 8331afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompPrimaryExpr: 83323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 83333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 83343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [15] PrimaryExpr ::= VariableReference 83353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | '(' Expr ')' 83363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | Literal 83373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | Number 83383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | FunctionCall 83393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 8340afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile a primary expression. 83413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 8342afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void 8343afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompPrimaryExpr(xmlXPathParserContextPtr ctxt) { 83443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 8345afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard if (CUR == '$') xmlXPathCompVariableReference(ctxt); 83463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else if (CUR == '(') { 83473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 83483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 8349afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompileExpr(ctxt); 835050fe8b1732048003f47b32b009507fe6cdecd39fAleksey Sanin CHECK_ERROR; 83513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (CUR != ')') { 83523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XP_ERROR(XPATH_EXPR_ERROR); 83533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 83543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 83553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 8356d1757abcb891e01a9017f4aad041cc306d0d467bWilliam M. Brack } else if (IS_ASCII_DIGIT(CUR) || (CUR == '.' && IS_ASCII_DIGIT(NXT(1)))) { 8357afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompNumber(ctxt); 83583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else if ((CUR == '\'') || (CUR == '"')) { 8359afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompLiteral(ctxt); 83603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else { 8361afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompFunctionCall(ctxt); 83623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 83633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 83643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 83653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 83663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 8367afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompFilterExpr: 83683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 83693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 83703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [20] FilterExpr ::= PrimaryExpr 83713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | FilterExpr Predicate 83723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 8373afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile a filter expression. 83743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Square brackets are used to filter expressions in the same way that 83753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * they are used in location paths. It is an error if the expression to 83763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * be filtered does not evaluate to a node-set. The context node list 83773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * used for evaluating the expression in square brackets is the node-set 83783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * to be filtered listed in document order. 83793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 83803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 8381afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void 8382afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompFilterExpr(xmlXPathParserContextPtr ctxt) { 8383afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompPrimaryExpr(ctxt); 83843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ERROR; 83853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 83863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 83873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while (CUR == '[') { 8388d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard xmlXPathCompPredicate(ctxt, 1); 83893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 83903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 83913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 83923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 83933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 83943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 83953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 83963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathScanName: 83973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 83983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 83993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Trickery: parse an XML name but without consuming the input flow 84003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Needed to avoid insanity in the parser state. 84013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 84023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [4] NameChar ::= Letter | Digit | '.' | '-' | '_' | ':' | 84033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * CombiningChar | Extender 84043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 84053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [5] Name ::= (Letter | '_' | ':') (NameChar)* 84063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 84073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [6] Names ::= Name (S Name)* 84083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 84093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the Name parsed or NULL 84103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 84113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 841256a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic xmlChar * 84133473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathScanName(xmlXPathParserContextPtr ctxt) { 8414032268145fad72bbf00c944c1f6a067e5da4a1e0Daniel Veillard int len = 0, l; 8415032268145fad72bbf00c944c1f6a067e5da4a1e0Daniel Veillard int c; 8416032268145fad72bbf00c944c1f6a067e5da4a1e0Daniel Veillard const xmlChar *cur; 8417032268145fad72bbf00c944c1f6a067e5da4a1e0Daniel Veillard xmlChar *ret; 84183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 8419032268145fad72bbf00c944c1f6a067e5da4a1e0Daniel Veillard cur = ctxt->cur; 8420032268145fad72bbf00c944c1f6a067e5da4a1e0Daniel Veillard 8421032268145fad72bbf00c944c1f6a067e5da4a1e0Daniel Veillard c = CUR_CHAR(l); 8422032268145fad72bbf00c944c1f6a067e5da4a1e0Daniel Veillard if ((c == ' ') || (c == '>') || (c == '/') || /* accelerators */ 8423032268145fad72bbf00c944c1f6a067e5da4a1e0Daniel Veillard (!IS_LETTER(c) && (c != '_') && 8424032268145fad72bbf00c944c1f6a067e5da4a1e0Daniel Veillard (c != ':'))) { 84253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 84263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 84273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 8428032268145fad72bbf00c944c1f6a067e5da4a1e0Daniel Veillard while ((c != ' ') && (c != '>') && (c != '/') && /* test bigname.xml */ 8429032268145fad72bbf00c944c1f6a067e5da4a1e0Daniel Veillard ((IS_LETTER(c)) || (IS_DIGIT(c)) || 8430032268145fad72bbf00c944c1f6a067e5da4a1e0Daniel Veillard (c == '.') || (c == '-') || 8431032268145fad72bbf00c944c1f6a067e5da4a1e0Daniel Veillard (c == '_') || (c == ':') || 8432032268145fad72bbf00c944c1f6a067e5da4a1e0Daniel Veillard (IS_COMBINING(c)) || 8433032268145fad72bbf00c944c1f6a067e5da4a1e0Daniel Veillard (IS_EXTENDER(c)))) { 8434032268145fad72bbf00c944c1f6a067e5da4a1e0Daniel Veillard len += l; 8435032268145fad72bbf00c944c1f6a067e5da4a1e0Daniel Veillard NEXTL(l); 8436032268145fad72bbf00c944c1f6a067e5da4a1e0Daniel Veillard c = CUR_CHAR(l); 84373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 8438032268145fad72bbf00c944c1f6a067e5da4a1e0Daniel Veillard ret = xmlStrndup(cur, ctxt->cur - cur); 8439032268145fad72bbf00c944c1f6a067e5da4a1e0Daniel Veillard ctxt->cur = cur; 8440032268145fad72bbf00c944c1f6a067e5da4a1e0Daniel Veillard return(ret); 84413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 84423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 84433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 8444afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompPathExpr: 84453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 84463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 84473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [19] PathExpr ::= LocationPath 84483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | FilterExpr 84493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | FilterExpr '/' RelativeLocationPath 84503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | FilterExpr '//' RelativeLocationPath 84513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 8452afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile a path expression. 84533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The / operator and // operators combine an arbitrary expression 84543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * and a relative location path. It is an error if the expression 84553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * does not evaluate to a node-set. 84563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The / operator does composition in the same way as when / is 84573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * used in a location path. As in location paths, // is short for 84583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * /descendant-or-self::node()/. 84593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 84603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 8461afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void 8462afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompPathExpr(xmlXPathParserContextPtr ctxt) { 84633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int lc = 1; /* Should we branch to LocationPath ? */ 84643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlChar *name = NULL; /* we may have to preparse a name to find out */ 84653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 84663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 8467d1757abcb891e01a9017f4aad041cc306d0d467bWilliam M. Brack if ((CUR == '$') || (CUR == '(') || 8468d1757abcb891e01a9017f4aad041cc306d0d467bWilliam M. Brack (IS_ASCII_DIGIT(CUR)) || 8469d1757abcb891e01a9017f4aad041cc306d0d467bWilliam M. Brack (CUR == '\'') || (CUR == '"') || 8470d1757abcb891e01a9017f4aad041cc306d0d467bWilliam M. Brack (CUR == '.' && IS_ASCII_DIGIT(NXT(1)))) { 84713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor lc = 0; 84723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else if (CUR == '*') { 84733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* relative or absolute location path */ 84743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor lc = 1; 84753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else if (CUR == '/') { 84763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* relative or absolute location path */ 84773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor lc = 1; 84783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else if (CUR == '@') { 84793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* relative abbreviated attribute location path */ 84803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor lc = 1; 84813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else if (CUR == '.') { 84823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* relative abbreviated attribute location path */ 84833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor lc = 1; 84843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else { 84853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 84863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Problem is finding if we have a name here whether it's: 84873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * - a nodetype 84883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * - a function call in which case it's followed by '(' 84893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * - an axis in which case it's followed by ':' 84903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * - a element name 84913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * We do an a priori analysis here rather than having to 84923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * maintain parsed token content through the recursive function 8493081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack * calls. This looks uglier but makes the code easier to 84943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * read/write/debug. 84953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 84963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 84973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor name = xmlXPathScanName(ctxt); 84983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((name != NULL) && (xmlStrstr(name, (xmlChar *) "::") != NULL)) { 84993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_STEP 85003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 85013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "PathExpr: Axis\n"); 85023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 85033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor lc = 1; 85043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(name); 85053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else if (name != NULL) { 85063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int len =xmlStrlen(name); 85073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 85083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 85093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while (NXT(len) != 0) { 85103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (NXT(len) == '/') { 85113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* element name */ 85123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_STEP 85133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 85143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "PathExpr: AbbrRelLocation\n"); 85153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 85163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor lc = 1; 85173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 851876e95df05556c9610b564b14cf578c8f9e34c9c1William M. Brack } else if (IS_BLANK_CH(NXT(len))) { 851978637da0ea1c833dfdfad87a9aa5bea14510d08aWilliam M. Brack /* ignore blanks */ 852078637da0ea1c833dfdfad87a9aa5bea14510d08aWilliam M. Brack ; 85213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else if (NXT(len) == ':') { 85223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_STEP 85233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 85243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "PathExpr: AbbrRelLocation\n"); 85253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 85263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor lc = 1; 85273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 85283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else if ((NXT(len) == '(')) { 85293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* Note Type or Function */ 85303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (xmlXPathIsNodeType(name)) { 85313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_STEP 85323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 85333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "PathExpr: Type search\n"); 85343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 85353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor lc = 1; 85363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else { 85373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_STEP 85383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 85393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "PathExpr: function call\n"); 85403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 85413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor lc = 0; 85423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 85433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 85443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else if ((NXT(len) == '[')) { 85453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* element name */ 85463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_STEP 85473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 85483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "PathExpr: AbbrRelLocation\n"); 85493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 85503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor lc = 1; 85513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 85523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else if ((NXT(len) == '<') || (NXT(len) == '>') || 85533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor (NXT(len) == '=')) { 85543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor lc = 1; 85553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 85563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else { 85573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor lc = 1; 85583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 85593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 85603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor len++; 85613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 85623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (NXT(len) == 0) { 85633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_STEP 85643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 85653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "PathExpr: AbbrRelLocation\n"); 85663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 85673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* element name */ 85683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor lc = 1; 85693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 85703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(name); 85713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else { 8572081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack /* make sure all cases are covered explicitly */ 85733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XP_ERROR(XPATH_EXPR_ERROR); 85743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 85753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 85763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 85773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (lc) { 85789e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (CUR == '/') { 85799e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard PUSH_LEAVE_EXPR(XPATH_OP_ROOT, 0, 0); 85809e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } else { 85819e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard PUSH_LEAVE_EXPR(XPATH_OP_NODE, 0, 0); 85823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 8583afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompLocationPath(ctxt); 85843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else { 8585afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompFilterExpr(ctxt); 85863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ERROR; 85873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((CUR == '/') && (NXT(1) == '/')) { 85883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP(2); 85893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 85909e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 85919e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard PUSH_LONG_EXPR(XPATH_OP_COLLECT, AXIS_DESCENDANT_OR_SELF, 85929e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard NODE_TEST_TYPE, NODE_TYPE_NODE, NULL, NULL); 85939e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard PUSH_UNARY_EXPR(XPATH_OP_RESET, ctxt->comp->last, 1, 0); 85949e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 8595afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompRelativeLocationPath(ctxt); 85963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else if (CUR == '/') { 8597afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompRelativeLocationPath(ctxt); 85983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 85993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 86003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 86013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 86023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 86033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 8604afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompUnionExpr: 86053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 86063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 86073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [18] UnionExpr ::= PathExpr 86083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | UnionExpr '|' PathExpr 86093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 8610afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile an union expression. 86113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 86123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 8613afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void 8614afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompUnionExpr(xmlXPathParserContextPtr ctxt) { 8615afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompPathExpr(ctxt); 86163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ERROR; 86173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 86183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while (CUR == '|') { 86199e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard int op1 = ctxt->comp->last; 86209e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard PUSH_LEAVE_EXPR(XPATH_OP_NODE, 0, 0); 86213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 86223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 86233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 8624afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompPathExpr(ctxt); 86253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 86269e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard PUSH_BINARY_EXPR(XPATH_OP_UNION, op1, ctxt->comp->last, 0, 0); 86279e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 86283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 86293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 86303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 86313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 86323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 8633afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompUnaryExpr: 86343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 86353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 86363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [27] UnaryExpr ::= UnionExpr 86373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | '-' UnaryExpr 86383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 8639afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile an unary expression. 86403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 86413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 8642afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void 8643afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompUnaryExpr(xmlXPathParserContextPtr ctxt) { 86443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int minus = 0; 86459e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard int found = 0; 86463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 86473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 864868d7b67ada0941ad7e1d02602f48de4015a67af3Daniel Veillard while (CUR == '-') { 864968d7b67ada0941ad7e1d02602f48de4015a67af3Daniel Veillard minus = 1 - minus; 86509e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard found = 1; 86513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 86523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 86533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 86549e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 8655afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompUnionExpr(ctxt); 86563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ERROR; 86579e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (found) { 86589e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (minus) 86599e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard PUSH_UNARY_EXPR(XPATH_OP_PLUS, ctxt->comp->last, 2, 0); 86609e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard else 86619e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard PUSH_UNARY_EXPR(XPATH_OP_PLUS, ctxt->comp->last, 3, 0); 86623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 86633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 86643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 86653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 8666afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompMultiplicativeExpr: 86673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 86683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 86693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [26] MultiplicativeExpr ::= UnaryExpr 86703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | MultiplicativeExpr MultiplyOperator UnaryExpr 86713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | MultiplicativeExpr 'div' UnaryExpr 86723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | MultiplicativeExpr 'mod' UnaryExpr 86733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [34] MultiplyOperator ::= '*' 86743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 8675afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile an Additive expression. 86763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 86773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 8678afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void 8679afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompMultiplicativeExpr(xmlXPathParserContextPtr ctxt) { 8680afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompUnaryExpr(ctxt); 86813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ERROR; 86823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 86833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while ((CUR == '*') || 86843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ((CUR == 'd') && (NXT(1) == 'i') && (NXT(2) == 'v')) || 86853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ((CUR == 'm') && (NXT(1) == 'o') && (NXT(2) == 'd'))) { 86863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int op = -1; 86879e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard int op1 = ctxt->comp->last; 86883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 86893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (CUR == '*') { 86903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor op = 0; 86913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 86923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else if (CUR == 'd') { 86933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor op = 1; 86943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP(3); 86953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else if (CUR == 'm') { 86963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor op = 2; 86973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP(3); 86983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 86993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 8700afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompUnaryExpr(ctxt); 87013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ERROR; 87029e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard PUSH_BINARY_EXPR(XPATH_OP_MULT, op1, ctxt->comp->last, op, 0); 87033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 87043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 87053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 87063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 87073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 8708afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompAdditiveExpr: 87093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 87103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 87113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [25] AdditiveExpr ::= MultiplicativeExpr 87123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | AdditiveExpr '+' MultiplicativeExpr 87133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | AdditiveExpr '-' MultiplicativeExpr 87143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 8715afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile an Additive expression. 87163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 87173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 8718afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void 8719afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompAdditiveExpr(xmlXPathParserContextPtr ctxt) { 87209e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 8721afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompMultiplicativeExpr(ctxt); 87223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ERROR; 87233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 87243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while ((CUR == '+') || (CUR == '-')) { 87253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int plus; 87269e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard int op1 = ctxt->comp->last; 87273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 87283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (CUR == '+') plus = 1; 87293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else plus = 0; 87303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 87313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 8732afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompMultiplicativeExpr(ctxt); 87333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ERROR; 87349e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard PUSH_BINARY_EXPR(XPATH_OP_PLUS, op1, ctxt->comp->last, plus, 0); 87353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 87363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 87373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 87383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 87393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 8740afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompRelationalExpr: 87413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 87423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 87433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [24] RelationalExpr ::= AdditiveExpr 87443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | RelationalExpr '<' AdditiveExpr 87453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | RelationalExpr '>' AdditiveExpr 87463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | RelationalExpr '<=' AdditiveExpr 87473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | RelationalExpr '>=' AdditiveExpr 87483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 87493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * A <= B > C is allowed ? Answer from James, yes with 87503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * (AdditiveExpr <= AdditiveExpr) > AdditiveExpr 87513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * which is basically what got implemented. 87523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 8753afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile a Relational expression, then push the result 87543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * on the stack 87553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 87563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 8757afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void 8758afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompRelationalExpr(xmlXPathParserContextPtr ctxt) { 8759afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompAdditiveExpr(ctxt); 87603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ERROR; 87613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 87623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while ((CUR == '<') || 87633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor (CUR == '>') || 87643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ((CUR == '<') && (NXT(1) == '=')) || 87653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ((CUR == '>') && (NXT(1) == '='))) { 87669e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard int inf, strict; 87679e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard int op1 = ctxt->comp->last; 87683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 87693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (CUR == '<') inf = 1; 87703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else inf = 0; 87713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (NXT(1) == '=') strict = 0; 87723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else strict = 1; 87733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 87743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (!strict) NEXT; 87753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 8776afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompAdditiveExpr(ctxt); 87773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ERROR; 87789e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard PUSH_BINARY_EXPR(XPATH_OP_CMP, op1, ctxt->comp->last, inf, strict); 87793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 87803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 87813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 87823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 87833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 8784afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompEqualityExpr: 87853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 87863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 87873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [23] EqualityExpr ::= RelationalExpr 87883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | EqualityExpr '=' RelationalExpr 87893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | EqualityExpr '!=' RelationalExpr 87903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 87913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * A != B != C is allowed ? Answer from James, yes with 87923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * (RelationalExpr = RelationalExpr) = RelationalExpr 87933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * (RelationalExpr != RelationalExpr) != RelationalExpr 87943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * which is basically what got implemented. 87953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 8796afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile an Equality expression. 87973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 87983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 8799afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void 8800afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompEqualityExpr(xmlXPathParserContextPtr ctxt) { 8801afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompRelationalExpr(ctxt); 88023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ERROR; 88033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 88043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while ((CUR == '=') || ((CUR == '!') && (NXT(1) == '='))) { 88059e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard int eq; 88069e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard int op1 = ctxt->comp->last; 88073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 88083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (CUR == '=') eq = 1; 88093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else eq = 0; 88103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 88113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (!eq) NEXT; 88123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 8813afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompRelationalExpr(ctxt); 88143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ERROR; 88159e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard PUSH_BINARY_EXPR(XPATH_OP_EQUAL, op1, ctxt->comp->last, eq, 0); 88163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 88173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 88183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 88193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 88203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 8821afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompAndExpr: 88223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 88233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 88243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [22] AndExpr ::= EqualityExpr 88253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | AndExpr 'and' EqualityExpr 88263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 8827afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile an AND expression. 88283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 88293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 8830afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void 8831afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompAndExpr(xmlXPathParserContextPtr ctxt) { 8832afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompEqualityExpr(ctxt); 88333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ERROR; 88343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 88353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while ((CUR == 'a') && (NXT(1) == 'n') && (NXT(2) == 'd')) { 88369e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard int op1 = ctxt->comp->last; 88373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP(3); 88383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 8839afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompEqualityExpr(ctxt); 88403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ERROR; 88419e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard PUSH_BINARY_EXPR(XPATH_OP_AND, op1, ctxt->comp->last, 0, 0); 88423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 88433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 88443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 88453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 88463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 8847591b4be0fe1986b5e71d54c5c063493987ef4285Daniel Veillard * xmlXPathCompileExpr: 88483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 88493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 88503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [14] Expr ::= OrExpr 88513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [21] OrExpr ::= AndExpr 88523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | OrExpr 'or' AndExpr 88533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 8854afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Parse and compile an expression 88553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 8856afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void 8857afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompileExpr(xmlXPathParserContextPtr ctxt) { 8858afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompAndExpr(ctxt); 88593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ERROR; 88603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 88613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while ((CUR == 'o') && (NXT(1) == 'r')) { 88629e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard int op1 = ctxt->comp->last; 88633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP(2); 88643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 8865afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompAndExpr(ctxt); 88663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ERROR; 88679e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard PUSH_BINARY_EXPR(XPATH_OP_OR, op1, ctxt->comp->last, 0, 0); 88689e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard op1 = ctxt->comp->nbStep; 88693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 88703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 88719e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (ctxt->comp->steps[ctxt->comp->last].op != XPATH_OP_VALUE) { 88729e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard /* more ops could be optimized too */ 88739e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard PUSH_UNARY_EXPR(XPATH_OP_SORT, ctxt->comp->last , 0, 0); 88749e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } 88753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 88763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 88773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 8878afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompPredicate: 88793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 8880d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * @filter: act as a filter 88813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 88823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [8] Predicate ::= '[' PredicateExpr ']' 88833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [9] PredicateExpr ::= Expr 88843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 8885afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile a predicate expression 88869e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard */ 8887afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void 8888d8df6c0e8c883e1d618388d266015dda36731440Daniel VeillardxmlXPathCompPredicate(xmlXPathParserContextPtr ctxt, int filter) { 88899e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard int op1 = ctxt->comp->last; 88909e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 88919e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard SKIP_BLANKS; 88929e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (CUR != '[') { 88939e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard XP_ERROR(XPATH_INVALID_PREDICATE_ERROR); 88949e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } 88959e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard NEXT; 88969e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard SKIP_BLANKS; 88979e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 88989e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard ctxt->comp->last = -1; 8899afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompileExpr(ctxt); 89009e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard CHECK_ERROR; 89019e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 89029e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (CUR != ']') { 89039e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard XP_ERROR(XPATH_INVALID_PREDICATE_ERROR); 89049e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } 89059e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 8906d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard if (filter) 8907d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard PUSH_BINARY_EXPR(XPATH_OP_FILTER, op1, ctxt->comp->last, 0, 0); 8908d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard else 8909d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard PUSH_BINARY_EXPR(XPATH_OP_PREDICATE, op1, ctxt->comp->last, 0, 0); 89109e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 89119e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard NEXT; 89129e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard SKIP_BLANKS; 89139e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard} 89149e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 89159e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard/** 8916afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompNodeTest: 89173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 89183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @test: pointer to a xmlXPathTestVal 89193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @type: pointer to a xmlXPathTypeVal 89203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @prefix: placeholder for a possible name prefix 89213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 89223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [7] NodeTest ::= NameTest 89233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | NodeType '(' ')' 89243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | 'processing-instruction' '(' Literal ')' 89253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 89263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [37] NameTest ::= '*' 89273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | NCName ':' '*' 89283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | QName 89293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [38] NodeType ::= 'comment' 89303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | 'text' 89313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | 'processing-instruction' 89323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | 'node' 89333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 8934081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack * Returns the name found and updates @test, @type and @prefix appropriately 89353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 893656a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic xmlChar * 8937afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompNodeTest(xmlXPathParserContextPtr ctxt, xmlXPathTestVal *test, 8938afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathTypeVal *type, const xmlChar **prefix, 8939afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlChar *name) { 89403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int blanks; 89413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 89423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((test == NULL) || (type == NULL) || (prefix == NULL)) { 89433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor STRANGE; 89443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 89453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 894678637da0ea1c833dfdfad87a9aa5bea14510d08aWilliam M. Brack *type = (xmlXPathTypeVal) 0; 894778637da0ea1c833dfdfad87a9aa5bea14510d08aWilliam M. Brack *test = (xmlXPathTestVal) 0; 89483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *prefix = NULL; 89493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 89503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 89513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((name == NULL) && (CUR == '*')) { 89523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 89533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * All elements 89543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 89553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 89563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *test = NODE_TEST_ALL; 89573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 89583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 89593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 89603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (name == NULL) 89613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor name = xmlXPathParseNCName(ctxt); 89623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (name == NULL) { 896324505b0f5c872c5afb6da5093565e5a6e09ca541Daniel Veillard XP_ERRORNULL(XPATH_EXPR_ERROR); 89643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 89653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 896676e95df05556c9610b564b14cf578c8f9e34c9c1William M. Brack blanks = IS_BLANK_CH(CUR); 89673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 89683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (CUR == '(') { 89693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 89703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 89713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * NodeType or PI search 89723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 89733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (xmlStrEqual(name, BAD_CAST "comment")) 89743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *type = NODE_TYPE_COMMENT; 89753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else if (xmlStrEqual(name, BAD_CAST "node")) 89763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *type = NODE_TYPE_NODE; 89773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else if (xmlStrEqual(name, BAD_CAST "processing-instruction")) 89783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *type = NODE_TYPE_PI; 89793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else if (xmlStrEqual(name, BAD_CAST "text")) 89803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *type = NODE_TYPE_TEXT; 89813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else { 89823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (name != NULL) 89833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(name); 898424505b0f5c872c5afb6da5093565e5a6e09ca541Daniel Veillard XP_ERRORNULL(XPATH_EXPR_ERROR); 89853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 89863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 89873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *test = NODE_TEST_TYPE; 89883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 89893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 89903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (*type == NODE_TYPE_PI) { 89913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 89923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Specific case: search a PI by name. 89933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 89943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (name != NULL) 89953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(name); 899682e4971dc2f470c9b6f19cf8b15ff32781067167Daniel Veillard name = NULL; 899782e4971dc2f470c9b6f19cf8b15ff32781067167Daniel Veillard if (CUR != ')') { 899882e4971dc2f470c9b6f19cf8b15ff32781067167Daniel Veillard name = xmlXPathParseLiteral(ctxt); 899924505b0f5c872c5afb6da5093565e5a6e09ca541Daniel Veillard CHECK_ERROR NULL; 9000ed23b7dc73f6c1146701ece20ed3f03d68366516Daniel Veillard *test = NODE_TEST_PI; 900182e4971dc2f470c9b6f19cf8b15ff32781067167Daniel Veillard SKIP_BLANKS; 900282e4971dc2f470c9b6f19cf8b15ff32781067167Daniel Veillard } 90033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 90043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (CUR != ')') { 90053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (name != NULL) 90063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(name); 900724505b0f5c872c5afb6da5093565e5a6e09ca541Daniel Veillard XP_ERRORNULL(XPATH_UNCLOSED_ERROR); 90083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 90093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 90103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(name); 90113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 90123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *test = NODE_TEST_NAME; 90133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((!blanks) && (CUR == ':')) { 90143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 90153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 90163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 9017fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * Since currently the parser context don't have a 9018fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * namespace list associated: 9019fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * The namespace name for this prefix can be computed 9020fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * only at evaluation time. The compilation is done 9021fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * outside of any context. 90223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 9023fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard#if 0 90243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *prefix = xmlXPathNsLookup(ctxt->context, name); 90253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (name != NULL) 90263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(name); 90273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (*prefix == NULL) { 90283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XP_ERROR0(XPATH_UNDEF_PREFIX_ERROR); 90293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 9030fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard#else 9031fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard *prefix = name; 9032fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard#endif 90333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 90343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (CUR == '*') { 90353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 90363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * All elements 90373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 90383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 90393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *test = NODE_TEST_ALL; 90403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 90413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 90423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 90433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor name = xmlXPathParseNCName(ctxt); 90443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (name == NULL) { 904524505b0f5c872c5afb6da5093565e5a6e09ca541Daniel Veillard XP_ERRORNULL(XPATH_EXPR_ERROR); 90463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 90473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 90483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(name); 90493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 90503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 90513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 90523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathIsAxisName: 90533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @name: a preparsed name token 90543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 90553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [6] AxisName ::= 'ancestor' 90563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | 'ancestor-or-self' 90573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | 'attribute' 90583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | 'child' 90593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | 'descendant' 90603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | 'descendant-or-self' 90613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | 'following' 90623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | 'following-sibling' 90633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | 'namespace' 90643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | 'parent' 90653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | 'preceding' 90663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | 'preceding-sibling' 90673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | 'self' 90683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 90693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the axis or 0 90703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 907156a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic xmlXPathAxisVal 90723473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathIsAxisName(const xmlChar *name) { 907378637da0ea1c833dfdfad87a9aa5bea14510d08aWilliam M. Brack xmlXPathAxisVal ret = (xmlXPathAxisVal) 0; 90743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor switch (name[0]) { 90753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case 'a': 90763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (xmlStrEqual(name, BAD_CAST "ancestor")) 90773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = AXIS_ANCESTOR; 90783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (xmlStrEqual(name, BAD_CAST "ancestor-or-self")) 90793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = AXIS_ANCESTOR_OR_SELF; 90803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (xmlStrEqual(name, BAD_CAST "attribute")) 90813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = AXIS_ATTRIBUTE; 90823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 90833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case 'c': 90843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (xmlStrEqual(name, BAD_CAST "child")) 90853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = AXIS_CHILD; 90863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 90873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case 'd': 90883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (xmlStrEqual(name, BAD_CAST "descendant")) 90893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = AXIS_DESCENDANT; 90903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (xmlStrEqual(name, BAD_CAST "descendant-or-self")) 90913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = AXIS_DESCENDANT_OR_SELF; 90923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 90933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case 'f': 90943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (xmlStrEqual(name, BAD_CAST "following")) 90953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = AXIS_FOLLOWING; 90963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (xmlStrEqual(name, BAD_CAST "following-sibling")) 90973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = AXIS_FOLLOWING_SIBLING; 90983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 90993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case 'n': 91003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (xmlStrEqual(name, BAD_CAST "namespace")) 91013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = AXIS_NAMESPACE; 91023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 91033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case 'p': 91043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (xmlStrEqual(name, BAD_CAST "parent")) 91053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = AXIS_PARENT; 91063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (xmlStrEqual(name, BAD_CAST "preceding")) 91073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = AXIS_PRECEDING; 91083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (xmlStrEqual(name, BAD_CAST "preceding-sibling")) 91093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = AXIS_PRECEDING_SIBLING; 91103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 91113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case 's': 91123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (xmlStrEqual(name, BAD_CAST "self")) 91133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = AXIS_SELF; 91143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 91153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 91163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ret); 91173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 91183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 91193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 9120afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompStep: 91213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 91223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 91233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [4] Step ::= AxisSpecifier NodeTest Predicate* 91243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | AbbreviatedStep 91253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 91263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [12] AbbreviatedStep ::= '.' | '..' 91273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 91283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [5] AxisSpecifier ::= AxisName '::' 91293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | AbbreviatedAxisSpecifier 91303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 91313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [13] AbbreviatedAxisSpecifier ::= '@'? 91323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 91333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Modified for XPtr range support as: 91343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 91353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [4xptr] Step ::= AxisSpecifier NodeTest Predicate* 91363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | AbbreviatedStep 91373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | 'range-to' '(' Expr ')' Predicate* 91383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 9139afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile one step in a Location Path 91403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * A location step of . is short for self::node(). This is 91413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * particularly useful in conjunction with //. For example, the 91423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * location path .//para is short for 91433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * self::node()/descendant-or-self::node()/child::para 91443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * and so will select all para descendant elements of the context 91453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * node. 91463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Similarly, a location step of .. is short for parent::node(). 91473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * For example, ../title is short for parent::node()/child::title 91483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * and so will select the title children of the parent of the context 91493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * node. 91503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 9151afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void 9152afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompStep(xmlXPathParserContextPtr ctxt) { 9153fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard#ifdef LIBXML_XPTR_ENABLED 9154fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard int rangeto = 0; 9155fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard int op2 = -1; 9156fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard#endif 9157fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard 91583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 91593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((CUR == '.') && (NXT(1) == '.')) { 91603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP(2); 91613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 91629e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard PUSH_LONG_EXPR(XPATH_OP_COLLECT, AXIS_PARENT, 91639e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard NODE_TEST_TYPE, NODE_TYPE_NODE, NULL, NULL); 91643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else if (CUR == '.') { 91653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 91663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 91673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else { 91683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlChar *name = NULL; 91693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor const xmlChar *prefix = NULL; 9170aac7c68e87d00732b319698723de1ec43252fb01Daniel Veillard xmlXPathTestVal test = (xmlXPathTestVal) 0; 917178637da0ea1c833dfdfad87a9aa5bea14510d08aWilliam M. Brack xmlXPathAxisVal axis = (xmlXPathAxisVal) 0; 9172aac7c68e87d00732b319698723de1ec43252fb01Daniel Veillard xmlXPathTypeVal type = (xmlXPathTypeVal) 0; 9173d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard int op1; 91743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 91753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 91763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The modification needed for XPointer change to the production 91773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 91783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef LIBXML_XPTR_ENABLED 9179fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard if (ctxt->xptr) { 91803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor name = xmlXPathParseNCName(ctxt); 91813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((name != NULL) && (xmlStrEqual(name, BAD_CAST "range-to"))) { 9182fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard op2 = ctxt->comp->last; 91833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(name); 91843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 91853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (CUR != '(') { 91863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XP_ERROR(XPATH_EXPR_ERROR); 91873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 91883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 91893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 91903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 9191afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompileExpr(ctxt); 9192fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard /* PUSH_BINARY_EXPR(XPATH_OP_RANGETO, op2, ctxt->comp->last, 0, 0); */ 91933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ERROR; 91943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 91953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 91963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (CUR != ')') { 91973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor XP_ERROR(XPATH_EXPR_ERROR); 91983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 91993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 9200fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard rangeto = 1; 92013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor goto eval_predicates; 92023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 92033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 92043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 92052156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard if (CUR == '*') { 92062156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard axis = AXIS_CHILD; 92072156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard } else { 92082156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard if (name == NULL) 92092156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard name = xmlXPathParseNCName(ctxt); 92102156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard if (name != NULL) { 92112156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard axis = xmlXPathIsAxisName(name); 92122156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard if (axis != 0) { 92132156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard SKIP_BLANKS; 92142156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard if ((CUR == ':') && (NXT(1) == ':')) { 92152156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard SKIP(2); 92162156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard xmlFree(name); 92172156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard name = NULL; 92182156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard } else { 92192156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard /* an element name can conflict with an axis one :-\ */ 92202156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard axis = AXIS_CHILD; 92212156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard } 92223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else { 92233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor axis = AXIS_CHILD; 92243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 92252156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard } else if (CUR == '@') { 92262156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard NEXT; 92272156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard axis = AXIS_ATTRIBUTE; 92283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else { 92292156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard axis = AXIS_CHILD; 92303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 92313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 92323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 92333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor CHECK_ERROR; 92343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 9235afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard name = xmlXPathCompNodeTest(ctxt, &test, &type, &prefix, name); 92363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (test == 0) 92373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return; 92383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 9239ed6c54971fdb7fa37c183b1a36c2e581c750984bDaniel Veillard if ((prefix != NULL) && (ctxt->context != NULL) && 9240ed6c54971fdb7fa37c183b1a36c2e581c750984bDaniel Veillard (ctxt->context->flags & XML_XPATH_CHECKNS)) { 9241ed6c54971fdb7fa37c183b1a36c2e581c750984bDaniel Veillard if (xmlXPathNsLookup(ctxt->context, prefix) == NULL) { 9242ed6c54971fdb7fa37c183b1a36c2e581c750984bDaniel Veillard xmlXPathErr(ctxt, XPATH_UNDEF_PREFIX_ERROR); 9243ed6c54971fdb7fa37c183b1a36c2e581c750984bDaniel Veillard } 9244ed6c54971fdb7fa37c183b1a36c2e581c750984bDaniel Veillard } 92453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_STEP 92463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 92473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "Basis : computing new set\n"); 92483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 92499e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 92503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_STEP 92513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, "Basis : "); 9252fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard if (ctxt->value == NULL) 9253fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard xmlGenericError(xmlGenericErrorContext, "no value\n"); 9254fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard else if (ctxt->value->nodesetval == NULL) 9255fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard xmlGenericError(xmlGenericErrorContext, "Empty\n"); 9256fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard else 9257fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard xmlGenericErrorContextNodeSet(stdout, ctxt->value->nodesetval); 92583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 92593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 92605bb9ccd56a812b65e94e71477389be7826203649Daniel Veillard#ifdef LIBXML_XPTR_ENABLED 92613473f88a7abdf4e585e267288fb77e898c580d2bOwen Tayloreval_predicates: 92625bb9ccd56a812b65e94e71477389be7826203649Daniel Veillard#endif 9263d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard op1 = ctxt->comp->last; 9264d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard ctxt->comp->last = -1; 9265d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard 92663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 92673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while (CUR == '[') { 9268d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard xmlXPathCompPredicate(ctxt, 0); 92693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 9270d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard 9271fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard#ifdef LIBXML_XPTR_ENABLED 9272fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard if (rangeto) { 9273fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard PUSH_BINARY_EXPR(XPATH_OP_RANGETO, op2, op1, 0, 0); 9274fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard } else 9275fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard#endif 9276fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard PUSH_FULL_EXPR(XPATH_OP_COLLECT, op1, ctxt->comp->last, axis, 9277fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard test, type, (void *)prefix, (void *)name); 9278d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard 92793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 92803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_STEP 92813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, "Step : "); 9282fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard if (ctxt->value == NULL) 9283fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard xmlGenericError(xmlGenericErrorContext, "no value\n"); 9284fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard else if (ctxt->value->nodesetval == NULL) 9285fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard xmlGenericError(xmlGenericErrorContext, "Empty\n"); 9286fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard else 9287fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard xmlGenericErrorContextNodeSet(xmlGenericErrorContext, 9288fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard ctxt->value->nodesetval); 92893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 92903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 92913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 92923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 9293afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompRelativeLocationPath: 92943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 92953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 92963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [3] RelativeLocationPath ::= Step 92973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | RelativeLocationPath '/' Step 92983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | AbbreviatedRelativeLocationPath 92993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [11] AbbreviatedRelativeLocationPath ::= RelativeLocationPath '//' Step 93003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 9301afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile a relative location path. 93023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 9303afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void 9304afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompRelativeLocationPath 93053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor(xmlXPathParserContextPtr ctxt) { 93063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 93073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((CUR == '/') && (NXT(1) == '/')) { 93083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP(2); 93093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 93109e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard PUSH_LONG_EXPR(XPATH_OP_COLLECT, AXIS_DESCENDANT_OR_SELF, 93119e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard NODE_TEST_TYPE, NODE_TYPE_NODE, NULL, NULL); 93123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else if (CUR == '/') { 93133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 93143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 93153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 9316afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompStep(ctxt); 93173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 93183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while (CUR == '/') { 93193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((CUR == '/') && (NXT(1) == '/')) { 93203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP(2); 93213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 93229e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard PUSH_LONG_EXPR(XPATH_OP_COLLECT, AXIS_DESCENDANT_OR_SELF, 93233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NODE_TEST_TYPE, NODE_TYPE_NODE, NULL, NULL); 9324afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompStep(ctxt); 93253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else if (CUR == '/') { 93263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 93273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 9328afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompStep(ctxt); 93293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 93303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 93313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 93323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 93333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 93343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 9335afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompLocationPath: 93363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath Parser context 93373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 93383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [1] LocationPath ::= RelativeLocationPath 93393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | AbsoluteLocationPath 93403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [2] AbsoluteLocationPath ::= '/' RelativeLocationPath? 93413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * | AbbreviatedAbsoluteLocationPath 93423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [10] AbbreviatedAbsoluteLocationPath ::= 93433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * '//' RelativeLocationPath 93443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 9345afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile a location path 9346afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * 93473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * // is short for /descendant-or-self::node()/. For example, 93483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * //para is short for /descendant-or-self::node()/child::para and 93493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * so will select any para element in the document (even a para element 93503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * that is a document element will be selected by //para since the 93513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * document element node is a child of the root node); div//para is 93523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * short for div/descendant-or-self::node()/child::para and so will 93533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * select all para descendants of div children. 93543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 9355afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void 9356afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompLocationPath(xmlXPathParserContextPtr ctxt) { 93573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 93583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (CUR != '/') { 9359afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompRelativeLocationPath(ctxt); 93603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else { 93613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while (CUR == '/') { 93623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((CUR == '/') && (NXT(1) == '/')) { 93633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP(2); 93643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SKIP_BLANKS; 93659e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard PUSH_LONG_EXPR(XPATH_OP_COLLECT, AXIS_DESCENDANT_OR_SELF, 93669e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard NODE_TEST_TYPE, NODE_TYPE_NODE, NULL, NULL); 9367afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompRelativeLocationPath(ctxt); 93683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else if (CUR == '/') { 93693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor NEXT; 9370608ad0791b3b35072c8021ea4f66cf9d700394b9Daniel Veillard SKIP_BLANKS; 9371608ad0791b3b35072c8021ea4f66cf9d700394b9Daniel Veillard if ((CUR != 0 ) && 9372d1757abcb891e01a9017f4aad041cc306d0d467bWilliam M. Brack ((IS_ASCII_LETTER(CUR)) || (CUR == '_') || (CUR == '.') || 9373608ad0791b3b35072c8021ea4f66cf9d700394b9Daniel Veillard (CUR == '@') || (CUR == '*'))) 9374afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompRelativeLocationPath(ctxt); 93753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 93763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 93773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 93783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 93793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 93809e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard/************************************************************************ 93819e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * * 93829e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * XPath precompiled expression evaluation * 93839e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * * 93849e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard ************************************************************************/ 93859e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 9386f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillardstatic int 9387d8df6c0e8c883e1d618388d266015dda36731440Daniel VeillardxmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op); 9388d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard 93899e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard/** 9390d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * xmlXPathNodeCollectAndTest: 9391d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * @ctxt: the XPath Parser context 9392d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * @op: the XPath precompiled step operation 9393f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * @first: pointer to the first element in document order 9394f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * @last: pointer to the last element in document order 93959e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * 9396d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * This is the function implementing a step: based on the current list 9397d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * of nodes, it builds up a new list, looking at all nodes under that 9398081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack * axis and selecting them. It also does the predicate filtering 9399d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * 9400d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * Pushes the new NodeSet resulting from the search. 9401f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * 9402081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack * Returns the number of nodes traversed 94039e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard */ 9404f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillardstatic int 9405d8df6c0e8c883e1d618388d266015dda36731440Daniel VeillardxmlXPathNodeCollectAndTest(xmlXPathParserContextPtr ctxt, 9406f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathStepOpPtr op, 9407f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlNodePtr * first, xmlNodePtr * last) 9408f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard{ 940978637da0ea1c833dfdfad87a9aa5bea14510d08aWilliam M. Brack xmlXPathAxisVal axis = (xmlXPathAxisVal) op->value; 941078637da0ea1c833dfdfad87a9aa5bea14510d08aWilliam M. Brack xmlXPathTestVal test = (xmlXPathTestVal) op->value2; 941178637da0ea1c833dfdfad87a9aa5bea14510d08aWilliam M. Brack xmlXPathTypeVal type = (xmlXPathTypeVal) op->value3; 9412d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard const xmlChar *prefix = op->value4; 9413d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard const xmlChar *name = op->value5; 9414e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard const xmlChar *URI = NULL; 94159e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 9416d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP 9417f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard int n = 0; 9418d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif 9419f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard int i, t = 0; 9420d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard xmlNodeSetPtr ret, list; 9421d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard xmlXPathTraversalFunction next = NULL; 9422f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard void (*addNode) (xmlNodeSetPtr, xmlNodePtr); 942375be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard xmlNodeSetPtr (*mergeNodeSet) (xmlNodeSetPtr, xmlNodeSetPtr); 9424d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard xmlNodePtr cur = NULL; 9425d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard xmlXPathObjectPtr obj; 9426d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard xmlNodeSetPtr nodelist; 9427d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard xmlNodePtr tmp; 9428d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard 9429f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard CHECK_TYPE0(XPATH_NODESET); 9430d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard obj = valuePop(ctxt); 9431d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard addNode = xmlXPathNodeSetAdd; 943275be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard mergeNodeSet = xmlXPathNodeSetMerge; 9433e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard if (prefix != NULL) { 9434f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard URI = xmlXPathNsLookup(ctxt->context, prefix); 94352c19a7bf2ee0f78485840cac50f2a989f5efe476William M. Brack if (URI == NULL) { 94362c19a7bf2ee0f78485840cac50f2a989f5efe476William M. Brack xmlXPathFreeObject(obj); 9437f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard XP_ERROR0(XPATH_UNDEF_PREFIX_ERROR); 94382c19a7bf2ee0f78485840cac50f2a989f5efe476William M. Brack } 9439e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard } 9440d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP 9441f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, "new step : "); 9442d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif 9443d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard switch (axis) { 9444d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard case AXIS_ANCESTOR: 9445d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP 9446f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, "axis 'ancestors' "); 9447d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif 9448f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard first = NULL; 9449f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard next = xmlXPathNextAncestor; 9450f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9451d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard case AXIS_ANCESTOR_OR_SELF: 9452d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP 9453f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, 9454f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard "axis 'ancestors-or-self' "); 9455d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif 9456f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard first = NULL; 9457f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard next = xmlXPathNextAncestorOrSelf; 9458f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9459d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard case AXIS_ATTRIBUTE: 9460d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP 9461f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, "axis 'attributes' "); 9462d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif 9463f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard first = NULL; 9464f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard last = NULL; 9465f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard next = xmlXPathNextAttribute; 946675be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard mergeNodeSet = xmlXPathNodeSetMergeUnique; 9467f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9468d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard case AXIS_CHILD: 9469d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP 9470f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, "axis 'child' "); 9471d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif 9472f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard last = NULL; 9473f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard next = xmlXPathNextChild; 947475be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard mergeNodeSet = xmlXPathNodeSetMergeUnique; 9475f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9476d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard case AXIS_DESCENDANT: 9477d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP 9478f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, "axis 'descendant' "); 9479d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif 9480f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard last = NULL; 9481f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard next = xmlXPathNextDescendant; 9482f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9483d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard case AXIS_DESCENDANT_OR_SELF: 9484d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP 9485f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, 9486f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard "axis 'descendant-or-self' "); 9487d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif 9488f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard last = NULL; 9489f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard next = xmlXPathNextDescendantOrSelf; 9490f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9491d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard case AXIS_FOLLOWING: 9492d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP 9493f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, "axis 'following' "); 9494d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif 9495f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard last = NULL; 9496f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard next = xmlXPathNextFollowing; 9497f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9498d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard case AXIS_FOLLOWING_SIBLING: 9499d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP 9500f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, 9501f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard "axis 'following-siblings' "); 9502d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif 9503f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard last = NULL; 9504f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard next = xmlXPathNextFollowingSibling; 9505f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9506d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard case AXIS_NAMESPACE: 9507d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP 9508f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, "axis 'namespace' "); 9509d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif 9510f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard first = NULL; 9511f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard last = NULL; 9512f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard next = (xmlXPathTraversalFunction) xmlXPathNextNamespace; 951375be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard mergeNodeSet = xmlXPathNodeSetMergeUnique; 9514f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9515d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard case AXIS_PARENT: 9516d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP 9517f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, "axis 'parent' "); 9518d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif 9519f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard first = NULL; 9520f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard next = xmlXPathNextParent; 9521f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9522d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard case AXIS_PRECEDING: 9523d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP 9524f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, "axis 'preceding' "); 9525d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif 9526f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard first = NULL; 9527f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard next = xmlXPathNextPrecedingInternal; 9528f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9529d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard case AXIS_PRECEDING_SIBLING: 9530d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP 9531f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, 9532f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard "axis 'preceding-sibling' "); 9533d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif 9534f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard first = NULL; 9535f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard next = xmlXPathNextPrecedingSibling; 9536f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9537d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard case AXIS_SELF: 9538d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP 9539f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, "axis 'self' "); 9540d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif 9541f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard first = NULL; 9542f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard last = NULL; 9543f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard next = xmlXPathNextSelf; 954475be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard mergeNodeSet = xmlXPathNodeSetMergeUnique; 9545f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9546d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard } 95472c19a7bf2ee0f78485840cac50f2a989f5efe476William M. Brack if (next == NULL) { 95482c19a7bf2ee0f78485840cac50f2a989f5efe476William M. Brack xmlXPathFreeObject(obj); 9549f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return(0); 95502c19a7bf2ee0f78485840cac50f2a989f5efe476William M. Brack } 9551d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard 9552d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard nodelist = obj->nodesetval; 9553d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard if (nodelist == NULL) { 9554f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathFreeObject(obj); 9555f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard valuePush(ctxt, xmlXPathWrapNodeSet(NULL)); 9556f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return(0); 9557d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard } 9558d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard addNode = xmlXPathNodeSetAddUnique; 9559d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard ret = NULL; 9560d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP 9561d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard xmlGenericError(xmlGenericErrorContext, 9562f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard " context contains %d nodes\n", nodelist->nodeNr); 9563d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard switch (test) { 9564f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case NODE_TEST_NONE: 9565f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, 9566f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard " searching for none !!!\n"); 9567f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9568f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case NODE_TEST_TYPE: 9569f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, 9570f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard " searching for type %d\n", type); 9571f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9572f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case NODE_TEST_PI: 9573f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, 9574f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard " searching for PI !!!\n"); 9575f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9576f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case NODE_TEST_ALL: 9577f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, 9578f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard " searching for *\n"); 9579f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9580f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case NODE_TEST_NS: 9581f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, 9582f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard " searching for namespace %s\n", 9583f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard prefix); 9584f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9585f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case NODE_TEST_NAME: 9586f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, 9587f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard " searching for name %s\n", name); 9588f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (prefix != NULL) 9589f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, 9590f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard " with namespace %s\n", prefix); 9591f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9592d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard } 9593d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard xmlGenericError(xmlGenericErrorContext, "Testing : "); 9594d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif 9595d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard /* 9596d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * 2.3 Node Tests 9597d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * - For the attribute axis, the principal node type is attribute. 9598d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * - For the namespace axis, the principal node type is namespace. 9599d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * - For other axes, the principal node type is element. 9600d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * 9601d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * A node test * is true for any node of the 9602cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * principal node type. For example, child::* will 9603d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * select all element children of the context node 9604d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard */ 9605d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard tmp = ctxt->context->node; 9606f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard for (i = 0; i < nodelist->nodeNr; i++) { 9607d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard ctxt->context->node = nodelist->nodeTab[i]; 9608d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard 9609f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard cur = NULL; 9610f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard list = xmlXPathNodeSetCreate(NULL); 9611f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard do { 9612f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard cur = next(ctxt, cur); 9613f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (cur == NULL) 9614f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9615f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((first != NULL) && (*first == cur)) 9616f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9617f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (((t % 256) == 0) && 9618f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (first != NULL) && (*first != NULL) && 9619f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (xmlXPathCmpNodes(*first, cur) >= 0)) 9620f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9621f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((last != NULL) && (*last == cur)) 9622f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9623f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (((t % 256) == 0) && 9624f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (last != NULL) && (*last != NULL) && 9625f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (xmlXPathCmpNodes(cur, *last) >= 0)) 9626f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9627d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard t++; 9628f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#ifdef DEBUG_STEP 9629d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard xmlGenericError(xmlGenericErrorContext, " %s", cur->name); 9630d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif 9631f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard switch (test) { 9632d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard case NODE_TEST_NONE: 9633f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->node = tmp; 96342c19a7bf2ee0f78485840cac50f2a989f5efe476William M. Brack xmlXPathFreeObject(obj); 9635f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard STRANGE return(t); 9636d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard case NODE_TEST_TYPE: 9637f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((cur->type == type) || 9638f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ((type == NODE_TYPE_NODE) && 9639f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ((cur->type == XML_DOCUMENT_NODE) || 9640f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (cur->type == XML_HTML_DOCUMENT_NODE) || 9641f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (cur->type == XML_ELEMENT_NODE) || 9642f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin (cur->type == XML_NAMESPACE_DECL) || 9643f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin (cur->type == XML_ATTRIBUTE_NODE) || 9644f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (cur->type == XML_PI_NODE) || 9645f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (cur->type == XML_COMMENT_NODE) || 9646f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (cur->type == XML_CDATA_SECTION_NODE) || 96477583a59b5a0792599a181f77aaf0a39749fada27Daniel Veillard (cur->type == XML_TEXT_NODE))) || 96487583a59b5a0792599a181f77aaf0a39749fada27Daniel Veillard ((type == NODE_TYPE_TEXT) && 96497583a59b5a0792599a181f77aaf0a39749fada27Daniel Veillard (cur->type == XML_CDATA_SECTION_NODE))) { 9650d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP 9651d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard n++; 9652d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif 9653f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard addNode(list, cur); 9654f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9655f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9656d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard case NODE_TEST_PI: 9657f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (cur->type == XML_PI_NODE) { 9658f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((name != NULL) && 9659f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (!xmlStrEqual(name, cur->name))) 9660f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9661d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP 9662f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard n++; 9663d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif 9664f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard addNode(list, cur); 9665f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9666f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9667d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard case NODE_TEST_ALL: 9668f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (axis == AXIS_ATTRIBUTE) { 9669f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (cur->type == XML_ATTRIBUTE_NODE) { 9670d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP 9671f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard n++; 9672d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif 9673f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard addNode(list, cur); 9674f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9675f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } else if (axis == AXIS_NAMESPACE) { 9676f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (cur->type == XML_NAMESPACE_DECL) { 9677d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP 9678f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard n++; 9679d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif 9680044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlXPathNodeSetAddNs(list, ctxt->context->node, 9681044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard (xmlNsPtr) cur); 9682f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9683f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } else { 9684f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (cur->type == XML_ELEMENT_NODE) { 9685f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (prefix == NULL) { 9686d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP 9687f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard n++; 9688d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif 9689f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard addNode(list, cur); 9690f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } else if ((cur->ns != NULL) && 9691f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (xmlStrEqual(URI, cur->ns->href))) { 9692d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP 9693f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard n++; 9694d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif 9695f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard addNode(list, cur); 9696f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9697f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9698f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9699f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9700f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case NODE_TEST_NS:{ 9701f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard TODO; 9702f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9703f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9704d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard case NODE_TEST_NAME: 9705f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard switch (cur->type) { 9706f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XML_ELEMENT_NODE: 9707f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (xmlStrEqual(name, cur->name)) { 9708f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (prefix == NULL) { 9709f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (cur->ns == NULL) { 9710d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP 9711f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard n++; 9712d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif 9713f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard addNode(list, cur); 9714f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9715f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } else { 9716f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((cur->ns != NULL) && 9717f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (xmlStrEqual(URI, 9718f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard cur->ns->href))) { 9719d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP 9720f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard n++; 9721d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif 9722f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard addNode(list, cur); 9723f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9724f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9725f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9726f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9727f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XML_ATTRIBUTE_NODE:{ 9728f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlAttrPtr attr = (xmlAttrPtr) cur; 9729f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 9730f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (xmlStrEqual(name, attr->name)) { 9731f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (prefix == NULL) { 9732f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((attr->ns == NULL) || 9733f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (attr->ns->prefix == NULL)) { 9734d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP 9735f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard n++; 9736d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif 9737f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard addNode(list, 9738f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (xmlNodePtr) attr); 9739f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9740f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } else { 9741f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((attr->ns != NULL) && 9742f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (xmlStrEqual(URI, 9743f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard attr->ns-> 9744f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard href))) { 9745d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP 9746f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard n++; 9747d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif 9748f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard addNode(list, 9749f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (xmlNodePtr) attr); 9750f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9751f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9752f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9753f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9754f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9755f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XML_NAMESPACE_DECL: 9756f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (cur->type == XML_NAMESPACE_DECL) { 9757f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlNsPtr ns = (xmlNsPtr) cur; 9758f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 9759f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((ns->prefix != NULL) && (name != NULL) 9760f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard && (xmlStrEqual(ns->prefix, name))) { 97618b8d2254fa1604efd37b3ba92eaeb2e40b2909a8Daniel Veillard#ifdef DEBUG_STEP 9762f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard n++; 97638b8d2254fa1604efd37b3ba92eaeb2e40b2909a8Daniel Veillard#endif 9764044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlXPathNodeSetAddNs(list, 9765044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard ctxt->context->node, (xmlNsPtr) cur); 9766f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9767f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9768f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9769f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard default: 9770f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9771f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9772f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9773f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9774f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9775f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } while (cur != NULL); 9776f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 9777f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* 9778f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * If there is some predicate filtering do it now 9779f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 97806fbcf42aa301dca50737c65fb738752328ca3a4cDaniel Veillard if ((op->ch2 != -1) && (list != NULL) && (list->nodeNr > 0)) { 9781f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathObjectPtr obj2; 9782f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 9783f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard valuePush(ctxt, xmlXPathWrapNodeSet(list)); 9784f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathCompOpEval(ctxt, &ctxt->comp->steps[op->ch2]); 9785f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard CHECK_TYPE0(XPATH_NODESET); 9786f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard obj2 = valuePop(ctxt); 9787f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard list = obj2->nodesetval; 9788f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard obj2->nodesetval = NULL; 9789f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathFreeObject(obj2); 97902c19a7bf2ee0f78485840cac50f2a989f5efe476William M. Brack if (ctxt->error != XPATH_EXPRESSION_OK) { 97912c19a7bf2ee0f78485840cac50f2a989f5efe476William M. Brack xmlXPathFreeObject(obj); 97922c19a7bf2ee0f78485840cac50f2a989f5efe476William M. Brack xmlXPathFreeNodeSet(list); 97932c19a7bf2ee0f78485840cac50f2a989f5efe476William M. Brack return(0); 97942c19a7bf2ee0f78485840cac50f2a989f5efe476William M. Brack } 9795f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9796f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (ret == NULL) { 9797f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ret = list; 9798f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } else { 979975be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard ret = mergeNodeSet(ret, list); 9800f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathFreeNodeSet(list); 9801f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9802d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard } 9803d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard ctxt->context->node = tmp; 9804d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP 9805d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard xmlGenericError(xmlGenericErrorContext, 9806f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard "\nExamined %d nodes, found %d nodes at that step\n", 9807f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard t, n); 9808d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif 9809d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard valuePush(ctxt, xmlXPathWrapNodeSet(ret)); 98100ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard if ((obj->boolval) && (obj->user != NULL)) { 98110ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard ctxt->value->boolval = 1; 98120ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard ctxt->value->user = obj->user; 98130ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard obj->user = NULL; 98140ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard obj->boolval = 0; 98150ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard } 98160ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard xmlXPathFreeObject(obj); 9817f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return(t); 9818d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard} 9819d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard 9820d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard/** 9821f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * xmlXPathNodeCollectAndTestNth: 9822f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * @ctxt: the XPath Parser context 9823f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * @op: the XPath precompiled step operation 9824f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * @indx: the index to collect 9825f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * @first: pointer to the first element in document order 9826f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * @last: pointer to the last element in document order 9827f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * 9828f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * This is the function implementing a step: based on the current list 9829f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * of nodes, it builds up a new list, looking at all nodes under that 9830081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack * axis and selecting them. It also does the predicate filtering 9831f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * 9832f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Pushes the new NodeSet resulting from the search. 9833f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Returns the number of node traversed 9834f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 9835f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillardstatic int 9836f06307e2c172284bb41376c396f757bdac9bdd19Daniel VeillardxmlXPathNodeCollectAndTestNth(xmlXPathParserContextPtr ctxt, 9837f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathStepOpPtr op, int indx, 9838f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlNodePtr * first, xmlNodePtr * last) 9839f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard{ 984078637da0ea1c833dfdfad87a9aa5bea14510d08aWilliam M. Brack xmlXPathAxisVal axis = (xmlXPathAxisVal) op->value; 984178637da0ea1c833dfdfad87a9aa5bea14510d08aWilliam M. Brack xmlXPathTestVal test = (xmlXPathTestVal) op->value2; 984278637da0ea1c833dfdfad87a9aa5bea14510d08aWilliam M. Brack xmlXPathTypeVal type = (xmlXPathTypeVal) op->value3; 9843f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard const xmlChar *prefix = op->value4; 9844f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard const xmlChar *name = op->value5; 9845f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard const xmlChar *URI = NULL; 9846f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard int n = 0, t = 0; 9847f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 9848f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard int i; 9849f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlNodeSetPtr list; 9850f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathTraversalFunction next = NULL; 9851f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard void (*addNode) (xmlNodeSetPtr, xmlNodePtr); 9852f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlNodePtr cur = NULL; 9853f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathObjectPtr obj; 9854f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlNodeSetPtr nodelist; 9855f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlNodePtr tmp; 9856f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 9857f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard CHECK_TYPE0(XPATH_NODESET); 9858f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard obj = valuePop(ctxt); 9859f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard addNode = xmlXPathNodeSetAdd; 9860f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (prefix != NULL) { 9861f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard URI = xmlXPathNsLookup(ctxt->context, prefix); 98622c19a7bf2ee0f78485840cac50f2a989f5efe476William M. Brack if (URI == NULL) { 98632c19a7bf2ee0f78485840cac50f2a989f5efe476William M. Brack xmlXPathFreeObject(obj); 9864f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard XP_ERROR0(XPATH_UNDEF_PREFIX_ERROR); 98652c19a7bf2ee0f78485840cac50f2a989f5efe476William M. Brack } 9866f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9867f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#ifdef DEBUG_STEP_NTH 9868f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, "new step : "); 9869f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (first != NULL) { 9870f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (*first != NULL) 9871f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, "first = %s ", 9872f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (*first)->name); 9873f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard else 9874f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, "first = NULL "); 9875f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9876f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (last != NULL) { 9877f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (*last != NULL) 9878f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, "last = %s ", 9879f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (*last)->name); 9880f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard else 9881f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, "last = NULL "); 9882f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9883f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#endif 9884f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard switch (axis) { 9885f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case AXIS_ANCESTOR: 9886f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#ifdef DEBUG_STEP_NTH 9887f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, "axis 'ancestors' "); 9888f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#endif 9889f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard first = NULL; 9890f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard next = xmlXPathNextAncestor; 9891f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9892f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case AXIS_ANCESTOR_OR_SELF: 9893f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#ifdef DEBUG_STEP_NTH 9894f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, 9895f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard "axis 'ancestors-or-self' "); 9896f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#endif 9897f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard first = NULL; 9898f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard next = xmlXPathNextAncestorOrSelf; 9899f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9900f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case AXIS_ATTRIBUTE: 9901f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#ifdef DEBUG_STEP_NTH 9902f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, "axis 'attributes' "); 9903f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#endif 9904f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard first = NULL; 9905f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard last = NULL; 9906f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard next = xmlXPathNextAttribute; 9907f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9908f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case AXIS_CHILD: 9909f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#ifdef DEBUG_STEP_NTH 9910f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, "axis 'child' "); 9911f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#endif 9912f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard last = NULL; 9913f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard next = xmlXPathNextChild; 9914f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9915f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case AXIS_DESCENDANT: 9916f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#ifdef DEBUG_STEP_NTH 9917f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, "axis 'descendant' "); 9918f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#endif 9919f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard last = NULL; 9920f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard next = xmlXPathNextDescendant; 9921f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9922f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case AXIS_DESCENDANT_OR_SELF: 9923f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#ifdef DEBUG_STEP_NTH 9924f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, 9925f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard "axis 'descendant-or-self' "); 9926f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#endif 9927f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard last = NULL; 9928f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard next = xmlXPathNextDescendantOrSelf; 9929f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9930f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case AXIS_FOLLOWING: 9931f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#ifdef DEBUG_STEP_NTH 9932f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, "axis 'following' "); 9933f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#endif 9934f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard last = NULL; 9935f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard next = xmlXPathNextFollowing; 9936f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9937f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case AXIS_FOLLOWING_SIBLING: 9938f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#ifdef DEBUG_STEP_NTH 9939f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, 9940f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard "axis 'following-siblings' "); 9941f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#endif 9942f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard last = NULL; 9943f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard next = xmlXPathNextFollowingSibling; 9944f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9945f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case AXIS_NAMESPACE: 9946f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#ifdef DEBUG_STEP_NTH 9947f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, "axis 'namespace' "); 9948f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#endif 9949f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard last = NULL; 9950f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard first = NULL; 9951f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard next = (xmlXPathTraversalFunction) xmlXPathNextNamespace; 9952f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9953f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case AXIS_PARENT: 9954f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#ifdef DEBUG_STEP_NTH 9955f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, "axis 'parent' "); 9956f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#endif 9957f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard first = NULL; 9958f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard next = xmlXPathNextParent; 9959f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9960f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case AXIS_PRECEDING: 9961f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#ifdef DEBUG_STEP_NTH 9962f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, "axis 'preceding' "); 9963f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#endif 9964f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard first = NULL; 9965f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard next = xmlXPathNextPrecedingInternal; 9966f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9967f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case AXIS_PRECEDING_SIBLING: 9968f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#ifdef DEBUG_STEP_NTH 9969f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, 9970f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard "axis 'preceding-sibling' "); 9971f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#endif 9972f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard first = NULL; 9973f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard next = xmlXPathNextPrecedingSibling; 9974f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9975f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case AXIS_SELF: 9976f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#ifdef DEBUG_STEP_NTH 9977f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, "axis 'self' "); 9978f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#endif 9979f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard first = NULL; 9980f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard last = NULL; 9981f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard next = xmlXPathNextSelf; 9982f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 9983f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 99842c19a7bf2ee0f78485840cac50f2a989f5efe476William M. Brack if (next == NULL) { 99852c19a7bf2ee0f78485840cac50f2a989f5efe476William M. Brack xmlXPathFreeObject(obj); 9986f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return(0); 99872c19a7bf2ee0f78485840cac50f2a989f5efe476William M. Brack } 9988f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 9989f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard nodelist = obj->nodesetval; 9990f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (nodelist == NULL) { 9991f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathFreeObject(obj); 9992f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard valuePush(ctxt, xmlXPathWrapNodeSet(NULL)); 9993f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return(0); 9994f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 9995f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard addNode = xmlXPathNodeSetAddUnique; 9996f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#ifdef DEBUG_STEP_NTH 9997f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, 9998f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard " context contains %d nodes\n", nodelist->nodeNr); 9999f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard switch (test) { 10000f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case NODE_TEST_NONE: 10001f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, 10002f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard " searching for none !!!\n"); 10003f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 10004f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case NODE_TEST_TYPE: 10005f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, 10006f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard " searching for type %d\n", type); 10007f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 10008f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case NODE_TEST_PI: 10009f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, 10010f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard " searching for PI !!!\n"); 10011f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 10012f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case NODE_TEST_ALL: 10013f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, 10014f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard " searching for *\n"); 10015f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 10016f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case NODE_TEST_NS: 10017f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, 10018f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard " searching for namespace %s\n", 10019f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard prefix); 10020f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 10021f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case NODE_TEST_NAME: 10022f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, 10023f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard " searching for name %s\n", name); 10024f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (prefix != NULL) 10025f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, 10026f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard " with namespace %s\n", prefix); 10027f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 10028f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10029f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, "Testing : "); 10030f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#endif 10031f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* 10032f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * 2.3 Node Tests 10033f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * - For the attribute axis, the principal node type is attribute. 10034f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * - For the namespace axis, the principal node type is namespace. 10035f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * - For other axes, the principal node type is element. 10036f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * 10037f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * A node test * is true for any node of the 10038cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * principal node type. For example, child::* will 10039f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * select all element children of the context node 10040f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 10041f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard tmp = ctxt->context->node; 10042f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard list = xmlXPathNodeSetCreate(NULL); 10043f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard for (i = 0; i < nodelist->nodeNr; i++) { 10044f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->node = nodelist->nodeTab[i]; 10045f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10046f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard cur = NULL; 10047f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard n = 0; 10048f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard do { 10049f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard cur = next(ctxt, cur); 10050f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (cur == NULL) 10051f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 10052f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((first != NULL) && (*first == cur)) 10053f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 10054f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (((t % 256) == 0) && 10055f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (first != NULL) && (*first != NULL) && 10056f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (xmlXPathCmpNodes(*first, cur) >= 0)) 10057f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 10058f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((last != NULL) && (*last == cur)) 10059f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 10060f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (((t % 256) == 0) && 10061f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (last != NULL) && (*last != NULL) && 10062f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (xmlXPathCmpNodes(cur, *last) >= 0)) 10063f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 10064f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard t++; 10065f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard switch (test) { 10066f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case NODE_TEST_NONE: 10067f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->node = tmp; 10068f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard STRANGE return(0); 10069f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case NODE_TEST_TYPE: 10070f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((cur->type == type) || 10071f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ((type == NODE_TYPE_NODE) && 10072f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ((cur->type == XML_DOCUMENT_NODE) || 10073f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (cur->type == XML_HTML_DOCUMENT_NODE) || 10074f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (cur->type == XML_ELEMENT_NODE) || 10075f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (cur->type == XML_PI_NODE) || 10076f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (cur->type == XML_COMMENT_NODE) || 10077f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (cur->type == XML_CDATA_SECTION_NODE) || 100788606bbbc0a04293afd7541033d6a83c4943a6f02Daniel Veillard (cur->type == XML_TEXT_NODE))) || 100798606bbbc0a04293afd7541033d6a83c4943a6f02Daniel Veillard ((type == NODE_TYPE_TEXT) && 100808606bbbc0a04293afd7541033d6a83c4943a6f02Daniel Veillard (cur->type == XML_CDATA_SECTION_NODE))) { 10081f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard n++; 10082f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (n == indx) 10083f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard addNode(list, cur); 10084f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10085f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 10086f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case NODE_TEST_PI: 10087f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (cur->type == XML_PI_NODE) { 10088f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((name != NULL) && 10089f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (!xmlStrEqual(name, cur->name))) 10090f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 10091f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard n++; 10092f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (n == indx) 10093f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard addNode(list, cur); 10094f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10095f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 10096f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case NODE_TEST_ALL: 10097f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (axis == AXIS_ATTRIBUTE) { 10098f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (cur->type == XML_ATTRIBUTE_NODE) { 10099f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard n++; 10100f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (n == indx) 10101f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard addNode(list, cur); 10102f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10103f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } else if (axis == AXIS_NAMESPACE) { 10104f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (cur->type == XML_NAMESPACE_DECL) { 10105f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard n++; 10106f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (n == indx) 10107044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlXPathNodeSetAddNs(list, ctxt->context->node, 10108044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard (xmlNsPtr) cur); 10109f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10110f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } else { 10111f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (cur->type == XML_ELEMENT_NODE) { 10112f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (prefix == NULL) { 10113f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard n++; 10114f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (n == indx) 10115f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard addNode(list, cur); 10116f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } else if ((cur->ns != NULL) && 10117f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (xmlStrEqual(URI, cur->ns->href))) { 10118f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard n++; 10119f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (n == indx) 10120f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard addNode(list, cur); 10121f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10122f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10123f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10124f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 10125f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case NODE_TEST_NS:{ 10126f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard TODO; 10127f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 10128f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10129f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case NODE_TEST_NAME: 10130f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard switch (cur->type) { 10131f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XML_ELEMENT_NODE: 10132f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (xmlStrEqual(name, cur->name)) { 10133f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (prefix == NULL) { 10134f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (cur->ns == NULL) { 10135f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard n++; 10136f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (n == indx) 10137f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard addNode(list, cur); 10138f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10139f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } else { 10140f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((cur->ns != NULL) && 10141f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (xmlStrEqual(URI, 10142f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard cur->ns->href))) { 10143f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard n++; 10144f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (n == indx) 10145f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard addNode(list, cur); 10146f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10147f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10148f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10149f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 10150f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XML_ATTRIBUTE_NODE:{ 10151f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlAttrPtr attr = (xmlAttrPtr) cur; 10152f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10153f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (xmlStrEqual(name, attr->name)) { 10154f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (prefix == NULL) { 10155f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((attr->ns == NULL) || 10156f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (attr->ns->prefix == NULL)) { 10157f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard n++; 10158f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (n == indx) 10159f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard addNode(list, cur); 10160f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10161f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } else { 10162f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((attr->ns != NULL) && 10163f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (xmlStrEqual(URI, 10164f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard attr->ns-> 10165f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard href))) { 10166f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard n++; 10167f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (n == indx) 10168f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard addNode(list, cur); 10169f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10170f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10171f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10172f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 10173f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10174f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XML_NAMESPACE_DECL: 10175f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (cur->type == XML_NAMESPACE_DECL) { 10176f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlNsPtr ns = (xmlNsPtr) cur; 10177f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10178f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((ns->prefix != NULL) && (name != NULL) 10179f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard && (xmlStrEqual(ns->prefix, name))) { 10180f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard n++; 10181f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (n == indx) 10182044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlXPathNodeSetAddNs(list, 10183044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard ctxt->context->node, (xmlNsPtr) cur); 10184f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10185f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10186f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 10187f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard default: 10188f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 10189f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10190f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 10191f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard break; 10192f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10193f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } while (n < indx); 10194f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10195f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->node = tmp; 10196f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#ifdef DEBUG_STEP_NTH 10197f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, 10198f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard "\nExamined %d nodes, found %d nodes at that step\n", 10199f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard t, list->nodeNr); 10200f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#endif 10201f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard valuePush(ctxt, xmlXPathWrapNodeSet(list)); 102020ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard if ((obj->boolval) && (obj->user != NULL)) { 102030ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard ctxt->value->boolval = 1; 102040ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard ctxt->value->user = obj->user; 102050ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard obj->user = NULL; 102060ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard obj->boolval = 0; 102070ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard } 102080ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard xmlXPathFreeObject(obj); 10209f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return(t); 10210f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard} 10211f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10212f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard/** 10213f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * xmlXPathCompOpEvalFirst: 10214d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * @ctxt: the XPath parser context with the compiled expression 10215d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * @op: an XPath compiled operation 10216f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * @first: the first elem found so far 10217d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * 10218f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Evaluate the Precompiled XPath operation searching only the first 10219f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * element in document order 10220f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * 10221f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Returns the number of examined objects. 10222d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard */ 10223f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillardstatic int 10224f06307e2c172284bb41376c396f757bdac9bdd19Daniel VeillardxmlXPathCompOpEvalFirst(xmlXPathParserContextPtr ctxt, 10225f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathStepOpPtr op, xmlNodePtr * first) 10226f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard{ 10227f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard int total = 0, cur; 10228d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard xmlXPathCompExprPtr comp; 10229d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard xmlXPathObjectPtr arg1, arg2; 10230d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard 10231556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 10232d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard comp = ctxt->comp; 10233d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard switch (op->op) { 10234f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_END: 10235f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (0); 10236f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_UNION: 10237f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total = 10238f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathCompOpEvalFirst(ctxt, &comp->steps[op->ch1], 10239f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard first); 10240556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 10241f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((ctxt->value != NULL) 10242f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard && (ctxt->value->type == XPATH_NODESET) 10243f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard && (ctxt->value->nodesetval != NULL) 10244f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard && (ctxt->value->nodesetval->nodeNr >= 1)) { 10245f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* 10246f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * limit tree traversing to first node in the result 10247f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 10248f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathNodeSetSort(ctxt->value->nodesetval); 10249f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard *first = ctxt->value->nodesetval->nodeTab[0]; 10250f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10251f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard cur = 10252f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathCompOpEvalFirst(ctxt, &comp->steps[op->ch2], 10253f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard first); 10254556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 10255f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard CHECK_TYPE0(XPATH_NODESET); 10256f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard arg2 = valuePop(ctxt); 10257f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10258f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard CHECK_TYPE0(XPATH_NODESET); 10259f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard arg1 = valuePop(ctxt); 10260f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10261f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard arg1->nodesetval = xmlXPathNodeSetMerge(arg1->nodesetval, 10262f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard arg2->nodesetval); 10263f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard valuePush(ctxt, arg1); 10264f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathFreeObject(arg2); 10265f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* optimizer */ 10266f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (total > cur) 10267f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathCompSwap(op); 10268f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total + cur); 10269f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_ROOT: 10270f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathRoot(ctxt); 10271f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (0); 10272f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_NODE: 10273f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch1 != -1) 10274f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]); 10275556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 10276f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch2 != -1) 10277f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]); 10278556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 10279f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard valuePush(ctxt, xmlXPathNewNodeSet(ctxt->context->node)); 10280f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 10281f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_RESET: 10282f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch1 != -1) 10283f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]); 10284556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 10285f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch2 != -1) 10286f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]); 10287556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 10288f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->node = NULL; 10289f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 10290f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_COLLECT:{ 10291f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch1 == -1) 10292f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 10293f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10294f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total = xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]); 10295556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 10296f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10297f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* 10298f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Optimization for [n] selection where n is a number 10299f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 10300f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((op->ch2 != -1) && 10301f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (comp->steps[op->ch2].op == XPATH_OP_PREDICATE) && 10302f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (comp->steps[op->ch2].ch1 == -1) && 10303f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (comp->steps[op->ch2].ch2 != -1) && 10304f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (comp->steps[comp->steps[op->ch2].ch2].op == 10305f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard XPATH_OP_VALUE)) { 10306f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathObjectPtr val; 10307f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10308f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard val = comp->steps[comp->steps[op->ch2].ch2].value4; 10309f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((val != NULL) && (val->type == XPATH_NUMBER)) { 10310f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard int indx = (int) val->floatval; 10311f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10312f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (val->floatval == (float) indx) { 10313f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathNodeCollectAndTestNth(ctxt, op, indx, 10314f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard first, NULL); 10315f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 10316f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10317f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10318f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10319f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathNodeCollectAndTest(ctxt, op, first, NULL); 10320f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 10321f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10322f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_VALUE: 10323f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard valuePush(ctxt, 10324f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathObjectCopy((xmlXPathObjectPtr) op->value4)); 10325f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (0); 10326f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_SORT: 10327f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch1 != -1) 10328f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += 10329f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathCompOpEvalFirst(ctxt, &comp->steps[op->ch1], 10330f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard first); 10331556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 10332f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((ctxt->value != NULL) 10333f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard && (ctxt->value->type == XPATH_NODESET) 10334f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard && (ctxt->value->nodesetval != NULL)) 10335f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathNodeSetSort(ctxt->value->nodesetval); 10336f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 10337f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard default: 10338f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (xmlXPathCompOpEval(ctxt, op)); 10339f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10340f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard} 1034142596ad20cdf1925dd79ea801cbe598b6e7b7aecDaniel Veillard 10342f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard/** 10343f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * xmlXPathCompOpEvalLast: 10344f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * @ctxt: the XPath parser context with the compiled expression 10345f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * @op: an XPath compiled operation 10346f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * @last: the last elem found so far 10347f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * 10348f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Evaluate the Precompiled XPath operation searching only the last 10349f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * element in document order 10350f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * 10351081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack * Returns the number of nodes traversed 10352f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 10353f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillardstatic int 10354f06307e2c172284bb41376c396f757bdac9bdd19Daniel VeillardxmlXPathCompOpEvalLast(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op, 10355f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlNodePtr * last) 10356f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard{ 10357f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard int total = 0, cur; 10358f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathCompExprPtr comp; 10359f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathObjectPtr arg1, arg2; 10360ce4fc56e1b56253ae794b47515948f3bc3142024William M. Brack xmlNodePtr bak; 10361ce4fc56e1b56253ae794b47515948f3bc3142024William M. Brack xmlDocPtr bakd; 10362ce4fc56e1b56253ae794b47515948f3bc3142024William M. Brack int pp; 10363ce4fc56e1b56253ae794b47515948f3bc3142024William M. Brack int cs; 103649e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 10365556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 10366f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard comp = ctxt->comp; 10367f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard switch (op->op) { 10368f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_END: 10369f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (0); 10370f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_UNION: 10371ce4fc56e1b56253ae794b47515948f3bc3142024William M. Brack bakd = ctxt->context->doc; 10372ce4fc56e1b56253ae794b47515948f3bc3142024William M. Brack bak = ctxt->context->node; 10373ce4fc56e1b56253ae794b47515948f3bc3142024William M. Brack pp = ctxt->context->proximityPosition; 10374ce4fc56e1b56253ae794b47515948f3bc3142024William M. Brack cs = ctxt->context->contextSize; 10375f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total = 10376f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathCompOpEvalLast(ctxt, &comp->steps[op->ch1], last); 10377556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 10378f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((ctxt->value != NULL) 10379f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard && (ctxt->value->type == XPATH_NODESET) 10380f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard && (ctxt->value->nodesetval != NULL) 10381f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard && (ctxt->value->nodesetval->nodeNr >= 1)) { 10382f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* 10383f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * limit tree traversing to first node in the result 10384f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 10385f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathNodeSetSort(ctxt->value->nodesetval); 10386f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard *last = 10387f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->value->nodesetval->nodeTab[ctxt->value-> 10388f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard nodesetval->nodeNr - 10389f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 1]; 10390f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10391ce4fc56e1b56253ae794b47515948f3bc3142024William M. Brack ctxt->context->doc = bakd; 10392ce4fc56e1b56253ae794b47515948f3bc3142024William M. Brack ctxt->context->node = bak; 10393ce4fc56e1b56253ae794b47515948f3bc3142024William M. Brack ctxt->context->proximityPosition = pp; 10394ce4fc56e1b56253ae794b47515948f3bc3142024William M. Brack ctxt->context->contextSize = cs; 10395f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard cur = 10396f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathCompOpEvalLast(ctxt, &comp->steps[op->ch2], last); 10397556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 10398f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((ctxt->value != NULL) 10399f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard && (ctxt->value->type == XPATH_NODESET) 10400f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard && (ctxt->value->nodesetval != NULL) 10401f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard && (ctxt->value->nodesetval->nodeNr >= 1)) { 10402f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10403f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard CHECK_TYPE0(XPATH_NODESET); 10404f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard arg2 = valuePop(ctxt); 10405f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10406f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard CHECK_TYPE0(XPATH_NODESET); 10407f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard arg1 = valuePop(ctxt); 10408f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10409f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard arg1->nodesetval = xmlXPathNodeSetMerge(arg1->nodesetval, 10410f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard arg2->nodesetval); 10411f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard valuePush(ctxt, arg1); 10412f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathFreeObject(arg2); 10413f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* optimizer */ 10414f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (total > cur) 10415f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathCompSwap(op); 10416f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total + cur); 10417f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_ROOT: 10418f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathRoot(ctxt); 10419f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (0); 10420f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_NODE: 10421f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch1 != -1) 10422f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]); 10423556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 10424f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch2 != -1) 10425f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]); 10426556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 10427f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard valuePush(ctxt, xmlXPathNewNodeSet(ctxt->context->node)); 10428f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 10429f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_RESET: 10430f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch1 != -1) 10431f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]); 10432556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 10433f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch2 != -1) 10434f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]); 10435556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 10436f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->node = NULL; 10437f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 10438f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_COLLECT:{ 10439f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch1 == -1) 10440f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (0); 10441f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10442f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]); 10443556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 10444f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10445f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* 10446f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Optimization for [n] selection where n is a number 10447f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 10448f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((op->ch2 != -1) && 10449f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (comp->steps[op->ch2].op == XPATH_OP_PREDICATE) && 10450f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (comp->steps[op->ch2].ch1 == -1) && 10451f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (comp->steps[op->ch2].ch2 != -1) && 10452f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (comp->steps[comp->steps[op->ch2].ch2].op == 10453f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard XPATH_OP_VALUE)) { 10454f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathObjectPtr val; 10455f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10456f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard val = comp->steps[comp->steps[op->ch2].ch2].value4; 10457f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((val != NULL) && (val->type == XPATH_NUMBER)) { 10458f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard int indx = (int) val->floatval; 10459f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10460f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (val->floatval == (float) indx) { 10461f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += 10462f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathNodeCollectAndTestNth(ctxt, op, 10463f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard indx, NULL, 10464f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard last); 10465f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 10466f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10467f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10468f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10469f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathNodeCollectAndTest(ctxt, op, NULL, last); 10470f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 10471f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10472f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_VALUE: 10473f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard valuePush(ctxt, 10474f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathObjectCopy((xmlXPathObjectPtr) op->value4)); 10475f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (0); 10476f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_SORT: 10477f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch1 != -1) 10478f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += 10479f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathCompOpEvalLast(ctxt, &comp->steps[op->ch1], 10480f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard last); 10481556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 10482f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((ctxt->value != NULL) 10483f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard && (ctxt->value->type == XPATH_NODESET) 10484f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard && (ctxt->value->nodesetval != NULL)) 10485f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathNodeSetSort(ctxt->value->nodesetval); 10486f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 10487f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard default: 10488f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (xmlXPathCompOpEval(ctxt, op)); 10489f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10490f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard} 104919e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 10492f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard/** 10493f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * xmlXPathCompOpEval: 10494f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * @ctxt: the XPath parser context with the compiled expression 10495f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * @op: an XPath compiled operation 10496f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * 10497f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Evaluate the Precompiled XPath operation 10498081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack * Returns the number of nodes traversed 10499f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 10500f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillardstatic int 10501f06307e2c172284bb41376c396f757bdac9bdd19Daniel VeillardxmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op) 10502f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard{ 10503f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard int total = 0; 10504f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard int equal, ret; 10505f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathCompExprPtr comp; 10506f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathObjectPtr arg1, arg2; 105077089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard xmlNodePtr bak; 105087089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard xmlDocPtr bakd; 105096000af549b49464a3b1947fc582998a1c9ff7c79William M. Brack int pp; 10510692092b5886073a8cd1c97bb7d57579e4a9cfc3fWilliam M. Brack int cs; 105119e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 10512556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 10513f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard comp = ctxt->comp; 10514f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard switch (op->op) { 10515f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_END: 10516f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (0); 10517f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_AND: 105187089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard bakd = ctxt->context->doc; 105197089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard bak = ctxt->context->node; 105206000af549b49464a3b1947fc582998a1c9ff7c79William M. Brack pp = ctxt->context->proximityPosition; 10521692092b5886073a8cd1c97bb7d57579e4a9cfc3fWilliam M. Brack cs = ctxt->context->contextSize; 10522f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]); 10523556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 10524f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathBooleanFunction(ctxt, 1); 10525f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((ctxt->value == NULL) || (ctxt->value->boolval == 0)) 10526f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 10527f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard arg2 = valuePop(ctxt); 105287089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard ctxt->context->doc = bakd; 105297089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard ctxt->context->node = bak; 105306000af549b49464a3b1947fc582998a1c9ff7c79William M. Brack ctxt->context->proximityPosition = pp; 10531692092b5886073a8cd1c97bb7d57579e4a9cfc3fWilliam M. Brack ctxt->context->contextSize = cs; 10532f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]); 10533556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard if (ctxt->error) { 10534556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard xmlXPathFreeObject(arg2); 10535556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard return(0); 10536556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard } 10537f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathBooleanFunction(ctxt, 1); 10538f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard arg1 = valuePop(ctxt); 10539f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard arg1->boolval &= arg2->boolval; 10540f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard valuePush(ctxt, arg1); 10541f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathFreeObject(arg2); 10542f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 10543f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_OR: 105447089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard bakd = ctxt->context->doc; 105457089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard bak = ctxt->context->node; 105466000af549b49464a3b1947fc582998a1c9ff7c79William M. Brack pp = ctxt->context->proximityPosition; 10547692092b5886073a8cd1c97bb7d57579e4a9cfc3fWilliam M. Brack cs = ctxt->context->contextSize; 10548f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]); 10549556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 10550f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathBooleanFunction(ctxt, 1); 10551f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((ctxt->value == NULL) || (ctxt->value->boolval == 1)) 10552f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 10553f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard arg2 = valuePop(ctxt); 105547089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard ctxt->context->doc = bakd; 105557089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard ctxt->context->node = bak; 105566000af549b49464a3b1947fc582998a1c9ff7c79William M. Brack ctxt->context->proximityPosition = pp; 10557692092b5886073a8cd1c97bb7d57579e4a9cfc3fWilliam M. Brack ctxt->context->contextSize = cs; 10558f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]); 10559556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard if (ctxt->error) { 10560556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard xmlXPathFreeObject(arg2); 10561556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard return(0); 10562556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard } 10563f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathBooleanFunction(ctxt, 1); 10564f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard arg1 = valuePop(ctxt); 10565f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard arg1->boolval |= arg2->boolval; 10566f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard valuePush(ctxt, arg1); 10567f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathFreeObject(arg2); 10568f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 10569f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_EQUAL: 105707089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard bakd = ctxt->context->doc; 105717089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard bak = ctxt->context->node; 105726000af549b49464a3b1947fc582998a1c9ff7c79William M. Brack pp = ctxt->context->proximityPosition; 10573692092b5886073a8cd1c97bb7d57579e4a9cfc3fWilliam M. Brack cs = ctxt->context->contextSize; 10574f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]); 10575556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 105767089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard ctxt->context->doc = bakd; 105777089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard ctxt->context->node = bak; 105786000af549b49464a3b1947fc582998a1c9ff7c79William M. Brack ctxt->context->proximityPosition = pp; 10579692092b5886073a8cd1c97bb7d57579e4a9cfc3fWilliam M. Brack ctxt->context->contextSize = cs; 10580f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]); 10581556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 105820c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack if (op->value) 105830c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack equal = xmlXPathEqualValues(ctxt); 105840c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack else 105850c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack equal = xmlXPathNotEqualValues(ctxt); 105860c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack valuePush(ctxt, xmlXPathNewBoolean(equal)); 10587f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 10588f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_CMP: 105897089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard bakd = ctxt->context->doc; 105907089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard bak = ctxt->context->node; 105916000af549b49464a3b1947fc582998a1c9ff7c79William M. Brack pp = ctxt->context->proximityPosition; 10592692092b5886073a8cd1c97bb7d57579e4a9cfc3fWilliam M. Brack cs = ctxt->context->contextSize; 10593f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]); 10594556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 105957089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard ctxt->context->doc = bakd; 105967089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard ctxt->context->node = bak; 105976000af549b49464a3b1947fc582998a1c9ff7c79William M. Brack ctxt->context->proximityPosition = pp; 10598692092b5886073a8cd1c97bb7d57579e4a9cfc3fWilliam M. Brack ctxt->context->contextSize = cs; 10599f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]); 10600556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 10601f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ret = xmlXPathCompareValues(ctxt, op->value, op->value2); 10602f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard valuePush(ctxt, xmlXPathNewBoolean(ret)); 10603f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 10604f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_PLUS: 106057089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard bakd = ctxt->context->doc; 106067089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard bak = ctxt->context->node; 106076000af549b49464a3b1947fc582998a1c9ff7c79William M. Brack pp = ctxt->context->proximityPosition; 10608692092b5886073a8cd1c97bb7d57579e4a9cfc3fWilliam M. Brack cs = ctxt->context->contextSize; 10609f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]); 10610556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 106117089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard if (op->ch2 != -1) { 106127089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard ctxt->context->doc = bakd; 106137089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard ctxt->context->node = bak; 106146000af549b49464a3b1947fc582998a1c9ff7c79William M. Brack ctxt->context->proximityPosition = pp; 10615692092b5886073a8cd1c97bb7d57579e4a9cfc3fWilliam M. Brack ctxt->context->contextSize = cs; 10616f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]); 106177089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard } 10618556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 10619f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->value == 0) 10620f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathSubValues(ctxt); 10621f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard else if (op->value == 1) 10622f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathAddValues(ctxt); 10623f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard else if (op->value == 2) 10624f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathValueFlipSign(ctxt); 10625f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard else if (op->value == 3) { 10626f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard CAST_TO_NUMBER; 10627f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard CHECK_TYPE0(XPATH_NUMBER); 10628f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10629f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 10630f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_MULT: 106317089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard bakd = ctxt->context->doc; 106327089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard bak = ctxt->context->node; 106336000af549b49464a3b1947fc582998a1c9ff7c79William M. Brack pp = ctxt->context->proximityPosition; 10634692092b5886073a8cd1c97bb7d57579e4a9cfc3fWilliam M. Brack cs = ctxt->context->contextSize; 10635f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]); 10636556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 106377089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard ctxt->context->doc = bakd; 106387089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard ctxt->context->node = bak; 106396000af549b49464a3b1947fc582998a1c9ff7c79William M. Brack ctxt->context->proximityPosition = pp; 10640692092b5886073a8cd1c97bb7d57579e4a9cfc3fWilliam M. Brack ctxt->context->contextSize = cs; 10641f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]); 10642556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 10643f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->value == 0) 10644f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathMultValues(ctxt); 10645f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard else if (op->value == 1) 10646f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathDivValues(ctxt); 10647f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard else if (op->value == 2) 10648f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathModValues(ctxt); 10649f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 10650f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_UNION: 106517089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard bakd = ctxt->context->doc; 106527089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard bak = ctxt->context->node; 106536000af549b49464a3b1947fc582998a1c9ff7c79William M. Brack pp = ctxt->context->proximityPosition; 10654692092b5886073a8cd1c97bb7d57579e4a9cfc3fWilliam M. Brack cs = ctxt->context->contextSize; 10655f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]); 10656556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 106577089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard ctxt->context->doc = bakd; 106587089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard ctxt->context->node = bak; 106596000af549b49464a3b1947fc582998a1c9ff7c79William M. Brack ctxt->context->proximityPosition = pp; 10660692092b5886073a8cd1c97bb7d57579e4a9cfc3fWilliam M. Brack ctxt->context->contextSize = cs; 10661f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]); 10662556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 10663f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard CHECK_TYPE0(XPATH_NODESET); 10664f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard arg2 = valuePop(ctxt); 10665f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10666f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard CHECK_TYPE0(XPATH_NODESET); 10667f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard arg1 = valuePop(ctxt); 10668f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10669f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard arg1->nodesetval = xmlXPathNodeSetMerge(arg1->nodesetval, 10670f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard arg2->nodesetval); 10671f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard valuePush(ctxt, arg1); 10672f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathFreeObject(arg2); 10673f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 10674f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_ROOT: 10675f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathRoot(ctxt); 10676f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 10677f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_NODE: 10678f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch1 != -1) 10679f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]); 10680556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 10681f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch2 != -1) 10682f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]); 10683556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 10684f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard valuePush(ctxt, xmlXPathNewNodeSet(ctxt->context->node)); 10685f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 10686f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_RESET: 10687f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch1 != -1) 10688f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]); 10689556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 10690f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch2 != -1) 10691f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]); 10692556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 10693f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->node = NULL; 10694f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 10695f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_COLLECT:{ 10696f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch1 == -1) 10697f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 10698f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10699f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]); 10700556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 10701f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10702f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* 10703f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Optimization for [n] selection where n is a number 10704f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 10705f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((op->ch2 != -1) && 10706f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (comp->steps[op->ch2].op == XPATH_OP_PREDICATE) && 10707f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (comp->steps[op->ch2].ch1 == -1) && 10708f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (comp->steps[op->ch2].ch2 != -1) && 10709f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (comp->steps[comp->steps[op->ch2].ch2].op == 10710f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard XPATH_OP_VALUE)) { 10711f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathObjectPtr val; 10712f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10713f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard val = comp->steps[comp->steps[op->ch2].ch2].value4; 10714f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((val != NULL) && (val->type == XPATH_NUMBER)) { 10715f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard int indx = (int) val->floatval; 10716f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10717f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (val->floatval == (float) indx) { 10718f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += 10719f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathNodeCollectAndTestNth(ctxt, op, 10720f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard indx, NULL, 10721f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard NULL); 10722f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 10723f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10724f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10725f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10726f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathNodeCollectAndTest(ctxt, op, NULL, NULL); 10727f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 10728f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10729f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_VALUE: 10730f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard valuePush(ctxt, 10731f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathObjectCopy((xmlXPathObjectPtr) op->value4)); 10732f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 10733f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_VARIABLE:{ 10734556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard xmlXPathObjectPtr val; 10735556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard 10736f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch1 != -1) 10737f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += 10738f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]); 10739556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard if (op->value5 == NULL) { 10740556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard val = xmlXPathVariableLookup(ctxt->context, op->value4); 10741556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard if (val == NULL) { 10742556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard ctxt->error = XPATH_UNDEF_VARIABLE_ERROR; 10743556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard return(0); 10744556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard } 10745556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard valuePush(ctxt, val); 10746556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard } else { 10747f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard const xmlChar *URI; 10748f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10749f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard URI = xmlXPathNsLookup(ctxt->context, op->value5); 10750f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (URI == NULL) { 10751f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, 10752cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard "xmlXPathCompOpEval: variable %s bound to undefined prefix %s\n", 10753f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard op->value4, op->value5); 10754f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 10755f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10756556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard val = xmlXPathVariableLookupNS(ctxt->context, 10757556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard op->value4, URI); 10758556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard if (val == NULL) { 10759556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard ctxt->error = XPATH_UNDEF_VARIABLE_ERROR; 10760556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard return(0); 10761556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard } 10762556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard valuePush(ctxt, val); 10763f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10764f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 10765f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10766f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_FUNCTION:{ 10767f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathFunction func; 10768f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard const xmlChar *oldFunc, *oldFuncURI; 10769556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard int i; 10770f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10771f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch1 != -1) 10772f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += 10773f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]); 10774556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard if (ctxt->valueNr < op->value) { 10775556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, 10776cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard "xmlXPathCompOpEval: parameter error\n"); 10777556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard ctxt->error = XPATH_INVALID_OPERAND; 10778556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard return (total); 10779556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard } 10780556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard for (i = 0; i < op->value; i++) 10781556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard if (ctxt->valueTab[(ctxt->valueNr - 1) - i] == NULL) { 10782556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, 10783cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard "xmlXPathCompOpEval: parameter error\n"); 10784556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard ctxt->error = XPATH_INVALID_OPERAND; 10785556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard return (total); 10786556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard } 10787f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->cache != NULL) 10788ad0e67c57f26f691fc120d5c5336cee9885cf324William M. Brack XML_CAST_FPTR(func) = op->cache; 10789f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard else { 10790f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard const xmlChar *URI = NULL; 10791f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10792f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->value5 == NULL) 10793f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard func = 10794f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathFunctionLookup(ctxt->context, 10795f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard op->value4); 10796f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard else { 10797f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard URI = xmlXPathNsLookup(ctxt->context, op->value5); 10798f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (URI == NULL) { 10799f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, 10800cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard "xmlXPathCompOpEval: function %s bound to undefined prefix %s\n", 10801f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard op->value4, op->value5); 10802f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 10803f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10804f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard func = xmlXPathFunctionLookupNS(ctxt->context, 10805f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard op->value4, URI); 10806f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10807f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (func == NULL) { 10808f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlGenericError(xmlGenericErrorContext, 10809cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard "xmlXPathCompOpEval: function %s not found\n", 10810f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard op->value4); 10811f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard XP_ERROR0(XPATH_UNKNOWN_FUNC_ERROR); 10812f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10813ad0e67c57f26f691fc120d5c5336cee9885cf324William M. Brack op->cache = XML_CAST_FPTR(func); 10814f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard op->cacheURI = (void *) URI; 10815f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10816f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard oldFunc = ctxt->context->function; 10817f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard oldFuncURI = ctxt->context->functionURI; 10818f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->function = op->value4; 10819f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->functionURI = op->cacheURI; 10820f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard func(ctxt, op->value); 10821f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->function = oldFunc; 10822f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->functionURI = oldFuncURI; 10823f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 10824f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10825f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_ARG: 10826088bf1163080cbbb72ba9d4a52ab08cc7c8ff6c7Daniel Veillard bakd = ctxt->context->doc; 10827088bf1163080cbbb72ba9d4a52ab08cc7c8ff6c7Daniel Veillard bak = ctxt->context->node; 10828645a924a9d50d8e0eced5dd7277214a65756c2e1William M. Brack pp = ctxt->context->proximityPosition; 10829645a924a9d50d8e0eced5dd7277214a65756c2e1William M. Brack cs = ctxt->context->contextSize; 10830f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch1 != -1) 10831f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]); 10832645a924a9d50d8e0eced5dd7277214a65756c2e1William M. Brack ctxt->context->contextSize = cs; 10833645a924a9d50d8e0eced5dd7277214a65756c2e1William M. Brack ctxt->context->proximityPosition = pp; 10834088bf1163080cbbb72ba9d4a52ab08cc7c8ff6c7Daniel Veillard ctxt->context->node = bak; 10835645a924a9d50d8e0eced5dd7277214a65756c2e1William M. Brack ctxt->context->doc = bakd; 10836556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 1083772ee48d55f9002544d011826e2897b5054b7e32cWilliam M. Brack if (op->ch2 != -1) { 10838f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]); 1083972ee48d55f9002544d011826e2897b5054b7e32cWilliam M. Brack ctxt->context->doc = bakd; 1084072ee48d55f9002544d011826e2897b5054b7e32cWilliam M. Brack ctxt->context->node = bak; 1084172ee48d55f9002544d011826e2897b5054b7e32cWilliam M. Brack CHECK_ERROR0; 1084272ee48d55f9002544d011826e2897b5054b7e32cWilliam M. Brack } 10843f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 10844f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_PREDICATE: 10845f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_FILTER:{ 10846f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathObjectPtr res; 10847f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathObjectPtr obj, tmp; 10848f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlNodeSetPtr newset = NULL; 10849f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlNodeSetPtr oldset; 10850f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlNodePtr oldnode; 108513794b9e84ac51072830a0b34d1ddd0378c0f7cb6William M. Brack xmlDocPtr oldDoc; 10852f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard int i; 10853f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10854f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* 10855f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Optimization for ()[1] selection i.e. the first elem 10856f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 10857f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((op->ch1 != -1) && (op->ch2 != -1) && 10858f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (comp->steps[op->ch1].op == XPATH_OP_SORT) && 10859f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (comp->steps[op->ch2].op == XPATH_OP_VALUE)) { 10860f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathObjectPtr val; 10861f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10862f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard val = comp->steps[op->ch2].value4; 10863f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((val != NULL) && (val->type == XPATH_NUMBER) && 10864f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (val->floatval == 1.0)) { 10865f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlNodePtr first = NULL; 10866f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10867f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += 10868f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathCompOpEvalFirst(ctxt, 10869f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard &comp->steps[op->ch1], 10870f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard &first); 10871556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 10872f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* 10873f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * The nodeset should be in document order, 10874f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Keep only the first value 10875f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 10876f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((ctxt->value != NULL) && 10877f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (ctxt->value->type == XPATH_NODESET) && 10878f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (ctxt->value->nodesetval != NULL) && 10879f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (ctxt->value->nodesetval->nodeNr > 1)) 10880f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->value->nodesetval->nodeNr = 1; 10881f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 10882f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10883f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10884f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* 10885f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Optimization for ()[last()] selection i.e. the last elem 10886f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 10887f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((op->ch1 != -1) && (op->ch2 != -1) && 10888f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (comp->steps[op->ch1].op == XPATH_OP_SORT) && 10889f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (comp->steps[op->ch2].op == XPATH_OP_SORT)) { 10890f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard int f = comp->steps[op->ch2].ch1; 10891f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10892f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((f != -1) && 10893f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (comp->steps[f].op == XPATH_OP_FUNCTION) && 10894f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (comp->steps[f].value5 == NULL) && 10895f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (comp->steps[f].value == 0) && 10896f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (comp->steps[f].value4 != NULL) && 10897f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (xmlStrEqual 10898f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (comp->steps[f].value4, BAD_CAST "last"))) { 10899f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlNodePtr last = NULL; 10900f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10901f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += 10902f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathCompOpEvalLast(ctxt, 10903f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard &comp->steps[op->ch1], 10904f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard &last); 10905556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 10906f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* 10907f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * The nodeset should be in document order, 10908f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Keep only the last value 10909f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 10910f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((ctxt->value != NULL) && 10911f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (ctxt->value->type == XPATH_NODESET) && 10912f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (ctxt->value->nodesetval != NULL) && 10913f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (ctxt->value->nodesetval->nodeTab != NULL) && 10914f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (ctxt->value->nodesetval->nodeNr > 1)) { 10915f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->value->nodesetval->nodeTab[0] = 10916f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->value->nodesetval->nodeTab[ctxt-> 10917f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard value-> 10918f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard nodesetval-> 10919f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard nodeNr - 10920f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 1]; 10921f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->value->nodesetval->nodeNr = 1; 10922f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10923f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 10924f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10925f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10926f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10927f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch1 != -1) 10928f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += 10929f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]); 10930556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 10931f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch2 == -1) 10932f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 10933f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (ctxt->value == NULL) 10934f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 10935f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10936f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard oldnode = ctxt->context->node; 109379e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 10938f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#ifdef LIBXML_XPTR_ENABLED 10939f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* 10940f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Hum are we filtering the result of an XPointer expression 10941f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 10942f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (ctxt->value->type == XPATH_LOCATIONSET) { 10943f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlLocationSetPtr newlocset = NULL; 10944f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlLocationSetPtr oldlocset; 10945f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10946f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* 10947f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Extract the old locset, and then evaluate the result of the 10948f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * expression for all the element in the locset. use it to grow 10949f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * up a new locset. 10950f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 10951f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard CHECK_TYPE0(XPATH_LOCATIONSET); 10952f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard obj = valuePop(ctxt); 10953f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard oldlocset = obj->user; 10954f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->node = NULL; 10955f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10956f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((oldlocset == NULL) || (oldlocset->locNr == 0)) { 10957f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->contextSize = 0; 10958f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->proximityPosition = 0; 10959f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch2 != -1) 10960f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += 10961f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathCompOpEval(ctxt, 10962f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard &comp->steps[op->ch2]); 10963f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard res = valuePop(ctxt); 10964f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (res != NULL) 10965f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathFreeObject(res); 10966f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard valuePush(ctxt, obj); 10967f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard CHECK_ERROR0; 10968f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 10969f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 10970f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard newlocset = xmlXPtrLocationSetCreate(NULL); 10971f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10972f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard for (i = 0; i < oldlocset->locNr; i++) { 10973f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* 10974f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Run the evaluation with a node list made of a 10975f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * single item in the nodelocset. 10976f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 10977f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->node = oldlocset->locTab[i]->user; 10978f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->contextSize = oldlocset->locNr; 10979f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->proximityPosition = i + 1; 10980f7eb794c142e31ca895f2d7743f872a809e514abWilliam M. Brack tmp = xmlXPathNewNodeSet(ctxt->context->node); 10981f7eb794c142e31ca895f2d7743f872a809e514abWilliam M. Brack valuePush(ctxt, tmp); 10982f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10983f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch2 != -1) 10984f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += 10985f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathCompOpEval(ctxt, 10986f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard &comp->steps[op->ch2]); 109872c19a7bf2ee0f78485840cac50f2a989f5efe476William M. Brack if (ctxt->error != XPATH_EXPRESSION_OK) { 109882c19a7bf2ee0f78485840cac50f2a989f5efe476William M. Brack xmlXPathFreeObject(obj); 109892c19a7bf2ee0f78485840cac50f2a989f5efe476William M. Brack return(0); 109902c19a7bf2ee0f78485840cac50f2a989f5efe476William M. Brack } 10991f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 10992f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* 10993f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * The result of the evaluation need to be tested to 10994f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * decided whether the filter succeeded or not 10995f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 10996f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard res = valuePop(ctxt); 10997f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (xmlXPathEvaluatePredicateResult(ctxt, res)) { 10998f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPtrLocationSetAdd(newlocset, 10999f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathObjectCopy 11000f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (oldlocset->locTab[i])); 11001f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 11002f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 11003f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* 11004f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Cleanup 11005f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 11006f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (res != NULL) 11007f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathFreeObject(res); 11008f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (ctxt->value == tmp) { 11009f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard res = valuePop(ctxt); 11010f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathFreeObject(res); 11011f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 11012f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 11013f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->node = NULL; 11014f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 11015f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 11016f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* 11017f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * The result is used as the new evaluation locset. 11018f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 11019f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathFreeObject(obj); 11020f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->node = NULL; 11021f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->contextSize = -1; 11022f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->proximityPosition = -1; 11023f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard valuePush(ctxt, xmlXPtrWrapLocationSet(newlocset)); 11024f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->node = oldnode; 11025f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 11026f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 110279e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard#endif /* LIBXML_XPTR_ENABLED */ 110289e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 11029f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* 11030f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Extract the old set, and then evaluate the result of the 11031f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * expression for all the element in the set. use it to grow 11032f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * up a new set. 11033f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 11034f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard CHECK_TYPE0(XPATH_NODESET); 11035f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard obj = valuePop(ctxt); 11036f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard oldset = obj->nodesetval; 11037f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 11038f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard oldnode = ctxt->context->node; 110393794b9e84ac51072830a0b34d1ddd0378c0f7cb6William M. Brack oldDoc = ctxt->context->doc; 11040f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->node = NULL; 11041f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 11042f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((oldset == NULL) || (oldset->nodeNr == 0)) { 11043f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->contextSize = 0; 11044f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->proximityPosition = 0; 110458fad8bff2c2e0b064a6d48d4eeb663804de5545fWilliam M. Brack/* 11046f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch2 != -1) 11047f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += 11048f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathCompOpEval(ctxt, 11049f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard &comp->steps[op->ch2]); 11050556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 11051f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard res = valuePop(ctxt); 11052f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (res != NULL) 11053f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathFreeObject(res); 110548fad8bff2c2e0b064a6d48d4eeb663804de5545fWilliam M. Brack*/ 11055f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard valuePush(ctxt, obj); 11056f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->node = oldnode; 11057f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard CHECK_ERROR0; 11058f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } else { 11059f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* 11060f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Initialize the new set. 110613794b9e84ac51072830a0b34d1ddd0378c0f7cb6William M. Brack * Also set the xpath document in case things like 110623794b9e84ac51072830a0b34d1ddd0378c0f7cb6William M. Brack * key() evaluation are attempted on the predicate 11063f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 11064f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard newset = xmlXPathNodeSetCreate(NULL); 11065f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 11066f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard for (i = 0; i < oldset->nodeNr; i++) { 11067f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* 11068f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Run the evaluation with a node list made of 11069f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * a single item in the nodeset. 11070f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 11071f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->node = oldset->nodeTab[i]; 110723794b9e84ac51072830a0b34d1ddd0378c0f7cb6William M. Brack if ((oldset->nodeTab[i]->type != XML_NAMESPACE_DECL) && 110733794b9e84ac51072830a0b34d1ddd0378c0f7cb6William M. Brack (oldset->nodeTab[i]->doc != NULL)) 110743794b9e84ac51072830a0b34d1ddd0378c0f7cb6William M. Brack ctxt->context->doc = oldset->nodeTab[i]->doc; 11075f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard tmp = xmlXPathNewNodeSet(ctxt->context->node); 11076f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard valuePush(ctxt, tmp); 11077f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->contextSize = oldset->nodeNr; 11078f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->proximityPosition = i + 1; 11079f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 11080f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch2 != -1) 11081f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += 11082f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathCompOpEval(ctxt, 11083f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard &comp->steps[op->ch2]); 110842c19a7bf2ee0f78485840cac50f2a989f5efe476William M. Brack if (ctxt->error != XPATH_EXPRESSION_OK) { 110852c19a7bf2ee0f78485840cac50f2a989f5efe476William M. Brack xmlXPathFreeNodeSet(newset); 110862c19a7bf2ee0f78485840cac50f2a989f5efe476William M. Brack xmlXPathFreeObject(obj); 110872c19a7bf2ee0f78485840cac50f2a989f5efe476William M. Brack return(0); 110882c19a7bf2ee0f78485840cac50f2a989f5efe476William M. Brack } 11089f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 11090f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* 11091081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack * The result of the evaluation needs to be tested to 11092081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack * decide whether the filter succeeded or not 11093f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 11094f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard res = valuePop(ctxt); 11095f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (xmlXPathEvaluatePredicateResult(ctxt, res)) { 11096f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathNodeSetAdd(newset, oldset->nodeTab[i]); 11097f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 11098f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 11099f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* 11100f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Cleanup 11101f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 11102f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (res != NULL) 11103f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathFreeObject(res); 11104f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (ctxt->value == tmp) { 11105f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard res = valuePop(ctxt); 11106f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathFreeObject(res); 11107f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 11108f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 11109f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->node = NULL; 11110f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 11111f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 11112f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* 11113f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * The result is used as the new evaluation set. 11114f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 11115f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathFreeObject(obj); 11116f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->node = NULL; 11117f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->contextSize = -1; 11118f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->proximityPosition = -1; 111193794b9e84ac51072830a0b34d1ddd0378c0f7cb6William M. Brack /* may want to move this past the '}' later */ 111203794b9e84ac51072830a0b34d1ddd0378c0f7cb6William M. Brack ctxt->context->doc = oldDoc; 11121f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard valuePush(ctxt, xmlXPathWrapNodeSet(newset)); 11122f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 11123f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->node = oldnode; 11124f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 11125f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 11126f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_SORT: 11127f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch1 != -1) 11128f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]); 11129556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard CHECK_ERROR0; 11130f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((ctxt->value != NULL) && 11131f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (ctxt->value->type == XPATH_NODESET) && 11132f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard (ctxt->value->nodesetval != NULL)) 11133f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathNodeSetSort(ctxt->value->nodesetval); 11134f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 111359e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard#ifdef LIBXML_XPTR_ENABLED 11136f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard case XPATH_OP_RANGETO:{ 11137f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathObjectPtr range; 11138f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathObjectPtr res, obj; 11139f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathObjectPtr tmp; 11140081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack xmlLocationSetPtr newlocset = NULL; 11141081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack xmlLocationSetPtr oldlocset; 11142f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlNodeSetPtr oldset; 1114372ee48d55f9002544d011826e2897b5054b7e32cWilliam M. Brack int i, j; 11144f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 11145f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch1 != -1) 11146f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += 11147f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]); 11148f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch2 == -1) 11149f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 11150f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 11151081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack if (ctxt->value->type == XPATH_LOCATIONSET) { 11152081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack /* 11153081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack * Extract the old locset, and then evaluate the result of the 11154081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack * expression for all the element in the locset. use it to grow 11155081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack * up a new locset. 11156081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack */ 11157081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack CHECK_TYPE0(XPATH_LOCATIONSET); 11158081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack obj = valuePop(ctxt); 11159081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack oldlocset = obj->user; 11160f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 11161081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack if ((oldlocset == NULL) || (oldlocset->locNr == 0)) { 1116272ee48d55f9002544d011826e2897b5054b7e32cWilliam M. Brack ctxt->context->node = NULL; 11163081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack ctxt->context->contextSize = 0; 11164081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack ctxt->context->proximityPosition = 0; 11165081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack total += xmlXPathCompOpEval(ctxt,&comp->steps[op->ch2]); 11166081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack res = valuePop(ctxt); 11167081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack if (res != NULL) 11168081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack xmlXPathFreeObject(res); 11169081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack valuePush(ctxt, obj); 11170081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack CHECK_ERROR0; 11171081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack return (total); 11172081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack } 11173081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack newlocset = xmlXPtrLocationSetCreate(NULL); 11174f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 11175081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack for (i = 0; i < oldlocset->locNr; i++) { 11176f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* 11177081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack * Run the evaluation with a node list made of a 11178081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack * single item in the nodelocset. 11179f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 11180f7eb794c142e31ca895f2d7743f872a809e514abWilliam M. Brack ctxt->context->node = oldlocset->locTab[i]->user; 11181f7eb794c142e31ca895f2d7743f872a809e514abWilliam M. Brack ctxt->context->contextSize = oldlocset->locNr; 11182f7eb794c142e31ca895f2d7743f872a809e514abWilliam M. Brack ctxt->context->proximityPosition = i + 1; 11183f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard tmp = xmlXPathNewNodeSet(ctxt->context->node); 11184f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard valuePush(ctxt, tmp); 11185f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 11186f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (op->ch2 != -1) 11187f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard total += 11188f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathCompOpEval(ctxt, 11189f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard &comp->steps[op->ch2]); 111902c19a7bf2ee0f78485840cac50f2a989f5efe476William M. Brack if (ctxt->error != XPATH_EXPRESSION_OK) { 111912c19a7bf2ee0f78485840cac50f2a989f5efe476William M. Brack xmlXPathFreeObject(obj); 111922c19a7bf2ee0f78485840cac50f2a989f5efe476William M. Brack return(0); 111932c19a7bf2ee0f78485840cac50f2a989f5efe476William M. Brack } 11194f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 11195f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard res = valuePop(ctxt); 1119672ee48d55f9002544d011826e2897b5054b7e32cWilliam M. Brack if (res->type == XPATH_LOCATIONSET) { 1119772ee48d55f9002544d011826e2897b5054b7e32cWilliam M. Brack xmlLocationSetPtr rloc = 1119872ee48d55f9002544d011826e2897b5054b7e32cWilliam M. Brack (xmlLocationSetPtr)res->user; 1119972ee48d55f9002544d011826e2897b5054b7e32cWilliam M. Brack for (j=0; j<rloc->locNr; j++) { 1120072ee48d55f9002544d011826e2897b5054b7e32cWilliam M. Brack range = xmlXPtrNewRange( 1120172ee48d55f9002544d011826e2897b5054b7e32cWilliam M. Brack oldlocset->locTab[i]->user, 1120272ee48d55f9002544d011826e2897b5054b7e32cWilliam M. Brack oldlocset->locTab[i]->index, 1120372ee48d55f9002544d011826e2897b5054b7e32cWilliam M. Brack rloc->locTab[j]->user2, 1120472ee48d55f9002544d011826e2897b5054b7e32cWilliam M. Brack rloc->locTab[j]->index2); 1120572ee48d55f9002544d011826e2897b5054b7e32cWilliam M. Brack if (range != NULL) { 1120672ee48d55f9002544d011826e2897b5054b7e32cWilliam M. Brack xmlXPtrLocationSetAdd(newlocset, range); 1120772ee48d55f9002544d011826e2897b5054b7e32cWilliam M. Brack } 1120872ee48d55f9002544d011826e2897b5054b7e32cWilliam M. Brack } 1120972ee48d55f9002544d011826e2897b5054b7e32cWilliam M. Brack } else { 1121072ee48d55f9002544d011826e2897b5054b7e32cWilliam M. Brack range = xmlXPtrNewRangeNodeObject( 1121172ee48d55f9002544d011826e2897b5054b7e32cWilliam M. Brack (xmlNodePtr)oldlocset->locTab[i]->user, res); 1121272ee48d55f9002544d011826e2897b5054b7e32cWilliam M. Brack if (range != NULL) { 1121372ee48d55f9002544d011826e2897b5054b7e32cWilliam M. Brack xmlXPtrLocationSetAdd(newlocset,range); 1121472ee48d55f9002544d011826e2897b5054b7e32cWilliam M. Brack } 11215f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 11216f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 11217f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* 11218f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Cleanup 11219f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 11220f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (res != NULL) 11221f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathFreeObject(res); 11222f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (ctxt->value == tmp) { 11223f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard res = valuePop(ctxt); 11224f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathFreeObject(res); 11225f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 11226f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 11227f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->node = NULL; 11228f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 1122972ee48d55f9002544d011826e2897b5054b7e32cWilliam M. Brack } else { /* Not a location set */ 11230081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack CHECK_TYPE0(XPATH_NODESET); 11231081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack obj = valuePop(ctxt); 11232081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack oldset = obj->nodesetval; 11233081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack ctxt->context->node = NULL; 11234081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack 11235081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack newlocset = xmlXPtrLocationSetCreate(NULL); 11236081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack 11237081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack if (oldset != NULL) { 11238081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack for (i = 0; i < oldset->nodeNr; i++) { 11239081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack /* 11240081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack * Run the evaluation with a node list made of a single item 11241081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack * in the nodeset. 11242081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack */ 11243081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack ctxt->context->node = oldset->nodeTab[i]; 11244081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack tmp = xmlXPathNewNodeSet(ctxt->context->node); 11245081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack valuePush(ctxt, tmp); 11246081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack 11247081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack if (op->ch2 != -1) 11248081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack total += 11249081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack xmlXPathCompOpEval(ctxt, 11250081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack &comp->steps[op->ch2]); 112512c19a7bf2ee0f78485840cac50f2a989f5efe476William M. Brack if (ctxt->error != XPATH_EXPRESSION_OK) { 112522c19a7bf2ee0f78485840cac50f2a989f5efe476William M. Brack xmlXPathFreeObject(obj); 112532c19a7bf2ee0f78485840cac50f2a989f5efe476William M. Brack return(0); 112542c19a7bf2ee0f78485840cac50f2a989f5efe476William M. Brack } 11255081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack 11256081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack res = valuePop(ctxt); 11257081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack range = 11258081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack xmlXPtrNewRangeNodeObject(oldset->nodeTab[i], 11259081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack res); 11260081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack if (range != NULL) { 11261081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack xmlXPtrLocationSetAdd(newlocset, range); 11262081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack } 11263081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack 11264081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack /* 11265081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack * Cleanup 11266081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack */ 11267081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack if (res != NULL) 11268081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack xmlXPathFreeObject(res); 11269081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack if (ctxt->value == tmp) { 11270081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack res = valuePop(ctxt); 11271081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack xmlXPathFreeObject(res); 11272081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack } 11273081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack 11274081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack ctxt->context->node = NULL; 11275081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack } 11276081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack } 11277f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 11278f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 11279f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard /* 11280f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * The result is used as the new evaluation set. 11281f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */ 11282f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard xmlXPathFreeObject(obj); 11283f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->node = NULL; 11284f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->contextSize = -1; 11285f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard ctxt->context->proximityPosition = -1; 11286081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack valuePush(ctxt, xmlXPtrWrapLocationSet(newlocset)); 11287f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 11288f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 112899e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard#endif /* LIBXML_XPTR_ENABLED */ 112909e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } 112919e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlGenericError(xmlGenericErrorContext, 11292f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard "XPath: unknown precompiled operation %d\n", op->op); 11293f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard return (total); 112949e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard} 112959e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 1129656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard#ifdef XPATH_STREAMING 1129756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard/** 1129856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard * xmlXPathRunStreamEval: 1129956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard * @ctxt: the XPath parser context with the compiled expression 1130056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard * 1130156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard * Evaluate the Precompiled Streamable XPath expression in the given context. 1130256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard */ 1130356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillardstatic xmlXPathObjectPtr 1130456de87ee0d147d04a041eb1ec95048566375bc3fDaniel VeillardxmlXPathRunStreamEval(xmlXPathContextPtr ctxt, xmlPatternPtr comp) { 11305f03a8cdacdce917d09972c65371953e8a57a2ac3Daniel Veillard int max_depth, min_depth; 1130697258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik int from_root; 1130756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard int ret, depth; 1130897258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik#ifdef XP_PATTERN_TO_ANY_NODE_ENABLED 1130997258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik int eval_all_nodes; 1131097258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik#endif 1131112d37ab63441baf9e03db70168cc1d0d6f1c2373William M. Brack xmlNodePtr cur = NULL, limit = NULL; 1131256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard xmlXPathObjectPtr retval; 1131356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard xmlStreamCtxtPtr patstream; 1131497258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik 1131597258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik int nb_nodes = 0; 1131656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard 1131756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard if ((ctxt == NULL) || (comp == NULL)) 1131856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard return(NULL); 1131956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard max_depth = xmlPatternMaxDepth(comp); 1132056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard if (max_depth == -1) 1132156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard return(NULL); 1132256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard if (max_depth == -2) 1132356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard max_depth = 10000; 11324f03a8cdacdce917d09972c65371953e8a57a2ac3Daniel Veillard min_depth = xmlPatternMinDepth(comp); 11325f03a8cdacdce917d09972c65371953e8a57a2ac3Daniel Veillard if (min_depth == -1) 11326f03a8cdacdce917d09972c65371953e8a57a2ac3Daniel Veillard return(NULL); 1132756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard from_root = xmlPatternFromRoot(comp); 1132856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard if (from_root < 0) 1132956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard return(NULL); 11330fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard#if 0 11331fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard printf("stream eval: depth %d from root %d\n", max_depth, from_root); 11332fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard#endif 1133356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard 1133456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard retval = xmlXPathNewNodeSet(NULL); 1133556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard if (retval == NULL) 1133656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard return(NULL); 1133756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard 11338f03a8cdacdce917d09972c65371953e8a57a2ac3Daniel Veillard /* 11339f03a8cdacdce917d09972c65371953e8a57a2ac3Daniel Veillard * handle the special cases of / amd . being matched 11340f03a8cdacdce917d09972c65371953e8a57a2ac3Daniel Veillard */ 11341f03a8cdacdce917d09972c65371953e8a57a2ac3Daniel Veillard if (min_depth == 0) { 11342f03a8cdacdce917d09972c65371953e8a57a2ac3Daniel Veillard if (from_root) { 11343f03a8cdacdce917d09972c65371953e8a57a2ac3Daniel Veillard xmlXPathNodeSetAddUnique(retval->nodesetval, (xmlNodePtr) ctxt->doc); 11344f03a8cdacdce917d09972c65371953e8a57a2ac3Daniel Veillard } else { 11345f03a8cdacdce917d09972c65371953e8a57a2ac3Daniel Veillard xmlXPathNodeSetAddUnique(retval->nodesetval, ctxt->node); 11346f03a8cdacdce917d09972c65371953e8a57a2ac3Daniel Veillard } 11347f03a8cdacdce917d09972c65371953e8a57a2ac3Daniel Veillard } 11348f03a8cdacdce917d09972c65371953e8a57a2ac3Daniel Veillard if (max_depth == 0) { 1134956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard return(retval); 1135056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard } 11351f03a8cdacdce917d09972c65371953e8a57a2ac3Daniel Veillard 1135256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard if (from_root) { 1135312d37ab63441baf9e03db70168cc1d0d6f1c2373William M. Brack cur = (xmlNodePtr)ctxt->doc; 1135456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard } else if (ctxt->node != NULL) { 1135556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard switch (ctxt->node->type) { 1135656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard case XML_ELEMENT_NODE: 1135756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard case XML_DOCUMENT_NODE: 1135856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard case XML_DOCUMENT_FRAG_NODE: 1135956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard case XML_HTML_DOCUMENT_NODE: 1136056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard#ifdef LIBXML_DOCB_ENABLED 1136156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard case XML_DOCB_DOCUMENT_NODE: 1136256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard#endif 1136356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard cur = ctxt->node; 1136456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard break; 1136556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard case XML_ATTRIBUTE_NODE: 1136656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard case XML_TEXT_NODE: 1136756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard case XML_CDATA_SECTION_NODE: 1136856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard case XML_ENTITY_REF_NODE: 1136956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard case XML_ENTITY_NODE: 1137056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard case XML_PI_NODE: 1137156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard case XML_COMMENT_NODE: 1137256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard case XML_NOTATION_NODE: 1137356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard case XML_DTD_NODE: 1137456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard case XML_DOCUMENT_TYPE_NODE: 1137556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard case XML_ELEMENT_DECL: 1137656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard case XML_ATTRIBUTE_DECL: 1137756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard case XML_ENTITY_DECL: 1137856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard case XML_NAMESPACE_DECL: 1137956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard case XML_XINCLUDE_START: 1138056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard case XML_XINCLUDE_END: 1138156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard break; 1138256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard } 1138356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard limit = cur; 1138456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard } 1138556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard if (cur == NULL) 1138656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard return(retval); 1138756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard 1138856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard patstream = xmlPatternGetStreamCtxt(comp); 1138956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard if (patstream == NULL) { 1139056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard return(retval); 1139156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard } 1139256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard 1139397258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik#ifdef XP_PATTERN_TO_ANY_NODE_ENABLED 1139497258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik eval_all_nodes = xmlStreamWantsAnyNode(patstream); 1139597258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik#endif 1139697258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik 1139756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard if (from_root) { 1139856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard ret = xmlStreamPush(patstream, NULL, NULL); 1139956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard if (ret < 0) { 1140056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard } else if (ret == 1) { 1140156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard xmlXPathNodeSetAddUnique(retval->nodesetval, cur); 1140256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard } 1140356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard } 1140456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard depth = 0; 1140556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard goto scan_children; 1140656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillardnext_node: 11407d3ff7ef6d3247872b1231718bdf1773c16d88806Daniel Veillard do { 1140856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard nb_nodes++; 1140997258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik 1141097258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik switch (cur->type) { 1141197258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik case XML_ELEMENT_NODE: 1141297258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik#ifdef XP_PATTERN_TO_ANY_NODE_ENABLED 1141397258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik case XML_TEXT_NODE: 1141497258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik case XML_CDATA_SECTION_NODE: 1141597258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik case XML_COMMENT_NODE: 1141697258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik case XML_PI_NODE: 1141797258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik#endif 1141897258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik if (cur->type == XML_ELEMENT_NODE) { 1141997258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik ret = xmlStreamPush(patstream, cur->name, 1142056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard (cur->ns ? cur->ns->href : NULL)); 11421fbb619f4762fd50630e3ec22589838d089cd2f08William M. Brack } 1142297258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik#ifdef XP_PATTERN_TO_ANY_NODE_ENABLED 1142397258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik else if (eval_all_nodes) 1142497258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik ret = xmlStreamPushNode(patstream, NULL, NULL, cur->type); 1142597258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik else 1142697258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik break; 1142797258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik#endif 1142897258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik 1142997258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik if (ret < 0) { 1143097258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik /* NOP. */ 1143197258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik } else if (ret == 1) { 1143297258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik xmlXPathNodeSetAddUnique(retval->nodesetval, cur); 1143397258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik } 1143497258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik if ((cur->children == NULL) || (depth >= max_depth)) { 1143597258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik ret = xmlStreamPop(patstream); 1143697258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik while (cur->next != NULL) { 1143797258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik cur = cur->next; 1143897258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik if ((cur->type != XML_ENTITY_DECL) && 1143997258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik (cur->type != XML_DTD_NODE)) 1144097258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik goto next_node; 1144197258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik } 1144297258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik } 1144397258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik default: 1144497258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik break; 1144597258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik } 1144656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard 1144756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillardscan_children: 1144856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard if ((cur->children != NULL) && (depth < max_depth)) { 1144956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard /* 1145097258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik * Do not descend on entities declarations 1145156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard */ 1145256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard if (cur->children->type != XML_ENTITY_DECL) { 1145356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard cur = cur->children; 1145456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard depth++; 1145556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard /* 1145656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard * Skip DTDs 1145756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard */ 1145856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard if (cur->type != XML_DTD_NODE) 1145956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard continue; 1146056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard } 1146156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard } 1146256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard 1146356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard if (cur == limit) 1146456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard break; 1146556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard 1146656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard while (cur->next != NULL) { 1146756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard cur = cur->next; 1146856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard if ((cur->type != XML_ENTITY_DECL) && 1146956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard (cur->type != XML_DTD_NODE)) 1147056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard goto next_node; 1147156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard } 1147256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard 1147356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard do { 1147456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard cur = cur->parent; 1147556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard depth--; 1147656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard if ((cur == NULL) || (cur == limit)) 1147756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard goto done; 1147897258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik if (cur->type == XML_ELEMENT_NODE) { 1147997258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik ret = xmlStreamPop(patstream); 1148097258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik } 1148197258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik#ifdef XP_PATTERN_TO_ANY_NODE_ENABLED 1148297258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik else if ((eval_all_nodes) && 1148397258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik ((cur->type == XML_TEXT_NODE) || 1148497258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik (cur->type == XML_CDATA_SECTION_NODE) || 1148597258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik (cur->type == XML_COMMENT_NODE) || 1148697258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik (cur->type == XML_PI_NODE))) 1148797258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik { 1148897258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik ret = xmlStreamPop(patstream); 1148997258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik } 1149097258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik#endif 1149156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard if (cur->next != NULL) { 1149256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard cur = cur->next; 1149356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard break; 1149456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard } 1149556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard } while (cur != NULL); 1149656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard 1149756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard } while ((cur != NULL) && (depth >= 0)); 1149856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillarddone: 11499fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard#if 0 11500fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard printf("stream eval: checked %d nodes selected %d\n", 11501fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard nb_nodes, retval->nodesetval->nodeNr); 11502fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard#endif 1150356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard xmlFreeStreamCtxt(patstream); 1150456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard return(retval); 1150556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard} 1150656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard#endif /* XPATH_STREAMING */ 1150756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard 115089e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard/** 115099e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * xmlXPathRunEval: 115109e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * @ctxt: the XPath parser context with the compiled expression 115119e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * 115129e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * Evaluate the Precompiled XPath expression in the given context. 115139e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard */ 11514fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillardstatic void 115159e7160d45a18bfa26d708e22ba991f7670d0128bDaniel VeillardxmlXPathRunEval(xmlXPathParserContextPtr ctxt) { 115169e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlXPathCompExprPtr comp; 115179e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 115189e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if ((ctxt == NULL) || (ctxt->comp == NULL)) 115199e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard return; 115209e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 115219e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (ctxt->valueTab == NULL) { 115229e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard /* Allocate the value stack */ 115239e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard ctxt->valueTab = (xmlXPathObjectPtr *) 115249e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlMalloc(10 * sizeof(xmlXPathObjectPtr)); 115259e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (ctxt->valueTab == NULL) { 11526d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard xmlXPathPErrMemory(ctxt, "creating evaluation context\n"); 115279e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlFree(ctxt); 115289e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } 115299e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard ctxt->valueNr = 0; 115309e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard ctxt->valueMax = 10; 115319e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard ctxt->value = NULL; 115329e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } 1153356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard#ifdef XPATH_STREAMING 1153456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard if (ctxt->comp->stream) { 1153556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard xmlXPathObjectPtr ret; 1153656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard ret = xmlXPathRunStreamEval(ctxt->context, ctxt->comp->stream); 1153756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard if (ret != NULL) { 1153856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard valuePush(ctxt, ret); 1153956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard return; 1154056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard } 1154156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard } 1154256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard#endif 115439e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard comp = ctxt->comp; 1154429b6f76c5326616aed5dcff9cb55145137863e97Aleksey Sanin if(comp->last < 0) { 1154529b6f76c5326616aed5dcff9cb55145137863e97Aleksey Sanin xmlGenericError(xmlGenericErrorContext, 1154629b6f76c5326616aed5dcff9cb55145137863e97Aleksey Sanin "xmlXPathRunEval: last is less than zero\n"); 1154729b6f76c5326616aed5dcff9cb55145137863e97Aleksey Sanin return; 1154829b6f76c5326616aed5dcff9cb55145137863e97Aleksey Sanin } 115499e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlXPathCompOpEval(ctxt, &comp->steps[comp->last]); 115509e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard} 115519e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 11552afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard/************************************************************************ 11553afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * * 11554afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Public interfaces * 11555afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * * 11556afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard ************************************************************************/ 11557afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard 11558afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard/** 11559fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * xmlXPathEvalPredicate: 11560fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * @ctxt: the XPath context 11561fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * @res: the Predicate Expression evaluation result 11562fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * 11563fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * Evaluate a predicate result for the current node. 11564fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * A PredicateExpr is evaluated by evaluating the Expr and converting 11565fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * the result to a boolean. If the result is a number, the result will 11566fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * be converted to true if the number is equal to the position of the 11567fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * context node in the context node list (as returned by the position 11568fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * function) and will be converted to false otherwise; if the result 11569fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * is not a number, then the result will be converted as if by a call 11570fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * to the boolean function. 11571fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * 11572cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * Returns 1 if predicate is true, 0 otherwise 11573fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard */ 11574fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillardint 11575fbf8a2d0c8145b713099df63d174154a8442e60dDaniel VeillardxmlXPathEvalPredicate(xmlXPathContextPtr ctxt, xmlXPathObjectPtr res) { 11576ce682bc24b79f1dd29b781d4c17f9bf169ce7e32Daniel Veillard if ((ctxt == NULL) || (res == NULL)) return(0); 11577fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard switch (res->type) { 11578fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard case XPATH_BOOLEAN: 11579fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard return(res->boolval); 11580fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard case XPATH_NUMBER: 11581fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard return(res->floatval == ctxt->proximityPosition); 11582fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard case XPATH_NODESET: 11583fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard case XPATH_XSLT_TREE: 11584d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard if (res->nodesetval == NULL) 11585d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard return(0); 11586fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard return(res->nodesetval->nodeNr != 0); 11587fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard case XPATH_STRING: 11588fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard return((res->stringval != NULL) && 11589fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard (xmlStrlen(res->stringval) != 0)); 11590fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard default: 11591fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard STRANGE 11592fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard } 11593fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard return(0); 11594fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard} 11595fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard 11596fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard/** 11597afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathEvaluatePredicateResult: 11598afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * @ctxt: the XPath Parser context 11599afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * @res: the Predicate Expression evaluation result 11600afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * 11601afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Evaluate a predicate result for the current node. 11602afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * A PredicateExpr is evaluated by evaluating the Expr and converting 11603afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * the result to a boolean. If the result is a number, the result will 11604afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * be converted to true if the number is equal to the position of the 11605afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * context node in the context node list (as returned by the position 11606afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * function) and will be converted to false otherwise; if the result 11607afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * is not a number, then the result will be converted as if by a call 11608afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * to the boolean function. 11609afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * 11610cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * Returns 1 if predicate is true, 0 otherwise 11611afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard */ 11612afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardint 11613afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathEvaluatePredicateResult(xmlXPathParserContextPtr ctxt, 11614afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathObjectPtr res) { 11615ce682bc24b79f1dd29b781d4c17f9bf169ce7e32Daniel Veillard if ((ctxt == NULL) || (res == NULL)) return(0); 11616afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard switch (res->type) { 11617afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard case XPATH_BOOLEAN: 11618afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard return(res->boolval); 11619afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard case XPATH_NUMBER: 116209ea6231ecef04c848b688355b8f7532dd5e4c6f8Daniel Veillard#if defined(__BORLANDC__) || (defined(_MSC_VER) && (_MSC_VER == 1200)) 116217c4eb63bb01d754b17860cd7dc2ab2fef81f6a08Daniel Veillard return((res->floatval == ctxt->context->proximityPosition) && 116227c4eb63bb01d754b17860cd7dc2ab2fef81f6a08Daniel Veillard (!xmlXPathIsNaN(res->floatval))); /* MSC pbm Mark Vakoc !*/ 116232582a338bff77569b5aadbba8f40e1f3862d090dDaniel Veillard#else 11624afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard return(res->floatval == ctxt->context->proximityPosition); 116252582a338bff77569b5aadbba8f40e1f3862d090dDaniel Veillard#endif 11626afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard case XPATH_NODESET: 11627afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard case XPATH_XSLT_TREE: 1162873639a73c5a51c3739595f54c338bb531c1319c2Daniel Veillard if (res->nodesetval == NULL) 11629911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard return(0); 11630afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard return(res->nodesetval->nodeNr != 0); 11631afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard case XPATH_STRING: 11632afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard return((res->stringval != NULL) && 11633afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard (xmlStrlen(res->stringval) != 0)); 11634081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack#ifdef LIBXML_XPTR_ENABLED 11635081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack case XPATH_LOCATIONSET:{ 11636081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack xmlLocationSetPtr ptr = res->user; 11637081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack if (ptr == NULL) 11638081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack return(0); 11639081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack return (ptr->locNr != 0); 11640081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack } 11641081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack#endif 11642afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard default: 11643afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard STRANGE 11644afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard } 11645afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard return(0); 11646afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard} 11647afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard 1164856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard#ifdef XPATH_STREAMING 1164956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard/** 1165056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard * xmlXPathTryStreamCompile: 1165156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard * @ctxt: an XPath context 1165256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard * @str: the XPath expression 1165356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard * 1165456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard * Try to compile the XPath expression as a streamable subset. 1165556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard * 1165656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard * Returns the compiled expression or NULL if failed to compile. 1165756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard */ 1165856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillardstatic xmlXPathCompExprPtr 1165956de87ee0d147d04a041eb1ec95048566375bc3fDaniel VeillardxmlXPathTryStreamCompile(xmlXPathContextPtr ctxt, const xmlChar *str) { 1166056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard /* 1166156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard * Optimization: use streaming patterns when the XPath expression can 1166256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard * be compiled to a stream lookup 1166356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard */ 1166456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard xmlPatternPtr stream; 1166556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard xmlXPathCompExprPtr comp; 1166656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard xmlDictPtr dict = NULL; 1166756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard const xmlChar **namespaces = NULL; 1166856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard xmlNsPtr ns; 1166956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard int i, j; 1167056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard 1167156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard if ((!xmlStrchr(str, '[')) && (!xmlStrchr(str, '(')) && 1167256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard (!xmlStrchr(str, '@'))) { 116731f33c4d61f3cc9820643ef726b373ec3044bcac3Daniel Veillard const xmlChar *tmp; 116741f33c4d61f3cc9820643ef726b373ec3044bcac3Daniel Veillard 116751f33c4d61f3cc9820643ef726b373ec3044bcac3Daniel Veillard /* 116766ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik * We don't try to handle expressions using the verbose axis 116776ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik * specifiers ("::"), just the simplied form at this point. 116786ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik * Additionally, if there is no list of namespaces available and 116796ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik * there's a ":" in the expression, indicating a prefixed QName, 116806ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik * then we won't try to compile either. xmlPatterncompile() needs 116816ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik * to have a list of namespaces at compilation time in order to 116826ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik * compile prefixed name tests. 116831f33c4d61f3cc9820643ef726b373ec3044bcac3Daniel Veillard */ 116841f33c4d61f3cc9820643ef726b373ec3044bcac3Daniel Veillard tmp = xmlStrchr(str, ':'); 116856ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik if ((tmp != NULL) && 116866ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik ((ctxt == NULL) || (ctxt->nsNr == 0) || (tmp[1] == ':'))) 116876ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik return(NULL); 116881f33c4d61f3cc9820643ef726b373ec3044bcac3Daniel Veillard 1168956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard if (ctxt != NULL) { 1169056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard dict = ctxt->dict; 1169156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard if (ctxt->nsNr > 0) { 11692dbfe05aff4d242e31fcd7621a4901a6fa10b988eDaniel Veillard namespaces = xmlMalloc(2 * (ctxt->nsNr + 1) * sizeof(xmlChar*)); 1169356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard if (namespaces == NULL) { 1169456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard xmlXPathErrMemory(ctxt, "allocating namespaces array\n"); 1169556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard return(NULL); 1169656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard } 1169756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard for (i = 0, j = 0; (j < ctxt->nsNr); j++) { 1169856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard ns = ctxt->namespaces[j]; 1169956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard namespaces[i++] = ns->href; 1170056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard namespaces[i++] = ns->prefix; 1170156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard } 1170256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard namespaces[i++] = NULL; 1170356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard namespaces[i++] = NULL; 1170456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard } 1170556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard } 1170656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard 11707ea152c05b3f3d9e47b282b88ffdb16fcb8c779c1William M. Brack stream = xmlPatterncompile(str, dict, XML_PATTERN_XPATH, 11708ea152c05b3f3d9e47b282b88ffdb16fcb8c779c1William M. Brack &namespaces[0]); 117096ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik if (namespaces != NULL) { 117106ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik xmlFree((xmlChar **)namespaces); 117116ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik } 1171256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard if ((stream != NULL) && (xmlPatternStreamable(stream) == 1)) { 1171356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard comp = xmlXPathNewCompExpr(); 1171456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard if (comp == NULL) { 1171556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard xmlXPathErrMemory(ctxt, "allocating streamable expression\n"); 1171656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard return(NULL); 1171756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard } 1171856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard comp->stream = stream; 1171956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard comp->dict = dict; 1172056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard if (comp->dict) 1172156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard xmlDictReference(comp->dict); 1172256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard return(comp); 1172356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard } 1172456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard xmlFreePattern(stream); 1172556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard } 1172656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard return(NULL); 1172756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard} 1172856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard#endif /* XPATH_STREAMING */ 1172956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard 11730afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard/** 117314773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard * xmlXPathCtxtCompile: 117324773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard * @ctxt: an XPath context 11733afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * @str: the XPath expression 11734afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * 11735afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile an XPath expression 11736afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * 11737591b4be0fe1986b5e71d54c5c063493987ef4285Daniel Veillard * Returns the xmlXPathCompExprPtr resulting from the compilation or NULL. 11738afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * the caller has to free the object. 11739afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard */ 11740afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompExprPtr 117414773df2a58be83e1b9b1b55840371acf37386820Daniel VeillardxmlXPathCtxtCompile(xmlXPathContextPtr ctxt, const xmlChar *str) { 117424773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard xmlXPathParserContextPtr pctxt; 11743afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathCompExprPtr comp; 11744afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard 1174556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard#ifdef XPATH_STREAMING 1174656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard comp = xmlXPathTryStreamCompile(ctxt, str); 1174756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard if (comp != NULL) 1174856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard return(comp); 1174956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard#endif 1175056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard 11751afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathInit(); 11752afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard 117534773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard pctxt = xmlXPathNewParserContext(str, ctxt); 117544773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard xmlXPathCompileExpr(pctxt); 11755ae9733aeaf99e5d967b6b2cd961c98bf58cfbb4cDaniel Veillard 117564773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard if( pctxt->error != XPATH_EXPRESSION_OK ) 11757ae9733aeaf99e5d967b6b2cd961c98bf58cfbb4cDaniel Veillard { 117584773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard xmlXPathFreeParserContext(pctxt); 1175924505b0f5c872c5afb6da5093565e5a6e09ca541Daniel Veillard return(NULL); 11760ae9733aeaf99e5d967b6b2cd961c98bf58cfbb4cDaniel Veillard } 11761ae9733aeaf99e5d967b6b2cd961c98bf58cfbb4cDaniel Veillard 117624773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard if (*pctxt->cur != 0) { 1176350fe8b1732048003f47b32b009507fe6cdecd39fAleksey Sanin /* 1176450fe8b1732048003f47b32b009507fe6cdecd39fAleksey Sanin * aleksey: in some cases this line prints *second* error message 1176550fe8b1732048003f47b32b009507fe6cdecd39fAleksey Sanin * (see bug #78858) and probably this should be fixed. 1176650fe8b1732048003f47b32b009507fe6cdecd39fAleksey Sanin * However, we are not sure that all error messages are printed 1176750fe8b1732048003f47b32b009507fe6cdecd39fAleksey Sanin * out in other places. It's not critical so we leave it as-is for now 1176850fe8b1732048003f47b32b009507fe6cdecd39fAleksey Sanin */ 117694773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard xmlXPatherror(pctxt, __FILE__, __LINE__, XPATH_EXPR_ERROR); 1177040af649f9b5b32f97879f10432c56bb5ef60c958Daniel Veillard comp = NULL; 1177140af649f9b5b32f97879f10432c56bb5ef60c958Daniel Veillard } else { 117724773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard comp = pctxt->comp; 117734773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard pctxt->comp = NULL; 1177440af649f9b5b32f97879f10432c56bb5ef60c958Daniel Veillard } 117754773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard xmlXPathFreeParserContext(pctxt); 11776f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if (comp != NULL) { 11777ceb09b956efa2cf1ec41c1887394396e5a6030f2Daniel Veillard comp->expr = xmlStrdup(str); 11778ceb09b956efa2cf1ec41c1887394396e5a6030f2Daniel Veillard#ifdef DEBUG_EVAL_COUNTS 11779f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard comp->string = xmlStrdup(str); 11780f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard comp->nb = 0; 11781f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#endif 11782ceb09b956efa2cf1ec41c1887394396e5a6030f2Daniel Veillard } 11783afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard return(comp); 11784afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard} 11785afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard 117869e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard/** 117874773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard * xmlXPathCompile: 117884773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard * @str: the XPath expression 117894773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard * 117904773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard * Compile an XPath expression 117914773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard * 117924773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard * Returns the xmlXPathCompExprPtr resulting from the compilation or NULL. 117934773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard * the caller has to free the object. 117944773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard */ 117954773df2a58be83e1b9b1b55840371acf37386820Daniel VeillardxmlXPathCompExprPtr 117964773df2a58be83e1b9b1b55840371acf37386820Daniel VeillardxmlXPathCompile(const xmlChar *str) { 117974773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard return(xmlXPathCtxtCompile(NULL, str)); 117984773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard} 117994773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard 118004773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard/** 118019e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * xmlXPathCompiledEval: 118029e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * @comp: the compiled XPath expression 118039e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * @ctx: the XPath context 118049e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * 118059e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * Evaluate the Precompiled XPath expression in the given context. 118069e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * 11807cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * Returns the xmlXPathObjectPtr resulting from the evaluation or NULL. 118089e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * the caller has to free the object. 118099e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard */ 118109e7160d45a18bfa26d708e22ba991f7670d0128bDaniel VeillardxmlXPathObjectPtr 118119e7160d45a18bfa26d708e22ba991f7670d0128bDaniel VeillardxmlXPathCompiledEval(xmlXPathCompExprPtr comp, xmlXPathContextPtr ctx) { 118129e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlXPathParserContextPtr ctxt; 118139e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlXPathObjectPtr res, tmp, init = NULL; 118149e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard int stack = 0; 118158146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard#ifndef LIBXML_THREAD_ENABLED 118168146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard static int reentance = 0; 118178146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard#endif 118189e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 11819f13f77f0e6a7876063d5fba15c096befb0827cedWilliam M. Brack CHECK_CTXT(ctx) 11820f13f77f0e6a7876063d5fba15c096befb0827cedWilliam M. Brack 11821f13f77f0e6a7876063d5fba15c096befb0827cedWilliam M. Brack if (comp == NULL) 118229e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard return(NULL); 118239e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlXPathInit(); 118249e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 118258146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard#ifndef LIBXML_THREAD_ENABLED 118268146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard reentance++; 118278146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard if (reentance > 1) 118288146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard xmlXPathDisableOptimizer = 1; 118298146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard#endif 118308146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard 11831f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#ifdef DEBUG_EVAL_COUNTS 11832f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard comp->nb++; 11833f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard if ((comp->string != NULL) && (comp->nb > 100)) { 11834f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard fprintf(stderr, "100 x %s\n", comp->string); 11835f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard comp->nb = 0; 11836f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard } 11837f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#endif 118389e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard ctxt = xmlXPathCompParserContext(comp, ctx); 118399e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlXPathRunEval(ctxt); 118409e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 118419e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (ctxt->value == NULL) { 118429e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlGenericError(xmlGenericErrorContext, 11843cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard "xmlXPathCompiledEval: evaluation failed\n"); 118449e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard res = NULL; 118459e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } else { 118469e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard res = valuePop(ctxt); 118479e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } 118489e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 11849f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard 118509e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard do { 118519e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard tmp = valuePop(ctxt); 118529e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (tmp != NULL) { 118539e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (tmp != init) 118549e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard stack++; 118559e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlXPathFreeObject(tmp); 118569e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } 118579e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } while (tmp != NULL); 118589e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if ((stack != 0) && (res != NULL)) { 118599e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlGenericError(xmlGenericErrorContext, 11860cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard "xmlXPathCompiledEval: %d object left on the stack\n", 118619e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard stack); 118629e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } 118639e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard if (ctxt->error != XPATH_EXPRESSION_OK) { 118649e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlXPathFreeObject(res); 118659e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard res = NULL; 118669e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard } 118679e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 118689e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 11869afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard ctxt->comp = NULL; 118709e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard xmlXPathFreeParserContext(ctxt); 118718146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard#ifndef LIBXML_THREAD_ENABLED 118728146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard reentance--; 118738146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard#endif 118749e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard return(res); 118759e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard} 118769e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 11877afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard/** 11878afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathEvalExpr: 11879afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * @ctxt: the XPath Parser context 11880afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * 11881afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Parse and evaluate an XPath expression in the given context, 11882afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * then push the result on the context stack 11883afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard */ 11884afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardvoid 11885afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathEvalExpr(xmlXPathParserContextPtr ctxt) { 1188656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard#ifdef XPATH_STREAMING 1188756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard xmlXPathCompExprPtr comp; 1188856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard#endif 1188956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard 11890a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard if (ctxt == NULL) return; 1189156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard 1189256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard#ifdef XPATH_STREAMING 1189356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard comp = xmlXPathTryStreamCompile(ctxt->context, ctxt->base); 1189456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard if (comp != NULL) { 1189556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard if (ctxt->comp != NULL) 1189656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard xmlXPathFreeCompExpr(ctxt->comp); 1189756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard ctxt->comp = comp; 1189856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard if (ctxt->cur != NULL) 1189956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard while (*ctxt->cur != 0) ctxt->cur++; 1190056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard } else 1190156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard#endif 1190256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard { 1190356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard xmlXPathCompileExpr(ctxt); 1190456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard } 1190550fe8b1732048003f47b32b009507fe6cdecd39fAleksey Sanin CHECK_ERROR; 11906afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard xmlXPathRunEval(ctxt); 11907afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard} 119089e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 119093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 119103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathEval: 119113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @str: the XPath expression 119123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctx: the XPath context 119133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 119143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Evaluate the XPath Location Path in the given context. 119153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 11916cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * Returns the xmlXPathObjectPtr resulting from the evaluation or NULL. 119173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the caller has to free the object. 119183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 119193473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathObjectPtr 119203473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathEval(const xmlChar *str, xmlXPathContextPtr ctx) { 119213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathParserContextPtr ctxt; 119223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr res, tmp, init = NULL; 119233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int stack = 0; 119243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 11925f13f77f0e6a7876063d5fba15c096befb0827cedWilliam M. Brack CHECK_CTXT(ctx) 119263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 11927f13f77f0e6a7876063d5fba15c096befb0827cedWilliam M. Brack xmlXPathInit(); 119283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 119293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ctxt = xmlXPathNewParserContext(str, ctx); 119303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathEvalExpr(ctxt); 119313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 119323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->value == NULL) { 119333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 119343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "xmlXPathEval: evaluation failed\n"); 119353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor res = NULL; 1193656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard } else if ((*ctxt->cur != 0) && (ctxt->comp != NULL) 1193756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard#ifdef XPATH_STREAMING 1193856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard && (ctxt->comp->stream == NULL) 1193956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard#endif 1194056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard ) { 119413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPatherror(ctxt, __FILE__, __LINE__, XPATH_EXPR_ERROR); 119423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor res = NULL; 119433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else { 119443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor res = valuePop(ctxt); 119453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 119463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 119473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor do { 119483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor tmp = valuePop(ctxt); 119493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (tmp != NULL) { 119503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (tmp != init) 119513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor stack++; 119523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(tmp); 119533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 119543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } while (tmp != NULL); 119553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((stack != 0) && (res != NULL)) { 119563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 119573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "xmlXPathEval: %d object left on the stack\n", 119583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor stack); 119593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 119603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->error != XPATH_EXPRESSION_OK) { 119613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(res); 119623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor res = NULL; 119633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 119649e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard 119653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeParserContext(ctxt); 119663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(res); 119673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 119683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 119693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 119703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathEvalExpression: 119713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @str: the XPath expression 119723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath context 119733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 119743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Evaluate the XPath expression in the given context. 119753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 119763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the xmlXPathObjectPtr resulting from the evaluation or NULL. 119773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the caller has to free the object. 119783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 119793473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathObjectPtr 119803473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathEvalExpression(const xmlChar *str, xmlXPathContextPtr ctxt) { 119813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathParserContextPtr pctxt; 119823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathObjectPtr res, tmp; 119833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int stack = 0; 119843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 11985f13f77f0e6a7876063d5fba15c096befb0827cedWilliam M. Brack CHECK_CTXT(ctxt) 119863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 11987f13f77f0e6a7876063d5fba15c096befb0827cedWilliam M. Brack xmlXPathInit(); 119883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 119893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor pctxt = xmlXPathNewParserContext(str, ctxt); 119903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathEvalExpr(pctxt); 119913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 119923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (*pctxt->cur != 0) { 119933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPatherror(pctxt, __FILE__, __LINE__, XPATH_EXPR_ERROR); 119943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor res = NULL; 119953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else { 119963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor res = valuePop(pctxt); 119973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 119983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor do { 119993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor tmp = valuePop(pctxt); 120003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (tmp != NULL) { 120013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeObject(tmp); 120023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor stack++; 120033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 120043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } while (tmp != NULL); 120053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((stack != 0) && (res != NULL)) { 120063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 120073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "xmlXPathEvalExpression: %d object left on the stack\n", 120083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor stack); 120093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 120103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFreeParserContext(pctxt); 120113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(res); 120123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 120133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1201442766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard/************************************************************************ 1201542766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * * 1201642766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * Extra functions not pertaining to the XPath spec * 1201742766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * * 1201842766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard ************************************************************************/ 1201942766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard/** 1202042766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * xmlXPathEscapeUriFunction: 1202142766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * @ctxt: the XPath Parser context 1202242766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * @nargs: the number of arguments 1202342766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * 1202442766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * Implement the escape-uri() XPath function 1202542766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * string escape-uri(string $str, bool $escape-reserved) 1202642766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * 1202742766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * This function applies the URI escaping rules defined in section 2 of [RFC 1202842766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * 2396] to the string supplied as $uri-part, which typically represents all 1202942766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * or part of a URI. The effect of the function is to replace any special 1203042766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * character in the string by an escape sequence of the form %xx%yy..., 1203142766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * where xxyy... is the hexadecimal representation of the octets used to 1203242766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * represent the character in UTF-8. 1203342766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * 1203442766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * The set of characters that are escaped depends on the setting of the 1203542766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * boolean argument $escape-reserved. 1203642766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * 1203742766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * If $escape-reserved is true, all characters are escaped other than lower 1203842766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * case letters a-z, upper case letters A-Z, digits 0-9, and the characters 1203942766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * referred to in [RFC 2396] as "marks": specifically, "-" | "_" | "." | "!" 1204042766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * | "~" | "*" | "'" | "(" | ")". The "%" character itself is escaped only 1204142766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * if it is not followed by two hexadecimal digits (that is, 0-9, a-f, and 1204242766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * A-F). 1204342766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * 1204442766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * If $escape-reserved is false, the behavior differs in that characters 1204542766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * referred to in [RFC 2396] as reserved characters are not escaped. These 1204642766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * characters are ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" | "$" | ",". 1204742766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * 1204842766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * [RFC 2396] does not define whether escaped URIs should use lower case or 1204942766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * upper case for hexadecimal digits. To ensure that escaped URIs can be 1205042766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * compared using string comparison functions, this function must always use 1205142766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * the upper-case letters A-F. 1205242766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * 1205342766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * Generally, $escape-reserved should be set to true when escaping a string 1205442766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * that is to form a single part of a URI, and to false when escaping an 1205542766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * entire URI or URI reference. 1205642766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * 1205742766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * In the case of non-ascii characters, the string is encoded according to 1205842766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * utf-8 and then converted according to RFC 2396. 1205942766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * 1206042766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * Examples 1206142766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * xf:escape-uri ("gopher://spinaltap.micro.umn.edu/00/Weather/California/Los%20Angeles#ocean"), true()) 1206242766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * returns "gopher%3A%2F%2Fspinaltap.micro.umn.edu%2F00%2FWeather%2FCalifornia%2FLos%20Angeles%23ocean" 1206342766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * xf:escape-uri ("gopher://spinaltap.micro.umn.edu/00/Weather/California/Los%20Angeles#ocean"), false()) 1206442766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * returns "gopher://spinaltap.micro.umn.edu/00/Weather/California/Los%20Angeles%23ocean" 1206542766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * 1206642766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard */ 12067118aed78f360f51d182770e62b251ef324707aa2Daniel Veillardstatic void 1206842766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel VeillardxmlXPathEscapeUriFunction(xmlXPathParserContextPtr ctxt, int nargs) { 1206942766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard xmlXPathObjectPtr str; 1207042766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard int escape_reserved; 1207142766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard xmlBufferPtr target; 1207242766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard xmlChar *cptr; 1207342766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard xmlChar escape[4]; 1207442766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard 1207542766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard CHECK_ARITY(2); 1207642766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard 1207742766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard escape_reserved = xmlXPathPopBoolean(ctxt); 1207842766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard 1207942766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard CAST_TO_STRING; 1208042766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard str = valuePop(ctxt); 1208142766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard 1208242766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard target = xmlBufferCreate(); 1208342766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard 1208442766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard escape[0] = '%'; 1208542766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard escape[3] = 0; 1208642766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard 1208742766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard if (target) { 1208842766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard for (cptr = str->stringval; *cptr; cptr++) { 1208942766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard if ((*cptr >= 'A' && *cptr <= 'Z') || 1209042766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard (*cptr >= 'a' && *cptr <= 'z') || 1209142766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard (*cptr >= '0' && *cptr <= '9') || 1209242766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard *cptr == '-' || *cptr == '_' || *cptr == '.' || 1209342766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard *cptr == '!' || *cptr == '~' || *cptr == '*' || 1209442766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard *cptr == '\''|| *cptr == '(' || *cptr == ')' || 1209542766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard (*cptr == '%' && 1209642766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard ((cptr[1] >= 'A' && cptr[1] <= 'F') || 1209742766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard (cptr[1] >= 'a' && cptr[1] <= 'f') || 1209842766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard (cptr[1] >= '0' && cptr[1] <= '9')) && 1209942766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard ((cptr[2] >= 'A' && cptr[2] <= 'F') || 1210042766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard (cptr[2] >= 'a' && cptr[2] <= 'f') || 1210142766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard (cptr[2] >= '0' && cptr[2] <= '9'))) || 1210242766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard (!escape_reserved && 1210342766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard (*cptr == ';' || *cptr == '/' || *cptr == '?' || 1210442766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard *cptr == ':' || *cptr == '@' || *cptr == '&' || 1210542766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard *cptr == '=' || *cptr == '+' || *cptr == '$' || 1210642766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard *cptr == ','))) { 1210742766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard xmlBufferAdd(target, cptr, 1); 1210842766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard } else { 1210942766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard if ((*cptr >> 4) < 10) 1211042766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard escape[1] = '0' + (*cptr >> 4); 1211142766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard else 1211242766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard escape[1] = 'A' - 10 + (*cptr >> 4); 1211342766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard if ((*cptr & 0xF) < 10) 1211442766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard escape[2] = '0' + (*cptr & 0xF); 1211542766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard else 1211642766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard escape[2] = 'A' - 10 + (*cptr & 0xF); 1211742766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard 1211842766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard xmlBufferAdd(target, &escape[0], 3); 1211942766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard } 1212042766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard } 1212142766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard } 1212242766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard valuePush(ctxt, xmlXPathNewString(xmlBufferContent(target))); 1212342766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard xmlBufferFree(target); 1212442766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard xmlXPathFreeObject(str); 1212542766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard} 1212642766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard 121273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 121283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathRegisterAllFunctions: 121293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the XPath context 121303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 121313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Registers all default XPath functions in this context 121323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 121333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 121343473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathRegisterAllFunctions(xmlXPathContextPtr ctxt) 121353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor{ 121363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisterFunc(ctxt, (const xmlChar *)"boolean", 121373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathBooleanFunction); 121383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisterFunc(ctxt, (const xmlChar *)"ceiling", 121393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathCeilingFunction); 121403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisterFunc(ctxt, (const xmlChar *)"count", 121413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathCountFunction); 121423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisterFunc(ctxt, (const xmlChar *)"concat", 121433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathConcatFunction); 121443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisterFunc(ctxt, (const xmlChar *)"contains", 121453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathContainsFunction); 121463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisterFunc(ctxt, (const xmlChar *)"id", 121473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathIdFunction); 121483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisterFunc(ctxt, (const xmlChar *)"false", 121493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFalseFunction); 121503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisterFunc(ctxt, (const xmlChar *)"floor", 121513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathFloorFunction); 121523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisterFunc(ctxt, (const xmlChar *)"last", 121533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathLastFunction); 121543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisterFunc(ctxt, (const xmlChar *)"lang", 121553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathLangFunction); 121563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisterFunc(ctxt, (const xmlChar *)"local-name", 121573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathLocalNameFunction); 121583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisterFunc(ctxt, (const xmlChar *)"not", 121593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathNotFunction); 121603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisterFunc(ctxt, (const xmlChar *)"name", 121613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathNameFunction); 121623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisterFunc(ctxt, (const xmlChar *)"namespace-uri", 121633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathNamespaceURIFunction); 121643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisterFunc(ctxt, (const xmlChar *)"normalize-space", 121653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathNormalizeFunction); 121663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisterFunc(ctxt, (const xmlChar *)"number", 121673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathNumberFunction); 121683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisterFunc(ctxt, (const xmlChar *)"position", 121693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathPositionFunction); 121703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisterFunc(ctxt, (const xmlChar *)"round", 121713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRoundFunction); 121723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisterFunc(ctxt, (const xmlChar *)"string", 121733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathStringFunction); 121743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisterFunc(ctxt, (const xmlChar *)"string-length", 121753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathStringLengthFunction); 121763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisterFunc(ctxt, (const xmlChar *)"starts-with", 121773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathStartsWithFunction); 121783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisterFunc(ctxt, (const xmlChar *)"substring", 121793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathSubstringFunction); 121803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisterFunc(ctxt, (const xmlChar *)"substring-before", 121813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathSubstringBeforeFunction); 121823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisterFunc(ctxt, (const xmlChar *)"substring-after", 121833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathSubstringAfterFunction); 121843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisterFunc(ctxt, (const xmlChar *)"sum", 121853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathSumFunction); 121863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisterFunc(ctxt, (const xmlChar *)"true", 121873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathTrueFunction); 121883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathRegisterFunc(ctxt, (const xmlChar *)"translate", 121893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlXPathTranslateFunction); 1219042766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard 1219142766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard xmlXPathRegisterFuncNS(ctxt, (const xmlChar *)"escape-uri", 1219242766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard (const xmlChar *)"http://www.w3.org/2002/08/xquery-functions", 1219342766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard xmlXPathEscapeUriFunction); 121943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 121953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 121963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif /* LIBXML_XPATH_ENABLED */ 121975d4644ef6e38479a648615eca758c5e962a141d5Daniel Veillard#define bottom_xpath 121985d4644ef6e38479a648615eca758c5e962a141d5Daniel Veillard#include "elfgcchack.h" 12199