xpath.c revision db3ce96906c09559d944c72b69eb984105f34776
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
5a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik *f
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
6245490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard#define TODO								\
63d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard    xmlGenericError(xmlGenericErrorContext,				\
64d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard	    "Unimplemented block at %s:%d\n",				\
65d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard            __FILE__, __LINE__);
66d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard
67d1757abcb891e01a9017f4aad041cc306d0d467bWilliam M. Brack/*
685691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik* XP_OPTIMIZED_NON_ELEM_COMPARISON:
692bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik* If defined, this will use xmlXPathCmpNodesExt() instead of
702bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik* xmlXPathCmpNodes(). The new function is optimized comparison of
712bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik* non-element nodes; actually it will speed up comparison only if
722bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik* xmlXPathOrderDocElems() was called in order to index the elements of
732bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik* a tree in document order; Libxslt does such an indexing, thus it will
742bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik* benefit from this optimization.
752bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik*/
765691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik#define XP_OPTIMIZED_NON_ELEM_COMPARISON
775691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik
785691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik/*
795691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik* XP_OPTIMIZED_FILTER_FIRST:
805691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik* If defined, this will optimize expressions like "key('foo', 'val')[b][1]"
815691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik* in a way, that it stop evaluation at the first node.
8245490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard*/
835691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik#define XP_OPTIMIZED_FILTER_FIRST
845691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik
8597258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik/*
86a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik* XP_DEBUG_OBJ_USAGE:
87a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik* Internal flag to enable tracking of how much XPath objects have been
88a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik* created.
89a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik*/
90a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik/* #define XP_DEBUG_OBJ_USAGE */
91a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
92a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik/*
93d1757abcb891e01a9017f4aad041cc306d0d467bWilliam M. Brack * TODO:
94d1757abcb891e01a9017f4aad041cc306d0d467bWilliam M. Brack * There are a few spots where some tests are done which depend upon ascii
95d1757abcb891e01a9017f4aad041cc306d0d467bWilliam M. Brack * data.  These should be enhanced for full UTF8 support (see particularly
96d1757abcb891e01a9017f4aad041cc306d0d467bWilliam M. Brack * any use of the macros IS_ASCII_CHARACTER and IS_ASCII_DIGIT)
97d1757abcb891e01a9017f4aad041cc306d0d467bWilliam M. Brack */
9897258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik
9921e4ef20f64ebd740ebac0ead5d85a5631d2db5eWilliam M. Brack#if defined(LIBXML_XPATH_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED)
100a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
101a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik/************************************************************************
10245490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *									*
10345490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *			Floating point stuff				*
10445490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *									*
1059e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard ************************************************************************/
1069e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
107c0631a608f62902eca453096f0b2fc5b449b0b0aDaniel Veillard#ifndef TRIO_REPLACE_STDIO
108cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard#define TRIO_PUBLIC static
109c0631a608f62902eca453096f0b2fc5b449b0b0aDaniel Veillard#endif
110cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard#include "trionan.c"
111cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard
1123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/*
1133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The lack of portability of this section of the libc is annoying !
1143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
1153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylordouble xmlXPathNAN = 0;
1163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylordouble xmlXPathPINF = 1;
1173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylordouble xmlXPathNINF = -1;
11824505b0f5c872c5afb6da5093565e5a6e09ca541Daniel Veillardstatic double xmlXPathNZERO = 0; /* not exported from headers */
11920ee8c03107e5d5724765da513d595fdaf290dceDaniel Veillardstatic int xmlXPathInitialized = 0;
1203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
1213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
1223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathInit:
1233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
1243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Initialize the XPath environment
1253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
1263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
1273473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathInit(void) {
12820ee8c03107e5d5724765da513d595fdaf290dceDaniel Veillard    if (xmlXPathInitialized) return;
1293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
130450296070e14629141738fbb34b9a0ad13af1f02Bjorn Reese    xmlXPathPINF = trio_pinf();
131450296070e14629141738fbb34b9a0ad13af1f02Bjorn Reese    xmlXPathNINF = trio_ninf();
132450296070e14629141738fbb34b9a0ad13af1f02Bjorn Reese    xmlXPathNAN = trio_nan();
1335fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard    xmlXPathNZERO = trio_nzero();
1343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
13520ee8c03107e5d5724765da513d595fdaf290dceDaniel Veillard    xmlXPathInitialized = 1;
1363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
1373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
138cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard/**
139cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * xmlXPathIsNaN:
140cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * @val:  a double value
141cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard *
142cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * Provides a portable isnan() function to detect whether a double
143cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * is a NotaNumber. Based on trio code
144cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * http://sourceforge.net/projects/ctrio/
14545490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *
146cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * Returns 1 if the value is a NaN, 0 otherwise
147cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard */
148cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillardint
149cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel VeillardxmlXPathIsNaN(double val) {
150cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard    return(trio_isnan(val));
151cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard}
152cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard
153cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard/**
154cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * xmlXPathIsInf:
155cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * @val:  a double value
156cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard *
157cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * Provides a portable isinf() function to detect whether a double
158cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * is a +Infinite or -Infinite. Based on trio code
159cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * http://sourceforge.net/projects/ctrio/
16045490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *
161cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * Returns 1 vi the value is +Infinite, -1 if -Infinite, 0 otherwise
162cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard */
163cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillardint
164cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel VeillardxmlXPathIsInf(double val) {
165cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard    return(trio_isinf(val));
166cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard}
167cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard
1684432df239b7aba6bff86c838e0be11d08f283b76Daniel Veillard#endif /* SCHEMAS or XPATH */
1694432df239b7aba6bff86c838e0be11d08f283b76Daniel Veillard#ifdef LIBXML_XPATH_ENABLED
1705fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard/**
1715fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard * xmlXPathGetSign:
1725fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard * @val:  a double value
1735fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard *
1745fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard * Provides a portable function to detect the sign of a double
1755fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard * Modified from trio code
1765fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard * http://sourceforge.net/projects/ctrio/
17745490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *
1785fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard * Returns 1 if the value is Negative, 0 if positive
1795fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard */
18021458c85e209cd2621ac3eadfee075ae2dc0121dDaniel Veillardstatic int
1815fc1f0893af6ffe76453ac16817204a866bdeab2Daniel VeillardxmlXPathGetSign(double val) {
18221458c85e209cd2621ac3eadfee075ae2dc0121dDaniel Veillard    return(trio_signbit(val));
1835fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard}
1845fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard
1855fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard
186d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillard/*
187d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillard * TODO: when compatibility allows remove all "fake node libxslt" strings
188d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillard *       the test should just be name[0] = ' '
189d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillard */
190074f37e7ebd5e76ceb584a89745a9e84df5b3be2Daniel Veillard#ifdef DEBUG_XPATH_EXPRESSION
191074f37e7ebd5e76ceb584a89745a9e84df5b3be2Daniel Veillard#define DEBUG_STEP
192074f37e7ebd5e76ceb584a89745a9e84df5b3be2Daniel Veillard#define DEBUG_EXPR
193074f37e7ebd5e76ceb584a89745a9e84df5b3be2Daniel Veillard#define DEBUG_EVAL_COUNTS
194074f37e7ebd5e76ceb584a89745a9e84df5b3be2Daniel Veillard#endif
195d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillard
196d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillardstatic xmlNs xmlXPathXMLNamespaceStruct = {
197d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillard    NULL,
198d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillard    XML_NAMESPACE_DECL,
199d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillard    XML_XML_NAMESPACE,
200d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillard    BAD_CAST "xml",
201ee0b982fe81018f8a190f62335c0e7957f4c5bcdWilliam M. Brack    NULL,
202d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillard    NULL
203d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillard};
204d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillardstatic xmlNsPtr xmlXPathXMLNamespace = &xmlXPathXMLNamespaceStruct;
205d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillard#ifndef LIBXML_THREAD_ENABLED
20645490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard/*
207d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillard * Optimizer is disabled only when threaded apps are detected while
208d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillard * the library ain't compiled for thread safety.
209d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillard */
210d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillardstatic int xmlXPathDisableOptimizer = 0;
211d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillard#endif
212d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillard
2133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/************************************************************************
214d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard *									*
215d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard *			Error handling routines				*
216d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard *									*
217d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard ************************************************************************/
218d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard
21924505b0f5c872c5afb6da5093565e5a6e09ca541Daniel Veillard/**
22024505b0f5c872c5afb6da5093565e5a6e09ca541Daniel Veillard * XP_ERRORNULL:
22124505b0f5c872c5afb6da5093565e5a6e09ca541Daniel Veillard * @X:  the error code
22224505b0f5c872c5afb6da5093565e5a6e09ca541Daniel Veillard *
22324505b0f5c872c5afb6da5093565e5a6e09ca541Daniel Veillard * Macro to raise an XPath error and return NULL.
22424505b0f5c872c5afb6da5093565e5a6e09ca541Daniel Veillard */
22524505b0f5c872c5afb6da5093565e5a6e09ca541Daniel Veillard#define XP_ERRORNULL(X)							\
22624505b0f5c872c5afb6da5093565e5a6e09ca541Daniel Veillard    { xmlXPathErr(ctxt, X); return(NULL); }
22724505b0f5c872c5afb6da5093565e5a6e09ca541Daniel Veillard
228081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack/*
229081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack * The array xmlXPathErrorMessages corresponds to the enum xmlXPathError
230081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack */
231d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillardstatic const char *xmlXPathErrorMessages[] = {
232d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard    "Ok\n",
233d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard    "Number encoding\n",
234d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard    "Unfinished literal\n",
235d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard    "Start of literal\n",
236d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard    "Expected $ for variable reference\n",
237d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard    "Undefined variable\n",
238d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard    "Invalid predicate\n",
239d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard    "Invalid expression\n",
240d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard    "Missing closing curly brace\n",
241d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard    "Unregistered function\n",
242d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard    "Invalid operand\n",
243d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard    "Invalid type\n",
244d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard    "Invalid number of arguments\n",
245d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard    "Invalid context size\n",
246d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard    "Invalid context position\n",
247d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard    "Memory allocation error\n",
248d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard    "Syntax error\n",
249d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard    "Resource error\n",
250d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard    "Sub resource error\n",
251d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard    "Undefined namespace prefix\n",
252d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard    "Encoding error\n",
25357b2516af5e2e06c54750b6549723cf5b8edf8a4Daniel Veillard    "Char out of XML range\n",
254cd65bc9a49b406899c78e9e8f6757acca54fc04eWilliam M. Brack    "Invalid or incomplete context\n",
255cd65bc9a49b406899c78e9e8f6757acca54fc04eWilliam M. Brack    "?? Unknown error ??\n"	/* Must be last in the list! */
256d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard};
257cd65bc9a49b406899c78e9e8f6757acca54fc04eWilliam M. Brack#define MAXERRNO ((int)(sizeof(xmlXPathErrorMessages) /	\
258cd65bc9a49b406899c78e9e8f6757acca54fc04eWilliam M. Brack		   sizeof(xmlXPathErrorMessages[0])) - 1)
259d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard/**
260d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard * xmlXPathErrMemory:
261d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard * @ctxt:  an XPath context
262d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard * @extra:  extra informations
263d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard *
264d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard * Handle a redefinition of attribute error
265d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard */
266d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillardstatic void
267d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel VeillardxmlXPathErrMemory(xmlXPathContextPtr ctxt, const char *extra)
268d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard{
269d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard    if (ctxt != NULL) {
270d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard        if (extra) {
271d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard            xmlChar buf[200];
272d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard
273d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard            xmlStrPrintf(buf, 200,
274d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard                         BAD_CAST "Memory allocation failed : %s\n",
275d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard                         extra);
276d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard            ctxt->lastError.message = (char *) xmlStrdup(buf);
277d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard        } else {
278d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard            ctxt->lastError.message = (char *)
279d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard	       xmlStrdup(BAD_CAST "Memory allocation failed\n");
280d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard        }
281d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard        ctxt->lastError.domain = XML_FROM_XPATH;
282d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard        ctxt->lastError.code = XML_ERR_NO_MEMORY;
283d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard	if (ctxt->error != NULL)
284d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard	    ctxt->error(ctxt->userData, &ctxt->lastError);
285d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard    } else {
286d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard        if (extra)
287659e71ec2476d24bfca0d6432a69ef9a49a62be4Daniel Veillard            __xmlRaiseError(NULL, NULL, NULL,
288d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard                            NULL, NULL, XML_FROM_XPATH,
289d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard                            XML_ERR_NO_MEMORY, XML_ERR_FATAL, NULL, 0,
290d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard                            extra, NULL, NULL, 0, 0,
291d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard                            "Memory allocation failed : %s\n", extra);
292d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard        else
293659e71ec2476d24bfca0d6432a69ef9a49a62be4Daniel Veillard            __xmlRaiseError(NULL, NULL, NULL,
294d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard                            NULL, NULL, XML_FROM_XPATH,
295d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard                            XML_ERR_NO_MEMORY, XML_ERR_FATAL, NULL, 0,
296d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard                            NULL, NULL, NULL, 0, 0,
297d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard                            "Memory allocation failed\n");
298d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard    }
299d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard}
300d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard
301d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard/**
3028de5c0bd79cceeca3d55d6dbf8f0248b7239e050Daniel Veillard * xmlXPathPErrMemory:
303d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard * @ctxt:  an XPath parser context
304d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard * @extra:  extra informations
305d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard *
306d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard * Handle a redefinition of attribute error
307d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard */
308d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillardstatic void
309d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel VeillardxmlXPathPErrMemory(xmlXPathParserContextPtr ctxt, const char *extra)
310d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard{
311d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard    if (ctxt == NULL)
312d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard	xmlXPathErrMemory(NULL, extra);
31311ce4004d86bb4b317c48b7d5124ba33e40e10f5Daniel Veillard    else {
31411ce4004d86bb4b317c48b7d5124ba33e40e10f5Daniel Veillard	ctxt->error = XPATH_MEMORY_ERROR;
315d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard	xmlXPathErrMemory(ctxt->context, extra);
31611ce4004d86bb4b317c48b7d5124ba33e40e10f5Daniel Veillard    }
317d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard}
318d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard
319d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard/**
320d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard * xmlXPathErr:
321d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard * @ctxt:  a XPath parser context
322d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard * @error:  the error code
323d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard *
324cd65bc9a49b406899c78e9e8f6757acca54fc04eWilliam M. Brack * Handle an XPath error
325d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard */
326d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillardvoid
327d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel VeillardxmlXPathErr(xmlXPathParserContextPtr ctxt, int error)
328d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard{
329cd65bc9a49b406899c78e9e8f6757acca54fc04eWilliam M. Brack    if ((error < 0) || (error > MAXERRNO))
330cd65bc9a49b406899c78e9e8f6757acca54fc04eWilliam M. Brack	error = MAXERRNO;
331f88d8cf9f1c9538dba187290ad5add003dc22bc7Daniel Veillard    if (ctxt == NULL) {
332659e71ec2476d24bfca0d6432a69ef9a49a62be4Daniel Veillard	__xmlRaiseError(NULL, NULL, NULL,
333d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard			NULL, NULL, XML_FROM_XPATH,
334d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard			error + XML_XPATH_EXPRESSION_OK - XPATH_EXPRESSION_OK,
335d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard			XML_ERR_ERROR, NULL, 0,
336d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard			NULL, NULL, NULL, 0, 0,
337d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard			xmlXPathErrorMessages[error]);
338d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard	return;
339d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard    }
340f88d8cf9f1c9538dba187290ad5add003dc22bc7Daniel Veillard    ctxt->error = error;
341f88d8cf9f1c9538dba187290ad5add003dc22bc7Daniel Veillard    if (ctxt->context == NULL) {
342f88d8cf9f1c9538dba187290ad5add003dc22bc7Daniel Veillard	__xmlRaiseError(NULL, NULL, NULL,
343f88d8cf9f1c9538dba187290ad5add003dc22bc7Daniel Veillard			NULL, NULL, XML_FROM_XPATH,
344f88d8cf9f1c9538dba187290ad5add003dc22bc7Daniel Veillard			error + XML_XPATH_EXPRESSION_OK - XPATH_EXPRESSION_OK,
345f88d8cf9f1c9538dba187290ad5add003dc22bc7Daniel Veillard			XML_ERR_ERROR, NULL, 0,
346f88d8cf9f1c9538dba187290ad5add003dc22bc7Daniel Veillard			(const char *) ctxt->base, NULL, NULL,
347f88d8cf9f1c9538dba187290ad5add003dc22bc7Daniel Veillard			ctxt->cur - ctxt->base, 0,
348f88d8cf9f1c9538dba187290ad5add003dc22bc7Daniel Veillard			xmlXPathErrorMessages[error]);
349f88d8cf9f1c9538dba187290ad5add003dc22bc7Daniel Veillard	return;
350f88d8cf9f1c9538dba187290ad5add003dc22bc7Daniel Veillard    }
3511b2be101e8c7c6c0b65d9961a302885aead9bc22Aleksey Sanin
3521b2be101e8c7c6c0b65d9961a302885aead9bc22Aleksey Sanin    /* cleanup current last error */
35345490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard    xmlResetError(&ctxt->context->lastError);
3541b2be101e8c7c6c0b65d9961a302885aead9bc22Aleksey Sanin
355d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard    ctxt->context->lastError.domain = XML_FROM_XPATH;
356d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard    ctxt->context->lastError.code = error + XML_XPATH_EXPRESSION_OK -
357d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard                           XPATH_EXPRESSION_OK;
358fcf719ce0a94f0d438f69b73cd1ca31a7000da81Daniel Veillard    ctxt->context->lastError.level = XML_ERR_ERROR;
359d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard    ctxt->context->lastError.str1 = (char *) xmlStrdup(ctxt->base);
360d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard    ctxt->context->lastError.int1 = ctxt->cur - ctxt->base;
361d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard    ctxt->context->lastError.node = ctxt->context->debugNode;
362d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard    if (ctxt->context->error != NULL) {
363d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard	ctxt->context->error(ctxt->context->userData,
364d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard	                     &ctxt->context->lastError);
365d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard    } else {
366659e71ec2476d24bfca0d6432a69ef9a49a62be4Daniel Veillard	__xmlRaiseError(NULL, NULL, NULL,
367d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard			NULL, ctxt->context->debugNode, XML_FROM_XPATH,
368d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard			error + XML_XPATH_EXPRESSION_OK - XPATH_EXPRESSION_OK,
369d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard			XML_ERR_ERROR, NULL, 0,
370d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard			(const char *) ctxt->base, NULL, NULL,
371d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard			ctxt->cur - ctxt->base, 0,
372d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard			xmlXPathErrorMessages[error]);
373d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard    }
374d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard
375d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard}
376d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard
377d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard/**
378d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard * xmlXPatherror:
379d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard * @ctxt:  the XPath Parser context
380d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard * @file:  the file name
381d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard * @line:  the line number
382d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard * @no:  the error number
383d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard *
384d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard * Formats an error message.
385d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard */
386d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillardvoid
387d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel VeillardxmlXPatherror(xmlXPathParserContextPtr ctxt, const char *file ATTRIBUTE_UNUSED,
388d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard              int line ATTRIBUTE_UNUSED, int no) {
389d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard    xmlXPathErr(ctxt, no);
390d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard}
391d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard
392a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik/************************************************************************
39345490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *									*
39445490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *			Utilities					*
39545490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *									*
396a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik ************************************************************************/
397a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
398a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik/**
399a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * xsltPointerList:
400a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik *
401a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * Pointer-list for various purposes.
402a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik */
403a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchciktypedef struct _xmlPointerList xmlPointerList;
404a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchciktypedef xmlPointerList *xmlPointerListPtr;
405a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikstruct _xmlPointerList {
406a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    void **items;
407a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    int number;
408a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    int size;
409a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik};
410a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik/*
411a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik* TODO: Since such a list-handling is used in xmlschemas.c and libxslt
412a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik* and here, we should make the functions public.
413a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik*/
414a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikstatic int
41545490aebe7a60704e8ed850c498969858ab900eeDaniel VeillardxmlPointerListAddSize(xmlPointerListPtr list,
416a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		       void *item,
417a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		       int initialSize)
418a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik{
419a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    if (list->items == NULL) {
420a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	if (initialSize <= 0)
421a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    initialSize = 1;
422a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	list->items = (void **) xmlMalloc(
423a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    initialSize * sizeof(void *));
424a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	if (list->items == NULL) {
425a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathErrMemory(NULL,
426a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		"xmlPointerListCreate: allocating item\n");
427a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    return(-1);
428a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	}
429a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	list->number = 0;
430a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	list->size = initialSize;
431a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    } else if (list->size <= list->number) {
432a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	list->size *= 2;
433a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	list->items = (void **) xmlRealloc(list->items,
434a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    list->size * sizeof(void *));
435a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	if (list->items == NULL) {
436a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathErrMemory(NULL,
437a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		"xmlPointerListCreate: re-allocating item\n");
438a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    list->size = 0;
439a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    return(-1);
440a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	}
441a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    }
442a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    list->items[list->number++] = item;
443a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    return(0);
444a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik}
445a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
446a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik/**
447a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * xsltPointerListCreate:
448a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik *
449a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * Creates an xsltPointerList structure.
450a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik *
451a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * Returns a xsltPointerList structure or NULL in case of an error.
452a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik */
453a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikstatic xmlPointerListPtr
454a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. BuchcikxmlPointerListCreate(int initialSize)
455a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik{
456a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlPointerListPtr ret;
457a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
458a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    ret = xmlMalloc(sizeof(xmlPointerList));
459a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    if (ret == NULL) {
460a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	xmlXPathErrMemory(NULL,
461a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    "xmlPointerListCreate: allocating item\n");
462a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	return (NULL);
463a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    }
464a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    memset(ret, 0, sizeof(xmlPointerList));
465a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    if (initialSize > 0) {
466a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	xmlPointerListAddSize(ret, NULL, initialSize);
467a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	ret->number = 0;
468a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    }
469a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    return (ret);
470a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik}
471a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
472a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik/**
473a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * xsltPointerListFree:
474a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik *
475a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * Frees the xsltPointerList structure. This does not free
476a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * the content of the list.
477a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik */
478a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikstatic void
479a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. BuchcikxmlPointerListFree(xmlPointerListPtr list)
480a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik{
481a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    if (list == NULL)
482a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	return;
483a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    if (list->items != NULL)
484a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	xmlFree(list->items);
485a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlFree(list);
486a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik}
487d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard
488d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard/************************************************************************
48945490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *									*
49045490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *			Parser Types					*
49145490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *									*
4929e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard ************************************************************************/
4939e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
4949e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard/*
4959e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * Types are private:
4969e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard */
4979e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
4989e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillardtypedef enum {
4999e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    XPATH_OP_END=0,
5009e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    XPATH_OP_AND,
5019e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    XPATH_OP_OR,
5029e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    XPATH_OP_EQUAL,
5039e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    XPATH_OP_CMP,
5049e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    XPATH_OP_PLUS,
5059e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    XPATH_OP_MULT,
5069e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    XPATH_OP_UNION,
5079e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    XPATH_OP_ROOT,
5089e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    XPATH_OP_NODE,
5095691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik    XPATH_OP_RESET, /* 10 */
5109e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    XPATH_OP_COLLECT,
5115691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik    XPATH_OP_VALUE, /* 12 */
5129e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    XPATH_OP_VARIABLE,
5139e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    XPATH_OP_FUNCTION,
5149e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    XPATH_OP_ARG,
5159e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    XPATH_OP_PREDICATE,
5165691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik    XPATH_OP_FILTER, /* 17 */
5175691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik    XPATH_OP_SORT /* 18 */
5189e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard#ifdef LIBXML_XPTR_ENABLED
5199e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    ,XPATH_OP_RANGETO
5209e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard#endif
5219e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard} xmlXPathOp;
5229e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
5239e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillardtypedef enum {
5249e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    AXIS_ANCESTOR = 1,
5259e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    AXIS_ANCESTOR_OR_SELF,
5269e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    AXIS_ATTRIBUTE,
5279e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    AXIS_CHILD,
5289e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    AXIS_DESCENDANT,
5299e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    AXIS_DESCENDANT_OR_SELF,
5309e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    AXIS_FOLLOWING,
5319e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    AXIS_FOLLOWING_SIBLING,
5329e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    AXIS_NAMESPACE,
5339e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    AXIS_PARENT,
5349e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    AXIS_PRECEDING,
5359e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    AXIS_PRECEDING_SIBLING,
53645490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard    AXIS_SELF
5379e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard} xmlXPathAxisVal;
5389e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
5399e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillardtypedef enum {
5409e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    NODE_TEST_NONE = 0,
5419e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    NODE_TEST_TYPE = 1,
5429e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    NODE_TEST_PI = 2,
5439e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    NODE_TEST_ALL = 3,
5449e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    NODE_TEST_NS = 4,
5459e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    NODE_TEST_NAME = 5
5469e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard} xmlXPathTestVal;
5479e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
5489e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillardtypedef enum {
5499e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    NODE_TYPE_NODE = 0,
5509e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    NODE_TYPE_COMMENT = XML_COMMENT_NODE,
5519e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    NODE_TYPE_TEXT = XML_TEXT_NODE,
55245490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard    NODE_TYPE_PI = XML_PI_NODE
5539e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard} xmlXPathTypeVal;
5549e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
555df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik#define XP_REWRITE_DOS_CHILD_ELEM 1
5569e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
5579e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillardtypedef struct _xmlXPathStepOp xmlXPathStepOp;
5589e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillardtypedef xmlXPathStepOp *xmlXPathStepOpPtr;
5599e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillardstruct _xmlXPathStepOp {
560081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack    xmlXPathOp op;		/* The identifier of the operation */
561081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack    int ch1;			/* First child */
562081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack    int ch2;			/* Second child */
5639e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    int value;
5649e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    int value2;
5659e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    int value3;
5669e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    void *value4;
5679e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    void *value5;
568e39a93d0d3df9907cf3538cd3f1fbbe4106e893dDaniel Veillard    void *cache;
56942596ad20cdf1925dd79ea801cbe598b6e7b7aecDaniel Veillard    void *cacheURI;
570df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik    int rewriteType;
5719e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard};
5729e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
5739e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillardstruct _xmlXPathCompExpr {
574081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack    int nbStep;			/* Number of steps in this expression */
575081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack    int maxStep;		/* Maximum number of steps allocated */
576081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack    xmlXPathStepOp *steps;	/* ops for computation of this expression */
577081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack    int last;			/* index of last step in expression */
578081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack    xmlChar *expr;		/* the expression being computed */
5794773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard    xmlDictPtr dict;		/* the dictionnary to use if any */
580f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#ifdef DEBUG_EVAL_COUNTS
581f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    int nb;
582f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    xmlChar *string;
583f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#endif
58456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard#ifdef XPATH_STREAMING
58556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard    xmlPatternPtr stream;
58656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard#endif
5879e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard};
5889e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
5899e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard/************************************************************************
59045490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *									*
59145490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *			Forward declarations				*
59245490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *									*
593631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik ************************************************************************/
594631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcikstatic void
595631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. BuchcikxmlXPathFreeValueTree(xmlNodeSetPtr obj);
596631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcikstatic void
597631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. BuchcikxmlXPathReleaseObject(xmlXPathContextPtr ctxt, xmlXPathObjectPtr obj);
598631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcikstatic int
599631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. BuchcikxmlXPathCompOpEvalFirst(xmlXPathParserContextPtr ctxt,
600631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik                        xmlXPathStepOpPtr op, xmlNodePtr *first);
601631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcikstatic int
602631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. BuchcikxmlXPathCompOpEvalToBoolean(xmlXPathParserContextPtr ctxt,
603324c75b3c3edffcd30e7afa2a32f0d83d928b10dKasimier T. Buchcik			    xmlXPathStepOpPtr op,
604324c75b3c3edffcd30e7afa2a32f0d83d928b10dKasimier T. Buchcik			    int isPredicate);
605631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik
606631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik/************************************************************************
60745490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *									*
60845490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *			Parser Type functions				*
60945490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *									*
6109e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard ************************************************************************/
6119e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
6129e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard/**
6139e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * xmlXPathNewCompExpr:
6149e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard *
6159e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * Create a new Xpath component
6169e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard *
6179e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * Returns the newly allocated xmlXPathCompExprPtr or NULL in case of error
6189e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard */
61956a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic xmlXPathCompExprPtr
6209e7160d45a18bfa26d708e22ba991f7670d0128bDaniel VeillardxmlXPathNewCompExpr(void) {
6219e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    xmlXPathCompExprPtr cur;
6229e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
6239e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    cur = (xmlXPathCompExprPtr) xmlMalloc(sizeof(xmlXPathCompExpr));
6249e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    if (cur == NULL) {
625d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard        xmlXPathErrMemory(NULL, "allocating component\n");
6269e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	return(NULL);
6279e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    }
6289e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    memset(cur, 0, sizeof(xmlXPathCompExpr));
6299e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    cur->maxStep = 10;
6309e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    cur->nbStep = 0;
6319e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    cur->steps = (xmlXPathStepOp *) xmlMalloc(cur->maxStep *
6329e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	                                   sizeof(xmlXPathStepOp));
6339e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    if (cur->steps == NULL) {
634d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard        xmlXPathErrMemory(NULL, "allocating steps\n");
6359e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	xmlFree(cur);
6369e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	return(NULL);
6379e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    }
6389e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    memset(cur->steps, 0, cur->maxStep * sizeof(xmlXPathStepOp));
6399e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    cur->last = -1;
640f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#ifdef DEBUG_EVAL_COUNTS
641f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    cur->nb = 0;
642f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#endif
6439e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    return(cur);
6449e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard}
6459e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
6469e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard/**
6479e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * xmlXPathFreeCompExpr:
6489e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * @comp:  an XPATH comp
6499e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard *
6509e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * Free up the memory allocated by @comp
6519e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard */
6529e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillardvoid
653f06307e2c172284bb41376c396f757bdac9bdd19Daniel VeillardxmlXPathFreeCompExpr(xmlXPathCompExprPtr comp)
654f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard{
6559e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    xmlXPathStepOpPtr op;
6569e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    int i;
6579e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
6589e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    if (comp == NULL)
659f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        return;
6604773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard    if (comp->dict == NULL) {
6614773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard	for (i = 0; i < comp->nbStep; i++) {
6624773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard	    op = &comp->steps[i];
6634773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard	    if (op->value4 != NULL) {
6644773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard		if (op->op == XPATH_OP_VALUE)
6654773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard		    xmlXPathFreeObject(op->value4);
6664773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard		else
6674773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard		    xmlFree(op->value4);
6684773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard	    }
6694773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard	    if (op->value5 != NULL)
6704773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard		xmlFree(op->value5);
6714773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard	}
6724773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard    } else {
6734773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard	for (i = 0; i < comp->nbStep; i++) {
6744773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard	    op = &comp->steps[i];
6754773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard	    if (op->value4 != NULL) {
6764773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard		if (op->op == XPATH_OP_VALUE)
6774773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard		    xmlXPathFreeObject(op->value4);
6784773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard	    }
6794773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard	}
6804773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard        xmlDictFree(comp->dict);
6819e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    }
6829e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    if (comp->steps != NULL) {
683f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        xmlFree(comp->steps);
6849e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    }
685f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#ifdef DEBUG_EVAL_COUNTS
686f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    if (comp->string != NULL) {
687f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        xmlFree(comp->string);
688f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    }
689f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#endif
69056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard#ifdef XPATH_STREAMING
69156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard    if (comp->stream != NULL) {
69256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard        xmlFreePatternList(comp->stream);
69356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard    }
69456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard#endif
695118aed78f360f51d182770e62b251ef324707aa2Daniel Veillard    if (comp->expr != NULL) {
696118aed78f360f51d182770e62b251ef324707aa2Daniel Veillard        xmlFree(comp->expr);
697118aed78f360f51d182770e62b251ef324707aa2Daniel Veillard    }
698f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
6999e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    xmlFree(comp);
7009e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard}
7019e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
7029e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard/**
7039e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * xmlXPathCompExprAdd:
7049e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * @comp:  the compiled expression
7059e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * @ch1: first child index
7069e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * @ch2: second child index
7079e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * @op:  an op
7089e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * @value:  the first int value
7099e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * @value2:  the second int value
7109e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * @value3:  the third int value
7119e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * @value4:  the first string value
7129e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * @value5:  the second string value
7139e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard *
714081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack * Add a step to an XPath Compiled Expression
7159e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard *
7169e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * Returns -1 in case of failure, the index otherwise
7179e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard */
71856a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic int
7199e7160d45a18bfa26d708e22ba991f7670d0128bDaniel VeillardxmlXPathCompExprAdd(xmlXPathCompExprPtr comp, int ch1, int ch2,
7209e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard   xmlXPathOp op, int value,
7219e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard   int value2, int value3, void *value4, void *value5) {
7229e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    if (comp->nbStep >= comp->maxStep) {
7239e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	xmlXPathStepOp *real;
7249e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
7259e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	comp->maxStep *= 2;
7269e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	real = (xmlXPathStepOp *) xmlRealloc(comp->steps,
7279e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		                      comp->maxStep * sizeof(xmlXPathStepOp));
7289e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	if (real == NULL) {
7299e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    comp->maxStep /= 2;
730d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard	    xmlXPathErrMemory(NULL, "adding step\n");
7319e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    return(-1);
7329e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	}
7339e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	comp->steps = real;
7349e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    }
7359e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    comp->last = comp->nbStep;
7366422d916d929cb8653d950d4b424388a7ea7230dKasimier T. Buchcik    comp->steps[comp->nbStep].rewriteType = 0;
7379e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    comp->steps[comp->nbStep].ch1 = ch1;
7389e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    comp->steps[comp->nbStep].ch2 = ch2;
7399e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    comp->steps[comp->nbStep].op = op;
7409e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    comp->steps[comp->nbStep].value = value;
7419e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    comp->steps[comp->nbStep].value2 = value2;
7429e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    comp->steps[comp->nbStep].value3 = value3;
7434773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard    if ((comp->dict != NULL) &&
7444773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard        ((op == XPATH_OP_FUNCTION) || (op == XPATH_OP_VARIABLE) ||
7454773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard	 (op == XPATH_OP_COLLECT))) {
7464773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard        if (value4 != NULL) {
747b337795500cbe3fc47ac2b81f3d955126c6fbfdeDaniel Veillard	    comp->steps[comp->nbStep].value4 = (xmlChar *)
748c07ed5e6a14fb801cfd6bbb2a582caf726e5324eWilliam M. Brack	        (void *)xmlDictLookup(comp->dict, value4, -1);
7494773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard	    xmlFree(value4);
7504773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard	} else
7514773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard	    comp->steps[comp->nbStep].value4 = NULL;
7524773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard        if (value5 != NULL) {
753b337795500cbe3fc47ac2b81f3d955126c6fbfdeDaniel Veillard	    comp->steps[comp->nbStep].value5 = (xmlChar *)
754c07ed5e6a14fb801cfd6bbb2a582caf726e5324eWilliam M. Brack	        (void *)xmlDictLookup(comp->dict, value5, -1);
7554773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard	    xmlFree(value5);
7564773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard	} else
7574773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard	    comp->steps[comp->nbStep].value5 = NULL;
7584773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard    } else {
7594773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard	comp->steps[comp->nbStep].value4 = value4;
7604773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard	comp->steps[comp->nbStep].value5 = value5;
7614773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard    }
762e39a93d0d3df9907cf3538cd3f1fbbe4106e893dDaniel Veillard    comp->steps[comp->nbStep].cache = NULL;
7639e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    return(comp->nbStep++);
7649e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard}
7659e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
766f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard/**
767f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * xmlXPathCompSwap:
768f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * @comp:  the compiled expression
769f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * @op: operation index
770f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard *
771f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Swaps 2 operations in the compiled expression
772f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */
773f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillardstatic void
774f06307e2c172284bb41376c396f757bdac9bdd19Daniel VeillardxmlXPathCompSwap(xmlXPathStepOpPtr op) {
775f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    int tmp;
776f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
777bc6f759ac9b41773e3643ad288b5214732051c98Daniel Veillard#ifndef LIBXML_THREAD_ENABLED
7788146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard    /*
7798146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard     * Since this manipulates possibly shared variables, this is
780081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack     * disabled if one detects that the library is used in a multithreaded
7818146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard     * application
7828146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard     */
7838146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard    if (xmlXPathDisableOptimizer)
7848146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard	return;
7858146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard#endif
7868146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard
787f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    tmp = op->ch1;
788f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    op->ch1 = op->ch2;
789f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    op->ch2 = tmp;
790f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard}
791f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
792d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#define PUSH_FULL_EXPR(op, op1, op2, val, val2, val3, val4, val5)	\
793d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard    xmlXPathCompExprAdd(ctxt->comp, (op1), (op2),			\
794d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	                (op), (val), (val2), (val3), (val4), (val5))
7959e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard#define PUSH_LONG_EXPR(op, val, val2, val3, val4, val5)			\
7969e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    xmlXPathCompExprAdd(ctxt->comp, ctxt->comp->last, -1,		\
7979e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	                (op), (val), (val2), (val3), (val4), (val5))
7989e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
79945490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard#define PUSH_LEAVE_EXPR(op, val, val2)					\
8009e7160d45a18bfa26d708e22ba991f7670d0128bDaniel VeillardxmlXPathCompExprAdd(ctxt->comp, -1, -1, (op), (val), (val2), 0 ,NULL ,NULL)
8019e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
80245490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard#define PUSH_UNARY_EXPR(op, ch, val, val2)				\
8039e7160d45a18bfa26d708e22ba991f7670d0128bDaniel VeillardxmlXPathCompExprAdd(ctxt->comp, (ch), -1, (op), (val), (val2), 0 ,NULL ,NULL)
8049e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
80545490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard#define PUSH_BINARY_EXPR(op, ch1, ch2, val, val2)			\
806081719182de3d15e6a438f32fdc3d1ca240a08e8William M. BrackxmlXPathCompExprAdd(ctxt->comp, (ch1), (ch2), (op),			\
807081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack			(val), (val2), 0 ,NULL ,NULL)
8089e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
8099e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard/************************************************************************
8103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *									*
81145490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *		XPath object cache structures				*
812a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik *									*
813a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik ************************************************************************/
814a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
815a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik/* #define XP_DEFAULT_CACHE_ON */
816a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
8175869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik#define XP_HAS_CACHE(c) ((c != NULL) && ((c)->cache != NULL))
818a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
8195869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchciktypedef struct _xmlXPathContextCache xmlXPathContextCache;
8205869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchciktypedef xmlXPathContextCache *xmlXPathContextCachePtr;
8215869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcikstruct _xmlXPathContextCache {
82275af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik    xmlPointerListPtr nodesetObjs;  /* contains xmlXPathObjectPtr */
82375af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik    xmlPointerListPtr stringObjs;   /* contains xmlXPathObjectPtr */
82475af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik    xmlPointerListPtr booleanObjs;  /* contains xmlXPathObjectPtr */
82575af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik    xmlPointerListPtr numberObjs;   /* contains xmlXPathObjectPtr */
82675af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik    xmlPointerListPtr miscObjs;     /* contains xmlXPathObjectPtr */
827a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    int maxNodeset;
828a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    int maxString;
829a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    int maxBoolean;
830a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    int maxNumber;
831a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    int maxMisc;
832a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#ifdef XP_DEBUG_OBJ_USAGE
833a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    int dbgCachedAll;
834a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    int dbgCachedNodeset;
835a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    int dbgCachedString;
836a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    int dbgCachedBool;
837a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    int dbgCachedNumber;
838a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    int dbgCachedPoint;
839a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    int dbgCachedRange;
840a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    int dbgCachedLocset;
841a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    int dbgCachedUsers;
842a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    int dbgCachedXSLTTree;
84345490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard    int dbgCachedUndefined;
84445490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
845a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
846a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    int dbgReusedAll;
847a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    int dbgReusedNodeset;
848a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    int dbgReusedString;
849a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    int dbgReusedBool;
850a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    int dbgReusedNumber;
851a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    int dbgReusedPoint;
852a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    int dbgReusedRange;
853a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    int dbgReusedLocset;
854a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    int dbgReusedUsers;
855a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    int dbgReusedXSLTTree;
856a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    int dbgReusedUndefined;
857a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
858a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#endif
859a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik};
860a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
861a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik/************************************************************************
862a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik *									*
86345490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *		Debugging related functions				*
8643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *									*
8653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ************************************************************************/
8663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
86745490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard#define STRANGE							\
8683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlGenericError(xmlGenericErrorContext,				\
8693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    "Internal error at %s:%d\n",				\
8703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            __FILE__, __LINE__);
8713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
8723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef LIBXML_DEBUG_ENABLED
87356a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic void
87456a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel VeillardxmlXPathDebugDumpNode(FILE *output, xmlNodePtr cur, int depth) {
8753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    int i;
8763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    char shift[100];
8773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
8783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    for (i = 0;((i < depth) && (i < 25));i++)
8793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        shift[2 * i] = shift[2 * i + 1] = ' ';
8803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    shift[2 * i] = shift[2 * i + 1] = 0;
8813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (cur == NULL) {
8823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	fprintf(output, shift);
8833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	fprintf(output, "Node is NULL !\n");
8843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return;
88545490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
8863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
8873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
8883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if ((cur->type == XML_DOCUMENT_NODE) ||
8893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	     (cur->type == XML_HTML_DOCUMENT_NODE)) {
8903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	fprintf(output, shift);
8913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	fprintf(output, " /\n");
8923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    } else if (cur->type == XML_ATTRIBUTE_NODE)
8933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	xmlDebugDumpAttr(output, (xmlAttrPtr)cur, depth);
8943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    else
8953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	xmlDebugDumpOneNode(output, cur, depth);
8963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
89756a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic void
89856a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel VeillardxmlXPathDebugDumpNodeList(FILE *output, xmlNodePtr cur, int depth) {
899f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard    xmlNodePtr tmp;
900f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard    int i;
901f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard    char shift[100];
902f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard
903f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard    for (i = 0;((i < depth) && (i < 25));i++)
904f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard        shift[2 * i] = shift[2 * i + 1] = ' ';
905f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard    shift[2 * i] = shift[2 * i + 1] = 0;
906f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard    if (cur == NULL) {
907f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard	fprintf(output, shift);
908f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard	fprintf(output, "Node is NULL !\n");
909f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard	return;
91045490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
911f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard    }
912f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard
913f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard    while (cur != NULL) {
914f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard	tmp = cur;
915f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard	cur = cur->next;
916f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard	xmlDebugDumpOneNode(output, tmp, depth);
917f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard    }
918f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard}
9193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
92056a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic void
92156a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel VeillardxmlXPathDebugDumpNodeSet(FILE *output, xmlNodeSetPtr cur, int depth) {
9223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    int i;
9233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    char shift[100];
9243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
9253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    for (i = 0;((i < depth) && (i < 25));i++)
9263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        shift[2 * i] = shift[2 * i + 1] = ' ';
9273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    shift[2 * i] = shift[2 * i + 1] = 0;
9283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
9293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (cur == NULL) {
9303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	fprintf(output, shift);
9313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	fprintf(output, "NodeSet is NULL !\n");
9323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return;
93345490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
9343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
9353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
936911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard    if (cur != NULL) {
937911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard	fprintf(output, "Set contains %d nodes:\n", cur->nodeNr);
938911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard	for (i = 0;i < cur->nodeNr;i++) {
939911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard	    fprintf(output, shift);
940911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard	    fprintf(output, "%d", i + 1);
941911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard	    xmlXPathDebugDumpNode(output, cur->nodeTab[i], depth + 1);
942911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard	}
9433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
9443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
9453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
94656a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic void
94756a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel VeillardxmlXPathDebugDumpValueTree(FILE *output, xmlNodeSetPtr cur, int depth) {
948f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard    int i;
949f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard    char shift[100];
950f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard
951f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard    for (i = 0;((i < depth) && (i < 25));i++)
952f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard        shift[2 * i] = shift[2 * i + 1] = ' ';
953f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard    shift[2 * i] = shift[2 * i + 1] = 0;
954f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard
955f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard    if ((cur == NULL) || (cur->nodeNr == 0) || (cur->nodeTab[0] == NULL)) {
956f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard	fprintf(output, shift);
957f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard	fprintf(output, "Value Tree is NULL !\n");
958f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard	return;
95945490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
960f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard    }
961f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard
962f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard    fprintf(output, shift);
963f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard    fprintf(output, "%d", i + 1);
964f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard    xmlXPathDebugDumpNodeList(output, cur->nodeTab[0]->children, depth + 1);
965f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard}
9663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#if defined(LIBXML_XPTR_ENABLED)
96756a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic void
96856a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel VeillardxmlXPathDebugDumpLocationSet(FILE *output, xmlLocationSetPtr cur, int depth) {
9693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    int i;
9703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    char shift[100];
9713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
9723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    for (i = 0;((i < depth) && (i < 25));i++)
9733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        shift[2 * i] = shift[2 * i + 1] = ' ';
9743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    shift[2 * i] = shift[2 * i + 1] = 0;
9753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
9763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (cur == NULL) {
9773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	fprintf(output, shift);
9783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	fprintf(output, "LocationSet is NULL !\n");
9793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return;
98045490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
9813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
9823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
9833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    for (i = 0;i < cur->locNr;i++) {
9843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	fprintf(output, shift);
9853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        fprintf(output, "%d : ", i + 1);
9863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	xmlXPathDebugDumpObject(output, cur->locTab[i], depth + 1);
9873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
9883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
989017b108fcf16dbce05ca7ebd75763f3d888abb5fDaniel Veillard#endif /* LIBXML_XPTR_ENABLED */
9903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
991afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard/**
992afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathDebugDumpObject:
993afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * @output:  the FILE * to dump the output
994afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * @cur:  the object to inspect
995afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * @depth:  indentation level
996afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard *
997afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Dump the content of the object for debugging purposes
998afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard */
999afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardvoid
1000afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathDebugDumpObject(FILE *output, xmlXPathObjectPtr cur, int depth) {
10013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    int i;
10023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    char shift[100];
10033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
1004a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard    if (output == NULL) return;
1005a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard
10063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    for (i = 0;((i < depth) && (i < 25));i++)
10073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        shift[2 * i] = shift[2 * i + 1] = ' ';
10083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    shift[2 * i] = shift[2 * i + 1] = 0;
10093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
101097258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik
101145490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard    fprintf(output, shift);
10123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
10133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (cur == NULL) {
10143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        fprintf(output, "Object is empty (NULL)\n");
10153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return;
10163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
10173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    switch(cur->type) {
10183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        case XPATH_UNDEFINED:
10193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    fprintf(output, "Object is uninitialized\n");
10203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    break;
10213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        case XPATH_NODESET:
10223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    fprintf(output, "Object is a Node Set :\n");
10233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    xmlXPathDebugDumpNodeSet(output, cur->nodesetval, depth);
10243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    break;
10253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XPATH_XSLT_TREE:
10263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    fprintf(output, "Object is an XSLT value tree :\n");
1027f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard	    xmlXPathDebugDumpValueTree(output, cur->nodesetval, depth);
10283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    break;
10293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        case XPATH_BOOLEAN:
10303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    fprintf(output, "Object is a Boolean : ");
10313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    if (cur->boolval) fprintf(output, "true\n");
10323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    else fprintf(output, "false\n");
10333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    break;
10343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        case XPATH_NUMBER:
1035cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard	    switch (xmlXPathIsInf(cur->floatval)) {
1036357c960e4035ee2fb40d0072bb7bde4533be76f8Daniel Veillard	    case 1:
10375fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard		fprintf(output, "Object is a number : Infinity\n");
1038357c960e4035ee2fb40d0072bb7bde4533be76f8Daniel Veillard		break;
1039357c960e4035ee2fb40d0072bb7bde4533be76f8Daniel Veillard	    case -1:
1040357c960e4035ee2fb40d0072bb7bde4533be76f8Daniel Veillard		fprintf(output, "Object is a number : -Infinity\n");
1041357c960e4035ee2fb40d0072bb7bde4533be76f8Daniel Veillard		break;
1042357c960e4035ee2fb40d0072bb7bde4533be76f8Daniel Veillard	    default:
1043cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard		if (xmlXPathIsNaN(cur->floatval)) {
1044357c960e4035ee2fb40d0072bb7bde4533be76f8Daniel Veillard		    fprintf(output, "Object is a number : NaN\n");
1045d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard		} else if (cur->floatval == 0 && xmlXPathGetSign(cur->floatval) != 0) {
1046d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard		    fprintf(output, "Object is a number : 0\n");
1047357c960e4035ee2fb40d0072bb7bde4533be76f8Daniel Veillard		} else {
1048357c960e4035ee2fb40d0072bb7bde4533be76f8Daniel Veillard		    fprintf(output, "Object is a number : %0g\n", cur->floatval);
1049357c960e4035ee2fb40d0072bb7bde4533be76f8Daniel Veillard		}
1050357c960e4035ee2fb40d0072bb7bde4533be76f8Daniel Veillard	    }
10513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    break;
10523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        case XPATH_STRING:
10533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    fprintf(output, "Object is a string : ");
10543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    xmlDebugDumpString(output, cur->stringval);
10553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    fprintf(output, "\n");
10563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    break;
10573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XPATH_POINT:
10583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    fprintf(output, "Object is a point : index %d in node", cur->index);
10593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    xmlXPathDebugDumpNode(output, (xmlNodePtr) cur->user, depth + 1);
10603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    fprintf(output, "\n");
10613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    break;
10623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XPATH_RANGE:
10633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    if ((cur->user2 == NULL) ||
10643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		((cur->user2 == cur->user) && (cur->index == cur->index2))) {
10653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		fprintf(output, "Object is a collapsed range :\n");
10663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		fprintf(output, shift);
10673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		if (cur->index >= 0)
10683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    fprintf(output, "index %d in ", cur->index);
10693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		fprintf(output, "node\n");
10703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		xmlXPathDebugDumpNode(output, (xmlNodePtr) cur->user,
10713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor			              depth + 1);
10723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    } else  {
10733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		fprintf(output, "Object is a range :\n");
10743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		fprintf(output, shift);
10753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		fprintf(output, "From ");
10763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		if (cur->index >= 0)
10773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    fprintf(output, "index %d in ", cur->index);
10783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		fprintf(output, "node\n");
10793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		xmlXPathDebugDumpNode(output, (xmlNodePtr) cur->user,
10803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor			              depth + 1);
10813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		fprintf(output, shift);
10823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		fprintf(output, "To ");
10833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		if (cur->index2 >= 0)
10843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    fprintf(output, "index %d in ", cur->index2);
10853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		fprintf(output, "node\n");
10863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		xmlXPathDebugDumpNode(output, (xmlNodePtr) cur->user2,
10873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor			              depth + 1);
10883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		fprintf(output, "\n");
10893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    }
10903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    break;
10913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XPATH_LOCATIONSET:
10923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#if defined(LIBXML_XPTR_ENABLED)
10933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    fprintf(output, "Object is a Location Set:\n");
10943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    xmlXPathDebugDumpLocationSet(output,
10953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    (xmlLocationSetPtr) cur->user, depth);
10963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif
10973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    break;
10983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XPATH_USERS:
10993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    fprintf(output, "Object is user defined\n");
11003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    break;
11013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
11023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
11039e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
110456a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic void
110556a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel VeillardxmlXPathDebugDumpStepOp(FILE *output, xmlXPathCompExprPtr comp,
11069e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	                     xmlXPathStepOpPtr op, int depth) {
11079e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    int i;
11089e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    char shift[100];
11099e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
11109e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    for (i = 0;((i < depth) && (i < 25));i++)
11119e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard        shift[2 * i] = shift[2 * i + 1] = ' ';
11129e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    shift[2 * i] = shift[2 * i + 1] = 0;
11139e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
11149e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    fprintf(output, shift);
11159e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    if (op == NULL) {
11169e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	fprintf(output, "Step is NULL\n");
11179e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	return;
11189e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    }
11199e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    switch (op->op) {
11209e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard        case XPATH_OP_END:
11219e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    fprintf(output, "END"); break;
11229e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard        case XPATH_OP_AND:
11239e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    fprintf(output, "AND"); break;
11249e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard        case XPATH_OP_OR:
11259e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    fprintf(output, "OR"); break;
11269e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard        case XPATH_OP_EQUAL:
11279e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	     if (op->value)
11289e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		 fprintf(output, "EQUAL =");
11299e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	     else
11309e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		 fprintf(output, "EQUAL !=");
11319e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	     break;
11329e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard        case XPATH_OP_CMP:
11339e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	     if (op->value)
11349e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		 fprintf(output, "CMP <");
11359e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	     else
11369e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		 fprintf(output, "CMP >");
11379e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	     if (!op->value2)
11389e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		 fprintf(output, "=");
11399e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	     break;
11409e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard        case XPATH_OP_PLUS:
11419e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	     if (op->value == 0)
11429e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		 fprintf(output, "PLUS -");
11439e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	     else if (op->value == 1)
11449e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		 fprintf(output, "PLUS +");
11459e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	     else if (op->value == 2)
11469e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		 fprintf(output, "PLUS unary -");
11479e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	     else if (op->value == 3)
11489e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		 fprintf(output, "PLUS unary - -");
11499e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	     break;
11509e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard        case XPATH_OP_MULT:
11519e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	     if (op->value == 0)
11529e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		 fprintf(output, "MULT *");
11539e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	     else if (op->value == 1)
11549e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		 fprintf(output, "MULT div");
11559e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	     else
11569e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		 fprintf(output, "MULT mod");
11579e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	     break;
11589e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard        case XPATH_OP_UNION:
11599e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	     fprintf(output, "UNION"); break;
11609e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard        case XPATH_OP_ROOT:
11619e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	     fprintf(output, "ROOT"); break;
11629e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard        case XPATH_OP_NODE:
11639e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	     fprintf(output, "NODE"); break;
11649e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard        case XPATH_OP_RESET:
11659e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	     fprintf(output, "RESET"); break;
11669e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard        case XPATH_OP_SORT:
11679e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	     fprintf(output, "SORT"); break;
11689e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard        case XPATH_OP_COLLECT: {
116978637da0ea1c833dfdfad87a9aa5bea14510d08aWilliam M. Brack	    xmlXPathAxisVal axis = (xmlXPathAxisVal)op->value;
117078637da0ea1c833dfdfad87a9aa5bea14510d08aWilliam M. Brack	    xmlXPathTestVal test = (xmlXPathTestVal)op->value2;
117178637da0ea1c833dfdfad87a9aa5bea14510d08aWilliam M. Brack	    xmlXPathTypeVal type = (xmlXPathTypeVal)op->value3;
11729e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    const xmlChar *prefix = op->value4;
11739e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    const xmlChar *name = op->value5;
11749e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
11759e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    fprintf(output, "COLLECT ");
11769e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    switch (axis) {
11779e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		case AXIS_ANCESTOR:
11789e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    fprintf(output, " 'ancestors' "); break;
11799e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		case AXIS_ANCESTOR_OR_SELF:
11809e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    fprintf(output, " 'ancestors-or-self' "); break;
11819e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		case AXIS_ATTRIBUTE:
11829e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    fprintf(output, " 'attributes' "); break;
11839e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		case AXIS_CHILD:
11849e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    fprintf(output, " 'child' "); break;
11859e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		case AXIS_DESCENDANT:
11869e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    fprintf(output, " 'descendant' "); break;
11879e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		case AXIS_DESCENDANT_OR_SELF:
11889e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    fprintf(output, " 'descendant-or-self' "); break;
11899e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		case AXIS_FOLLOWING:
11909e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    fprintf(output, " 'following' "); break;
11919e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		case AXIS_FOLLOWING_SIBLING:
11929e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    fprintf(output, " 'following-siblings' "); break;
11939e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		case AXIS_NAMESPACE:
11949e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    fprintf(output, " 'namespace' "); break;
11959e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		case AXIS_PARENT:
11969e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    fprintf(output, " 'parent' "); break;
11979e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		case AXIS_PRECEDING:
11989e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    fprintf(output, " 'preceding' "); break;
11999e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		case AXIS_PRECEDING_SIBLING:
12009e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    fprintf(output, " 'preceding-sibling' "); break;
12019e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		case AXIS_SELF:
12029e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    fprintf(output, " 'self' "); break;
12039e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    }
12049e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    switch (test) {
12059e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard                case NODE_TEST_NONE:
12069e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    fprintf(output, "'none' "); break;
12079e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard                case NODE_TEST_TYPE:
12089e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    fprintf(output, "'type' "); break;
12099e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard                case NODE_TEST_PI:
12109e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    fprintf(output, "'PI' "); break;
12119e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard                case NODE_TEST_ALL:
12129e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    fprintf(output, "'all' "); break;
12139e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard                case NODE_TEST_NS:
12149e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    fprintf(output, "'namespace' "); break;
12159e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard                case NODE_TEST_NAME:
12169e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    fprintf(output, "'name' "); break;
12179e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    }
12189e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    switch (type) {
12199e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard                case NODE_TYPE_NODE:
12209e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    fprintf(output, "'node' "); break;
12219e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard                case NODE_TYPE_COMMENT:
12229e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    fprintf(output, "'comment' "); break;
12239e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard                case NODE_TYPE_TEXT:
12249e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    fprintf(output, "'text' "); break;
12259e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard                case NODE_TYPE_PI:
12269e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    fprintf(output, "'PI' "); break;
12279e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    }
12289e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    if (prefix != NULL)
12299e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		fprintf(output, "%s:", prefix);
12309e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    if (name != NULL)
1231580ced8ee28ecd99374da9383897678e4ba6c358Daniel Veillard		fprintf(output, "%s", (const char *) name);
12329e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    break;
12339e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
12349e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard        }
12359e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	case XPATH_OP_VALUE: {
12369e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    xmlXPathObjectPtr object = (xmlXPathObjectPtr) op->value4;
12379e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
12389e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    fprintf(output, "ELEM ");
12399e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    xmlXPathDebugDumpObject(output, object, 0);
12409e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    goto finish;
12419e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	}
12429e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	case XPATH_OP_VARIABLE: {
12439e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    const xmlChar *prefix = op->value5;
12449e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    const xmlChar *name = op->value4;
12459e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
12469e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    if (prefix != NULL)
12479e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		fprintf(output, "VARIABLE %s:%s", prefix, name);
12489e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    else
12499e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		fprintf(output, "VARIABLE %s", name);
12509e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    break;
12519e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	}
12529e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	case XPATH_OP_FUNCTION: {
12539e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    int nbargs = op->value;
12549e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    const xmlChar *prefix = op->value5;
12559e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    const xmlChar *name = op->value4;
12569e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
12579e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    if (prefix != NULL)
12589e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		fprintf(output, "FUNCTION %s:%s(%d args)",
12599e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard			prefix, name, nbargs);
12609e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    else
12619e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		fprintf(output, "FUNCTION %s(%d args)", name, nbargs);
12629e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    break;
12639e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	}
12649e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard        case XPATH_OP_ARG: fprintf(output, "ARG"); break;
12659e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard        case XPATH_OP_PREDICATE: fprintf(output, "PREDICATE"); break;
1266d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard        case XPATH_OP_FILTER: fprintf(output, "FILTER"); break;
1267fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard#ifdef LIBXML_XPTR_ENABLED
1268fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard        case XPATH_OP_RANGETO: fprintf(output, "RANGETO"); break;
1269fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard#endif
12709e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	default:
12719e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard        fprintf(output, "UNKNOWN %d\n", op->op); return;
12729e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    }
1273a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    fprintf(output, "\n");
1274a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikfinish:
1275a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    if (op->ch1 >= 0)
1276a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	xmlXPathDebugDumpStepOp(output, comp, &comp->steps[op->ch1], depth + 1);
1277a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    if (op->ch2 >= 0)
1278a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	xmlXPathDebugDumpStepOp(output, comp, &comp->steps[op->ch2], depth + 1);
1279a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik}
1280a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
1281a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik/**
1282a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * xmlXPathDebugDumpCompExpr:
1283a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * @output:  the FILE * for the output
1284a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * @comp:  the precompiled XPath expression
1285a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * @depth:  the indentation level.
1286a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik *
1287a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * Dumps the tree of the compiled XPath expression.
1288a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik */
1289a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikvoid
1290a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. BuchcikxmlXPathDebugDumpCompExpr(FILE *output, xmlXPathCompExprPtr comp,
1291a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	                  int depth) {
1292a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    int i;
1293a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    char shift[100];
1294a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
1295a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    if ((output == NULL) || (comp == NULL)) return;
1296a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
1297a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    for (i = 0;((i < depth) && (i < 25));i++)
1298a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik        shift[2 * i] = shift[2 * i + 1] = ' ';
1299a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    shift[2 * i] = shift[2 * i + 1] = 0;
1300a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
1301a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    fprintf(output, shift);
1302a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
1303a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    fprintf(output, "Compiled Expression : %d elements\n",
1304a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    comp->nbStep);
1305a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    i = comp->last;
1306a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathDebugDumpStepOp(output, comp, &comp->steps[i], depth + 1);
1307a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik}
1308a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
1309a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#ifdef XP_DEBUG_OBJ_USAGE
1310a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
1311a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik/*
1312a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik* XPath object usage related debugging variables.
1313a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik*/
1314a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikstatic int xmlXPathDebugObjCounterUndefined = 0;
1315a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikstatic int xmlXPathDebugObjCounterNodeset = 0;
1316a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikstatic int xmlXPathDebugObjCounterBool = 0;
1317a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikstatic int xmlXPathDebugObjCounterNumber = 0;
1318a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikstatic int xmlXPathDebugObjCounterString = 0;
1319a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikstatic int xmlXPathDebugObjCounterPoint = 0;
1320a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikstatic int xmlXPathDebugObjCounterRange = 0;
1321a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikstatic int xmlXPathDebugObjCounterLocset = 0;
1322a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikstatic int xmlXPathDebugObjCounterUsers = 0;
1323a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikstatic int xmlXPathDebugObjCounterXSLTTree = 0;
1324a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikstatic int xmlXPathDebugObjCounterAll = 0;
1325a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
1326a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikstatic int xmlXPathDebugObjTotalUndefined = 0;
1327a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikstatic int xmlXPathDebugObjTotalNodeset = 0;
1328a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikstatic int xmlXPathDebugObjTotalBool = 0;
1329a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikstatic int xmlXPathDebugObjTotalNumber = 0;
1330a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikstatic int xmlXPathDebugObjTotalString = 0;
1331a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikstatic int xmlXPathDebugObjTotalPoint = 0;
1332a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikstatic int xmlXPathDebugObjTotalRange = 0;
1333a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikstatic int xmlXPathDebugObjTotalLocset = 0;
1334a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikstatic int xmlXPathDebugObjTotalUsers = 0;
1335a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikstatic int xmlXPathDebugObjTotalXSLTTree = 0;
133645490aebe7a60704e8ed850c498969858ab900eeDaniel Veillardstatic int xmlXPathDebugObjTotalAll = 0;
1337a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
1338a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikstatic int xmlXPathDebugObjMaxUndefined = 0;
1339a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikstatic int xmlXPathDebugObjMaxNodeset = 0;
1340a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikstatic int xmlXPathDebugObjMaxBool = 0;
1341a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikstatic int xmlXPathDebugObjMaxNumber = 0;
1342a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikstatic int xmlXPathDebugObjMaxString = 0;
1343a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikstatic int xmlXPathDebugObjMaxPoint = 0;
1344a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikstatic int xmlXPathDebugObjMaxRange = 0;
1345a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikstatic int xmlXPathDebugObjMaxLocset = 0;
1346a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikstatic int xmlXPathDebugObjMaxUsers = 0;
1347a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikstatic int xmlXPathDebugObjMaxXSLTTree = 0;
1348a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikstatic int xmlXPathDebugObjMaxAll = 0;
1349a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
1350a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik/* REVISIT TODO: Make this static when committing */
1351a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikstatic void
1352a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. BuchcikxmlXPathDebugObjUsageReset(xmlXPathContextPtr ctxt)
1353a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik{
1354a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    if (ctxt != NULL) {
13555869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik	if (ctxt->cache != NULL) {
13565869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik	    xmlXPathContextCachePtr cache =
13575869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik		(xmlXPathContextCachePtr) ctxt->cache;
1358a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
1359a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    cache->dbgCachedAll = 0;
1360a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    cache->dbgCachedNodeset = 0;
1361a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    cache->dbgCachedString = 0;
1362a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    cache->dbgCachedBool = 0;
1363a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    cache->dbgCachedNumber = 0;
1364a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    cache->dbgCachedPoint = 0;
1365a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    cache->dbgCachedRange = 0;
1366a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    cache->dbgCachedLocset = 0;
1367a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    cache->dbgCachedUsers = 0;
1368a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    cache->dbgCachedXSLTTree = 0;
136945490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	    cache->dbgCachedUndefined = 0;
1370a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
1371a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    cache->dbgReusedAll = 0;
1372a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    cache->dbgReusedNodeset = 0;
1373a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    cache->dbgReusedString = 0;
1374a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    cache->dbgReusedBool = 0;
1375a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    cache->dbgReusedNumber = 0;
1376a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    cache->dbgReusedPoint = 0;
1377a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    cache->dbgReusedRange = 0;
1378a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    cache->dbgReusedLocset = 0;
1379a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    cache->dbgReusedUsers = 0;
1380a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    cache->dbgReusedXSLTTree = 0;
1381a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    cache->dbgReusedUndefined = 0;
1382a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	}
138345490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard    }
1384a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
1385a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathDebugObjCounterUndefined = 0;
1386a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathDebugObjCounterNodeset = 0;
1387a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathDebugObjCounterBool = 0;
1388a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathDebugObjCounterNumber = 0;
1389a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathDebugObjCounterString = 0;
1390a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathDebugObjCounterPoint = 0;
1391a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathDebugObjCounterRange = 0;
1392a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathDebugObjCounterLocset = 0;
1393a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathDebugObjCounterUsers = 0;
1394a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathDebugObjCounterXSLTTree = 0;
1395a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathDebugObjCounterAll = 0;
139645490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
1397a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathDebugObjTotalUndefined = 0;
1398a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathDebugObjTotalNodeset = 0;
1399a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathDebugObjTotalBool = 0;
1400a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathDebugObjTotalNumber = 0;
1401a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathDebugObjTotalString = 0;
1402a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathDebugObjTotalPoint = 0;
1403a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathDebugObjTotalRange = 0;
1404a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathDebugObjTotalLocset = 0;
1405a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathDebugObjTotalUsers = 0;
1406a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathDebugObjTotalXSLTTree = 0;
140745490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard    xmlXPathDebugObjTotalAll = 0;
1408a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
1409a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathDebugObjMaxUndefined = 0;
1410a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathDebugObjMaxNodeset = 0;
1411a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathDebugObjMaxBool = 0;
1412a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathDebugObjMaxNumber = 0;
1413a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathDebugObjMaxString = 0;
1414a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathDebugObjMaxPoint = 0;
1415a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathDebugObjMaxRange = 0;
1416a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathDebugObjMaxLocset = 0;
1417a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathDebugObjMaxUsers = 0;
1418a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathDebugObjMaxXSLTTree = 0;
1419a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathDebugObjMaxAll = 0;
1420a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
1421a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik}
1422a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
1423a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikstatic void
1424a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. BuchcikxmlXPathDebugObjUsageRequested(xmlXPathContextPtr ctxt,
1425a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik			      xmlXPathObjectType objType)
1426a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik{
1427a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    int isCached = 0;
1428a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
1429a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    if (ctxt != NULL) {
14305869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik	if (ctxt->cache != NULL) {
14315869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik	    xmlXPathContextCachePtr cache =
14325869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik		(xmlXPathContextCachePtr) ctxt->cache;
143345490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
1434a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    isCached = 1;
143545490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
143645490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	    cache->dbgReusedAll++;
1437a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    switch (objType) {
1438a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		case XPATH_UNDEFINED:
1439a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    cache->dbgReusedUndefined++;
1440a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    break;
1441a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		case XPATH_NODESET:
1442a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    cache->dbgReusedNodeset++;
1443a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    break;
1444a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		case XPATH_BOOLEAN:
1445a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    cache->dbgReusedBool++;
1446a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    break;
1447a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		case XPATH_NUMBER:
1448a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    cache->dbgReusedNumber++;
1449a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    break;
1450a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		case XPATH_STRING:
1451a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    cache->dbgReusedString++;
1452a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    break;
1453a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		case XPATH_POINT:
1454a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    cache->dbgReusedPoint++;
1455a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    break;
1456a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		case XPATH_RANGE:
1457a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    cache->dbgReusedRange++;
1458a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    break;
1459a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		case XPATH_LOCATIONSET:
1460a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    cache->dbgReusedLocset++;
1461a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    break;
1462a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		case XPATH_USERS:
1463a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    cache->dbgReusedUsers++;
1464a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    break;
1465a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		case XPATH_XSLT_TREE:
1466a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    cache->dbgReusedXSLTTree++;
1467a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    break;
1468a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		default:
1469a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    break;
147045490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	    }
1471a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	}
1472a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    }
1473a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
1474a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    switch (objType) {
1475a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	case XPATH_UNDEFINED:
1476a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    if (! isCached)
1477a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		xmlXPathDebugObjTotalUndefined++;
147845490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	    xmlXPathDebugObjCounterUndefined++;
1479a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    if (xmlXPathDebugObjCounterUndefined >
1480a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		xmlXPathDebugObjMaxUndefined)
1481a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		xmlXPathDebugObjMaxUndefined =
1482a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    xmlXPathDebugObjCounterUndefined;
1483a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    break;
1484a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	case XPATH_NODESET:
1485a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    if (! isCached)
1486a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		xmlXPathDebugObjTotalNodeset++;
148745490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	    xmlXPathDebugObjCounterNodeset++;
1488a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    if (xmlXPathDebugObjCounterNodeset >
1489a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		xmlXPathDebugObjMaxNodeset)
1490a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		xmlXPathDebugObjMaxNodeset =
1491a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    xmlXPathDebugObjCounterNodeset;
1492a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    break;
1493a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	case XPATH_BOOLEAN:
1494a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    if (! isCached)
1495a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		xmlXPathDebugObjTotalBool++;
149645490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	    xmlXPathDebugObjCounterBool++;
1497a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    if (xmlXPathDebugObjCounterBool >
1498a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		xmlXPathDebugObjMaxBool)
1499a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		xmlXPathDebugObjMaxBool =
1500a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    xmlXPathDebugObjCounterBool;
1501a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    break;
1502a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	case XPATH_NUMBER:
1503a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    if (! isCached)
1504a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		xmlXPathDebugObjTotalNumber++;
150545490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	    xmlXPathDebugObjCounterNumber++;
1506a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    if (xmlXPathDebugObjCounterNumber >
1507a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		xmlXPathDebugObjMaxNumber)
1508a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		xmlXPathDebugObjMaxNumber =
1509a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    xmlXPathDebugObjCounterNumber;
1510a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    break;
1511a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	case XPATH_STRING:
1512a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    if (! isCached)
1513a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		xmlXPathDebugObjTotalString++;
151445490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	    xmlXPathDebugObjCounterString++;
1515a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    if (xmlXPathDebugObjCounterString >
1516a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		xmlXPathDebugObjMaxString)
1517a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		xmlXPathDebugObjMaxString =
1518a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    xmlXPathDebugObjCounterString;
1519a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    break;
1520a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	case XPATH_POINT:
1521a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    if (! isCached)
1522a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		xmlXPathDebugObjTotalPoint++;
152345490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	    xmlXPathDebugObjCounterPoint++;
1524a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    if (xmlXPathDebugObjCounterPoint >
1525a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		xmlXPathDebugObjMaxPoint)
1526a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		xmlXPathDebugObjMaxPoint =
1527a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    xmlXPathDebugObjCounterPoint;
1528a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    break;
1529a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	case XPATH_RANGE:
1530a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    if (! isCached)
1531a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		xmlXPathDebugObjTotalRange++;
1532a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathDebugObjCounterRange++;
1533a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    if (xmlXPathDebugObjCounterRange >
1534a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		xmlXPathDebugObjMaxRange)
1535a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		xmlXPathDebugObjMaxRange =
1536a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    xmlXPathDebugObjCounterRange;
1537a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    break;
1538a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	case XPATH_LOCATIONSET:
1539a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    if (! isCached)
1540a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		xmlXPathDebugObjTotalLocset++;
1541a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathDebugObjCounterLocset++;
1542a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    if (xmlXPathDebugObjCounterLocset >
1543a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		xmlXPathDebugObjMaxLocset)
1544a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		xmlXPathDebugObjMaxLocset =
1545a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    xmlXPathDebugObjCounterLocset;
1546a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    break;
1547a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	case XPATH_USERS:
1548a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    if (! isCached)
1549a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		xmlXPathDebugObjTotalUsers++;
155045490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	    xmlXPathDebugObjCounterUsers++;
1551a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    if (xmlXPathDebugObjCounterUsers >
1552a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		xmlXPathDebugObjMaxUsers)
1553a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		xmlXPathDebugObjMaxUsers =
1554a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    xmlXPathDebugObjCounterUsers;
1555a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    break;
1556a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	case XPATH_XSLT_TREE:
1557a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    if (! isCached)
1558a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		xmlXPathDebugObjTotalXSLTTree++;
155945490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	    xmlXPathDebugObjCounterXSLTTree++;
1560a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    if (xmlXPathDebugObjCounterXSLTTree >
1561a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		xmlXPathDebugObjMaxXSLTTree)
1562a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		xmlXPathDebugObjMaxXSLTTree =
1563a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    xmlXPathDebugObjCounterXSLTTree;
1564a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    break;
1565a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	default:
1566a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    break;
1567a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    }
1568a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    if (! isCached)
1569a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	xmlXPathDebugObjTotalAll++;
1570a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathDebugObjCounterAll++;
1571a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    if (xmlXPathDebugObjCounterAll >
1572a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	xmlXPathDebugObjMaxAll)
1573a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	xmlXPathDebugObjMaxAll =
1574a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathDebugObjCounterAll;
1575a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik}
1576a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
1577a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikstatic void
1578a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. BuchcikxmlXPathDebugObjUsageReleased(xmlXPathContextPtr ctxt,
1579a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik			      xmlXPathObjectType objType)
1580a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik{
1581a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    int isCached = 0;
1582a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
1583a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    if (ctxt != NULL) {
15845869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik	if (ctxt->cache != NULL) {
15855869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik	    xmlXPathContextCachePtr cache =
15865869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik		(xmlXPathContextCachePtr) ctxt->cache;
1587a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
158845490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	    isCached = 1;
158945490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
1590a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    cache->dbgCachedAll++;
1591a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    switch (objType) {
1592a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		case XPATH_UNDEFINED:
1593a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    cache->dbgCachedUndefined++;
1594a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    break;
1595a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		case XPATH_NODESET:
1596a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    cache->dbgCachedNodeset++;
1597a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    break;
1598a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		case XPATH_BOOLEAN:
1599a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    cache->dbgCachedBool++;
1600a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    break;
1601a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		case XPATH_NUMBER:
1602a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    cache->dbgCachedNumber++;
1603a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    break;
1604a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		case XPATH_STRING:
1605a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    cache->dbgCachedString++;
1606a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    break;
1607a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		case XPATH_POINT:
1608a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    cache->dbgCachedPoint++;
1609a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    break;
1610a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		case XPATH_RANGE:
1611a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    cache->dbgCachedRange++;
1612a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    break;
1613a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		case XPATH_LOCATIONSET:
1614a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    cache->dbgCachedLocset++;
1615a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    break;
1616a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		case XPATH_USERS:
1617a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    cache->dbgCachedUsers++;
1618a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    break;
1619a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		case XPATH_XSLT_TREE:
1620a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    cache->dbgCachedXSLTTree++;
1621a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    break;
1622a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		default:
1623a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    break;
1624a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    }
162545490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
1626a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	}
1627a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    }
1628a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    switch (objType) {
1629a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	case XPATH_UNDEFINED:
1630a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathDebugObjCounterUndefined--;
1631a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    break;
1632a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	case XPATH_NODESET:
1633a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathDebugObjCounterNodeset--;
1634a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    break;
1635a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	case XPATH_BOOLEAN:
1636a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathDebugObjCounterBool--;
1637a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    break;
1638a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	case XPATH_NUMBER:
1639a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathDebugObjCounterNumber--;
1640a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    break;
1641a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	case XPATH_STRING:
1642a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathDebugObjCounterString--;
1643a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    break;
1644a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	case XPATH_POINT:
1645a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathDebugObjCounterPoint--;
1646a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    break;
1647a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	case XPATH_RANGE:
1648a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathDebugObjCounterRange--;
1649a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    break;
1650a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	case XPATH_LOCATIONSET:
1651a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathDebugObjCounterLocset--;
1652a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    break;
1653a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	case XPATH_USERS:
1654a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathDebugObjCounterUsers--;
1655a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    break;
1656a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	case XPATH_XSLT_TREE:
1657a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathDebugObjCounterXSLTTree--;
1658a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    break;
1659a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	default:
1660a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    break;
166145490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard    }
1662a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathDebugObjCounterAll--;
1663a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik}
1664a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
1665a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik/* REVISIT TODO: Make this static when committing */
1666a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikstatic void
1667a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. BuchcikxmlXPathDebugObjUsageDisplay(xmlXPathContextPtr ctxt)
1668a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik{
1669a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    int reqAll, reqNodeset, reqString, reqBool, reqNumber,
1670a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	reqXSLTTree, reqUndefined;
1671a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    int caAll = 0, caNodeset = 0, caString = 0, caBool = 0,
1672a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	caNumber = 0, caXSLTTree = 0, caUndefined = 0;
1673a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    int reAll = 0, reNodeset = 0, reString = 0, reBool = 0,
1674a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	reNumber = 0, reXSLTTree = 0, reUndefined = 0;
1675a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    int leftObjs = xmlXPathDebugObjCounterAll;
1676a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
1677a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    reqAll = xmlXPathDebugObjTotalAll;
1678a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    reqNodeset = xmlXPathDebugObjTotalNodeset;
1679a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    reqString = xmlXPathDebugObjTotalString;
1680a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    reqBool = xmlXPathDebugObjTotalBool;
1681a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    reqNumber = xmlXPathDebugObjTotalNumber;
1682a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    reqXSLTTree = xmlXPathDebugObjTotalXSLTTree;
1683a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    reqUndefined = xmlXPathDebugObjTotalUndefined;
168445490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
1685a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    printf("# XPath object usage:\n");
1686a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
1687a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    if (ctxt != NULL) {
16885869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik	if (ctxt->cache != NULL) {
16895869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik	    xmlXPathContextCachePtr cache =
16905869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik		(xmlXPathContextCachePtr) ctxt->cache;
1691a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
1692a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    reAll = cache->dbgReusedAll;
1693a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    reqAll += reAll;
1694a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    reNodeset = cache->dbgReusedNodeset;
1695a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    reqNodeset += reNodeset;
1696a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    reString = cache->dbgReusedString;
1697a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    reqString += reString;
1698a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    reBool = cache->dbgReusedBool;
1699a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    reqBool += reBool;
1700a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    reNumber = cache->dbgReusedNumber;
1701a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    reqNumber += reNumber;
1702a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    reXSLTTree = cache->dbgReusedXSLTTree;
1703a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    reqXSLTTree += reXSLTTree;
1704a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    reUndefined = cache->dbgReusedUndefined;
1705a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    reqUndefined += reUndefined;
170645490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
1707a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    caAll = cache->dbgCachedAll;
1708a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    caBool = cache->dbgCachedBool;
1709a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    caNodeset = cache->dbgCachedNodeset;
1710a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    caString = cache->dbgCachedString;
1711a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    caNumber = cache->dbgCachedNumber;
1712a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    caXSLTTree = cache->dbgCachedXSLTTree;
1713a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    caUndefined = cache->dbgCachedUndefined;
171445490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
1715a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    if (cache->nodesetObjs)
1716a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		leftObjs -= cache->nodesetObjs->number;
1717a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    if (cache->stringObjs)
1718a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		leftObjs -= cache->stringObjs->number;
1719a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    if (cache->booleanObjs)
1720a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		leftObjs -= cache->booleanObjs->number;
1721a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    if (cache->numberObjs)
1722a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		leftObjs -= cache->numberObjs->number;
1723a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    if (cache->miscObjs)
1724a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		leftObjs -= cache->miscObjs->number;
1725a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	}
1726a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    }
172745490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
172845490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard    printf("# all\n");
1729a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    printf("#   total  : %d\n", reqAll);
1730a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    printf("#   left  : %d\n", leftObjs);
1731a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    printf("#   created: %d\n", xmlXPathDebugObjTotalAll);
1732a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    printf("#   reused : %d\n", reAll);
1733a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    printf("#   max    : %d\n", xmlXPathDebugObjMaxAll);
1734a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
1735a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    printf("# node-sets\n");
1736a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    printf("#   total  : %d\n", reqNodeset);
1737a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    printf("#   created: %d\n", xmlXPathDebugObjTotalNodeset);
1738a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    printf("#   reused : %d\n", reNodeset);
1739a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    printf("#   max    : %d\n", xmlXPathDebugObjMaxNodeset);
1740a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
1741a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    printf("# strings\n");
1742a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    printf("#   total  : %d\n", reqString);
1743a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    printf("#   created: %d\n", xmlXPathDebugObjTotalString);
1744a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    printf("#   reused : %d\n", reString);
1745a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    printf("#   max    : %d\n", xmlXPathDebugObjMaxString);
1746a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
1747a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    printf("# booleans\n");
1748a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    printf("#   total  : %d\n", reqBool);
1749a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    printf("#   created: %d\n", xmlXPathDebugObjTotalBool);
1750a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    printf("#   reused : %d\n", reBool);
1751a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    printf("#   max    : %d\n", xmlXPathDebugObjMaxBool);
1752a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
1753a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    printf("# numbers\n");
1754a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    printf("#   total  : %d\n", reqNumber);
1755a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    printf("#   created: %d\n", xmlXPathDebugObjTotalNumber);
1756a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    printf("#   reused : %d\n", reNumber);
1757a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    printf("#   max    : %d\n", xmlXPathDebugObjMaxNumber);
1758a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
1759a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    printf("# XSLT result tree fragments\n");
1760a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    printf("#   total  : %d\n", reqXSLTTree);
1761a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    printf("#   created: %d\n", xmlXPathDebugObjTotalXSLTTree);
1762a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    printf("#   reused : %d\n", reXSLTTree);
1763a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    printf("#   max    : %d\n", xmlXPathDebugObjMaxXSLTTree);
1764a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
1765a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    printf("# undefined\n");
1766a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    printf("#   total  : %d\n", reqUndefined);
1767a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    printf("#   created: %d\n", xmlXPathDebugObjTotalUndefined);
1768a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    printf("#   reused : %d\n", reUndefined);
1769a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    printf("#   max    : %d\n", xmlXPathDebugObjMaxUndefined);
1770a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
1771a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik}
1772a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
1773a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#endif /* XP_DEBUG_OBJ_USAGE */
1774a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
1775a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#endif /* LIBXML_DEBUG_ENABLED */
1776a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
1777a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik/************************************************************************
1778a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik *									*
1779a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik *			XPath object caching				*
1780a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik *									*
1781a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik ************************************************************************/
1782a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
1783a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik/**
17845869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik * xmlXPathNewCache:
1785a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik *
1786a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * Create a new object cache
1787a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik *
17885869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik * Returns the xmlXPathCache just allocated.
1789a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik */
17905869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcikstatic xmlXPathContextCachePtr
17915869469f42db259a21fb0721d66513de0b619097Kasimier T. BuchcikxmlXPathNewCache(void)
1792a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik{
17935869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik    xmlXPathContextCachePtr ret;
1794a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
17955869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik    ret = (xmlXPathContextCachePtr) xmlMalloc(sizeof(xmlXPathContextCache));
1796a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    if (ret == NULL) {
1797a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik        xmlXPathErrMemory(NULL, "creating object cache\n");
1798a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	return(NULL);
1799a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    }
18005869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik    memset(ret, 0 , (size_t) sizeof(xmlXPathContextCache));
1801a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    ret->maxNodeset = 100;
1802a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    ret->maxString = 100;
1803a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    ret->maxBoolean = 100;
1804a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    ret->maxNumber = 100;
1805a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    ret->maxMisc = 100;
1806a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    return(ret);
1807a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik}
1808a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
1809a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikstatic void
18105869469f42db259a21fb0721d66513de0b619097Kasimier T. BuchcikxmlXPathCacheFreeObjectList(xmlPointerListPtr list)
1811a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik{
1812a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    int i;
1813a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathObjectPtr obj;
1814a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
1815a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    if (list == NULL)
1816a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	return;
1817a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
1818a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    for (i = 0; i < list->number; i++) {
1819a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	obj = list->items[i];
1820a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	/*
1821a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	* Note that it is already assured that we don't need to
1822a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	* look out for namespace nodes in the node-set.
1823a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	*/
1824a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	if (obj->nodesetval != NULL) {
1825a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    if (obj->nodesetval->nodeTab != NULL)
1826a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		xmlFree(obj->nodesetval->nodeTab);
1827a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlFree(obj->nodesetval);
1828a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	}
1829a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	xmlFree(obj);
1830a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#ifdef XP_DEBUG_OBJ_USAGE
1831a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	xmlXPathDebugObjCounterAll--;
1832a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#endif
1833a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    }
1834a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlPointerListFree(list);
1835a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik}
1836a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
1837a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikstatic void
18385869469f42db259a21fb0721d66513de0b619097Kasimier T. BuchcikxmlXPathFreeCache(xmlXPathContextCachePtr cache)
1839a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik{
1840a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    if (cache == NULL)
1841a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	return;
1842a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    if (cache->nodesetObjs)
18435869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik	xmlXPathCacheFreeObjectList(cache->nodesetObjs);
1844a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    if (cache->stringObjs)
18455869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik	xmlXPathCacheFreeObjectList(cache->stringObjs);
1846a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    if (cache->booleanObjs)
18475869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik	xmlXPathCacheFreeObjectList(cache->booleanObjs);
1848a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    if (cache->numberObjs)
18495869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik	xmlXPathCacheFreeObjectList(cache->numberObjs);
1850a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    if (cache->miscObjs)
185145490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	xmlXPathCacheFreeObjectList(cache->miscObjs);
1852a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlFree(cache);
1853a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik}
1854a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
1855a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik/**
18565869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik * xmlXPathContextSetCache:
1857a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik *
1858a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * @ctxt:  the XPath context
1859a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * @active: enables/disables (creates/frees) the cache
186045490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard * @value: a value with semantics dependant on @options
18615869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik * @options: options (currently only the value 0 is used)
1862a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik *
1863a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * Creates/frees an object cache on the XPath context.
1864a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * If activates XPath objects (xmlXPathObject) will be cached internally
18651b2be101e8c7c6c0b65d9961a302885aead9bc22Aleksey Sanin * to be reused.
18661b2be101e8c7c6c0b65d9961a302885aead9bc22Aleksey Sanin * @options:
18671b2be101e8c7c6c0b65d9961a302885aead9bc22Aleksey Sanin *   0: This will set the XPath object caching:
18681b2be101e8c7c6c0b65d9961a302885aead9bc22Aleksey Sanin *      @value:
18691b2be101e8c7c6c0b65d9961a302885aead9bc22Aleksey Sanin *        This will set the maximum number of XPath objects
18705869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik *        to be cached per slot
18715869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik *        There are 5 slots for: node-set, string, number, boolean, and
18721b2be101e8c7c6c0b65d9961a302885aead9bc22Aleksey Sanin *        misc objects. Use <0 for the default number (100).
18735869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik *   Other values for @options have currently no effect.
1874a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik *
1875a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * Returns 0 if the setting succeeded, and -1 on API or internal errors.
1876a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik */
1877a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikint
18785869469f42db259a21fb0721d66513de0b619097Kasimier T. BuchcikxmlXPathContextSetCache(xmlXPathContextPtr ctxt,
18795869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik			int active,
18805869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik			int value,
18815869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik			int options)
1882a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik{
1883a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    if (ctxt == NULL)
1884a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	return(-1);
1885a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    if (active) {
18865869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik	xmlXPathContextCachePtr cache;
188745490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
18885869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik	if (ctxt->cache == NULL) {
18895869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik	    ctxt->cache = xmlXPathNewCache();
18905869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik	    if (ctxt->cache == NULL)
1891a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		return(-1);
1892a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	}
18931b2be101e8c7c6c0b65d9961a302885aead9bc22Aleksey Sanin	cache = (xmlXPathContextCachePtr) ctxt->cache;
18945869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik	if (options == 0) {
18955869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik	    if (value < 0)
18965869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik		value = 100;
18975869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik	    cache->maxNodeset = value;
18985869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik	    cache->maxString = value;
18995869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik	    cache->maxNumber = value;
19005869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik	    cache->maxBoolean = value;
19011b2be101e8c7c6c0b65d9961a302885aead9bc22Aleksey Sanin	    cache->maxMisc = value;
19025869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik	}
19035869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik    } else if (ctxt->cache != NULL) {
19045869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik	xmlXPathFreeCache((xmlXPathContextCachePtr) ctxt->cache);
19055869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik	ctxt->cache = NULL;
1906a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    }
1907a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    return(0);
1908a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik}
1909a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
1910a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik/**
1911a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * xmlXPathCacheWrapNodeSet:
1912a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * @ctxt: the XPath context
1913a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * @val:  the NodePtr value
1914a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik *
1915a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * This is the cached version of xmlXPathWrapNodeSet().
1916a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * Wrap the Nodeset @val in a new xmlXPathObjectPtr
1917a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik *
1918a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * Returns the created or reused object.
1919a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik */
1920a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikstatic xmlXPathObjectPtr
1921a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. BuchcikxmlXPathCacheWrapNodeSet(xmlXPathContextPtr ctxt, xmlNodeSetPtr val)
192245490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard{
19235869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik    if ((ctxt != NULL) && (ctxt->cache != NULL)) {
19245869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik	xmlXPathContextCachePtr cache =
19255869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik	    (xmlXPathContextCachePtr) ctxt->cache;
1926a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
1927a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	if ((cache->miscObjs != NULL) &&
1928a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    (cache->miscObjs->number != 0))
1929a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	{
1930a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathObjectPtr ret;
193145490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
1932a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    ret = (xmlXPathObjectPtr)
1933a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		cache->miscObjs->items[--cache->miscObjs->number];
1934a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    ret->type = XPATH_NODESET;
1935a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    ret->nodesetval = val;
1936a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#ifdef XP_DEBUG_OBJ_USAGE
1937a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathDebugObjUsageRequested(ctxt, XPATH_NODESET);
1938a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#endif
193945490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	    return(ret);
1940a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	}
1941a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    }
194245490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
1943a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    return(xmlXPathWrapNodeSet(val));
194445490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
1945a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik}
1946a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
1947a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik/**
1948a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * xmlXPathCacheWrapString:
1949a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * @ctxt: the XPath context
1950a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * @val:  the xmlChar * value
1951a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik *
1952a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * This is the cached version of xmlXPathWrapString().
1953a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * Wraps the @val string into an XPath object.
1954a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik *
1955a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * Returns the created or reused object.
1956a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik */
1957a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikstatic xmlXPathObjectPtr
1958a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. BuchcikxmlXPathCacheWrapString(xmlXPathContextPtr ctxt, xmlChar *val)
195945490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard{
19605869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik    if ((ctxt != NULL) && (ctxt->cache != NULL)) {
19615869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik	xmlXPathContextCachePtr cache = (xmlXPathContextCachePtr) ctxt->cache;
1962a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
1963a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	if ((cache->stringObjs != NULL) &&
1964a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    (cache->stringObjs->number != 0))
1965a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	{
196645490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
1967a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathObjectPtr ret;
196845490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
1969a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    ret = (xmlXPathObjectPtr)
1970a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		cache->stringObjs->items[--cache->stringObjs->number];
1971a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    ret->type = XPATH_STRING;
1972a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    ret->stringval = val;
1973a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#ifdef XP_DEBUG_OBJ_USAGE
1974a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathDebugObjUsageRequested(ctxt, XPATH_STRING);
1975a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#endif
1976a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    return(ret);
1977a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	} else if ((cache->miscObjs != NULL) &&
1978a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    (cache->miscObjs->number != 0))
1979a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	{
1980a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathObjectPtr ret;
1981a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    /*
1982a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    * Fallback to misc-cache.
1983a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    */
1984a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    ret = (xmlXPathObjectPtr)
1985a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		cache->miscObjs->items[--cache->miscObjs->number];
1986a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
1987a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    ret->type = XPATH_STRING;
1988a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    ret->stringval = val;
1989a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#ifdef XP_DEBUG_OBJ_USAGE
1990a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathDebugObjUsageRequested(ctxt, XPATH_STRING);
1991a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#endif
1992a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    return(ret);
1993a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	}
1994a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    }
1995a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    return(xmlXPathWrapString(val));
1996a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik}
1997a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
1998a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik/**
1999a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * xmlXPathCacheNewNodeSet:
2000a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * @ctxt: the XPath context
2001a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * @val:  the NodePtr value
2002a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik *
2003a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * This is the cached version of xmlXPathNewNodeSet().
2004a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * Acquire an xmlXPathObjectPtr of type NodeSet and initialize
2005a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * it with the single Node @val
2006a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik *
2007a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * Returns the created or reused object.
2008a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik */
2009a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikstatic xmlXPathObjectPtr
2010a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. BuchcikxmlXPathCacheNewNodeSet(xmlXPathContextPtr ctxt, xmlNodePtr val)
2011a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik{
20125869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik    if ((ctxt != NULL) && (ctxt->cache)) {
20135869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik	xmlXPathContextCachePtr cache = (xmlXPathContextCachePtr) ctxt->cache;
2014a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
2015a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	if ((cache->nodesetObjs != NULL) &&
2016a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    (cache->nodesetObjs->number != 0))
201745490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	{
2018a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathObjectPtr ret;
2019a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    /*
2020a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    * Use the nodset-cache.
202145490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	    */
2022a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    ret = (xmlXPathObjectPtr)
2023a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		cache->nodesetObjs->items[--cache->nodesetObjs->number];
2024a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    ret->type = XPATH_NODESET;
2025a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    ret->boolval = 0;
202645490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	    if (val) {
2027a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		if ((ret->nodesetval->nodeMax == 0) ||
2028a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    (val->type == XML_NAMESPACE_DECL))
2029a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		{
203045490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard		    xmlXPathNodeSetAddUnique(ret->nodesetval, val);
2031a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		} else {
2032a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    ret->nodesetval->nodeTab[0] = val;
2033a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    ret->nodesetval->nodeNr = 1;
2034a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		}
2035a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    }
2036a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#ifdef XP_DEBUG_OBJ_USAGE
2037a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathDebugObjUsageRequested(ctxt, XPATH_NODESET);
2038a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#endif
2039a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    return(ret);
2040a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	} else if ((cache->miscObjs != NULL) &&
2041a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    (cache->miscObjs->number != 0))
2042a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	{
2043a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathObjectPtr ret;
2044a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    /*
2045a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    * Fallback to misc-cache.
2046a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    */
2047a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
2048a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    ret = (xmlXPathObjectPtr)
2049a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		cache->miscObjs->items[--cache->miscObjs->number];
2050a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
2051a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    ret->type = XPATH_NODESET;
2052a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    ret->boolval = 0;
2053a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    ret->nodesetval = xmlXPathNodeSetCreate(val);
2054a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#ifdef XP_DEBUG_OBJ_USAGE
2055a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathDebugObjUsageRequested(ctxt, XPATH_NODESET);
2056a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#endif
2057a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    return(ret);
2058a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	}
2059a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    }
2060a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    return(xmlXPathNewNodeSet(val));
2061a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik}
2062a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
2063a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik/**
2064a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * xmlXPathCacheNewCString:
2065a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * @ctxt: the XPath context
2066a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * @val:  the char * value
2067a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik *
2068a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * This is the cached version of xmlXPathNewCString().
2069a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * Acquire an xmlXPathObjectPtr of type string and of value @val
2070a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik *
2071a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * Returns the created or reused object.
2072a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik */
2073a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikstatic xmlXPathObjectPtr
2074a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. BuchcikxmlXPathCacheNewCString(xmlXPathContextPtr ctxt, const char *val)
207545490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard{
20765869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik    if ((ctxt != NULL) && (ctxt->cache)) {
20775869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik	xmlXPathContextCachePtr cache = (xmlXPathContextCachePtr) ctxt->cache;
2078a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
2079a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	if ((cache->stringObjs != NULL) &&
2080a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    (cache->stringObjs->number != 0))
208145490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	{
2082a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathObjectPtr ret;
208345490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
2084a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    ret = (xmlXPathObjectPtr)
2085a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		cache->stringObjs->items[--cache->stringObjs->number];
2086a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
2087a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    ret->type = XPATH_STRING;
2088a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    ret->stringval = xmlStrdup(BAD_CAST val);
2089a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#ifdef XP_DEBUG_OBJ_USAGE
2090a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathDebugObjUsageRequested(ctxt, XPATH_STRING);
2091a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#endif
2092a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    return(ret);
2093a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	} else if ((cache->miscObjs != NULL) &&
2094a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    (cache->miscObjs->number != 0))
2095a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	{
2096a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathObjectPtr ret;
2097a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
2098a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    ret = (xmlXPathObjectPtr)
2099a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		cache->miscObjs->items[--cache->miscObjs->number];
2100a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
2101a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    ret->type = XPATH_STRING;
2102a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    ret->stringval = xmlStrdup(BAD_CAST val);
2103a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#ifdef XP_DEBUG_OBJ_USAGE
2104a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathDebugObjUsageRequested(ctxt, XPATH_STRING);
2105a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#endif
2106a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    return(ret);
2107a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	}
2108a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    }
2109a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    return(xmlXPathNewCString(val));
2110a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik}
2111a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
2112a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik/**
2113a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * xmlXPathCacheNewString:
2114a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * @ctxt: the XPath context
2115a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * @val:  the xmlChar * value
2116a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik *
2117a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * This is the cached version of xmlXPathNewString().
2118a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * Acquire an xmlXPathObjectPtr of type string and of value @val
2119a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik *
2120a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * Returns the created or reused object.
2121a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik */
2122a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikstatic xmlXPathObjectPtr
2123a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. BuchcikxmlXPathCacheNewString(xmlXPathContextPtr ctxt, const xmlChar *val)
212445490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard{
21255869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik    if ((ctxt != NULL) && (ctxt->cache)) {
21265869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik	xmlXPathContextCachePtr cache = (xmlXPathContextCachePtr) ctxt->cache;
2127a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
2128a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	if ((cache->stringObjs != NULL) &&
2129a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    (cache->stringObjs->number != 0))
213045490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	{
2131a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathObjectPtr ret;
213245490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
2133a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    ret = (xmlXPathObjectPtr)
2134a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		cache->stringObjs->items[--cache->stringObjs->number];
2135a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    ret->type = XPATH_STRING;
2136a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    if (val != NULL)
2137a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		ret->stringval = xmlStrdup(val);
2138a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    else
2139a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		ret->stringval = xmlStrdup((const xmlChar *)"");
2140a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#ifdef XP_DEBUG_OBJ_USAGE
2141a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathDebugObjUsageRequested(ctxt, XPATH_STRING);
2142a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#endif
2143a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    return(ret);
2144a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	} else if ((cache->miscObjs != NULL) &&
2145a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    (cache->miscObjs->number != 0))
2146a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	{
2147a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathObjectPtr ret;
2148a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
2149a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    ret = (xmlXPathObjectPtr)
2150a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		cache->miscObjs->items[--cache->miscObjs->number];
2151a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
2152a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    ret->type = XPATH_STRING;
2153a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    if (val != NULL)
2154a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		ret->stringval = xmlStrdup(val);
2155a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    else
2156a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		ret->stringval = xmlStrdup((const xmlChar *)"");
2157a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#ifdef XP_DEBUG_OBJ_USAGE
2158a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathDebugObjUsageRequested(ctxt, XPATH_STRING);
2159a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#endif
2160a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    return(ret);
2161a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	}
2162a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    }
2163a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    return(xmlXPathNewString(val));
2164a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik}
2165a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
2166a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik/**
2167a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * xmlXPathCacheNewBoolean:
2168a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * @ctxt: the XPath context
2169a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * @val:  the boolean value
2170a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik *
2171a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * This is the cached version of xmlXPathNewBoolean().
2172a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * Acquires an xmlXPathObjectPtr of type boolean and of value @val
2173a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik *
2174a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * Returns the created or reused object.
2175a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik */
2176a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikstatic xmlXPathObjectPtr
2177a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. BuchcikxmlXPathCacheNewBoolean(xmlXPathContextPtr ctxt, int val)
217845490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard{
21795869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik    if ((ctxt != NULL) && (ctxt->cache)) {
21805869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik	xmlXPathContextCachePtr cache = (xmlXPathContextCachePtr) ctxt->cache;
2181a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
2182a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	if ((cache->booleanObjs != NULL) &&
2183a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    (cache->booleanObjs->number != 0))
218445490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	{
2185a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathObjectPtr ret;
218645490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
2187a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    ret = (xmlXPathObjectPtr)
2188a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		cache->booleanObjs->items[--cache->booleanObjs->number];
2189a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    ret->type = XPATH_BOOLEAN;
2190a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    ret->boolval = (val != 0);
2191a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#ifdef XP_DEBUG_OBJ_USAGE
2192a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathDebugObjUsageRequested(ctxt, XPATH_BOOLEAN);
2193a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#endif
2194a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    return(ret);
2195a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	} else if ((cache->miscObjs != NULL) &&
2196a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    (cache->miscObjs->number != 0))
2197a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	{
2198a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathObjectPtr ret;
2199a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
2200a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    ret = (xmlXPathObjectPtr)
2201a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		cache->miscObjs->items[--cache->miscObjs->number];
2202a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
2203a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    ret->type = XPATH_BOOLEAN;
2204a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    ret->boolval = (val != 0);
2205a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#ifdef XP_DEBUG_OBJ_USAGE
2206a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathDebugObjUsageRequested(ctxt, XPATH_BOOLEAN);
2207a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#endif
2208a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    return(ret);
2209a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	}
2210a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    }
2211a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    return(xmlXPathNewBoolean(val));
2212a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik}
2213a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
2214a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik/**
2215a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * xmlXPathCacheNewFloat:
2216a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * @ctxt: the XPath context
2217a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * @val:  the double value
2218a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik *
2219a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * This is the cached version of xmlXPathNewFloat().
2220a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * Acquires an xmlXPathObjectPtr of type double and of value @val
2221a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik *
2222a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * Returns the created or reused object.
2223a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik */
2224a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikstatic xmlXPathObjectPtr
2225a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. BuchcikxmlXPathCacheNewFloat(xmlXPathContextPtr ctxt, double val)
2226a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik{
22275869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik     if ((ctxt != NULL) && (ctxt->cache)) {
22285869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik	xmlXPathContextCachePtr cache = (xmlXPathContextCachePtr) ctxt->cache;
2229a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
2230a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	if ((cache->numberObjs != NULL) &&
2231a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    (cache->numberObjs->number != 0))
223245490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	{
2233a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathObjectPtr ret;
223445490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
2235a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    ret = (xmlXPathObjectPtr)
2236a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		cache->numberObjs->items[--cache->numberObjs->number];
2237a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    ret->type = XPATH_NUMBER;
2238a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    ret->floatval = val;
2239a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#ifdef XP_DEBUG_OBJ_USAGE
2240a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathDebugObjUsageRequested(ctxt, XPATH_NUMBER);
2241a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#endif
2242a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    return(ret);
2243a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	} else if ((cache->miscObjs != NULL) &&
2244a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    (cache->miscObjs->number != 0))
2245a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	{
2246a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathObjectPtr ret;
2247a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
2248a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    ret = (xmlXPathObjectPtr)
2249a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		cache->miscObjs->items[--cache->miscObjs->number];
2250a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
2251a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    ret->type = XPATH_NUMBER;
2252a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    ret->floatval = val;
2253a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#ifdef XP_DEBUG_OBJ_USAGE
2254a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathDebugObjUsageRequested(ctxt, XPATH_NUMBER);
2255a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#endif
2256a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    return(ret);
2257a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	}
2258a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    }
2259a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    return(xmlXPathNewFloat(val));
2260a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik}
2261a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
2262a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik/**
2263a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * xmlXPathCacheConvertString:
2264a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * @ctxt: the XPath context
2265a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * @val:  an XPath object
2266a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik *
2267a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * This is the cached version of xmlXPathConvertString().
2268a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * Converts an existing object to its string() equivalent
2269a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik *
2270a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * Returns a created or reused object, the old one is freed (cached)
2271a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik *         (or the operation is done directly on @val)
2272a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik */
2273a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
2274a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikstatic xmlXPathObjectPtr
2275a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. BuchcikxmlXPathCacheConvertString(xmlXPathContextPtr ctxt, xmlXPathObjectPtr val) {
227645490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard    xmlChar *res = NULL;
2277a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
2278a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    if (val == NULL)
2279a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	return(xmlXPathCacheNewCString(ctxt, ""));
2280a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
2281a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    switch (val->type) {
2282a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    case XPATH_UNDEFINED:
2283a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#ifdef DEBUG_EXPR
2284a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	xmlGenericError(xmlGenericErrorContext, "STRING: undefined\n");
2285a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#endif
2286a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	break;
2287a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    case XPATH_NODESET:
2288a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    case XPATH_XSLT_TREE:
2289a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	res = xmlXPathCastNodeSetToString(val->nodesetval);
2290a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	break;
2291a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    case XPATH_STRING:
2292a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	return(val);
2293a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    case XPATH_BOOLEAN:
2294a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	res = xmlXPathCastBooleanToString(val->boolval);
2295a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	break;
2296a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    case XPATH_NUMBER:
2297a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	res = xmlXPathCastNumberToString(val->floatval);
2298a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	break;
2299a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    case XPATH_USERS:
2300a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    case XPATH_POINT:
2301a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    case XPATH_RANGE:
2302a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    case XPATH_LOCATIONSET:
2303a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	TODO;
2304a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	break;
2305a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    }
2306a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathReleaseObject(ctxt, val);
2307a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    if (res == NULL)
2308a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	return(xmlXPathCacheNewCString(ctxt, ""));
2309a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    return(xmlXPathCacheWrapString(ctxt, res));
23109e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard}
231156a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillard
23125e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard/**
2313a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * xmlXPathCacheObjectCopy:
2314a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * @ctxt: the XPath context
2315a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * @val:  the original object
23165e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard *
2317a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * This is the cached version of xmlXPathObjectCopy().
2318a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * Acquire a copy of a given object
2319a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik *
2320a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * Returns a created or reused created object.
23215e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard */
2322a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikstatic xmlXPathObjectPtr
2323a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. BuchcikxmlXPathCacheObjectCopy(xmlXPathContextPtr ctxt, xmlXPathObjectPtr val)
2324a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik{
2325a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    if (val == NULL)
2326a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	return(NULL);
2327a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard
2328631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik    if (XP_HAS_CACHE(ctxt)) {
2329631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	switch (val->type) {
2330631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    case XPATH_NODESET:
2331a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		return(xmlXPathCacheWrapNodeSet(ctxt,
2332a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    xmlXPathNodeSetMerge(NULL, val->nodesetval)));
2333631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    case XPATH_STRING:
2334a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		return(xmlXPathCacheNewString(ctxt, val->stringval));
2335631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    case XPATH_BOOLEAN:
2336a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		return(xmlXPathCacheNewBoolean(ctxt, val->boolval));
2337631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    case XPATH_NUMBER:
2338631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik		return(xmlXPathCacheNewFloat(ctxt, val->floatval));
2339631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    default:
2340631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik		break;
2341631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	}
2342a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    }
2343a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    return(xmlXPathObjectCopy(val));
2344a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik}
23459e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
2346a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik/**
2347a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * xmlXPathCacheConvertBoolean:
2348a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * @ctxt: the XPath context
2349a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * @val:  an XPath object
2350a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik *
2351a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * This is the cached version of xmlXPathConvertBoolean().
2352a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * Converts an existing object to its boolean() equivalent
2353a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik *
2354a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * Returns a created or reused object, the old one is freed (or the operation
2355a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik *         is done directly on @val)
2356a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik */
2357a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikstatic xmlXPathObjectPtr
2358a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. BuchcikxmlXPathCacheConvertBoolean(xmlXPathContextPtr ctxt, xmlXPathObjectPtr val) {
2359a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathObjectPtr ret;
236045490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
2361a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    if (val == NULL)
2362a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	return(xmlXPathCacheNewBoolean(ctxt, 0));
2363a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    if (val->type == XPATH_BOOLEAN)
2364a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	return(val);
2365a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    ret = xmlXPathCacheNewBoolean(ctxt, xmlXPathCastToBoolean(val));
2366a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathReleaseObject(ctxt, val);
2367a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    return(ret);
2368a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik}
23699e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
2370a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik/**
2371a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * xmlXPathCacheConvertNumber:
2372a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * @ctxt: the XPath context
2373a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * @val:  an XPath object
2374a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik *
2375a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * This is the cached version of xmlXPathConvertNumber().
2376a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * Converts an existing object to its number() equivalent
2377a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik *
2378a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * Returns a created or reused object, the old one is freed (or the operation
2379a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik *         is done directly on @val)
2380a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik */
2381a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikstatic xmlXPathObjectPtr
2382a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. BuchcikxmlXPathCacheConvertNumber(xmlXPathContextPtr ctxt, xmlXPathObjectPtr val) {
2383a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathObjectPtr ret;
238445490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
2385a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    if (val == NULL)
2386a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	return(xmlXPathCacheNewFloat(ctxt, 0.0));
2387a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    if (val->type == XPATH_NUMBER)
2388a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	return(val);
2389a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    ret = xmlXPathCacheNewFloat(ctxt, xmlXPathCastToNumber(val));
2390a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathReleaseObject(ctxt, val);
2391a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    return(ret);
23929e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard}
23933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
23943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/************************************************************************
23953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *									*
239645490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *		Parser stacks related functions and macros		*
23973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *									*
23983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ************************************************************************/
23993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
24005e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard/**
24015e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard * valuePop:
24025e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard * @ctxt: an XPath evaluation context
24035e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard *
24045e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard * Pops the top XPath object from the value stack
24055e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard *
24065e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard * Returns the XPath object just removed
24075e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard */
240824505b0f5c872c5afb6da5093565e5a6e09ca541Daniel VeillardxmlXPathObjectPtr
24091c732d2e10935529b717864b6fa4296f80edace1Daniel VeillardvaluePop(xmlXPathParserContextPtr ctxt)
24101c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard{
24111c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard    xmlXPathObjectPtr ret;
24121c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard
2413a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard    if ((ctxt == NULL) || (ctxt->valueNr <= 0))
241424505b0f5c872c5afb6da5093565e5a6e09ca541Daniel Veillard        return (NULL);
24151c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard    ctxt->valueNr--;
24161c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard    if (ctxt->valueNr > 0)
24171c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard        ctxt->value = ctxt->valueTab[ctxt->valueNr - 1];
24181c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard    else
24191c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard        ctxt->value = NULL;
24201c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard    ret = ctxt->valueTab[ctxt->valueNr];
242124505b0f5c872c5afb6da5093565e5a6e09ca541Daniel Veillard    ctxt->valueTab[ctxt->valueNr] = NULL;
24221c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard    return (ret);
24231c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard}
24245e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard/**
24255e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard * valuePush:
24265e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard * @ctxt:  an XPath evaluation context
24275e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard * @value:  the XPath object
24285e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard *
24295e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard * Pushes a new XPath object on top of the value stack
2430cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard *
2431cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * returns the number of items on the value stack
24325e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard */
243324505b0f5c872c5afb6da5093565e5a6e09ca541Daniel Veillardint
24341c732d2e10935529b717864b6fa4296f80edace1Daniel VeillardvaluePush(xmlXPathParserContextPtr ctxt, xmlXPathObjectPtr value)
24351c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard{
2436a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard    if ((ctxt == NULL) || (value == NULL)) return(-1);
24371c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard    if (ctxt->valueNr >= ctxt->valueMax) {
2438a918b5b08ac20d4e7c765bdce653969ebad6c315Daniel Veillard        xmlXPathObjectPtr *tmp;
2439a918b5b08ac20d4e7c765bdce653969ebad6c315Daniel Veillard
2440a918b5b08ac20d4e7c765bdce653969ebad6c315Daniel Veillard        tmp = (xmlXPathObjectPtr *) xmlRealloc(ctxt->valueTab,
2441a918b5b08ac20d4e7c765bdce653969ebad6c315Daniel Veillard                                             2 * ctxt->valueMax *
24421c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard                                             sizeof(ctxt->valueTab[0]));
2443a918b5b08ac20d4e7c765bdce653969ebad6c315Daniel Veillard        if (tmp == NULL) {
24441c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard            xmlGenericError(xmlGenericErrorContext, "realloc failed !\n");
24451c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard            return (0);
24461c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard        }
2447a918b5b08ac20d4e7c765bdce653969ebad6c315Daniel Veillard        ctxt->valueMax *= 2;
2448a918b5b08ac20d4e7c765bdce653969ebad6c315Daniel Veillard	ctxt->valueTab = tmp;
24491c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard    }
24501c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard    ctxt->valueTab[ctxt->valueNr] = value;
24511c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard    ctxt->value = value;
24521c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard    return (ctxt->valueNr++);
24531c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard}
24543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
2455f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/**
2456f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathPopBoolean:
2457f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @ctxt:  an XPath parser context
2458f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *
2459f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Pops a boolean from the stack, handling conversion if needed.
2460f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Check error with #xmlXPathCheckError.
2461f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *
2462f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns the boolean
2463f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */
2464f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyerint
2465f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathPopBoolean (xmlXPathParserContextPtr ctxt) {
2466f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    xmlXPathObjectPtr obj;
2467f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    int ret;
2468f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer
2469f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    obj = valuePop(ctxt);
2470f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    if (obj == NULL) {
2471f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer	xmlXPathSetError(ctxt, XPATH_INVALID_OPERAND);
2472f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer	return(0);
2473f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    }
2474081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack    if (obj->type != XPATH_BOOLEAN)
2475081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack	ret = xmlXPathCastToBoolean(obj);
2476081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack    else
2477081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack        ret = obj->boolval;
2478a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathReleaseObject(ctxt->context, obj);
2479f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    return(ret);
2480f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer}
2481f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer
2482f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/**
2483f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathPopNumber:
2484f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @ctxt:  an XPath parser context
2485f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *
2486f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Pops a number from the stack, handling conversion if needed.
2487f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Check error with #xmlXPathCheckError.
2488f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *
2489f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns the number
2490f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */
2491f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyerdouble
2492f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathPopNumber (xmlXPathParserContextPtr ctxt) {
2493f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    xmlXPathObjectPtr obj;
2494f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    double ret;
2495f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer
2496f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    obj = valuePop(ctxt);
2497f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    if (obj == NULL) {
2498f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer	xmlXPathSetError(ctxt, XPATH_INVALID_OPERAND);
2499f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer	return(0);
2500f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    }
2501081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack    if (obj->type != XPATH_NUMBER)
2502081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack	ret = xmlXPathCastToNumber(obj);
2503081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack    else
2504081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack        ret = obj->floatval;
2505a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathReleaseObject(ctxt->context, obj);
2506f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    return(ret);
2507f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer}
2508f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer
2509f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/**
2510f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathPopString:
2511f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @ctxt:  an XPath parser context
2512f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *
2513f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Pops a string from the stack, handling conversion if needed.
2514f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Check error with #xmlXPathCheckError.
2515f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *
2516f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns the string
2517f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */
2518f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlChar *
2519f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathPopString (xmlXPathParserContextPtr ctxt) {
2520f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    xmlXPathObjectPtr obj;
2521f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    xmlChar * ret;
2522f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer
2523f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    obj = valuePop(ctxt);
2524f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    if (obj == NULL) {
2525f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer	xmlXPathSetError(ctxt, XPATH_INVALID_OPERAND);
2526f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer	return(NULL);
2527f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    }
2528081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack    ret = xmlXPathCastToString(obj);	/* this does required strdup */
2529f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    /* TODO: needs refactoring somewhere else */
2530f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    if (obj->stringval == ret)
2531f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer	obj->stringval = NULL;
2532a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathReleaseObject(ctxt->context, obj);
2533f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    return(ret);
2534f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer}
2535f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer
2536f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/**
2537f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathPopNodeSet:
2538f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @ctxt:  an XPath parser context
2539f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *
2540f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Pops a node-set from the stack, handling conversion if needed.
2541f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Check error with #xmlXPathCheckError.
2542f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *
2543f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns the node-set
2544f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */
2545f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlNodeSetPtr
2546f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathPopNodeSet (xmlXPathParserContextPtr ctxt) {
2547f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    xmlXPathObjectPtr obj;
2548f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    xmlNodeSetPtr ret;
2549f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer
2550f2a36f98e16efa8a89d9bed359d59be10e5d33cdDaniel Veillard    if (ctxt == NULL) return(NULL);
2551f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    if (ctxt->value == NULL) {
2552f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer	xmlXPathSetError(ctxt, XPATH_INVALID_OPERAND);
2553f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer	return(NULL);
2554f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    }
2555f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    if (!xmlXPathStackIsNodeSet(ctxt)) {
2556f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer	xmlXPathSetTypeError(ctxt);
2557f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer	return(NULL);
2558f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    }
2559f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    obj = valuePop(ctxt);
2560f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    ret = obj->nodesetval;
2561e9449c5d29d87b1dc51de7784ed947ae1e3da831William M. Brack#if 0
25629deb242b558cbcff45165866e0634a1962404885Daniel Veillard    /* to fix memory leak of not clearing obj->user */
25639deb242b558cbcff45165866e0634a1962404885Daniel Veillard    if (obj->boolval && obj->user != NULL)
25649deb242b558cbcff45165866e0634a1962404885Daniel Veillard        xmlFreeNodeList((xmlNodePtr) obj->user);
2565e9449c5d29d87b1dc51de7784ed947ae1e3da831William M. Brack#endif
2566a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    obj->nodesetval = NULL;
2567a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathReleaseObject(ctxt->context, obj);
2568f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    return(ret);
2569f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer}
2570f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer
2571f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/**
2572f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathPopExternal:
2573f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @ctxt:  an XPath parser context
2574f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *
2575cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * Pops an external object from the stack, handling conversion if needed.
2576f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Check error with #xmlXPathCheckError.
2577f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *
2578f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns the object
2579f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */
2580f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyervoid *
2581f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathPopExternal (xmlXPathParserContextPtr ctxt) {
2582f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    xmlXPathObjectPtr obj;
2583f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    void * ret;
2584f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer
2585a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard    if ((ctxt == NULL) || (ctxt->value == NULL)) {
2586f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer	xmlXPathSetError(ctxt, XPATH_INVALID_OPERAND);
2587f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer	return(NULL);
2588f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    }
2589f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    if (ctxt->value->type != XPATH_USERS) {
2590f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer	xmlXPathSetTypeError(ctxt);
2591f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer	return(NULL);
2592f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    }
2593f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    obj = valuePop(ctxt);
2594f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    ret = obj->user;
2595a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    obj->user = NULL;
2596a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathReleaseObject(ctxt->context, obj);
2597f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    return(ret);
2598f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer}
2599f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer
26003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/*
26013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Macros for accessing the content. Those should be used only by the parser,
26023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * and not exported.
26033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
26043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Dirty macros, i.e. one need to make assumption on the context to use them
26053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
26063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *   CUR_PTR return the current pointer to the xmlChar to be parsed.
26073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *   CUR     returns the current xmlChar value, i.e. a 8 bit value
26083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *           in ISO-Latin or UTF-8.
26093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *           This should be used internally by the parser
26103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *           only to compare to ASCII values otherwise it would break when
26113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *           running with UTF-8 encoding.
26123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *   NXT(n)  returns the n'th next xmlChar. Same as CUR is should be used only
26133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *           to compare on ASCII based substring.
26143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *   SKIP(n) Skip n xmlChar, and must also be used only to skip ASCII defined
26153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *           strings within the parser.
26163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *   CURRENT Returns the current char value, with the full decoding of
26173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *           UTF-8 if we are using this mode. It returns an int.
26183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *   NEXT    Skip to the next character, this does the proper decoding
26193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *           in UTF-8 mode. It also pop-up unfinished entities on the fly.
26203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *           It returns the pointer to the current xmlChar.
26213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
26223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
26233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define CUR (*ctxt->cur)
26243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define SKIP(val) ctxt->cur += (val)
26253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define NXT(val) ctxt->cur[(val)]
26263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define CUR_PTR ctxt->cur
262761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard#define CUR_CHAR(l) xmlXPathCurrentChar(ctxt, &l)
262861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard
262961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard#define COPY_BUF(l,b,i,v)                                              \
263061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard    if (l == 1) b[i++] = (xmlChar) v;                                  \
263161d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard    else i += xmlCopyChar(l,&b[i],v)
263261d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard
263361d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard#define NEXTL(l)  ctxt->cur += l
26343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
263545490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard#define SKIP_BLANKS							\
263676e95df05556c9610b564b14cf578c8f9e34c9c1William M. Brack    while (IS_BLANK_CH(*(ctxt->cur))) NEXT
26373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
26383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define CURRENT (*ctxt->cur)
26393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define NEXT ((*ctxt->cur) ?  ctxt->cur++: ctxt->cur)
26403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
2641e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese
2642e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese#ifndef DBL_DIG
2643e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese#define DBL_DIG 16
2644e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese#endif
2645e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese#ifndef DBL_EPSILON
2646e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese#define DBL_EPSILON 1E-9
2647e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese#endif
2648e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese
2649e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese#define UPPER_DOUBLE 1E9
2650e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese#define LOWER_DOUBLE 1E-5
2651ca79788eaa34765e184801c4db50560e5a0dda91William M. Brack#define	LOWER_DOUBLE_EXP 5
2652e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese
2653e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese#define INTEGER_DIGITS DBL_DIG
2654ca79788eaa34765e184801c4db50560e5a0dda91William M. Brack#define FRACTION_DIGITS (DBL_DIG + 1 + (LOWER_DOUBLE_EXP))
2655e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese#define EXPONENT_DIGITS (3 + 2)
2656e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese
2657e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese/**
2658e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese * xmlXPathFormatNumber:
2659e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese * @number:     number to format
2660e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese * @buffer:     output buffer
2661e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese * @buffersize: size of output buffer
2662e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese *
2663e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese * Convert the number into a string representation.
2664e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese */
2665e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reesestatic void
2666e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn ReesexmlXPathFormatNumber(double number, char buffer[], int buffersize)
2667e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese{
2668cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard    switch (xmlXPathIsInf(number)) {
2669e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese    case 1:
26705fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard	if (buffersize > (int)sizeof("Infinity"))
267149cc97565fbe2928388a1e437c44429097a504aeAleksey Sanin	    snprintf(buffer, buffersize, "Infinity");
2672e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese	break;
2673e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese    case -1:
2674e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese	if (buffersize > (int)sizeof("-Infinity"))
267549cc97565fbe2928388a1e437c44429097a504aeAleksey Sanin	    snprintf(buffer, buffersize, "-Infinity");
2676e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese	break;
2677e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese    default:
2678cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard	if (xmlXPathIsNaN(number)) {
2679e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese	    if (buffersize > (int)sizeof("NaN"))
268049cc97565fbe2928388a1e437c44429097a504aeAleksey Sanin		snprintf(buffer, buffersize, "NaN");
2681d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard	} else if (number == 0 && xmlXPathGetSign(number) != 0) {
268249cc97565fbe2928388a1e437c44429097a504aeAleksey Sanin	    snprintf(buffer, buffersize, "0");
268328cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard	} else if (number == ((int) number)) {
268428cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard	    char work[30];
268528cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard	    char *ptr, *cur;
2686b3d1491b69060f8a67516b9a3ef12617adf88954Daniel Veillard	    int value = (int) number;
268728cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard
268828cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard            ptr = &buffer[0];
268928cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard	    if (value == 0) {
269028cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard		*ptr++ = '0';
269128cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard	    } else {
2692b3d1491b69060f8a67516b9a3ef12617adf88954Daniel Veillard		snprintf(work, 29, "%d", value);
269328cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard		cur = &work[0];
2694b3d1491b69060f8a67516b9a3ef12617adf88954Daniel Veillard		while ((*cur) && (ptr - buffer < buffersize)) {
2695b3d1491b69060f8a67516b9a3ef12617adf88954Daniel Veillard		    *ptr++ = *cur++;
269628cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard		}
269728cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard	    }
269828cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard	    if (ptr - buffer < buffersize) {
269928cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard		*ptr = 0;
270028cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard	    } else if (buffersize > 0) {
270128cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard		ptr--;
270228cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard		*ptr = 0;
270328cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard	    }
2704e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese	} else {
2705ca79788eaa34765e184801c4db50560e5a0dda91William M. Brack	    /*
2706ca79788eaa34765e184801c4db50560e5a0dda91William M. Brack	      For the dimension of work,
2707ca79788eaa34765e184801c4db50560e5a0dda91William M. Brack	          DBL_DIG is number of significant digits
2708ca79788eaa34765e184801c4db50560e5a0dda91William M. Brack		  EXPONENT is only needed for "scientific notation"
2709ca79788eaa34765e184801c4db50560e5a0dda91William M. Brack	          3 is sign, decimal point, and terminating zero
2710ca79788eaa34765e184801c4db50560e5a0dda91William M. Brack		  LOWER_DOUBLE_EXP is max number of leading zeroes in fraction
2711ca79788eaa34765e184801c4db50560e5a0dda91William M. Brack	      Note that this dimension is slightly (a few characters)
2712ca79788eaa34765e184801c4db50560e5a0dda91William M. Brack	      larger than actually necessary.
2713ca79788eaa34765e184801c4db50560e5a0dda91William M. Brack	    */
2714ca79788eaa34765e184801c4db50560e5a0dda91William M. Brack	    char work[DBL_DIG + EXPONENT_DIGITS + 3 + LOWER_DOUBLE_EXP];
271570a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese	    int integer_place, fraction_place;
271670a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese	    char *ptr;
271770a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese	    char *after_fraction;
271870a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese	    double absolute_value;
271970a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese	    int size;
272070a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese
272170a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese	    absolute_value = fabs(number);
272270a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese
272370a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese	    /*
272470a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese	     * First choose format - scientific or regular floating point.
272570a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese	     * In either case, result is in work, and after_fraction points
272670a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese	     * just past the fractional part.
272770a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese	    */
272870a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese	    if ( ((absolute_value > UPPER_DOUBLE) ||
272970a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese		  (absolute_value < LOWER_DOUBLE)) &&
273070a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese		 (absolute_value != 0.0) ) {
273170a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese		/* Use scientific notation */
273270a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese		integer_place = DBL_DIG + EXPONENT_DIGITS + 1;
273370a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese		fraction_place = DBL_DIG - 1;
273411ce4004d86bb4b317c48b7d5124ba33e40e10f5Daniel Veillard		size = snprintf(work, sizeof(work),"%*.*e",
273570a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese			 integer_place, fraction_place, number);
273611ce4004d86bb4b317c48b7d5124ba33e40e10f5Daniel Veillard		while ((size > 0) && (work[size] != 'e')) size--;
273711ce4004d86bb4b317c48b7d5124ba33e40e10f5Daniel Veillard
2738e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese	    }
273970a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese	    else {
274070a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese		/* Use regular notation */
2741ca79788eaa34765e184801c4db50560e5a0dda91William M. Brack		if (absolute_value > 0.0) {
2742ca79788eaa34765e184801c4db50560e5a0dda91William M. Brack		    integer_place = (int)log10(absolute_value);
2743ca79788eaa34765e184801c4db50560e5a0dda91William M. Brack		    if (integer_place > 0)
2744ca79788eaa34765e184801c4db50560e5a0dda91William M. Brack		        fraction_place = DBL_DIG - integer_place - 1;
2745ca79788eaa34765e184801c4db50560e5a0dda91William M. Brack		    else
2746ca79788eaa34765e184801c4db50560e5a0dda91William M. Brack		        fraction_place = DBL_DIG - integer_place;
2747ca79788eaa34765e184801c4db50560e5a0dda91William M. Brack		} else {
2748ca79788eaa34765e184801c4db50560e5a0dda91William M. Brack		    fraction_place = 1;
2749ca79788eaa34765e184801c4db50560e5a0dda91William M. Brack		}
275070a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese		size = snprintf(work, sizeof(work), "%0.*f",
275170a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese				fraction_place, number);
2752e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese	    }
2753e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese
275470a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese	    /* Remove fractional trailing zeroes */
2755ca79788eaa34765e184801c4db50560e5a0dda91William M. Brack	    after_fraction = work + size;
275670a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese	    ptr = after_fraction;
275770a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese	    while (*(--ptr) == '0')
275870a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese		;
275970a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese	    if (*ptr != '.')
276070a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese	        ptr++;
27615dd3c9622ab6a8e75870bc5351499155e7963abcDaniel Veillard	    while ((*ptr++ = *after_fraction++) != 0);
276270a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese
276370a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese	    /* Finally copy result back to caller */
276470a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese	    size = strlen(work) + 1;
276570a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese	    if (size > buffersize) {
276670a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese		work[buffersize - 1] = 0;
276770a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese		size = buffersize;
276870a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese	    }
27695dd3c9622ab6a8e75870bc5351499155e7963abcDaniel Veillard	    memmove(buffer, work, size);
2770e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese	}
2771e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese	break;
2772e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese    }
2773e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese}
2774e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese
27753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
27763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/************************************************************************
27773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *									*
27783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *			Routines to handle NodeSets			*
27793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *									*
27803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ************************************************************************/
27813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
27823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
2783e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard * xmlXPathOrderDocElems:
2784e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard * @doc:  an input document
2785e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard *
2786e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard * Call this routine to speed up XPath computation on static documents.
2787e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard * This stamps all the element nodes with the document order
2788e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard * Like for line information, the order is kept in the element->content
2789081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack * field, the value stored is actually - the node number (starting at -1)
2790081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack * to be able to differentiate from line numbers.
2791e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard *
2792081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack * Returns the number of elements found in the document or -1 in case
2793e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard *    of error.
2794e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard */
2795e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillardlong
2796e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel VeillardxmlXPathOrderDocElems(xmlDocPtr doc) {
2797e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard    long count = 0;
2798e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard    xmlNodePtr cur;
2799e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard
2800e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard    if (doc == NULL)
2801e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard	return(-1);
2802e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard    cur = doc->children;
2803e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard    while (cur != NULL) {
2804e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard	if (cur->type == XML_ELEMENT_NODE) {
2805e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard	    cur->content = (void *) (-(++count));
2806e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard	    if (cur->children != NULL) {
2807e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard		cur = cur->children;
2808e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard		continue;
2809e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard	    }
2810e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard	}
2811e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard	if (cur->next != NULL) {
2812e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard	    cur = cur->next;
2813e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard	    continue;
2814e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard	}
2815e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard	do {
2816e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard	    cur = cur->parent;
2817e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard	    if (cur == NULL)
2818e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard		break;
2819e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard	    if (cur == (xmlNodePtr) doc) {
2820e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard		cur = NULL;
2821e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard		break;
2822e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard	    }
2823e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard	    if (cur->next != NULL) {
2824e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard		cur = cur->next;
2825e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard		break;
2826e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard	    }
2827e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard	} while (cur != NULL);
2828e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard    }
2829e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard    return(count);
2830e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard}
2831e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard
2832e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard/**
28333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathCmpNodes:
28343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @node1:  the first node
28353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @node2:  the second node
28363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
28373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Compare two nodes w.r.t document order
28383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
28393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns -2 in case of error 1 if first point < second point, 0 if
2840081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack *         it's the same node, -1 otherwise
28413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
28423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorint
28433473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathCmpNodes(xmlNodePtr node1, xmlNodePtr node2) {
28443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    int depth1, depth2;
2845edfd588e95d7c4690b5e85880521a32c20ed4fdeDaniel Veillard    int attr1 = 0, attr2 = 0;
2846e8d1bd9daa881b01259e83eab60df8cbb56785c6William M. Brack    xmlNodePtr attrNode1 = NULL, attrNode2 = NULL;
28473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlNodePtr cur, root;
28483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
28493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if ((node1 == NULL) || (node2 == NULL))
28503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(-2);
28513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    /*
28523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor     * a couple of optimizations which will avoid computations in most cases
28533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor     */
2854ee0b982fe81018f8a190f62335c0e7957f4c5bcdWilliam M. Brack    if (node1 == node2)		/* trivial case */
2855ee0b982fe81018f8a190f62335c0e7957f4c5bcdWilliam M. Brack	return(0);
2856edfd588e95d7c4690b5e85880521a32c20ed4fdeDaniel Veillard    if (node1->type == XML_ATTRIBUTE_NODE) {
2857edfd588e95d7c4690b5e85880521a32c20ed4fdeDaniel Veillard	attr1 = 1;
2858e8d1bd9daa881b01259e83eab60df8cbb56785c6William M. Brack	attrNode1 = node1;
2859edfd588e95d7c4690b5e85880521a32c20ed4fdeDaniel Veillard	node1 = node1->parent;
2860edfd588e95d7c4690b5e85880521a32c20ed4fdeDaniel Veillard    }
2861edfd588e95d7c4690b5e85880521a32c20ed4fdeDaniel Veillard    if (node2->type == XML_ATTRIBUTE_NODE) {
2862edfd588e95d7c4690b5e85880521a32c20ed4fdeDaniel Veillard	attr2 = 1;
2863e8d1bd9daa881b01259e83eab60df8cbb56785c6William M. Brack	attrNode2 = node2;
2864edfd588e95d7c4690b5e85880521a32c20ed4fdeDaniel Veillard	node2 = node2->parent;
2865edfd588e95d7c4690b5e85880521a32c20ed4fdeDaniel Veillard    }
2866edfd588e95d7c4690b5e85880521a32c20ed4fdeDaniel Veillard    if (node1 == node2) {
2867e8d1bd9daa881b01259e83eab60df8cbb56785c6William M. Brack	if (attr1 == attr2) {
2868e8d1bd9daa881b01259e83eab60df8cbb56785c6William M. Brack	    /* not required, but we keep attributes in order */
2869e8d1bd9daa881b01259e83eab60df8cbb56785c6William M. Brack	    if (attr1 != 0) {
2870e8d1bd9daa881b01259e83eab60df8cbb56785c6William M. Brack	        cur = attrNode2->prev;
2871e8d1bd9daa881b01259e83eab60df8cbb56785c6William M. Brack		while (cur != NULL) {
2872e8d1bd9daa881b01259e83eab60df8cbb56785c6William M. Brack		    if (cur == attrNode1)
2873e8d1bd9daa881b01259e83eab60df8cbb56785c6William M. Brack		        return (1);
2874e8d1bd9daa881b01259e83eab60df8cbb56785c6William M. Brack		    cur = cur->prev;
2875e8d1bd9daa881b01259e83eab60df8cbb56785c6William M. Brack		}
2876e8d1bd9daa881b01259e83eab60df8cbb56785c6William M. Brack		return (-1);
2877e8d1bd9daa881b01259e83eab60df8cbb56785c6William M. Brack	    }
2878edfd588e95d7c4690b5e85880521a32c20ed4fdeDaniel Veillard	    return(0);
2879e8d1bd9daa881b01259e83eab60df8cbb56785c6William M. Brack	}
2880edfd588e95d7c4690b5e85880521a32c20ed4fdeDaniel Veillard	if (attr2 == 1)
2881edfd588e95d7c4690b5e85880521a32c20ed4fdeDaniel Veillard	    return(1);
2882edfd588e95d7c4690b5e85880521a32c20ed4fdeDaniel Veillard	return(-1);
2883edfd588e95d7c4690b5e85880521a32c20ed4fdeDaniel Veillard    }
2884b33c201978ed1c434877cdc6e2000b7012cc26f9Daniel Veillard    if ((node1->type == XML_NAMESPACE_DECL) ||
2885b33c201978ed1c434877cdc6e2000b7012cc26f9Daniel Veillard        (node2->type == XML_NAMESPACE_DECL))
2886b33c201978ed1c434877cdc6e2000b7012cc26f9Daniel Veillard	return(1);
28873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (node1 == node2->prev)
28883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(1);
28893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (node1 == node2->next)
28903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(-1);
28913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
28923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    /*
2893e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard     * Speedup using document order if availble.
28947216cfd6622d947695c67b7b430edef8cc0af967Daniel Veillard     */
28957216cfd6622d947695c67b7b430edef8cc0af967Daniel Veillard    if ((node1->type == XML_ELEMENT_NODE) &&
28967216cfd6622d947695c67b7b430edef8cc0af967Daniel Veillard	(node2->type == XML_ELEMENT_NODE) &&
2897e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard	(0 > (long) node1->content) &&
2898e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard	(0 > (long) node2->content) &&
2899e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard	(node1->doc == node2->doc)) {
2900e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard	long l1, l2;
2901e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard
2902e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard	l1 = -((long) node1->content);
2903e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard	l2 = -((long) node2->content);
29047216cfd6622d947695c67b7b430edef8cc0af967Daniel Veillard	if (l1 < l2)
29057216cfd6622d947695c67b7b430edef8cc0af967Daniel Veillard	    return(1);
29067216cfd6622d947695c67b7b430edef8cc0af967Daniel Veillard	if (l1 > l2)
29077216cfd6622d947695c67b7b430edef8cc0af967Daniel Veillard	    return(-1);
29087216cfd6622d947695c67b7b430edef8cc0af967Daniel Veillard    }
2909e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard
29107216cfd6622d947695c67b7b430edef8cc0af967Daniel Veillard    /*
29113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor     * compute depth to root
29123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor     */
29133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    for (depth2 = 0, cur = node2;cur->parent != NULL;cur = cur->parent) {
29143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (cur == node1)
29153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    return(1);
29163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	depth2++;
29173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
29183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    root = cur;
29193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    for (depth1 = 0, cur = node1;cur->parent != NULL;cur = cur->parent) {
29203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (cur == node2)
29213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    return(-1);
29223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	depth1++;
29233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
29243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    /*
29253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor     * Distinct document (or distinct entities :-( ) case.
29263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor     */
29273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (root != cur) {
29283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(-2);
29293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
29303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    /*
29313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor     * get the nearest common ancestor.
29323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor     */
29333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    while (depth1 > depth2) {
29343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	depth1--;
29353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	node1 = node1->parent;
29363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
29373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    while (depth2 > depth1) {
29383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	depth2--;
29393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	node2 = node2->parent;
29403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
29413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    while (node1->parent != node2->parent) {
29423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	node1 = node1->parent;
29433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	node2 = node2->parent;
29443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	/* should not happen but just in case ... */
29453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if ((node1 == NULL) || (node2 == NULL))
29463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    return(-2);
29473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
29483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    /*
29493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor     * Find who's first.
29503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor     */
2951f49be4778db34e8bbcfabc5d5f1ad33c594b7387Daniel Veillard    if (node1 == node2->prev)
2952f49be4778db34e8bbcfabc5d5f1ad33c594b7387Daniel Veillard	return(1);
29533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (node1 == node2->next)
29543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(-1);
2955f49be4778db34e8bbcfabc5d5f1ad33c594b7387Daniel Veillard    /*
2956f49be4778db34e8bbcfabc5d5f1ad33c594b7387Daniel Veillard     * Speedup using document order if availble.
2957f49be4778db34e8bbcfabc5d5f1ad33c594b7387Daniel Veillard     */
2958f49be4778db34e8bbcfabc5d5f1ad33c594b7387Daniel Veillard    if ((node1->type == XML_ELEMENT_NODE) &&
2959f49be4778db34e8bbcfabc5d5f1ad33c594b7387Daniel Veillard	(node2->type == XML_ELEMENT_NODE) &&
2960f49be4778db34e8bbcfabc5d5f1ad33c594b7387Daniel Veillard	(0 > (long) node1->content) &&
2961f49be4778db34e8bbcfabc5d5f1ad33c594b7387Daniel Veillard	(0 > (long) node2->content) &&
2962f49be4778db34e8bbcfabc5d5f1ad33c594b7387Daniel Veillard	(node1->doc == node2->doc)) {
2963f49be4778db34e8bbcfabc5d5f1ad33c594b7387Daniel Veillard	long l1, l2;
2964f49be4778db34e8bbcfabc5d5f1ad33c594b7387Daniel Veillard
2965f49be4778db34e8bbcfabc5d5f1ad33c594b7387Daniel Veillard	l1 = -((long) node1->content);
2966f49be4778db34e8bbcfabc5d5f1ad33c594b7387Daniel Veillard	l2 = -((long) node2->content);
2967f49be4778db34e8bbcfabc5d5f1ad33c594b7387Daniel Veillard	if (l1 < l2)
2968f49be4778db34e8bbcfabc5d5f1ad33c594b7387Daniel Veillard	    return(1);
2969f49be4778db34e8bbcfabc5d5f1ad33c594b7387Daniel Veillard	if (l1 > l2)
2970f49be4778db34e8bbcfabc5d5f1ad33c594b7387Daniel Veillard	    return(-1);
2971f49be4778db34e8bbcfabc5d5f1ad33c594b7387Daniel Veillard    }
2972f49be4778db34e8bbcfabc5d5f1ad33c594b7387Daniel Veillard
29733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    for (cur = node1->next;cur != NULL;cur = cur->next)
29743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (cur == node2)
29753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    return(1);
29763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(-1); /* assume there is no sibling list corruption */
29773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
29783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
29795691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik#ifdef XP_OPTIMIZED_NON_ELEM_COMPARISON
29802bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik/**
29812bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik * xmlXPathCmpNodesExt:
29822bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik * @node1:  the first node
29832bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik * @node2:  the second node
29842bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik *
29852bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik * Compare two nodes w.r.t document order.
29862bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik * This one is optimized for handling of non-element nodes.
29872bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik *
29882bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik * Returns -2 in case of error 1 if first point < second point, 0 if
29892bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik *         it's the same node, -1 otherwise
29902bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik */
29912bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcikstatic int
29922bdabbd711356e534940431053523f1538d1a93eKasimier T. BuchcikxmlXPathCmpNodesExt(xmlNodePtr node1, xmlNodePtr node2) {
29932bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik    int depth1, depth2;
29942bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik    int misc = 0, precedence1 = 0, precedence2 = 0;
29952bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik    xmlNodePtr miscNode1 = NULL, miscNode2 = NULL;
29962bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik    xmlNodePtr cur, root;
299764f7e1a85fe9c973cf9b21cc0bd53efa6cc3dafcKasimier T. Buchcik    long l1, l2;
29982bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik
29992bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik    if ((node1 == NULL) || (node2 == NULL))
30002bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	return(-2);
30012bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik
30022bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik    if (node1 == node2)
30032bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	return(0);
300445490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
30052bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik    /*
30062bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik     * a couple of optimizations which will avoid computations in most cases
300745490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard     */
30082bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik    switch (node1->type) {
30092bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	case XML_ELEMENT_NODE:
301064f7e1a85fe9c973cf9b21cc0bd53efa6cc3dafcKasimier T. Buchcik	    if (node2->type == XML_ELEMENT_NODE) {
301164f7e1a85fe9c973cf9b21cc0bd53efa6cc3dafcKasimier T. Buchcik		if ((0 > (long) node1->content) && /* TODO: Would a != 0 suffice here? */
301264f7e1a85fe9c973cf9b21cc0bd53efa6cc3dafcKasimier T. Buchcik		    (0 > (long) node2->content) &&
301364f7e1a85fe9c973cf9b21cc0bd53efa6cc3dafcKasimier T. Buchcik		    (node1->doc == node2->doc))
301445490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard		{
301564f7e1a85fe9c973cf9b21cc0bd53efa6cc3dafcKasimier T. Buchcik		    l1 = -((long) node1->content);
301664f7e1a85fe9c973cf9b21cc0bd53efa6cc3dafcKasimier T. Buchcik		    l2 = -((long) node2->content);
301764f7e1a85fe9c973cf9b21cc0bd53efa6cc3dafcKasimier T. Buchcik		    if (l1 < l2)
301864f7e1a85fe9c973cf9b21cc0bd53efa6cc3dafcKasimier T. Buchcik			return(1);
301964f7e1a85fe9c973cf9b21cc0bd53efa6cc3dafcKasimier T. Buchcik		    if (l1 > l2)
302064f7e1a85fe9c973cf9b21cc0bd53efa6cc3dafcKasimier T. Buchcik			return(-1);
302164f7e1a85fe9c973cf9b21cc0bd53efa6cc3dafcKasimier T. Buchcik		} else
302245490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard		    goto turtle_comparison;
302364f7e1a85fe9c973cf9b21cc0bd53efa6cc3dafcKasimier T. Buchcik	    }
30242bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	    break;
30252bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	case XML_ATTRIBUTE_NODE:
30262bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	    precedence1 = 1; /* element is owner */
30272bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	    miscNode1 = node1;
30282bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	    node1 = node1->parent;
30292bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	    misc = 1;
30302bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	    break;
30312bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	case XML_TEXT_NODE:
30322bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	case XML_CDATA_SECTION_NODE:
30332bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	case XML_COMMENT_NODE:
30342bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	case XML_PI_NODE: {
30352bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	    miscNode1 = node1;
30362bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	    /*
30372bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	    * Find nearest element node.
303845490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	    */
30392bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	    if (node1->prev != NULL) {
30402bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik		do {
30412bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik		    node1 = node1->prev;
30422bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik		    if (node1->type == XML_ELEMENT_NODE) {
30432bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik			precedence1 = 3; /* element in prev-sibl axis */
30442bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik			break;
30452bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik		    }
30462bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik		    if (node1->prev == NULL) {
30472bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik			precedence1 = 2; /* element is parent */
30482bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik			/*
30492bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik			* URGENT TODO: Are there any cases, where the
30502bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik			* parent of such a node is not an element node?
30512bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik			*/
30522bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik			node1 = node1->parent;
30532bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik			break;
30542bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik		    }
30552bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik		} while (1);
30562bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	    } else {
30572bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik		precedence1 = 2; /* element is parent */
30582bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik		node1 = node1->parent;
30592bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	    }
306031700e63067962c632d9fa3d7a4d699a657e8e08William M. Brack	    if ((node1 == NULL) || (node1->type != XML_ELEMENT_NODE) ||
306131700e63067962c632d9fa3d7a4d699a657e8e08William M. Brack		(0 <= (long) node1->content)) {
30622bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik		/*
30632bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik		* Fallback for whatever case.
30642bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik		*/
30652bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik		node1 = miscNode1;
30662bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik		precedence1 = 0;
30672bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	    } else
30682bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik		misc = 1;
30692bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	}
30702bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	    break;
30712bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	case XML_NAMESPACE_DECL:
30722bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	    /*
30732bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	    * TODO: why do we return 1 for namespace nodes?
30742bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	    */
30752bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	    return(1);
30762bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	default:
30772bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	    break;
307845490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard    }
30792bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik    switch (node2->type) {
308045490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	case XML_ELEMENT_NODE:
30812bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	    break;
30822bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	case XML_ATTRIBUTE_NODE:
30832bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	    precedence2 = 1; /* element is owner */
30842bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	    miscNode2 = node2;
30852bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	    node2 = node2->parent;
30862bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	    misc = 1;
30872bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	    break;
30882bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	case XML_TEXT_NODE:
30892bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	case XML_CDATA_SECTION_NODE:
30902bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	case XML_COMMENT_NODE:
30912bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	case XML_PI_NODE: {
30922bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	    miscNode2 = node2;
30932bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	    if (node2->prev != NULL) {
30942bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik		do {
30952bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik		    node2 = node2->prev;
30962bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik		    if (node2->type == XML_ELEMENT_NODE) {
30972bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik			precedence2 = 3; /* element in prev-sibl axis */
30982bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik			break;
30992bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik		    }
31002bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik		    if (node2->prev == NULL) {
31012bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik			precedence2 = 2; /* element is parent */
31022bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik			node2 = node2->parent;
31032bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik			break;
31042bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik		    }
31052bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik		} while (1);
31062bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	    } else {
31072bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik		precedence2 = 2; /* element is parent */
31082bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik		node2 = node2->parent;
310945490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	    }
31102bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	    if ((node2 == NULL) || (node2->type != XML_ELEMENT_NODE) ||
31112bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik		(0 <= (long) node1->content))
31122bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	    {
31132bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik		node2 = miscNode2;
31142bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik		precedence2 = 0;
31152bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	    } else
31162bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik		misc = 1;
31172bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	}
31182bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	    break;
31192bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	case XML_NAMESPACE_DECL:
31202bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	    return(1);
31212bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	default:
31222bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	    break;
31232bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik    }
31242bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik    if (misc) {
31252bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	if (node1 == node2) {
31262bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	    if (precedence1 == precedence2) {
31272bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik		/*
31282bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik		* The ugly case; but normally there aren't many
31292bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik		* adjacent non-element nodes around.
31302bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik		*/
31312bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik		cur = miscNode2->prev;
31322bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik		while (cur != NULL) {
31332bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik		    if (cur == miscNode1)
31342bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik			return(1);
31352bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik		    if (cur->type == XML_ELEMENT_NODE)
31362bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik			return(-1);
31372bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik		    cur = cur->prev;
31382bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik		}
31392bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik		return (-1);
31402bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	    } else {
31412bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik		/*
31422bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik		* Evaluate based on higher precedence wrt to the element.
31432bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik		* TODO: This assumes attributes are sorted before content.
31442bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik		*   Is this 100% correct?
31452bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik		*/
31462bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik		if (precedence1 < precedence2)
314745490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard		    return(1);
31482bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik		else
314945490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard		    return(-1);
31502bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	    }
315145490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	}
31522bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	/*
31532bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	* Special case: One of the helper-elements is contained by the other.
31542bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	* <foo>
31552bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	*   <node2>
31562bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	*     <node1>Text-1(precedence1 == 2)</node1>
31572bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	*   </node2>
31582bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	*   Text-6(precedence2 == 3)
31592bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	* </foo>
316045490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	*/
31612bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	if ((precedence2 == 3) && (precedence1 > 1)) {
31622bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	    cur = node1->parent;
31632bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	    while (cur) {
31642bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik		if (cur == node2)
31652bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik		    return(1);
31662bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik		cur = cur->parent;
31672bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	    }
31682bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	}
316945490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	if ((precedence1 == 3) && (precedence2 > 1)) {
31702bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	    cur = node2->parent;
31712bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	    while (cur) {
31722bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik		if (cur == node1)
31732bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik		    return(-1);
31742bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik		cur = cur->parent;
31752bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	    }
31762bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	}
317745490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard    }
31782bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik
31792bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik    /*
31802bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik     * Speedup using document order if availble.
31812bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik     */
318245490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard    if ((node1->type == XML_ELEMENT_NODE) &&
31832bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	(node2->type == XML_ELEMENT_NODE) &&
31842bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	(0 > (long) node1->content) &&
31852bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	(0 > (long) node2->content) &&
318645490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	(node1->doc == node2->doc)) {
31872bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik
31882bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	l1 = -((long) node1->content);
31892bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	l2 = -((long) node2->content);
31902bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	if (l1 < l2)
31912bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	    return(1);
31922bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	if (l1 > l2)
31932bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	    return(-1);
31942bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik    }
31952bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik
319664f7e1a85fe9c973cf9b21cc0bd53efa6cc3dafcKasimier T. Buchcikturtle_comparison:
319764f7e1a85fe9c973cf9b21cc0bd53efa6cc3dafcKasimier T. Buchcik
319864f7e1a85fe9c973cf9b21cc0bd53efa6cc3dafcKasimier T. Buchcik    if (node1 == node2->prev)
319964f7e1a85fe9c973cf9b21cc0bd53efa6cc3dafcKasimier T. Buchcik	return(1);
320064f7e1a85fe9c973cf9b21cc0bd53efa6cc3dafcKasimier T. Buchcik    if (node1 == node2->next)
320164f7e1a85fe9c973cf9b21cc0bd53efa6cc3dafcKasimier T. Buchcik	return(-1);
32022bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik    /*
32032bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik     * compute depth to root
32042bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik     */
32052bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik    for (depth2 = 0, cur = node2;cur->parent != NULL;cur = cur->parent) {
32062bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	if (cur == node1)
32072bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	    return(1);
32082bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	depth2++;
32092bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik    }
32102bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik    root = cur;
32112bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik    for (depth1 = 0, cur = node1;cur->parent != NULL;cur = cur->parent) {
32122bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	if (cur == node2)
32132bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	    return(-1);
32142bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	depth1++;
32152bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik    }
32162bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik    /*
32172bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik     * Distinct document (or distinct entities :-( ) case.
32182bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik     */
32192bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik    if (root != cur) {
32202bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	return(-2);
32212bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik    }
32222bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik    /*
32232bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik     * get the nearest common ancestor.
32242bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik     */
32252bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik    while (depth1 > depth2) {
32262bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	depth1--;
32272bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	node1 = node1->parent;
32282bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik    }
32292bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik    while (depth2 > depth1) {
32302bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	depth2--;
32312bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	node2 = node2->parent;
32322bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik    }
32332bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik    while (node1->parent != node2->parent) {
32342bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	node1 = node1->parent;
32352bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	node2 = node2->parent;
32362bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	/* should not happen but just in case ... */
32372bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	if ((node1 == NULL) || (node2 == NULL))
32382bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	    return(-2);
32392bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik    }
32402bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik    /*
32412bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik     * Find who's first.
32422bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik     */
32432bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik    if (node1 == node2->prev)
32442bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	return(1);
32452bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik    if (node1 == node2->next)
32462bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	return(-1);
32472bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik    /*
32482bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik     * Speedup using document order if availble.
32492bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik     */
32502bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik    if ((node1->type == XML_ELEMENT_NODE) &&
32512bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	(node2->type == XML_ELEMENT_NODE) &&
32522bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	(0 > (long) node1->content) &&
32532bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	(0 > (long) node2->content) &&
325445490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	(node1->doc == node2->doc)) {
32552bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik
32562bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	l1 = -((long) node1->content);
32572bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	l2 = -((long) node2->content);
32582bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	if (l1 < l2)
32592bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	    return(1);
32602bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	if (l1 > l2)
32612bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	    return(-1);
32622bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik    }
32632bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik
32642bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik    for (cur = node1->next;cur != NULL;cur = cur->next)
32652bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	if (cur == node2)
32662bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	    return(1);
32672bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik    return(-1); /* assume there is no sibling list corruption */
32682bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik}
32695691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik#endif /* XP_OPTIMIZED_NON_ELEM_COMPARISON */
32702bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik
32713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
32723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNodeSetSort:
32733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @set:  the node set
32743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
32753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Sort the node set in document order
32763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
32773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
32783473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNodeSetSort(xmlNodeSetPtr set) {
3279e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese    int i, j, incr, len;
32803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlNodePtr tmp;
32813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
32823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (set == NULL)
32833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return;
32843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
32853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    /* Use Shell's sort to sort the node-set */
32863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    len = set->nodeNr;
32873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    for (incr = len / 2; incr > 0; incr /= 2) {
32883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	for (i = incr; i < len; i++) {
32893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    j = i - incr;
32903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    while (j >= 0) {
32915691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik#ifdef XP_OPTIMIZED_NON_ELEM_COMPARISON
32922bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik		if (xmlXPathCmpNodesExt(set->nodeTab[j],
32932bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik			set->nodeTab[j + incr]) == -1)
32942bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik#else
3295e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese		if (xmlXPathCmpNodes(set->nodeTab[j],
32962bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik			set->nodeTab[j + incr]) == -1)
32972bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik#endif
32982bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik		{
32993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    tmp = set->nodeTab[j];
33003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    set->nodeTab[j] = set->nodeTab[j + incr];
33013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    set->nodeTab[j + incr] = tmp;
33023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    j -= incr;
33033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		} else
33043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    break;
33053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    }
33063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
33073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
33083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
33093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
33103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define XML_NODESET_DEFAULT	10
33113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
3312044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * xmlXPathNodeSetDupNs:
3313044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * @node:  the parent node of the namespace XPath node
3314044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * @ns:  the libxml namespace declaration node.
3315044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard *
3316044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * Namespace node in libxml don't match the XPath semantic. In a node set
3317044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * the namespace nodes are duplicated and the next pointer is set to the
3318044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * parent node in the XPath semantic.
3319044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard *
3320044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * Returns the newly created object.
3321044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard */
3322044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillardstatic xmlNodePtr
3323044fc6b7476798cbb95277b4905e5111d7c2775dDaniel VeillardxmlXPathNodeSetDupNs(xmlNodePtr node, xmlNsPtr ns) {
3324044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    xmlNsPtr cur;
3325044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard
3326044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    if ((ns == NULL) || (ns->type != XML_NAMESPACE_DECL))
3327044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard	return(NULL);
3328044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    if ((node == NULL) || (node->type == XML_NAMESPACE_DECL))
3329044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard	return((xmlNodePtr) ns);
3330044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard
3331044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    /*
3332044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard     * Allocate a new Namespace and fill the fields.
3333044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard     */
3334044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    cur = (xmlNsPtr) xmlMalloc(sizeof(xmlNs));
3335044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    if (cur == NULL) {
3336d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard        xmlXPathErrMemory(NULL, "duplicating namespace\n");
3337044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard	return(NULL);
3338044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    }
3339044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    memset(cur, 0, sizeof(xmlNs));
3340044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    cur->type = XML_NAMESPACE_DECL;
3341044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    if (ns->href != NULL)
334245490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	cur->href = xmlStrdup(ns->href);
3343044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    if (ns->prefix != NULL)
334445490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	cur->prefix = xmlStrdup(ns->prefix);
3345044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    cur->next = (xmlNsPtr) node;
3346044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    return((xmlNodePtr) cur);
3347044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard}
3348044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard
3349044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard/**
3350044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * xmlXPathNodeSetFreeNs:
3351044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * @ns:  the XPath namespace node found in a nodeset.
3352044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard *
3353081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack * Namespace nodes in libxml don't match the XPath semantic. In a node set
3354044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * the namespace nodes are duplicated and the next pointer is set to the
3355081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack * parent node in the XPath semantic. Check if such a node needs to be freed
3356044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard */
3357f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Saninvoid
3358044fc6b7476798cbb95277b4905e5111d7c2775dDaniel VeillardxmlXPathNodeSetFreeNs(xmlNsPtr ns) {
3359044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    if ((ns == NULL) || (ns->type != XML_NAMESPACE_DECL))
3360044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard	return;
3361044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard
3362044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    if ((ns->next != NULL) && (ns->next->type != XML_NAMESPACE_DECL)) {
3363044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard	if (ns->href != NULL)
3364044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard	    xmlFree((xmlChar *)ns->href);
3365044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard	if (ns->prefix != NULL)
3366044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard	    xmlFree((xmlChar *)ns->prefix);
3367044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard	xmlFree(ns);
3368044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    }
3369044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard}
3370044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard
3371044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard/**
33723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNodeSetCreate:
33733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val:  an initial xmlNodePtr, or NULL
33743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
33753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Create a new xmlNodeSetPtr of type double and of value @val
33763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
33773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the newly created object.
33783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
33793473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNodeSetPtr
33803473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNodeSetCreate(xmlNodePtr val) {
33813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlNodeSetPtr ret;
33823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
33833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret = (xmlNodeSetPtr) xmlMalloc(sizeof(xmlNodeSet));
33843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ret == NULL) {
3385d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard        xmlXPathErrMemory(NULL, "creating nodeset\n");
33863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(NULL);
33873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
33883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    memset(ret, 0 , (size_t) sizeof(xmlNodeSet));
33893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (val != NULL) {
33903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        ret->nodeTab = (xmlNodePtr *) xmlMalloc(XML_NODESET_DEFAULT *
33913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor					     sizeof(xmlNodePtr));
33923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (ret->nodeTab == NULL) {
3393d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard	    xmlXPathErrMemory(NULL, "creating nodeset\n");
3394d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard	    xmlFree(ret);
33953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    return(NULL);
33963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
33973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	memset(ret->nodeTab, 0 ,
33983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	       XML_NODESET_DEFAULT * (size_t) sizeof(xmlNodePtr));
33993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        ret->nodeMax = XML_NODESET_DEFAULT;
3400044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard	if (val->type == XML_NAMESPACE_DECL) {
3401044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard	    xmlNsPtr ns = (xmlNsPtr) val;
3402044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard
3403044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard	    ret->nodeTab[ret->nodeNr++] =
3404044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard		xmlXPathNodeSetDupNs((xmlNodePtr) ns->next, ns);
3405044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard	} else
3406044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard	    ret->nodeTab[ret->nodeNr++] = val;
34073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
34083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(ret);
34093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
34103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
34115691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik/**
34129bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik * xmlXPathNodeSetCreateSize:
34139bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik * @size:  the initial size of the set
34149bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik *
34159bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik * Create a new xmlNodeSetPtr of type double and of value @val
34169bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik *
34179bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik * Returns the newly created object.
34189bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik */
34199bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcikstatic xmlNodeSetPtr
34209bca933a6e39bae6dd8952825528270f006c97dfKasimier T. BuchcikxmlXPathNodeSetCreateSize(int size) {
34219bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    xmlNodeSetPtr ret;
34229bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik
34239bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    ret = (xmlNodeSetPtr) xmlMalloc(sizeof(xmlNodeSet));
34249bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    if (ret == NULL) {
34259bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik        xmlXPathErrMemory(NULL, "creating nodeset\n");
34269bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	return(NULL);
34279bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    }
34289bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    memset(ret, 0 , (size_t) sizeof(xmlNodeSet));
34299bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    if (size < XML_NODESET_DEFAULT)
34309bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	size = XML_NODESET_DEFAULT;
34319bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    ret->nodeTab = (xmlNodePtr *) xmlMalloc(size * sizeof(xmlNodePtr));
34329bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    if (ret->nodeTab == NULL) {
34339bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	xmlXPathErrMemory(NULL, "creating nodeset\n");
34349bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	xmlFree(ret);
34359bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	return(NULL);
34369bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    }
34379bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    memset(ret->nodeTab, 0 , size * (size_t) sizeof(xmlNodePtr));
343845490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard    ret->nodeMax = size;
34399bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    return(ret);
34409bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik}
34419bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik
34429bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik/**
3443f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathNodeSetContains:
3444f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @cur:  the node-set
3445f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @val:  the node
3446f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *
3447f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * checks whether @cur contains @val
3448f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *
3449f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns true (1) if @cur contains @val, false (0) otherwise
3450f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */
3451f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyerint
3452f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathNodeSetContains (xmlNodeSetPtr cur, xmlNodePtr val) {
3453f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    int i;
3454f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer
3455a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard    if ((cur == NULL) || (val == NULL)) return(0);
3456044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    if (val->type == XML_NAMESPACE_DECL) {
3457044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard	for (i = 0; i < cur->nodeNr; i++) {
3458044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard	    if (cur->nodeTab[i]->type == XML_NAMESPACE_DECL) {
3459044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard		xmlNsPtr ns1, ns2;
3460044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard
3461044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard		ns1 = (xmlNsPtr) val;
3462044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard		ns2 = (xmlNsPtr) cur->nodeTab[i];
3463044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard		if (ns1 == ns2)
3464044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard		    return(1);
3465044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard		if ((ns1->next != NULL) && (ns2->next == ns1->next) &&
3466044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard	            (xmlStrEqual(ns1->prefix, ns2->prefix)))
3467044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard		    return(1);
3468044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard	    }
3469044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard	}
3470044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    } else {
3471044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard	for (i = 0; i < cur->nodeNr; i++) {
3472044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard	    if (cur->nodeTab[i] == val)
3473044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard		return(1);
3474044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard	}
3475f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    }
3476f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    return(0);
3477f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer}
3478f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer
3479f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/**
3480044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * xmlXPathNodeSetAddNs:
3481044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * @cur:  the initial node set
3482044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * @node:  the hosting node
3483044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * @ns:  a the namespace node
3484044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard *
3485044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * add a new namespace node to an existing NodeSet
3486044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard */
348779376ba94845db7096c3917f4f40baeb450eb0e9Aleksey Saninvoid
3488044fc6b7476798cbb95277b4905e5111d7c2775dDaniel VeillardxmlXPathNodeSetAddNs(xmlNodeSetPtr cur, xmlNodePtr node, xmlNsPtr ns) {
3489044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    int i;
3490044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard
349145490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
3492a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard    if ((cur == NULL) || (ns == NULL) || (node == NULL) ||
3493a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard        (ns->type != XML_NAMESPACE_DECL) ||
3494044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard	(node->type != XML_ELEMENT_NODE))
3495044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard	return;
3496044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard
3497081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack    /* @@ with_ns to check whether namespace nodes should be looked at @@ */
3498044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    /*
3499081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack     * prevent duplicates
3500044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard     */
3501044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    for (i = 0;i < cur->nodeNr;i++) {
3502044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard        if ((cur->nodeTab[i] != NULL) &&
3503044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard	    (cur->nodeTab[i]->type == XML_NAMESPACE_DECL) &&
3504c62a147963b5839fc815267706eaec381f90ca16Daniel Veillard	    (((xmlNsPtr)cur->nodeTab[i])->next == (xmlNsPtr) node) &&
3505044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard	    (xmlStrEqual(ns->prefix, ((xmlNsPtr)cur->nodeTab[i])->prefix)))
3506044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard	    return;
3507044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    }
3508044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard
3509044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    /*
3510044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard     * grow the nodeTab if needed
3511044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard     */
3512044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    if (cur->nodeMax == 0) {
3513044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard        cur->nodeTab = (xmlNodePtr *) xmlMalloc(XML_NODESET_DEFAULT *
3514044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard					     sizeof(xmlNodePtr));
3515044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard	if (cur->nodeTab == NULL) {
3516d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard	    xmlXPathErrMemory(NULL, "growing nodeset\n");
3517044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard	    return;
3518044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard	}
3519044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard	memset(cur->nodeTab, 0 ,
3520044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard	       XML_NODESET_DEFAULT * (size_t) sizeof(xmlNodePtr));
3521044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard        cur->nodeMax = XML_NODESET_DEFAULT;
3522044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    } else if (cur->nodeNr == cur->nodeMax) {
3523044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard        xmlNodePtr *temp;
3524044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard
3525044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard        cur->nodeMax *= 2;
3526044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard	temp = (xmlNodePtr *) xmlRealloc(cur->nodeTab, cur->nodeMax *
3527044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard				      sizeof(xmlNodePtr));
3528044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard	if (temp == NULL) {
3529d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard	    xmlXPathErrMemory(NULL, "growing nodeset\n");
3530044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard	    return;
3531044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard	}
3532044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard	cur->nodeTab = temp;
3533044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    }
3534044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    cur->nodeTab[cur->nodeNr++] = xmlXPathNodeSetDupNs(node, ns);
3535044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard}
3536044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard
3537044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard/**
35383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNodeSetAdd:
35393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur:  the initial node set
35403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val:  a new xmlNodePtr
35413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
3542cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * add a new xmlNodePtr to an existing NodeSet
35433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
35443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
35453473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNodeSetAdd(xmlNodeSetPtr cur, xmlNodePtr val) {
35463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    int i;
35473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
3548a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard    if ((cur == NULL) || (val == NULL)) return;
35493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
3550ef0b45016373d65700ef6f7d494a200758b2e4c5Daniel Veillard#if 0
3551652d8a949447833405cc0805f4b7ff1179e59ed2Daniel Veillard    if ((val->type == XML_ELEMENT_NODE) && (val->name[0] == ' '))
3552652d8a949447833405cc0805f4b7ff1179e59ed2Daniel Veillard	return;	/* an XSLT fake node */
3553ef0b45016373d65700ef6f7d494a200758b2e4c5Daniel Veillard#endif
3554652d8a949447833405cc0805f4b7ff1179e59ed2Daniel Veillard
3555081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack    /* @@ with_ns to check whether namespace nodes should be looked at @@ */
35563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    /*
3557081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack     * prevent duplcates
35583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor     */
35593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    for (i = 0;i < cur->nodeNr;i++)
35603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        if (cur->nodeTab[i] == val) return;
35613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
35623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    /*
35633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor     * grow the nodeTab if needed
35643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor     */
35653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (cur->nodeMax == 0) {
35663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        cur->nodeTab = (xmlNodePtr *) xmlMalloc(XML_NODESET_DEFAULT *
35673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor					     sizeof(xmlNodePtr));
35683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (cur->nodeTab == NULL) {
3569d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard	    xmlXPathErrMemory(NULL, "growing nodeset\n");
35703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    return;
35713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
35723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	memset(cur->nodeTab, 0 ,
35733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	       XML_NODESET_DEFAULT * (size_t) sizeof(xmlNodePtr));
35743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        cur->nodeMax = XML_NODESET_DEFAULT;
35753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    } else if (cur->nodeNr == cur->nodeMax) {
35763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        xmlNodePtr *temp;
35773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
35783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        cur->nodeMax *= 2;
35793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	temp = (xmlNodePtr *) xmlRealloc(cur->nodeTab, cur->nodeMax *
35803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor				      sizeof(xmlNodePtr));
35813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (temp == NULL) {
3582d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard	    xmlXPathErrMemory(NULL, "growing nodeset\n");
35833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    return;
35843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
35853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	cur->nodeTab = temp;
35863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
3587044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    if (val->type == XML_NAMESPACE_DECL) {
3588044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard	xmlNsPtr ns = (xmlNsPtr) val;
3589044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard
359045490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	cur->nodeTab[cur->nodeNr++] =
3591044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard	    xmlXPathNodeSetDupNs((xmlNodePtr) ns->next, ns);
3592044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    } else
3593044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard	cur->nodeTab[cur->nodeNr++] = val;
35943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
35953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
35963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
35973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNodeSetAddUnique:
35983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur:  the initial node set
35993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val:  a new xmlNodePtr
36003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
3601cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * add a new xmlNodePtr to an existing NodeSet, optimized version
36023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * when we are sure the node is not already in the set.
36033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
36043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
36053473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNodeSetAddUnique(xmlNodeSetPtr cur, xmlNodePtr val) {
3606a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard    if ((cur == NULL) || (val == NULL)) return;
36073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
3608ef0b45016373d65700ef6f7d494a200758b2e4c5Daniel Veillard#if 0
3609652d8a949447833405cc0805f4b7ff1179e59ed2Daniel Veillard    if ((val->type == XML_ELEMENT_NODE) && (val->name[0] == ' '))
3610652d8a949447833405cc0805f4b7ff1179e59ed2Daniel Veillard	return;	/* an XSLT fake node */
3611ef0b45016373d65700ef6f7d494a200758b2e4c5Daniel Veillard#endif
3612652d8a949447833405cc0805f4b7ff1179e59ed2Daniel Veillard
3613081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack    /* @@ with_ns to check whether namespace nodes should be looked at @@ */
36143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    /*
36153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor     * grow the nodeTab if needed
36163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor     */
36173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (cur->nodeMax == 0) {
36183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        cur->nodeTab = (xmlNodePtr *) xmlMalloc(XML_NODESET_DEFAULT *
36193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor					     sizeof(xmlNodePtr));
36203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (cur->nodeTab == NULL) {
3621d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard	    xmlXPathErrMemory(NULL, "growing nodeset\n");
36223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    return;
36233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
36243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	memset(cur->nodeTab, 0 ,
36253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	       XML_NODESET_DEFAULT * (size_t) sizeof(xmlNodePtr));
36263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        cur->nodeMax = XML_NODESET_DEFAULT;
36273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    } else if (cur->nodeNr == cur->nodeMax) {
36283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        xmlNodePtr *temp;
36293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
36303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        cur->nodeMax *= 2;
36313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	temp = (xmlNodePtr *) xmlRealloc(cur->nodeTab, cur->nodeMax *
36323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor				      sizeof(xmlNodePtr));
36333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (temp == NULL) {
3634d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard	    xmlXPathErrMemory(NULL, "growing nodeset\n");
36353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    return;
36363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
36373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	cur->nodeTab = temp;
36383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
3639044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    if (val->type == XML_NAMESPACE_DECL) {
3640044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard	xmlNsPtr ns = (xmlNsPtr) val;
3641044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard
364245490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	cur->nodeTab[cur->nodeNr++] =
3643044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard	    xmlXPathNodeSetDupNs((xmlNodePtr) ns->next, ns);
3644044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    } else
3645044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard	cur->nodeTab[cur->nodeNr++] = val;
36463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
36473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
36483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
36493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNodeSetMerge:
36503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val1:  the first NodeSet or NULL
36513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val2:  the second NodeSet
36523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
36533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Merges two nodesets, all nodes from @val2 are added to @val1
36543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * if @val1 is NULL, a new set is created and copied from @val2
36553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
3656cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * Returns @val1 once extended or NULL in case of error.
36573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
36583473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNodeSetPtr
36593473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNodeSetMerge(xmlNodeSetPtr val1, xmlNodeSetPtr val2) {
3660d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard    int i, j, initNr, skip;
36615691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik    xmlNodePtr n1, n2;
36623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
36633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (val2 == NULL) return(val1);
36643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (val1 == NULL) {
3665984a9aeddf69378a05f79ee750e7996bfa791c24Kasimier T. Buchcik	val1 = xmlXPathNodeSetCreate(NULL);
3666f88d849a4e994c94c0d0814a4befb43c990ceebdDaniel Veillard    if (val1 == NULL)
3667f88d849a4e994c94c0d0814a4befb43c990ceebdDaniel Veillard        return (NULL);
3668984a9aeddf69378a05f79ee750e7996bfa791c24Kasimier T. Buchcik#if 0
3669a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	/*
3670a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	* TODO: The optimization won't work in every case, since
3671a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	*  those nasty namespace nodes need to be added with
3672a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	*  xmlXPathNodeSetDupNs() to the set; thus a pure
3673a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	*  memcpy is not possible.
3674df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik	*  If there was a flag on the nodesetval, indicating that
3675df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik	*  some temporary nodes are in, that would be helpfull.
3676a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	*/
367745490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	/*
3678a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	* Optimization: Create an equally sized node-set
3679a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	* and memcpy the content.
3680a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	*/
3681a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	val1 = xmlXPathNodeSetCreateSize(val2->nodeNr);
3682a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	if (val1 == NULL)
3683a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    return(NULL);
3684a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	if (val2->nodeNr != 0) {
36855691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    if (val2->nodeNr == 1)
36865691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		*(val1->nodeTab) = *(val2->nodeTab);
36875691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    else {
36885691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		memcpy(val1->nodeTab, val2->nodeTab,
36895691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		    val2->nodeNr * sizeof(xmlNodePtr));
36905691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    }
36915691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    val1->nodeNr = val2->nodeNr;
3692a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	}
36935691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	return(val1);
3694a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#endif
36953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
36963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
3697081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack    /* @@ with_ns to check whether namespace nodes should be looked at @@ */
36983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    initNr = val1->nodeNr;
36993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
37003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    for (i = 0;i < val2->nodeNr;i++) {
370145490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	n2 = val2->nodeTab[i];
37023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	/*
3703081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack	 * check against duplicates
37043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	 */
3705d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	skip = 0;
3706d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	for (j = 0; j < initNr; j++) {
37075691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    n1 = val1->nodeTab[j];
37085691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    if (n1 == n2) {
3709d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard		skip = 1;
3710d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard		break;
37115691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    } else if ((n1->type == XML_NAMESPACE_DECL) &&
371245490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard		       (n2->type == XML_NAMESPACE_DECL)) {
37135691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		if ((((xmlNsPtr) n1)->next == ((xmlNsPtr) n2)->next) &&
37145691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		    (xmlStrEqual(((xmlNsPtr) n1)->prefix,
37155691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik			((xmlNsPtr) n2)->prefix)))
37165691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		{
3717044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard		    skip = 1;
3718044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard		    break;
3719044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard		}
3720d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	    }
3721d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	}
3722d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	if (skip)
3723d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	    continue;
37243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
37253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	/*
37263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	 * grow the nodeTab if needed
37273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	 */
37283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (val1->nodeMax == 0) {
37293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    val1->nodeTab = (xmlNodePtr *) xmlMalloc(XML_NODESET_DEFAULT *
37303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor						    sizeof(xmlNodePtr));
37313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    if (val1->nodeTab == NULL) {
3732d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard	        xmlXPathErrMemory(NULL, "merging nodeset\n");
37333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		return(NULL);
37343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    }
37353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    memset(val1->nodeTab, 0 ,
37363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		   XML_NODESET_DEFAULT * (size_t) sizeof(xmlNodePtr));
37373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    val1->nodeMax = XML_NODESET_DEFAULT;
37383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	} else if (val1->nodeNr == val1->nodeMax) {
37393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    xmlNodePtr *temp;
37403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
37413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    val1->nodeMax *= 2;
37423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    temp = (xmlNodePtr *) xmlRealloc(val1->nodeTab, val1->nodeMax *
37433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor					     sizeof(xmlNodePtr));
37443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    if (temp == NULL) {
3745d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard	        xmlXPathErrMemory(NULL, "merging nodeset\n");
37463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		return(NULL);
37473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    }
37483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    val1->nodeTab = temp;
37493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
37505691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	if (n2->type == XML_NAMESPACE_DECL) {
37515691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    xmlNsPtr ns = (xmlNsPtr) n2;
3752044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard
3753044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard	    val1->nodeTab[val1->nodeNr++] =
3754044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard		xmlXPathNodeSetDupNs((xmlNodePtr) ns->next, ns);
3755044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard	} else
37565691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    val1->nodeTab[val1->nodeNr++] = n2;
37573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
37583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
37593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(val1);
37603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
37613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
37629bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik#if 0 /* xmlXPathNodeSetMergeUnique() is currently not used anymore */
37633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
376475be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard * xmlXPathNodeSetMergeUnique:
376575be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard * @val1:  the first NodeSet or NULL
376675be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard * @val2:  the second NodeSet
376775be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard *
376875be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard * Merges two nodesets, all nodes from @val2 are added to @val1
376975be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard * if @val1 is NULL, a new set is created and copied from @val2
377075be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard *
377175be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard * Returns @val1 once extended or NULL in case of error.
377275be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard */
377375be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillardstatic xmlNodeSetPtr
377475be0130855fe02d238bbbf19a04d3c5eb45f494Daniel VeillardxmlXPathNodeSetMergeUnique(xmlNodeSetPtr val1, xmlNodeSetPtr val2) {
377578637da0ea1c833dfdfad87a9aa5bea14510d08aWilliam M. Brack    int i;
377675be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard
377775be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard    if (val2 == NULL) return(val1);
377875be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard    if (val1 == NULL) {
377975be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard	val1 = xmlXPathNodeSetCreate(NULL);
378075be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard    }
3781f88d849a4e994c94c0d0814a4befb43c990ceebdDaniel Veillard    if (val1 == NULL)
3782f88d849a4e994c94c0d0814a4befb43c990ceebdDaniel Veillard        return (NULL);
378375be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard
3784081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack    /* @@ with_ns to check whether namespace nodes should be looked at @@ */
378575be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard
378675be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard    for (i = 0;i < val2->nodeNr;i++) {
378775be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard	/*
378875be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard	 * grow the nodeTab if needed
378975be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard	 */
379075be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard	if (val1->nodeMax == 0) {
379175be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard	    val1->nodeTab = (xmlNodePtr *) xmlMalloc(XML_NODESET_DEFAULT *
379275be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard						    sizeof(xmlNodePtr));
379375be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard	    if (val1->nodeTab == NULL) {
3794d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard	        xmlXPathErrMemory(NULL, "merging nodeset\n");
379575be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard		return(NULL);
379675be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard	    }
379775be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard	    memset(val1->nodeTab, 0 ,
379875be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard		   XML_NODESET_DEFAULT * (size_t) sizeof(xmlNodePtr));
379975be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard	    val1->nodeMax = XML_NODESET_DEFAULT;
380075be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard	} else if (val1->nodeNr == val1->nodeMax) {
380175be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard	    xmlNodePtr *temp;
380275be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard
380375be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard	    val1->nodeMax *= 2;
380475be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard	    temp = (xmlNodePtr *) xmlRealloc(val1->nodeTab, val1->nodeMax *
380575be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard					     sizeof(xmlNodePtr));
380675be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard	    if (temp == NULL) {
3807d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard	        xmlXPathErrMemory(NULL, "merging nodeset\n");
380875be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard		return(NULL);
380975be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard	    }
381075be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard	    val1->nodeTab = temp;
381175be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard	}
381275be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard	if (val2->nodeTab[i]->type == XML_NAMESPACE_DECL) {
381375be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard	    xmlNsPtr ns = (xmlNsPtr) val2->nodeTab[i];
381475be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard
381575be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard	    val1->nodeTab[val1->nodeNr++] =
381675be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard		xmlXPathNodeSetDupNs((xmlNodePtr) ns->next, ns);
381775be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard	} else
381875be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard	    val1->nodeTab[val1->nodeNr++] = val2->nodeTab[i];
381975be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard    }
382075be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard
382175be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard    return(val1);
382275be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard}
38239bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik#endif /* xmlXPathNodeSetMergeUnique() is currently not used anymore */
38249bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik
38259bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik/**
38269bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik * xmlXPathNodeSetMergeAndClear:
38279bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik * @set1:  the first NodeSet or NULL
38289bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik * @set2:  the second NodeSet
38299bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik * @hasSet2NsNodes: 1 if set2 contains namespaces nodes
38309bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik *
38319bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik * Merges two nodesets, all nodes from @set2 are added to @set1
38329bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik * if @set1 is NULL, a new set is created and copied from @set2.
38339bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik * Checks for duplicate nodes. Clears set2.
38349bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik *
38359bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik * Returns @set1 once extended or NULL in case of error.
38369bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik */
38379bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcikstatic xmlNodeSetPtr
38389bca933a6e39bae6dd8952825528270f006c97dfKasimier T. BuchcikxmlXPathNodeSetMergeAndClear(xmlNodeSetPtr set1, xmlNodeSetPtr set2,
38399bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik			     int hasNullEntries)
38409bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik{
38419bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    if ((set1 == NULL) && (hasNullEntries == 0)) {
38429bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	/*
38439bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	* Note that doing a memcpy of the list, namespace nodes are
38449bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	* just assigned to set1, since set2 is cleared anyway.
38459bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	*/
38469bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	set1 = xmlXPathNodeSetCreateSize(set2->nodeNr);
38479bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	if (set1 == NULL)
38489bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    return(NULL);
38499bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	if (set2->nodeNr != 0) {
38509bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    memcpy(set1->nodeTab, set2->nodeTab,
38519bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		set2->nodeNr * sizeof(xmlNodePtr));
38529bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    set1->nodeNr = set2->nodeNr;
38539bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	}
38549bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    } else {
38559bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	int i, j, initNbSet1;
38569bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	xmlNodePtr n1, n2;
38579bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik
38589bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	if (set1 == NULL)
3859f88d849a4e994c94c0d0814a4befb43c990ceebdDaniel Veillard            set1 = xmlXPathNodeSetCreate(NULL);
3860f88d849a4e994c94c0d0814a4befb43c990ceebdDaniel Veillard        if (set1 == NULL)
3861f88d849a4e994c94c0d0814a4befb43c990ceebdDaniel Veillard            return (NULL);
38629bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik
386345490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	initNbSet1 = set1->nodeNr;
38649bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	for (i = 0;i < set2->nodeNr;i++) {
38659bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    n2 = set2->nodeTab[i];
38669bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    /*
38679bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    * Skip NULLed entries.
38689bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    */
38699bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    if (n2 == NULL)
38709bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		continue;
38719bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    /*
38729bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    * Skip duplicates.
38739bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    */
38749bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    for (j = 0; j < initNbSet1; j++) {
38759bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		n1 = set1->nodeTab[j];
387645490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard		if (n1 == n2) {
38779bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		    goto skip_node;
38789bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		} else if ((n1->type == XML_NAMESPACE_DECL) &&
38799bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		    (n2->type == XML_NAMESPACE_DECL))
388045490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard		{
38819bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		    if ((((xmlNsPtr) n1)->next == ((xmlNsPtr) n2)->next) &&
38829bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik			(xmlStrEqual(((xmlNsPtr) n1)->prefix,
38839bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik			((xmlNsPtr) n2)->prefix)))
38849bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		    {
38859bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik			/*
38869bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik			* Free the namespace node.
38879bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik			*/
38889bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik			set2->nodeTab[i] = NULL;
38899bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik			xmlXPathNodeSetFreeNs((xmlNsPtr) n2);
38909bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik			goto skip_node;
38919bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		    }
38929bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		}
38939bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    }
38949bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    /*
38959bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    * grow the nodeTab if needed
38969bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    */
38979bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    if (set1->nodeMax == 0) {
38989bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		set1->nodeTab = (xmlNodePtr *) xmlMalloc(
38999bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		    XML_NODESET_DEFAULT * sizeof(xmlNodePtr));
39009bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		if (set1->nodeTab == NULL) {
39019bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		    xmlXPathErrMemory(NULL, "merging nodeset\n");
39029bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		    return(NULL);
39039bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		}
39049bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		memset(set1->nodeTab, 0,
39059bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		    XML_NODESET_DEFAULT * (size_t) sizeof(xmlNodePtr));
39069bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		set1->nodeMax = XML_NODESET_DEFAULT;
39079bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    } else if (set1->nodeNr >= set1->nodeMax) {
39089bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		xmlNodePtr *temp;
390945490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
39109bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		set1->nodeMax *= 2;
39119bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		temp = (xmlNodePtr *) xmlRealloc(
39129bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		    set1->nodeTab, set1->nodeMax * sizeof(xmlNodePtr));
39139bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		if (temp == NULL) {
39149bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		    xmlXPathErrMemory(NULL, "merging nodeset\n");
39159bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		    return(NULL);
39169bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		}
39179bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		set1->nodeTab = temp;
39189bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    }
39199bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    if (n2->type == XML_NAMESPACE_DECL) {
39209bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		xmlNsPtr ns = (xmlNsPtr) n2;
392145490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
39229bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		set1->nodeTab[set1->nodeNr++] =
39239bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		    xmlXPathNodeSetDupNs((xmlNodePtr) ns->next, ns);
39249bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    } else
39259bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		set1->nodeTab[set1->nodeNr++] = n2;
39269bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcikskip_node:
39279bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    {}
39289bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	}
39299bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    }
39309bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    set2->nodeNr = 0;
39319bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    return(set1);
39329bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik}
39339bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik
39349bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik/**
39359bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik * xmlXPathNodeSetMergeAndClearNoDupls:
39369bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik * @set1:  the first NodeSet or NULL
39379bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik * @set2:  the second NodeSet
39389bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik * @hasSet2NsNodes: 1 if set2 contains namespaces nodes
39399bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik *
39409bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik * Merges two nodesets, all nodes from @set2 are added to @set1
39419bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik * if @set1 is NULL, a new set is created and copied from @set2.
39429bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik * Doesn't chack for duplicate nodes. Clears set2.
39439bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik *
39449bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik * Returns @set1 once extended or NULL in case of error.
39459bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik */
39469bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcikstatic xmlNodeSetPtr
39479bca933a6e39bae6dd8952825528270f006c97dfKasimier T. BuchcikxmlXPathNodeSetMergeAndClearNoDupls(xmlNodeSetPtr set1, xmlNodeSetPtr set2,
39489bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik				    int hasNullEntries)
394945490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard{
39509bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    if (set2 == NULL)
39519bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	return(set1);
39529bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    if ((set1 == NULL) && (hasNullEntries == 0)) {
39539bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	/*
39549bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	* Note that doing a memcpy of the list, namespace nodes are
39559bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	* just assigned to set1, since set2 is cleared anyway.
39569bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	*/
39579bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	set1 = xmlXPathNodeSetCreateSize(set2->nodeNr);
39589bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	if (set1 == NULL)
39599bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    return(NULL);
39609bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	if (set2->nodeNr != 0) {
39619bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    memcpy(set1->nodeTab, set2->nodeTab,
39629bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		set2->nodeNr * sizeof(xmlNodePtr));
39639bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    set1->nodeNr = set2->nodeNr;
39649bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	}
39659bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    } else {
39669bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	int i;
39679bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	xmlNodePtr n2;
39689bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik
39699bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	if (set1 == NULL)
39709bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    set1 = xmlXPathNodeSetCreate(NULL);
3971f88d849a4e994c94c0d0814a4befb43c990ceebdDaniel Veillard        if (set1 == NULL)
3972f88d849a4e994c94c0d0814a4befb43c990ceebdDaniel Veillard            return (NULL);
397345490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
39749bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	for (i = 0;i < set2->nodeNr;i++) {
39759bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    n2 = set2->nodeTab[i];
39769bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    /*
39779bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    * Skip NULLed entries.
39789bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    */
39799bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    if (n2 == NULL)
398045490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard		continue;
39819bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    if (set1->nodeMax == 0) {
39829bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		set1->nodeTab = (xmlNodePtr *) xmlMalloc(
39839bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		    XML_NODESET_DEFAULT * sizeof(xmlNodePtr));
39849bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		if (set1->nodeTab == NULL) {
39859bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		    xmlXPathErrMemory(NULL, "merging nodeset\n");
39869bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		    return(NULL);
39879bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		}
39889bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		memset(set1->nodeTab, 0,
39899bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		    XML_NODESET_DEFAULT * (size_t) sizeof(xmlNodePtr));
39909bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		set1->nodeMax = XML_NODESET_DEFAULT;
39919bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    } else if (set1->nodeNr >= set1->nodeMax) {
39929bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		xmlNodePtr *temp;
399345490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
39949bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		set1->nodeMax *= 2;
39959bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		temp = (xmlNodePtr *) xmlRealloc(
39969bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		    set1->nodeTab, set1->nodeMax * sizeof(xmlNodePtr));
39979bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		if (temp == NULL) {
39989bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		    xmlXPathErrMemory(NULL, "merging nodeset\n");
39999bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		    return(NULL);
40009bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		}
40019bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		set1->nodeTab = temp;
40029bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    }
40039bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    set1->nodeTab[set1->nodeNr++] = n2;
40049bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	}
40059bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    }
40069bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    set2->nodeNr = 0;
40079bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    return(set1);
40089bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik}
400975be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard
401075be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard/**
40113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNodeSetDel:
40123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur:  the initial node set
40133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val:  an xmlNodePtr
40143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
40153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Removes an xmlNodePtr from an existing NodeSet
40163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
40173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
40183473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNodeSetDel(xmlNodeSetPtr cur, xmlNodePtr val) {
40193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    int i;
40203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
40213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (cur == NULL) return;
40223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (val == NULL) return;
40233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
40243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    /*
4025081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack     * find node in nodeTab
40263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor     */
40273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    for (i = 0;i < cur->nodeNr;i++)
40283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        if (cur->nodeTab[i] == val) break;
40293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
4030081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack    if (i >= cur->nodeNr) {	/* not found */
40313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG
403245490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard        xmlGenericError(xmlGenericErrorContext,
40333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	        "xmlXPathNodeSetDel: Node %s wasn't found in NodeList\n",
40343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		val->name);
40353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif
40363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        return;
40373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
4038044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    if ((cur->nodeTab[i] != NULL) &&
4039044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard	(cur->nodeTab[i]->type == XML_NAMESPACE_DECL))
4040044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard	xmlXPathNodeSetFreeNs((xmlNsPtr) cur->nodeTab[i]);
40413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    cur->nodeNr--;
40423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    for (;i < cur->nodeNr;i++)
40433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        cur->nodeTab[i] = cur->nodeTab[i + 1];
40443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    cur->nodeTab[cur->nodeNr] = NULL;
40453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
40463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
40473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
40483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNodeSetRemove:
40493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur:  the initial node set
40503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val:  the index to remove
40513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
40523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Removes an entry from an existing NodeSet list.
40533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
40543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
40553473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNodeSetRemove(xmlNodeSetPtr cur, int val) {
40563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (cur == NULL) return;
40573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (val >= cur->nodeNr) return;
4058044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    if ((cur->nodeTab[val] != NULL) &&
4059044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard	(cur->nodeTab[val]->type == XML_NAMESPACE_DECL))
4060044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard	xmlXPathNodeSetFreeNs((xmlNsPtr) cur->nodeTab[val]);
40613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    cur->nodeNr--;
40623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    for (;val < cur->nodeNr;val++)
40633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        cur->nodeTab[val] = cur->nodeTab[val + 1];
40643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    cur->nodeTab[cur->nodeNr] = NULL;
40653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
40663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
40673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
40683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathFreeNodeSet:
40693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @obj:  the xmlNodeSetPtr to free
40703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
40713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Free the NodeSet compound (not the actual nodes !).
40723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
40733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
40743473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathFreeNodeSet(xmlNodeSetPtr obj) {
40753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (obj == NULL) return;
40763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (obj->nodeTab != NULL) {
4077044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard	int i;
4078044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard
4079081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack	/* @@ with_ns to check whether namespace nodes should be looked at @@ */
4080044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard	for (i = 0;i < obj->nodeNr;i++)
4081044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard	    if ((obj->nodeTab[i] != NULL) &&
4082044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard		(obj->nodeTab[i]->type == XML_NAMESPACE_DECL))
4083044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard		xmlXPathNodeSetFreeNs((xmlNsPtr) obj->nodeTab[i]);
40843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	xmlFree(obj->nodeTab);
40853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
40863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlFree(obj);
40873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
40883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
40893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
4090a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * xmlXPathNodeSetClear:
40919bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik * @set:  the node set to clear
409245490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *
4093a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * Clears the list from all temporary XPath objects (e.g. namespace nodes
4094a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * are feed), but does *not* free the list itself. Sets the length of the
4095a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * list to 0.
4096a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik */
4097a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikstatic void
40989bca933a6e39bae6dd8952825528270f006c97dfKasimier T. BuchcikxmlXPathNodeSetClear(xmlNodeSetPtr set, int hasNsNodes)
40999bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik{
4100a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    if ((set == NULL) || (set->nodeNr <= 0))
4101a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	return;
41029bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    else if (hasNsNodes) {
41039bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	int i;
41049bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	xmlNodePtr node;
410545490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
41069bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	for (i = 0; i < set->nodeNr; i++) {
41079bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    node = set->nodeTab[i];
41089bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    if ((node != NULL) &&
41099bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		(node->type == XML_NAMESPACE_DECL))
41109bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		xmlXPathNodeSetFreeNs((xmlNsPtr) node);
411145490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	}
4112a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    }
4113a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    set->nodeNr = 0;
4114a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik}
4115a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
4116a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik/**
41179bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik * xmlXPathNodeSetClearFromPos:
41189bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik * @set: the node set to be cleared
41199bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik * @pos: the start position to clear from
412045490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *
41219bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik * Clears the list from temporary XPath objects (e.g. namespace nodes
41229bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik * are feed) starting with the entry at @pos, but does *not* free the list
41239bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik * itself. Sets the length of the list to @pos.
41249bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik */
41259bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcikstatic void
41269bca933a6e39bae6dd8952825528270f006c97dfKasimier T. BuchcikxmlXPathNodeSetClearFromPos(xmlNodeSetPtr set, int pos, int hasNsNodes)
41279bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik{
41289bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    if ((set == NULL) || (set->nodeNr <= 0) || (pos >= set->nodeNr))
41299bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	return;
41309bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    else if ((hasNsNodes)) {
41319bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	int i;
41329bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	xmlNodePtr node;
413345490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
41349bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	for (i = pos; i < set->nodeNr; i++) {
41359bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    node = set->nodeTab[i];
41369bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    if ((node != NULL) &&
41379bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		(node->type == XML_NAMESPACE_DECL))
41389bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		xmlXPathNodeSetFreeNs((xmlNsPtr) node);
413945490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	}
41409bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    }
41419bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    set->nodeNr = pos;
41429bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik}
41439bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik
41449bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik/**
41453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathFreeValueTree:
41463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @obj:  the xmlNodeSetPtr to free
41473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
41483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Free the NodeSet compound and the actual tree, this is different
41493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * from xmlXPathFreeNodeSet()
41503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
415156a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic void
41523473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathFreeValueTree(xmlNodeSetPtr obj) {
41533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    int i;
41543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
41553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (obj == NULL) return;
41563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
41573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (obj->nodeTab != NULL) {
4158044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard	for (i = 0;i < obj->nodeNr;i++) {
4159044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard	    if (obj->nodeTab[i] != NULL) {
4160044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard		if (obj->nodeTab[i]->type == XML_NAMESPACE_DECL) {
4161044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard		    xmlXPathNodeSetFreeNs((xmlNsPtr) obj->nodeTab[i]);
4162044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard		} else {
4163044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard		    xmlFreeNodeList(obj->nodeTab[i]);
4164044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard		}
4165044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard	    }
4166044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard	}
41673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	xmlFree(obj->nodeTab);
41683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
41693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlFree(obj);
41703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
41713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
41723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#if defined(DEBUG) || defined(DEBUG_STEP)
41733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
41743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlGenericErrorContextNodeSet:
41753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @output:  a FILE * for the output
4176081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack * @obj:  the xmlNodeSetPtr to display
41773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
41783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Quick display of a NodeSet
41793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
41803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
41813473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlGenericErrorContextNodeSet(FILE *output, xmlNodeSetPtr obj) {
41823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    int i;
41833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
41843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (output == NULL) output = xmlGenericErrorContext;
41853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (obj == NULL)  {
41863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        fprintf(output, "NodeSet == NULL !\n");
41873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return;
41883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
41893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (obj->nodeNr == 0) {
41903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        fprintf(output, "NodeSet is empty\n");
41913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return;
41923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
41933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (obj->nodeTab == NULL) {
41943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	fprintf(output, " nodeTab == NULL !\n");
41953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return;
41963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
41973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    for (i = 0; i < obj->nodeNr; i++) {
41983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        if (obj->nodeTab[i] == NULL) {
41993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    fprintf(output, " NULL !\n");
42003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    return;
42013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        }
42023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if ((obj->nodeTab[i]->type == XML_DOCUMENT_NODE) ||
42033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    (obj->nodeTab[i]->type == XML_HTML_DOCUMENT_NODE))
42043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    fprintf(output, " /");
42053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	else if (obj->nodeTab[i]->name == NULL)
42063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    fprintf(output, " noname!");
42073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	else fprintf(output, " %s", obj->nodeTab[i]->name);
42083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
42093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    fprintf(output, "\n");
42103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
42113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif
42123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
42133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
42143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNewNodeSet:
42153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val:  the NodePtr value
42163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
42173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Create a new xmlXPathObjectPtr of type NodeSet and initialize
42183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * it with the single Node @val
42193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
42203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the newly created object.
42213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
42223473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathObjectPtr
42233473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNewNodeSet(xmlNodePtr val) {
42243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathObjectPtr ret;
42253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
42263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
42273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ret == NULL) {
4228d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard        xmlXPathErrMemory(NULL, "creating nodeset\n");
42293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(NULL);
42303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
42313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
42323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret->type = XPATH_NODESET;
423377851710aba3a0effdc6af67ea4caf212307420cDaniel Veillard    ret->boolval = 0;
42343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret->nodesetval = xmlXPathNodeSetCreate(val);
4235081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack    /* @@ with_ns to check whether namespace nodes should be looked at @@ */
4236a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#ifdef XP_DEBUG_OBJ_USAGE
4237a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathDebugObjUsageRequested(NULL, XPATH_NODESET);
4238a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#endif
42393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(ret);
42403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
42413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
42423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
42433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNewValueTree:
42443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val:  the NodePtr value
42453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
42463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Create a new xmlXPathObjectPtr of type Value Tree (XSLT) and initialize
42473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * it with the tree root @val
42483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
42493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the newly created object.
42503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
42513473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathObjectPtr
42523473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNewValueTree(xmlNodePtr val) {
42533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathObjectPtr ret;
42543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
42553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
42563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ret == NULL) {
4257d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard        xmlXPathErrMemory(NULL, "creating result value tree\n");
42583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(NULL);
42593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
42603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
42613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret->type = XPATH_XSLT_TREE;
42620ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard    ret->boolval = 1;
42630ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard    ret->user = (void *) val;
42643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret->nodesetval = xmlXPathNodeSetCreate(val);
4265a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#ifdef XP_DEBUG_OBJ_USAGE
4266a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathDebugObjUsageRequested(NULL, XPATH_XSLT_TREE);
4267a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#endif
42683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(ret);
42693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
42703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
42713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
42723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNewNodeSetList:
42733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val:  an existing NodeSet
42743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
42753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Create a new xmlXPathObjectPtr of type NodeSet and initialize
42763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * it with the Nodeset @val
42773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
42783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the newly created object.
42793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
42803473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathObjectPtr
4281044fc6b7476798cbb95277b4905e5111d7c2775dDaniel VeillardxmlXPathNewNodeSetList(xmlNodeSetPtr val)
4282044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard{
42833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathObjectPtr ret;
42843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    int i;
42853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
42863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (val == NULL)
4287044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard        ret = NULL;
42883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    else if (val->nodeTab == NULL)
4289044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard        ret = xmlXPathNewNodeSet(NULL);
4290044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    else {
4291044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard        ret = xmlXPathNewNodeSet(val->nodeTab[0]);
4292f88d849a4e994c94c0d0814a4befb43c990ceebdDaniel Veillard        if (ret)
4293f88d849a4e994c94c0d0814a4befb43c990ceebdDaniel Veillard            for (i = 1; i < val->nodeNr; ++i)
4294f88d849a4e994c94c0d0814a4befb43c990ceebdDaniel Veillard                xmlXPathNodeSetAddUnique(ret->nodesetval, val->nodeTab[i]);
4295044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    }
42963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
4297044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    return (ret);
42983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
42993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
43003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
43013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathWrapNodeSet:
43023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val:  the NodePtr value
43033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
43043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Wrap the Nodeset @val in a new xmlXPathObjectPtr
43053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
43063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the newly created object.
43073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
43083473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathObjectPtr
43093473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathWrapNodeSet(xmlNodeSetPtr val) {
43103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathObjectPtr ret;
43113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
43123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
43133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ret == NULL) {
4314d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard        xmlXPathErrMemory(NULL, "creating node set object\n");
43153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(NULL);
43163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
43173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
43183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret->type = XPATH_NODESET;
43193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret->nodesetval = val;
4320a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#ifdef XP_DEBUG_OBJ_USAGE
4321a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathDebugObjUsageRequested(NULL, XPATH_NODESET);
4322a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#endif
43233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(ret);
43243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
43253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
43263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
43273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathFreeNodeSetList:
43283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @obj:  an existing NodeSetList object
43293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
43303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Free up the xmlXPathObjectPtr @obj but don't deallocate the objects in
43313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the list contrary to xmlXPathFreeObject().
43323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
43333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
43343473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathFreeNodeSetList(xmlXPathObjectPtr obj) {
43353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (obj == NULL) return;
4336a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#ifdef XP_DEBUG_OBJ_USAGE
4337a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathDebugObjUsageReleased(NULL, obj->type);
4338a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#endif
43393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlFree(obj);
43403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
43413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
4342f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/**
4343f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathDifference:
4344f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes1:  a node-set
4345f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes2:  a node-set
4346f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *
4347f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Implements the EXSLT - Sets difference() function:
4348f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *    node-set set:difference (node-set, node-set)
4349f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *
4350f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns the difference between the two node sets, or nodes1 if
4351f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *         nodes2 is empty
4352f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */
4353f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlNodeSetPtr
4354f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathDifference (xmlNodeSetPtr nodes1, xmlNodeSetPtr nodes2) {
4355f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    xmlNodeSetPtr ret;
4356f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    int i, l1;
4357f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    xmlNodePtr cur;
4358f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer
4359f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    if (xmlXPathNodeSetIsEmpty(nodes2))
4360f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer	return(nodes1);
4361f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer
4362f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    ret = xmlXPathNodeSetCreate(NULL);
4363f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    if (xmlXPathNodeSetIsEmpty(nodes1))
4364f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer	return(ret);
4365f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer
4366f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    l1 = xmlXPathNodeSetGetLength(nodes1);
4367f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer
4368f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    for (i = 0; i < l1; i++) {
4369f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer	cur = xmlXPathNodeSetItem(nodes1, i);
4370f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer	if (!xmlXPathNodeSetContains(nodes2, cur))
4371f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer	    xmlXPathNodeSetAddUnique(ret, cur);
4372f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    }
4373f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    return(ret);
4374f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer}
4375f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer
4376f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/**
4377f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathIntersection:
4378f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes1:  a node-set
4379f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes2:  a node-set
4380f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *
4381f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Implements the EXSLT - Sets intersection() function:
4382f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *    node-set set:intersection (node-set, node-set)
4383f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *
4384f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns a node set comprising the nodes that are within both the
4385f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *         node sets passed as arguments
4386f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */
4387f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlNodeSetPtr
4388f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathIntersection (xmlNodeSetPtr nodes1, xmlNodeSetPtr nodes2) {
4389f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    xmlNodeSetPtr ret = xmlXPathNodeSetCreate(NULL);
4390f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    int i, l1;
4391f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    xmlNodePtr cur;
4392f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer
4393f88d849a4e994c94c0d0814a4befb43c990ceebdDaniel Veillard    if (ret == NULL)
4394f88d849a4e994c94c0d0814a4befb43c990ceebdDaniel Veillard        return(ret);
4395f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    if (xmlXPathNodeSetIsEmpty(nodes1))
4396f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer	return(ret);
4397f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    if (xmlXPathNodeSetIsEmpty(nodes2))
4398f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer	return(ret);
4399f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer
4400f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    l1 = xmlXPathNodeSetGetLength(nodes1);
4401f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer
4402f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    for (i = 0; i < l1; i++) {
4403f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer	cur = xmlXPathNodeSetItem(nodes1, i);
4404f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer	if (xmlXPathNodeSetContains(nodes2, cur))
4405f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer	    xmlXPathNodeSetAddUnique(ret, cur);
4406f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    }
4407f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    return(ret);
4408f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer}
4409f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer
4410f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/**
4411f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathDistinctSorted:
4412f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes:  a node-set, sorted by document order
4413f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *
4414f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Implements the EXSLT - Sets distinct() function:
4415f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *    node-set set:distinct (node-set)
441645490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *
4417f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns a subset of the nodes contained in @nodes, or @nodes if
4418f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *         it is empty
4419f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */
4420f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlNodeSetPtr
4421f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathDistinctSorted (xmlNodeSetPtr nodes) {
4422f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    xmlNodeSetPtr ret;
4423f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    xmlHashTablePtr hash;
4424f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    int i, l;
4425f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    xmlChar * strval;
4426f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    xmlNodePtr cur;
4427f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer
4428f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    if (xmlXPathNodeSetIsEmpty(nodes))
4429f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer	return(nodes);
4430f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer
4431f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    ret = xmlXPathNodeSetCreate(NULL);
4432f88d849a4e994c94c0d0814a4befb43c990ceebdDaniel Veillard    if (ret == NULL)
4433f88d849a4e994c94c0d0814a4befb43c990ceebdDaniel Veillard        return(ret);
4434f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    l = xmlXPathNodeSetGetLength(nodes);
4435f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    hash = xmlHashCreate (l);
4436f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    for (i = 0; i < l; i++) {
4437f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer	cur = xmlXPathNodeSetItem(nodes, i);
4438f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer	strval = xmlXPathCastNodeToString(cur);
4439f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer	if (xmlHashLookup(hash, strval) == NULL) {
4440f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer	    xmlHashAddEntry(hash, strval, strval);
4441f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer	    xmlXPathNodeSetAddUnique(ret, cur);
4442f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer	} else {
4443f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer	    xmlFree(strval);
4444f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer	}
4445f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    }
4446f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    xmlHashFree(hash, (xmlHashDeallocator) xmlFree);
4447f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    return(ret);
4448f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer}
4449f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer
4450f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/**
4451f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathDistinct:
4452f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes:  a node-set
4453f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *
4454f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Implements the EXSLT - Sets distinct() function:
4455f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *    node-set set:distinct (node-set)
4456f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes is sorted by document order, then #exslSetsDistinctSorted
4457f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * is called with the sorted node-set
4458f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *
4459f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns a subset of the nodes contained in @nodes, or @nodes if
4460f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *         it is empty
4461f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */
4462f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlNodeSetPtr
4463f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathDistinct (xmlNodeSetPtr nodes) {
4464f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    if (xmlXPathNodeSetIsEmpty(nodes))
4465f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer	return(nodes);
4466f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer
4467f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    xmlXPathNodeSetSort(nodes);
4468f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    return(xmlXPathDistinctSorted(nodes));
4469f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer}
4470f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer
4471f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/**
4472f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathHasSameNodes:
4473f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes1:  a node-set
4474f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes2:  a node-set
4475f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *
4476f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Implements the EXSLT - Sets has-same-nodes function:
4477f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *    boolean set:has-same-node(node-set, node-set)
4478f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *
4479f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns true (1) if @nodes1 shares any node with @nodes2, false (0)
4480f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *         otherwise
4481f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */
4482f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyerint
4483f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathHasSameNodes (xmlNodeSetPtr nodes1, xmlNodeSetPtr nodes2) {
4484f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    int i, l;
4485f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    xmlNodePtr cur;
4486f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer
4487f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    if (xmlXPathNodeSetIsEmpty(nodes1) ||
4488f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer	xmlXPathNodeSetIsEmpty(nodes2))
4489f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer	return(0);
4490f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer
4491f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    l = xmlXPathNodeSetGetLength(nodes1);
4492f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    for (i = 0; i < l; i++) {
4493f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer	cur = xmlXPathNodeSetItem(nodes1, i);
4494f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer	if (xmlXPathNodeSetContains(nodes2, cur))
4495f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer	    return(1);
4496f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    }
4497f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    return(0);
4498f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer}
4499f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer
4500f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/**
4501f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathNodeLeadingSorted:
4502f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes: a node-set, sorted by document order
4503f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @node: a node
4504f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *
4505f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Implements the EXSLT - Sets leading() function:
4506f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *    node-set set:leading (node-set, node-set)
4507f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *
4508f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns the nodes in @nodes that precede @node in document order,
4509f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *         @nodes if @node is NULL or an empty node-set if @nodes
4510f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *         doesn't contain @node
4511f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */
4512f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlNodeSetPtr
4513f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathNodeLeadingSorted (xmlNodeSetPtr nodes, xmlNodePtr node) {
4514f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    int i, l;
4515f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    xmlNodePtr cur;
4516f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    xmlNodeSetPtr ret;
4517f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer
4518f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    if (node == NULL)
4519f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer	return(nodes);
4520f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer
4521f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    ret = xmlXPathNodeSetCreate(NULL);
4522f88d849a4e994c94c0d0814a4befb43c990ceebdDaniel Veillard    if (ret == NULL)
4523f88d849a4e994c94c0d0814a4befb43c990ceebdDaniel Veillard        return(ret);
4524f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    if (xmlXPathNodeSetIsEmpty(nodes) ||
4525f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer	(!xmlXPathNodeSetContains(nodes, node)))
4526f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer	return(ret);
4527f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer
4528f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    l = xmlXPathNodeSetGetLength(nodes);
4529f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    for (i = 0; i < l; i++) {
4530f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer	cur = xmlXPathNodeSetItem(nodes, i);
4531f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer	if (cur == node)
4532f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer	    break;
4533f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer	xmlXPathNodeSetAddUnique(ret, cur);
4534f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    }
4535f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    return(ret);
4536f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer}
4537f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer
4538f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/**
4539f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathNodeLeading:
4540f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes:  a node-set
4541f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @node:  a node
4542f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *
4543f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Implements the EXSLT - Sets leading() function:
4544f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *    node-set set:leading (node-set, node-set)
4545f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes is sorted by document order, then #exslSetsNodeLeadingSorted
4546f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * is called.
4547f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *
4548f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns the nodes in @nodes that precede @node in document order,
4549f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *         @nodes if @node is NULL or an empty node-set if @nodes
4550f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *         doesn't contain @node
4551f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */
4552f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlNodeSetPtr
4553f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathNodeLeading (xmlNodeSetPtr nodes, xmlNodePtr node) {
4554f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    xmlXPathNodeSetSort(nodes);
4555f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    return(xmlXPathNodeLeadingSorted(nodes, node));
4556f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer}
4557f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer
4558f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/**
4559f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathLeadingSorted:
4560f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes1:  a node-set, sorted by document order
4561f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes2:  a node-set, sorted by document order
4562f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *
4563f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Implements the EXSLT - Sets leading() function:
4564f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *    node-set set:leading (node-set, node-set)
4565f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *
4566f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns the nodes in @nodes1 that precede the first node in @nodes2
4567f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *         in document order, @nodes1 if @nodes2 is NULL or empty or
4568f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *         an empty node-set if @nodes1 doesn't contain @nodes2
4569f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */
4570f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlNodeSetPtr
4571f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathLeadingSorted (xmlNodeSetPtr nodes1, xmlNodeSetPtr nodes2) {
4572f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    if (xmlXPathNodeSetIsEmpty(nodes2))
4573f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer	return(nodes1);
4574f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    return(xmlXPathNodeLeadingSorted(nodes1,
4575f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer				     xmlXPathNodeSetItem(nodes2, 1)));
4576f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer}
4577f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer
4578f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/**
4579f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathLeading:
4580f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes1:  a node-set
4581f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes2:  a node-set
4582f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *
4583f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Implements the EXSLT - Sets leading() function:
4584f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *    node-set set:leading (node-set, node-set)
4585f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes1 and @nodes2 are sorted by document order, then
4586f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * #exslSetsLeadingSorted is called.
4587f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *
4588f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns the nodes in @nodes1 that precede the first node in @nodes2
4589f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *         in document order, @nodes1 if @nodes2 is NULL or empty or
4590f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *         an empty node-set if @nodes1 doesn't contain @nodes2
4591f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */
4592f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlNodeSetPtr
4593f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathLeading (xmlNodeSetPtr nodes1, xmlNodeSetPtr nodes2) {
4594f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    if (xmlXPathNodeSetIsEmpty(nodes2))
4595f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer	return(nodes1);
4596f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    if (xmlXPathNodeSetIsEmpty(nodes1))
4597f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer	return(xmlXPathNodeSetCreate(NULL));
4598f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    xmlXPathNodeSetSort(nodes1);
4599f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    xmlXPathNodeSetSort(nodes2);
4600f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    return(xmlXPathNodeLeadingSorted(nodes1,
4601f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer				     xmlXPathNodeSetItem(nodes2, 1)));
4602f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer}
4603f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer
4604f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/**
4605f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathNodeTrailingSorted:
4606f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes: a node-set, sorted by document order
4607f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @node: a node
4608f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *
4609f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Implements the EXSLT - Sets trailing() function:
4610f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *    node-set set:trailing (node-set, node-set)
4611f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *
4612f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns the nodes in @nodes that follow @node in document order,
4613f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *         @nodes if @node is NULL or an empty node-set if @nodes
4614f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *         doesn't contain @node
4615f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */
4616f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlNodeSetPtr
4617f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathNodeTrailingSorted (xmlNodeSetPtr nodes, xmlNodePtr node) {
4618f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    int i, l;
4619f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    xmlNodePtr cur;
4620f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    xmlNodeSetPtr ret;
4621f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer
4622f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    if (node == NULL)
4623f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer	return(nodes);
4624f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer
4625f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    ret = xmlXPathNodeSetCreate(NULL);
4626f88d849a4e994c94c0d0814a4befb43c990ceebdDaniel Veillard    if (ret == NULL)
4627f88d849a4e994c94c0d0814a4befb43c990ceebdDaniel Veillard        return(ret);
4628f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    if (xmlXPathNodeSetIsEmpty(nodes) ||
4629f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer	(!xmlXPathNodeSetContains(nodes, node)))
4630f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer	return(ret);
4631f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer
4632f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    l = xmlXPathNodeSetGetLength(nodes);
463397ac819cc650e5241303baa65b0fd04d112fd9e1William M. Brack    for (i = l - 1; i >= 0; i--) {
4634f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer	cur = xmlXPathNodeSetItem(nodes, i);
4635f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer	if (cur == node)
4636f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer	    break;
4637f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer	xmlXPathNodeSetAddUnique(ret, cur);
4638f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    }
463997ac819cc650e5241303baa65b0fd04d112fd9e1William M. Brack    xmlXPathNodeSetSort(ret);	/* bug 413451 */
4640f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    return(ret);
4641f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer}
4642f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer
4643f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/**
4644f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathNodeTrailing:
4645f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes:  a node-set
4646f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @node:  a node
4647f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *
4648f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Implements the EXSLT - Sets trailing() function:
4649f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *    node-set set:trailing (node-set, node-set)
4650f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes is sorted by document order, then #xmlXPathNodeTrailingSorted
4651f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * is called.
4652f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *
4653f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns the nodes in @nodes that follow @node in document order,
4654f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *         @nodes if @node is NULL or an empty node-set if @nodes
4655f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *         doesn't contain @node
4656f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */
4657f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlNodeSetPtr
4658f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathNodeTrailing (xmlNodeSetPtr nodes, xmlNodePtr node) {
4659f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    xmlXPathNodeSetSort(nodes);
4660f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    return(xmlXPathNodeTrailingSorted(nodes, node));
4661f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer}
4662f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer
4663f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/**
4664f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathTrailingSorted:
4665f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes1:  a node-set, sorted by document order
4666f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes2:  a node-set, sorted by document order
4667f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *
4668f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Implements the EXSLT - Sets trailing() function:
4669f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *    node-set set:trailing (node-set, node-set)
4670f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *
4671f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns the nodes in @nodes1 that follow the first node in @nodes2
4672f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *         in document order, @nodes1 if @nodes2 is NULL or empty or
4673f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *         an empty node-set if @nodes1 doesn't contain @nodes2
4674f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */
4675f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlNodeSetPtr
4676f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathTrailingSorted (xmlNodeSetPtr nodes1, xmlNodeSetPtr nodes2) {
4677f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    if (xmlXPathNodeSetIsEmpty(nodes2))
4678f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer	return(nodes1);
4679f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    return(xmlXPathNodeTrailingSorted(nodes1,
4680f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer				      xmlXPathNodeSetItem(nodes2, 0)));
4681f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer}
4682f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer
4683f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/**
4684f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathTrailing:
4685f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes1:  a node-set
4686f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes2:  a node-set
4687f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *
4688f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Implements the EXSLT - Sets trailing() function:
4689f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *    node-set set:trailing (node-set, node-set)
4690f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes1 and @nodes2 are sorted by document order, then
4691f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * #xmlXPathTrailingSorted is called.
4692f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *
4693f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns the nodes in @nodes1 that follow the first node in @nodes2
4694f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *         in document order, @nodes1 if @nodes2 is NULL or empty or
4695f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *         an empty node-set if @nodes1 doesn't contain @nodes2
4696f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */
4697f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlNodeSetPtr
4698f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathTrailing (xmlNodeSetPtr nodes1, xmlNodeSetPtr nodes2) {
4699f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    if (xmlXPathNodeSetIsEmpty(nodes2))
4700f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer	return(nodes1);
4701f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    if (xmlXPathNodeSetIsEmpty(nodes1))
4702f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer	return(xmlXPathNodeSetCreate(NULL));
4703f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    xmlXPathNodeSetSort(nodes1);
4704f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    xmlXPathNodeSetSort(nodes2);
4705f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    return(xmlXPathNodeTrailingSorted(nodes1,
4706f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer				      xmlXPathNodeSetItem(nodes2, 0)));
4707f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer}
4708f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer
47093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/************************************************************************
47103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *									*
47113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *		Routines to handle extra functions			*
47123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *									*
47133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ************************************************************************/
47143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
47153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
47163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathRegisterFunc:
47173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath context
47183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @name:  the function name
47193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @f:  the function implementation or NULL
47203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
47213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Register a new function. If @f is NULL it unregisters the function
47223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
47233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns 0 in case of success, -1 in case of error
47243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
472545490aebe7a60704e8ed850c498969858ab900eeDaniel Veillardint
47263473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathRegisterFunc(xmlXPathContextPtr ctxt, const xmlChar *name,
47273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		     xmlXPathFunction f) {
47283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(xmlXPathRegisterFuncNS(ctxt, name, NULL, f));
47293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
47303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
47313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
47323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathRegisterFuncNS:
47333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath context
47343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @name:  the function name
47353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ns_uri:  the function namespace URI
47363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @f:  the function implementation or NULL
47373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
47383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Register a new function. If @f is NULL it unregisters the function
47393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
47403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns 0 in case of success, -1 in case of error
47413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
47423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorint
47433473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathRegisterFuncNS(xmlXPathContextPtr ctxt, const xmlChar *name,
47443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		       const xmlChar *ns_uri, xmlXPathFunction f) {
47453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ctxt == NULL)
47463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(-1);
47473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (name == NULL)
47483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(-1);
47493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
47503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ctxt->funcHash == NULL)
47513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	ctxt->funcHash = xmlHashCreate(0);
47523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ctxt->funcHash == NULL)
47533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(-1);
475494394cd1e494f8d669b310748f54192268185c8dDaniel Veillard    if (f == NULL)
475594394cd1e494f8d669b310748f54192268185c8dDaniel Veillard        return(xmlHashRemoveEntry2(ctxt->funcHash, name, ns_uri, NULL));
4756ad0e67c57f26f691fc120d5c5336cee9885cf324William M. Brack    return(xmlHashAddEntry2(ctxt->funcHash, name, ns_uri, XML_CAST_FPTR(f)));
47573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
47583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
47593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
4760ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer * xmlXPathRegisterFuncLookup:
4761ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer * @ctxt:  the XPath context
4762ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer * @f:  the lookup function
4763cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * @funcCtxt:  the lookup data
4764ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer *
4765cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * Registers an external mechanism to do function lookup.
4766ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer */
4767ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyervoid
4768ba4ad3263bf7f5625329f115367e0c7018521a16Thomas BroyerxmlXPathRegisterFuncLookup (xmlXPathContextPtr ctxt,
4769ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer			    xmlXPathFuncLookupFunc f,
4770ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer			    void *funcCtxt) {
4771ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer    if (ctxt == NULL)
4772ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer	return;
47736ebf3c4c1a78406d15e8629b4a7b3d52549f0c8bDaniel Veillard    ctxt->funcLookupFunc = f;
4774ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer    ctxt->funcLookupData = funcCtxt;
4775ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer}
4776ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer
4777ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer/**
47783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathFunctionLookup:
47793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath context
47803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @name:  the function name
47813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
47823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Search in the Function array of the context for the given
47833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * function.
47843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
47853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the xmlXPathFunction or NULL if not found
47863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
47873473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathFunction
47883473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathFunctionLookup(xmlXPathContextPtr ctxt, const xmlChar *name) {
4789ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer    if (ctxt == NULL)
4790ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer	return (NULL);
4791ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer
4792ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer    if (ctxt->funcLookupFunc != NULL) {
4793ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer	xmlXPathFunction ret;
479499e55ebe945f6f4de33e8454f2770e02295a3a00Daniel Veillard	xmlXPathFuncLookupFunc f;
4795ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer
47966ebf3c4c1a78406d15e8629b4a7b3d52549f0c8bDaniel Veillard	f = ctxt->funcLookupFunc;
4797963d2ae41574066f9b44bcae610dd280c1e57dd8Daniel Veillard	ret = f(ctxt->funcLookupData, name, NULL);
4798ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer	if (ret != NULL)
4799ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer	    return(ret);
4800ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer    }
48013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(xmlXPathFunctionLookupNS(ctxt, name, NULL));
48023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
48033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
48043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
48053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathFunctionLookupNS:
48063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath context
48073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @name:  the function name
48083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ns_uri:  the function namespace URI
48093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
48103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Search in the Function array of the context for the given
48113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * function.
48123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
48133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the xmlXPathFunction or NULL if not found
48143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
48153473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathFunction
48163473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathFunctionLookupNS(xmlXPathContextPtr ctxt, const xmlChar *name,
48173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor			 const xmlChar *ns_uri) {
4818ad0e67c57f26f691fc120d5c5336cee9885cf324William M. Brack    xmlXPathFunction ret;
481945490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
48203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ctxt == NULL)
48213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(NULL);
48223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (name == NULL)
48233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(NULL);
48243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
4825ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer    if (ctxt->funcLookupFunc != NULL) {
482699e55ebe945f6f4de33e8454f2770e02295a3a00Daniel Veillard	xmlXPathFuncLookupFunc f;
4827ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer
48286ebf3c4c1a78406d15e8629b4a7b3d52549f0c8bDaniel Veillard	f = ctxt->funcLookupFunc;
4829963d2ae41574066f9b44bcae610dd280c1e57dd8Daniel Veillard	ret = f(ctxt->funcLookupData, name, ns_uri);
4830ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer	if (ret != NULL)
4831ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer	    return(ret);
4832ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer    }
4833ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer
4834ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer    if (ctxt->funcHash == NULL)
4835ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer	return(NULL);
4836ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer
4837ad0e67c57f26f691fc120d5c5336cee9885cf324William M. Brack    XML_CAST_FPTR(ret) = xmlHashLookup2(ctxt->funcHash, name, ns_uri);
4838ad0e67c57f26f691fc120d5c5336cee9885cf324William M. Brack    return(ret);
48393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
48403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
48413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
48423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathRegisteredFuncsCleanup:
48433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath context
48443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
48453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Cleanup the XPath context data associated to registered functions
48463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
48473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
48483473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathRegisteredFuncsCleanup(xmlXPathContextPtr ctxt) {
48493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ctxt == NULL)
48503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return;
48513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
48523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlHashFree(ctxt->funcHash, NULL);
48533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ctxt->funcHash = NULL;
48543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
48553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
48563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/************************************************************************
48573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *									*
4858081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack *			Routines to handle Variables			*
48593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *									*
48603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ************************************************************************/
48613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
48623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
48633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathRegisterVariable:
48643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath context
48653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @name:  the variable name
48663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @value:  the variable value or NULL
48673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
48683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Register a new variable value. If @value is NULL it unregisters
48693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the variable
48703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
48713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns 0 in case of success, -1 in case of error
48723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
487345490aebe7a60704e8ed850c498969858ab900eeDaniel Veillardint
48743473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathRegisterVariable(xmlXPathContextPtr ctxt, const xmlChar *name,
48753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor			 xmlXPathObjectPtr value) {
48763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(xmlXPathRegisterVariableNS(ctxt, name, NULL, value));
48773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
48783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
48793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
48803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathRegisterVariableNS:
48813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath context
48823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @name:  the variable name
48833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ns_uri:  the variable namespace URI
48843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @value:  the variable value or NULL
48853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
48863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Register a new variable value. If @value is NULL it unregisters
48873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the variable
48883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
48893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns 0 in case of success, -1 in case of error
48903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
48913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorint
48923473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathRegisterVariableNS(xmlXPathContextPtr ctxt, const xmlChar *name,
48933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor			   const xmlChar *ns_uri,
48943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor			   xmlXPathObjectPtr value) {
48953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ctxt == NULL)
48963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(-1);
48973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (name == NULL)
48983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(-1);
48993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
49003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ctxt->varHash == NULL)
49013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	ctxt->varHash = xmlHashCreate(0);
49023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ctxt->varHash == NULL)
49033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(-1);
490494394cd1e494f8d669b310748f54192268185c8dDaniel Veillard    if (value == NULL)
490545490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard        return(xmlHashRemoveEntry2(ctxt->varHash, name, ns_uri,
490694394cd1e494f8d669b310748f54192268185c8dDaniel Veillard	                           (xmlHashDeallocator)xmlXPathFreeObject));
49073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(xmlHashUpdateEntry2(ctxt->varHash, name, ns_uri,
49083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor			       (void *) value,
49093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor			       (xmlHashDeallocator)xmlXPathFreeObject));
49103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
49113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
49123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
49133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathRegisterVariableLookup:
49143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath context
49153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @f:  the lookup function
49163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @data:  the lookup data
49173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
49183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * register an external mechanism to do variable lookup
49193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
49203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
49213473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathRegisterVariableLookup(xmlXPathContextPtr ctxt,
49223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	 xmlXPathVariableLookupFunc f, void *data) {
49233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ctxt == NULL)
49243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return;
49256ebf3c4c1a78406d15e8629b4a7b3d52549f0c8bDaniel Veillard    ctxt->varLookupFunc = f;
49263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ctxt->varLookupData = data;
49273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
49283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
49293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
49303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathVariableLookup:
49313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath context
49323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @name:  the variable name
49333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
49343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Search in the Variable array of the context for the given
49353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * variable value.
49363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
493773c9c049195bf897dbcb6308a1ab9d16b3fe6b2cDaniel Veillard * Returns a copy of the value or NULL if not found
49383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
49393473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathObjectPtr
49403473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathVariableLookup(xmlXPathContextPtr ctxt, const xmlChar *name) {
49413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ctxt == NULL)
49423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(NULL);
49433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
49443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ctxt->varLookupFunc != NULL) {
49453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	xmlXPathObjectPtr ret;
49463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
49473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	ret = ((xmlXPathVariableLookupFunc)ctxt->varLookupFunc)
49483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	        (ctxt->varLookupData, name, NULL);
4949556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard	return(ret);
49503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
49513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(xmlXPathVariableLookupNS(ctxt, name, NULL));
49523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
49533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
49543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
49553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathVariableLookupNS:
49563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath context
49573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @name:  the variable name
49583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ns_uri:  the variable namespace URI
49593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
49603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Search in the Variable array of the context for the given
496145490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard * variable value.
49623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
496373c9c049195bf897dbcb6308a1ab9d16b3fe6b2cDaniel Veillard * Returns the a copy of the value or NULL if not found
49643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
49653473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathObjectPtr
49663473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathVariableLookupNS(xmlXPathContextPtr ctxt, const xmlChar *name,
49673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor			 const xmlChar *ns_uri) {
49683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ctxt == NULL)
49693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(NULL);
49703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
49713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ctxt->varLookupFunc != NULL) {
49723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	xmlXPathObjectPtr ret;
49733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
49743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	ret = ((xmlXPathVariableLookupFunc)ctxt->varLookupFunc)
49753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	        (ctxt->varLookupData, name, ns_uri);
49763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (ret != NULL) return(ret);
49773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
49783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
49793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ctxt->varHash == NULL)
49803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(NULL);
49813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (name == NULL)
49823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(NULL);
49833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
4984a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    return(xmlXPathCacheObjectCopy(ctxt, (xmlXPathObjectPtr)
49858c357d58c2d1dde022b67393a47dcb52100ce129Daniel Veillard		xmlHashLookup2(ctxt->varHash, name, ns_uri)));
49863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
49873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
49883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
49893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathRegisteredVariablesCleanup:
49903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath context
49913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
49923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Cleanup the XPath context data associated to registered variables
49933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
49943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
49953473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathRegisteredVariablesCleanup(xmlXPathContextPtr ctxt) {
49963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ctxt == NULL)
49973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return;
49983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
499976d66f416d2d0d5db4a09d212b4e43087e9cdae7Daniel Veillard    xmlHashFree(ctxt->varHash, (xmlHashDeallocator)xmlXPathFreeObject);
50003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ctxt->varHash = NULL;
50013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
50023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
50033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
50043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathRegisterNs:
50053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath context
5006db3ce96906c09559d944c72b69eb984105f34776Daniel Veillard * @prefix:  the namespace prefix cannot be NULL or empty string
50073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ns_uri:  the namespace name
50083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
50093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Register a new namespace. If @ns_uri is NULL it unregisters
50103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the namespace
50113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
50123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns 0 in case of success, -1 in case of error
50133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
50143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorint
50153473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathRegisterNs(xmlXPathContextPtr ctxt, const xmlChar *prefix,
50163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor			   const xmlChar *ns_uri) {
50173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ctxt == NULL)
50183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(-1);
50193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (prefix == NULL)
50203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(-1);
5021db3ce96906c09559d944c72b69eb984105f34776Daniel Veillard    if (prefix[0] == 0)
5022db3ce96906c09559d944c72b69eb984105f34776Daniel Veillard	return(-1);
50233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
50243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ctxt->nsHash == NULL)
50253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	ctxt->nsHash = xmlHashCreate(10);
50263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ctxt->nsHash == NULL)
50273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(-1);
5028e991fe958f5269a459262bcff802a3d26167edb8Daniel Veillard    if (ns_uri == NULL)
502994394cd1e494f8d669b310748f54192268185c8dDaniel Veillard        return(xmlHashRemoveEntry(ctxt->nsHash, prefix,
5030e991fe958f5269a459262bcff802a3d26167edb8Daniel Veillard	                          (xmlHashDeallocator)xmlFree));
503142766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard    return(xmlHashUpdateEntry(ctxt->nsHash, prefix, (void *) xmlStrdup(ns_uri),
50323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor			      (xmlHashDeallocator)xmlFree));
50333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
50343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
50353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
50363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNsLookup:
50373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath context
50383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @prefix:  the namespace prefix value
50393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
50403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Search in the namespace declaration array of the context for the given
50413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * namespace name associated to the given prefix
50423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
50433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the value or NULL if not found
50443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
50453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorconst xmlChar *
50463473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNsLookup(xmlXPathContextPtr ctxt, const xmlChar *prefix) {
50473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ctxt == NULL)
50483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(NULL);
50493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (prefix == NULL)
50503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(NULL);
50513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
50523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef XML_XML_NAMESPACE
50533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (xmlStrEqual(prefix, (const xmlChar *) "xml"))
50543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(XML_XML_NAMESPACE);
50553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif
50563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
5057c8f620ba7f95b3ceb687699e140eeaa33343e41aDaniel Veillard    if (ctxt->namespaces != NULL) {
5058c8f620ba7f95b3ceb687699e140eeaa33343e41aDaniel Veillard	int i;
5059c8f620ba7f95b3ceb687699e140eeaa33343e41aDaniel Veillard
5060c8f620ba7f95b3ceb687699e140eeaa33343e41aDaniel Veillard	for (i = 0;i < ctxt->nsNr;i++) {
5061c8f620ba7f95b3ceb687699e140eeaa33343e41aDaniel Veillard	    if ((ctxt->namespaces[i] != NULL) &&
5062c8f620ba7f95b3ceb687699e140eeaa33343e41aDaniel Veillard		(xmlStrEqual(ctxt->namespaces[i]->prefix, prefix)))
5063c8f620ba7f95b3ceb687699e140eeaa33343e41aDaniel Veillard		return(ctxt->namespaces[i]->href);
5064c8f620ba7f95b3ceb687699e140eeaa33343e41aDaniel Veillard	}
5065c8f620ba7f95b3ceb687699e140eeaa33343e41aDaniel Veillard    }
50663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
50673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return((const xmlChar *) xmlHashLookup(ctxt->nsHash, prefix));
50683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
50693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
50703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
50715e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard * xmlXPathRegisteredNsCleanup:
50723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath context
50733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
50743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Cleanup the XPath context data associated to registered variables
50753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
50763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
50773473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathRegisteredNsCleanup(xmlXPathContextPtr ctxt) {
50783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ctxt == NULL)
50793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return;
50803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
508142766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard    xmlHashFree(ctxt->nsHash, (xmlHashDeallocator)xmlFree);
50823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ctxt->nsHash = NULL;
50833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
50843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
50853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/************************************************************************
50863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *									*
50873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *			Routines to handle Values			*
50883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *									*
50893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ************************************************************************/
50903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
5091081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack/* Allocations are terrible, one needs to optimize all this !!! */
50923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
50933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
50943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNewFloat:
50953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val:  the double value
50963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
50973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Create a new xmlXPathObjectPtr of type double and of value @val
50983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
50993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the newly created object.
51003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
51013473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathObjectPtr
51023473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNewFloat(double val) {
51033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathObjectPtr ret;
51043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
51053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
51063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ret == NULL) {
5107d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard        xmlXPathErrMemory(NULL, "creating float object\n");
51083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(NULL);
51093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
51103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
51113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret->type = XPATH_NUMBER;
51123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret->floatval = val;
5113a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#ifdef XP_DEBUG_OBJ_USAGE
5114a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathDebugObjUsageRequested(NULL, XPATH_NUMBER);
5115a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#endif
51163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(ret);
51173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
51183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
51193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
51203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNewBoolean:
51213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val:  the boolean value
51223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
51233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Create a new xmlXPathObjectPtr of type boolean and of value @val
51243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
51253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the newly created object.
51263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
51273473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathObjectPtr
51283473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNewBoolean(int val) {
51293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathObjectPtr ret;
51303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
51313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
51323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ret == NULL) {
5133d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard        xmlXPathErrMemory(NULL, "creating boolean object\n");
51343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(NULL);
51353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
51363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
51373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret->type = XPATH_BOOLEAN;
51383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret->boolval = (val != 0);
5139a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#ifdef XP_DEBUG_OBJ_USAGE
5140a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathDebugObjUsageRequested(NULL, XPATH_BOOLEAN);
5141a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#endif
51423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(ret);
51433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
51443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
51453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
51463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNewString:
51473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val:  the xmlChar * value
51483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
51493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Create a new xmlXPathObjectPtr of type string and of value @val
51503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
51513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the newly created object.
51523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
51533473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathObjectPtr
51543473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNewString(const xmlChar *val) {
51553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathObjectPtr ret;
51563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
51573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
51583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ret == NULL) {
5159d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard        xmlXPathErrMemory(NULL, "creating string object\n");
51603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(NULL);
51613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
51623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
51633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret->type = XPATH_STRING;
51643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (val != NULL)
51653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	ret->stringval = xmlStrdup(val);
51663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    else
51673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	ret->stringval = xmlStrdup((const xmlChar *)"");
5168a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#ifdef XP_DEBUG_OBJ_USAGE
5169a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathDebugObjUsageRequested(NULL, XPATH_STRING);
5170a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#endif
51713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(ret);
51723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
51733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
51743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
5175ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathWrapString:
5176ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @val:  the xmlChar * value
5177ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
5178ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Wraps the @val string into an XPath object.
5179ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
5180ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns the newly created object.
5181ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */
5182ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathObjectPtr
5183ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathWrapString (xmlChar *val) {
5184ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    xmlXPathObjectPtr ret;
5185ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
5186ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
5187ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    if (ret == NULL) {
5188d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard        xmlXPathErrMemory(NULL, "creating string object\n");
5189ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	return(NULL);
5190ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    }
5191ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
5192ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    ret->type = XPATH_STRING;
5193ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    ret->stringval = val;
5194a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#ifdef XP_DEBUG_OBJ_USAGE
5195a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathDebugObjUsageRequested(NULL, XPATH_STRING);
5196a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#endif
5197ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    return(ret);
5198ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard}
5199ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
5200ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/**
52013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNewCString:
52023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val:  the char * value
52033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
52043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Create a new xmlXPathObjectPtr of type string and of value @val
52053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
52063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the newly created object.
52073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
52083473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathObjectPtr
52093473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNewCString(const char *val) {
52103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathObjectPtr ret;
52113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
52123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
52133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ret == NULL) {
5214d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard        xmlXPathErrMemory(NULL, "creating string object\n");
52153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(NULL);
52163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
52173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
52183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret->type = XPATH_STRING;
52193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret->stringval = xmlStrdup(BAD_CAST val);
5220a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#ifdef XP_DEBUG_OBJ_USAGE
5221a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathDebugObjUsageRequested(NULL, XPATH_STRING);
5222a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#endif
52233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(ret);
52243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
52253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
52263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
5227ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathWrapCString:
5228ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @val:  the char * value
5229ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
5230ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Wraps a string into an XPath object.
5231ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
5232ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns the newly created object.
5233ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */
5234ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathObjectPtr
5235ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathWrapCString (char * val) {
5236ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    return(xmlXPathWrapString((xmlChar *)(val)));
5237ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard}
5238ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
5239ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/**
5240f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathWrapExternal:
5241f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @val:  the user data
5242f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *
5243f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Wraps the @val data into an XPath object.
5244f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *
5245f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns the newly created object.
5246f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */
5247f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathObjectPtr
5248f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathWrapExternal (void *val) {
5249f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    xmlXPathObjectPtr ret;
5250f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer
5251f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
5252f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    if (ret == NULL) {
5253d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard        xmlXPathErrMemory(NULL, "creating user object\n");
5254f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer	return(NULL);
5255f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    }
5256f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
5257f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    ret->type = XPATH_USERS;
5258f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    ret->user = val;
5259a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#ifdef XP_DEBUG_OBJ_USAGE
5260a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathDebugObjUsageRequested(NULL, XPATH_USERS);
5261a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#endif
5262f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    return(ret);
5263f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer}
5264f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer
5265f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/**
52663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathObjectCopy:
52673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val:  the original object
52683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
52693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * allocate a new copy of a given object
52703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
52713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the newly created object.
52723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
52733473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathObjectPtr
52743473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathObjectCopy(xmlXPathObjectPtr val) {
52753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathObjectPtr ret;
52763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
52773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (val == NULL)
52783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(NULL);
52793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
52803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
52813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ret == NULL) {
5282d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard        xmlXPathErrMemory(NULL, "copying object\n");
52833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(NULL);
52843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
52853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    memcpy(ret, val , (size_t) sizeof(xmlXPathObject));
5286a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#ifdef XP_DEBUG_OBJ_USAGE
5287a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathDebugObjUsageRequested(NULL, val->type);
5288a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#endif
52893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    switch (val->type) {
52903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XPATH_BOOLEAN:
52913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XPATH_NUMBER:
52923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XPATH_POINT:
52933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XPATH_RANGE:
52943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    break;
52953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XPATH_STRING:
52963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    ret->stringval = xmlStrdup(val->stringval);
52973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    break;
52983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XPATH_XSLT_TREE:
5299e9449c5d29d87b1dc51de7784ed947ae1e3da831William M. Brack#if 0
5300e9449c5d29d87b1dc51de7784ed947ae1e3da831William M. Brack/*
5301e9449c5d29d87b1dc51de7784ed947ae1e3da831William M. Brack  Removed 11 July 2004 - the current handling of xslt tmpRVT nodes means that
5302e9449c5d29d87b1dc51de7784ed947ae1e3da831William M. Brack  this previous handling is no longer correct, and can cause some serious
5303e9449c5d29d87b1dc51de7784ed947ae1e3da831William M. Brack  problems (ref. bug 145547)
5304e9449c5d29d87b1dc51de7784ed947ae1e3da831William M. Brack*/
53053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    if ((val->nodesetval != NULL) &&
53060ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard		(val->nodesetval->nodeTab != NULL)) {
53079adc0469d4691e798ea4ad59b84c874cdea8b38dDaniel Veillard		xmlNodePtr cur, tmp;
53089adc0469d4691e798ea4ad59b84c874cdea8b38dDaniel Veillard		xmlDocPtr top;
5309ef0b45016373d65700ef6f7d494a200758b2e4c5Daniel Veillard
53100ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard		ret->boolval = 1;
53119adc0469d4691e798ea4ad59b84c874cdea8b38dDaniel Veillard		top =  xmlNewDoc(NULL);
53129adc0469d4691e798ea4ad59b84c874cdea8b38dDaniel Veillard		top->name = (char *)
53139adc0469d4691e798ea4ad59b84c874cdea8b38dDaniel Veillard		    xmlStrdup(val->nodesetval->nodeTab[0]->name);
5314ef0b45016373d65700ef6f7d494a200758b2e4c5Daniel Veillard		ret->user = top;
5315ef0b45016373d65700ef6f7d494a200758b2e4c5Daniel Veillard		if (top != NULL) {
53169adc0469d4691e798ea4ad59b84c874cdea8b38dDaniel Veillard		    top->doc = top;
5317ef0b45016373d65700ef6f7d494a200758b2e4c5Daniel Veillard		    cur = val->nodesetval->nodeTab[0]->children;
5318ef0b45016373d65700ef6f7d494a200758b2e4c5Daniel Veillard		    while (cur != NULL) {
53199adc0469d4691e798ea4ad59b84c874cdea8b38dDaniel Veillard			tmp = xmlDocCopyNode(cur, top, 1);
53209adc0469d4691e798ea4ad59b84c874cdea8b38dDaniel Veillard			xmlAddChild((xmlNodePtr) top, tmp);
5321ef0b45016373d65700ef6f7d494a200758b2e4c5Daniel Veillard			cur = cur->next;
5322ef0b45016373d65700ef6f7d494a200758b2e4c5Daniel Veillard		    }
5323ef0b45016373d65700ef6f7d494a200758b2e4c5Daniel Veillard		}
5324e9449c5d29d87b1dc51de7784ed947ae1e3da831William M. Brack
53259adc0469d4691e798ea4ad59b84c874cdea8b38dDaniel Veillard		ret->nodesetval = xmlXPathNodeSetCreate((xmlNodePtr) top);
53260ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard	    } else
53273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		ret->nodesetval = xmlXPathNodeSetCreate(NULL);
53280ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard	    /* Deallocate the copied tree value */
53293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    break;
5330e9449c5d29d87b1dc51de7784ed947ae1e3da831William M. Brack#endif
53313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XPATH_NODESET:
53323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    ret->nodesetval = xmlXPathNodeSetMerge(NULL, val->nodesetval);
53330ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard	    /* Do not deallocate the copied tree value */
53340ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard	    ret->boolval = 0;
53353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    break;
53363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XPATH_LOCATIONSET:
53373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef LIBXML_XPTR_ENABLED
53383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	{
53393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    xmlLocationSetPtr loc = val->user;
53403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    ret->user = (void *) xmlXPtrLocationSetMerge(NULL, loc);
53413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    break;
53423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
53433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif
534447334c09f4373e4cff71334e60a623fee73a525fThomas Broyer        case XPATH_USERS:
534547334c09f4373e4cff71334e60a623fee73a525fThomas Broyer	    ret->user = val->user;
534645490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	    break;
534747334c09f4373e4cff71334e60a623fee73a525fThomas Broyer        case XPATH_UNDEFINED:
53483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    xmlGenericError(xmlGenericErrorContext,
53493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    "xmlXPathObjectCopy: unsupported type %d\n",
53503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    val->type);
53513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    break;
53523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
53533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(ret);
53543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
53553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
53563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
53573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathFreeObject:
53583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @obj:  the object to free
53593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
53603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Free up an xmlXPathObjectPtr object.
53613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
53623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
53633473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathFreeObject(xmlXPathObjectPtr obj) {
53643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (obj == NULL) return;
53650ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard    if ((obj->type == XPATH_NODESET) || (obj->type == XPATH_XSLT_TREE)) {
536677851710aba3a0effdc6af67ea4caf212307420cDaniel Veillard	if (obj->boolval) {
5367e9449c5d29d87b1dc51de7784ed947ae1e3da831William M. Brack#if 0
53680ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard	    if (obj->user != NULL) {
53690ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard                xmlXPathFreeNodeSet(obj->nodesetval);
537038bf6f042507c6051bfa2db5cc9b6666cfc35c2aDaniel Veillard		xmlFreeNodeList((xmlNodePtr) obj->user);
5371e9449c5d29d87b1dc51de7784ed947ae1e3da831William M. Brack	    } else
5372e9449c5d29d87b1dc51de7784ed947ae1e3da831William M. Brack#endif
5373a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    obj->type = XPATH_XSLT_TREE; /* TODO: Just for debugging. */
5374e9449c5d29d87b1dc51de7784ed947ae1e3da831William M. Brack	    if (obj->nodesetval != NULL)
537545490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard		xmlXPathFreeValueTree(obj->nodesetval);
537677851710aba3a0effdc6af67ea4caf212307420cDaniel Veillard	} else {
537777851710aba3a0effdc6af67ea4caf212307420cDaniel Veillard	    if (obj->nodesetval != NULL)
537877851710aba3a0effdc6af67ea4caf212307420cDaniel Veillard		xmlXPathFreeNodeSet(obj->nodesetval);
537977851710aba3a0effdc6af67ea4caf212307420cDaniel Veillard	}
53803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef LIBXML_XPTR_ENABLED
53813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    } else if (obj->type == XPATH_LOCATIONSET) {
53823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (obj->user != NULL)
53833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    xmlXPtrFreeLocationSet(obj->user);
53843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif
53853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    } else if (obj->type == XPATH_STRING) {
53863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (obj->stringval != NULL)
53873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    xmlFree(obj->stringval);
53883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
5389a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#ifdef XP_DEBUG_OBJ_USAGE
5390a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathDebugObjUsageReleased(NULL, obj->type);
5391a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#endif
539245490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard    xmlFree(obj);
5393a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik}
53943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
5395a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik/**
5396a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * xmlXPathReleaseObject:
5397a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * @obj:  the xmlXPathObjectPtr to free or to cache
5398a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik *
5399a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * Depending on the state of the cache this frees the given
5400a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * XPath object or stores it in the cache.
5401a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik */
5402a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikstatic void
5403a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. BuchcikxmlXPathReleaseObject(xmlXPathContextPtr ctxt, xmlXPathObjectPtr obj)
5404a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik{
5405a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#define XP_CACHE_ADD(sl, o) if (sl == NULL) { \
5406a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	sl = xmlPointerListCreate(10); if (sl == NULL) goto free_obj; } \
5407a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    if (xmlPointerListAddSize(sl, obj, 0) == -1) goto free_obj;
5408a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
5409a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#define XP_CACHE_WANTS(sl, n) ((sl == NULL) || ((sl)->number < n))
5410a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
5411a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    if (obj == NULL)
5412a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	return;
54135869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik    if ((ctxt == NULL) || (ctxt->cache == NULL)) {
5414a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	 xmlXPathFreeObject(obj);
541545490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard    } else {
54165869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik	xmlXPathContextCachePtr cache =
54175869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik	    (xmlXPathContextCachePtr) ctxt->cache;
5418a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
5419a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	switch (obj->type) {
5420a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    case XPATH_NODESET:
5421a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    case XPATH_XSLT_TREE:
5422a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		if (obj->nodesetval != NULL) {
5423a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    if (obj->boolval) {
542445490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard			/*
5425a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik			* It looks like the @boolval is used for
5426a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik			* evaluation if this an XSLT Result Tree Fragment.
5427a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik			* TODO: Check if this assumption is correct.
5428a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik			*/
5429a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik			obj->type = XPATH_XSLT_TREE; /* just for debugging */
5430a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik			xmlXPathFreeValueTree(obj->nodesetval);
5431a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik			obj->nodesetval = NULL;
5432a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    } else if ((obj->nodesetval->nodeMax <= 40) &&
5433a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik			(XP_CACHE_WANTS(cache->nodesetObjs,
5434a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik					cache->maxNodeset)))
5435a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    {
5436a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik			XP_CACHE_ADD(cache->nodesetObjs, obj);
5437a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik			goto obj_cached;
5438a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    } else {
5439a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik			xmlXPathFreeNodeSet(obj->nodesetval);
5440a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik			obj->nodesetval = NULL;
5441a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    }
5442a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		}
5443a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		break;
5444a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    case XPATH_STRING:
5445a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		if (obj->stringval != NULL)
5446a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    xmlFree(obj->stringval);
5447a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
5448a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		if (XP_CACHE_WANTS(cache->stringObjs, cache->maxString)) {
5449a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    XP_CACHE_ADD(cache->stringObjs, obj);
5450a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    goto obj_cached;
5451a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		}
5452a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		break;
5453a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    case XPATH_BOOLEAN:
5454a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		if (XP_CACHE_WANTS(cache->booleanObjs, cache->maxBoolean)) {
5455a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    XP_CACHE_ADD(cache->booleanObjs, obj);
5456a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    goto obj_cached;
5457a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		}
5458a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		break;
5459a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    case XPATH_NUMBER:
5460a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		if (XP_CACHE_WANTS(cache->numberObjs, cache->maxNumber)) {
5461a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    XP_CACHE_ADD(cache->numberObjs, obj);
5462a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    goto obj_cached;
5463a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		}
5464a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		break;
5465a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#ifdef LIBXML_XPTR_ENABLED
5466a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    case XPATH_LOCATIONSET:
5467a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		if (obj->user != NULL) {
5468a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    xmlXPtrFreeLocationSet(obj->user);
5469a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		}
5470a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		goto free_obj;
547145490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard#endif
5472a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    default:
5473a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		goto free_obj;
5474a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	}
5475a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
5476a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	/*
5477a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	* Fallback to adding to the misc-objects slot.
5478a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	*/
5479a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	if (XP_CACHE_WANTS(cache->miscObjs, cache->maxMisc)) {
5480a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    XP_CACHE_ADD(cache->miscObjs, obj);
5481a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	} else
5482a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    goto free_obj;
5483a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
5484a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikobj_cached:
5485a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
5486a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#ifdef XP_DEBUG_OBJ_USAGE
5487a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	xmlXPathDebugObjUsageReleased(ctxt, obj->type);
5488a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#endif
5489a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
5490a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	if (obj->nodesetval != NULL) {
5491a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlNodeSetPtr tmpset = obj->nodesetval;
549245490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
5493a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    /*
5494a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    * TODO: Due to those nasty ns-nodes, we need to traverse
5495a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    *  the list and free the ns-nodes.
5496a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    * URGENT TODO: Check if it's actually slowing things down.
5497a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    *  Maybe we shouldn't try to preserve the list.
5498a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    */
5499a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    if (tmpset->nodeNr > 1) {
5500a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		int i;
5501a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		xmlNodePtr node;
5502a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
5503a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		for (i = 0; i < tmpset->nodeNr; i++) {
5504a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    node = tmpset->nodeTab[i];
5505a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    if ((node != NULL) &&
5506a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik			(node->type == XML_NAMESPACE_DECL))
5507a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    {
5508a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik			xmlXPathNodeSetFreeNs((xmlNsPtr) node);
5509a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    }
5510a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		}
5511a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    } else if (tmpset->nodeNr == 1) {
5512a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		if ((tmpset->nodeTab[0] != NULL) &&
5513a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    (tmpset->nodeTab[0]->type == XML_NAMESPACE_DECL))
5514a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    xmlXPathNodeSetFreeNs((xmlNsPtr) tmpset->nodeTab[0]);
551545490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	    }
5516a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    tmpset->nodeNr = 0;
5517a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    memset(obj, 0, sizeof(xmlXPathObject));
5518a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    obj->nodesetval = tmpset;
5519a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	} else
5520a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    memset(obj, 0, sizeof(xmlXPathObject));
5521a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
5522a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	return;
5523a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
5524a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikfree_obj:
5525a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	/*
5526a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	* Cache is full; free the object.
552745490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	*/
5528a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	if (obj->nodesetval != NULL)
5529a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathFreeNodeSet(obj->nodesetval);
5530a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#ifdef XP_DEBUG_OBJ_USAGE
5531a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	xmlXPathDebugObjUsageReleased(NULL, obj->type);
5532a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#endif
5533a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	xmlFree(obj);
5534a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    }
5535a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    return;
55363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
55373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
5538ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
5539ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/************************************************************************
5540ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *									*
5541ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *			Type Casting Routines				*
5542ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *									*
5543ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ************************************************************************/
5544ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
5545ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/**
5546ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathCastBooleanToString:
5547ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @val:  a boolean
5548ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
5549ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts a boolean to its string value.
5550ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
5551ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns a newly allocated string.
5552ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */
5553ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlChar *
5554ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathCastBooleanToString (int val) {
5555ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    xmlChar *ret;
5556ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    if (val)
5557ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	ret = xmlStrdup((const xmlChar *) "true");
5558ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    else
5559ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	ret = xmlStrdup((const xmlChar *) "false");
5560ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    return(ret);
5561ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard}
5562ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
5563ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/**
5564ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathCastNumberToString:
5565ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @val:  a number
5566ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
5567ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts a number to its string value.
5568ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
5569ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns a newly allocated string.
5570ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */
5571ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlChar *
5572ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathCastNumberToString (double val) {
5573ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    xmlChar *ret;
5574cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard    switch (xmlXPathIsInf(val)) {
5575ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    case 1:
55765fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard	ret = xmlStrdup((const xmlChar *) "Infinity");
5577ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	break;
5578ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    case -1:
5579ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	ret = xmlStrdup((const xmlChar *) "-Infinity");
5580ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	break;
5581ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    default:
5582cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard	if (xmlXPathIsNaN(val)) {
5583ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	    ret = xmlStrdup((const xmlChar *) "NaN");
5584d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard	} else if (val == 0 && xmlXPathGetSign(val) != 0) {
5585d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard	    ret = xmlStrdup((const xmlChar *) "0");
5586ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	} else {
5587ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	    /* could be improved */
5588ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	    char buf[100];
558911ce4004d86bb4b317c48b7d5124ba33e40e10f5Daniel Veillard	    xmlXPathFormatNumber(val, buf, 99);
559011ce4004d86bb4b317c48b7d5124ba33e40e10f5Daniel Veillard	    buf[99] = 0;
5591ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	    ret = xmlStrdup((const xmlChar *) buf);
5592ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	}
5593ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    }
5594ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    return(ret);
5595ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard}
5596ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
5597ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/**
5598ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathCastNodeToString:
5599ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @node:  a node
5600ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
5601ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts a node to its string value.
5602ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
5603ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns a newly allocated string.
5604ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */
5605ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlChar *
5606ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathCastNodeToString (xmlNodePtr node) {
5607d611c88a010fa7c64c407155e43b04bc4c7e9e38William M. BrackxmlChar *ret;
5608d611c88a010fa7c64c407155e43b04bc4c7e9e38William M. Brack    if ((ret = xmlNodeGetContent(node)) == NULL)
5609d611c88a010fa7c64c407155e43b04bc4c7e9e38William M. Brack	ret = xmlStrdup((const xmlChar *) "");
5610d611c88a010fa7c64c407155e43b04bc4c7e9e38William M. Brack    return(ret);
5611ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard}
5612ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
5613ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/**
5614ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathCastNodeSetToString:
5615ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @ns:  a node-set
5616ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
5617ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts a node-set to its string value.
5618ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
5619ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns a newly allocated string.
5620ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */
5621ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlChar *
5622ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathCastNodeSetToString (xmlNodeSetPtr ns) {
5623ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    if ((ns == NULL) || (ns->nodeNr == 0) || (ns->nodeTab == NULL))
5624ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	return(xmlStrdup((const xmlChar *) ""));
5625ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
562664f7e1a85fe9c973cf9b21cc0bd53efa6cc3dafcKasimier T. Buchcik    if (ns->nodeNr > 1)
562764f7e1a85fe9c973cf9b21cc0bd53efa6cc3dafcKasimier T. Buchcik	xmlXPathNodeSetSort(ns);
5628ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    return(xmlXPathCastNodeToString(ns->nodeTab[0]));
5629ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard}
5630ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
5631ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/**
5632ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathCastToString:
5633ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @val:  an XPath object
5634ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
5635ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts an existing object to its string() equivalent
5636ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
563750128ad7cc312ad559801bbc7121201c1018857aKasimier T. Buchcik * Returns the allocated string value of the object, NULL in case of error.
563845490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *         It's up to the caller to free the string memory with xmlFree().
5639ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */
5640ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlChar *
5641ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathCastToString(xmlXPathObjectPtr val) {
5642ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    xmlChar *ret = NULL;
5643ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
5644ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    if (val == NULL)
5645ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	return(xmlStrdup((const xmlChar *) ""));
5646ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    switch (val->type) {
5647ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	case XPATH_UNDEFINED:
5648ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard#ifdef DEBUG_EXPR
5649ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	    xmlGenericError(xmlGenericErrorContext, "String: undefined\n");
5650ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard#endif
5651ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	    ret = xmlStrdup((const xmlChar *) "");
5652ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	    break;
5653ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard        case XPATH_NODESET:
56540c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack        case XPATH_XSLT_TREE:
5655ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	    ret = xmlXPathCastNodeSetToString(val->nodesetval);
5656ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	    break;
5657ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	case XPATH_STRING:
56584e2df54bb17645ef0d3f28b9665b2d2dde4b47a3Daniel Veillard	    return(xmlStrdup(val->stringval));
5659ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard        case XPATH_BOOLEAN:
5660ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	    ret = xmlXPathCastBooleanToString(val->boolval);
5661ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	    break;
5662ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	case XPATH_NUMBER: {
5663ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	    ret = xmlXPathCastNumberToString(val->floatval);
5664ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	    break;
5665ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	}
5666ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	case XPATH_USERS:
5667ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	case XPATH_POINT:
5668ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	case XPATH_RANGE:
5669ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	case XPATH_LOCATIONSET:
5670ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	    TODO
5671ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	    ret = xmlStrdup((const xmlChar *) "");
5672ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	    break;
5673ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    }
5674ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    return(ret);
5675ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard}
5676ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
5677ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/**
5678ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathConvertString:
5679ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @val:  an XPath object
5680ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
5681ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts an existing object to its string() equivalent
5682ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
5683ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns the new object, the old one is freed (or the operation
5684ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *         is done directly on @val)
5685ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */
5686ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathObjectPtr
5687ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathConvertString(xmlXPathObjectPtr val) {
5688ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    xmlChar *res = NULL;
5689ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
5690ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    if (val == NULL)
5691ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	return(xmlXPathNewCString(""));
5692ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
5693ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    switch (val->type) {
5694ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    case XPATH_UNDEFINED:
5695ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard#ifdef DEBUG_EXPR
5696ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	xmlGenericError(xmlGenericErrorContext, "STRING: undefined\n");
5697ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard#endif
5698ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	break;
5699ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    case XPATH_NODESET:
57000c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack    case XPATH_XSLT_TREE:
5701ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	res = xmlXPathCastNodeSetToString(val->nodesetval);
5702ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	break;
5703ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    case XPATH_STRING:
5704ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	return(val);
5705ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    case XPATH_BOOLEAN:
5706ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	res = xmlXPathCastBooleanToString(val->boolval);
5707ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	break;
5708ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    case XPATH_NUMBER:
5709ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	res = xmlXPathCastNumberToString(val->floatval);
5710ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	break;
5711ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    case XPATH_USERS:
5712ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    case XPATH_POINT:
5713ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    case XPATH_RANGE:
5714ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    case XPATH_LOCATIONSET:
5715ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	TODO;
5716ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	break;
5717ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    }
5718ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    xmlXPathFreeObject(val);
5719ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    if (res == NULL)
5720ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	return(xmlXPathNewCString(""));
5721ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    return(xmlXPathWrapString(res));
5722ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard}
5723ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
5724ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/**
5725ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathCastBooleanToNumber:
5726ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @val:  a boolean
5727ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
5728ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts a boolean to its number value
5729ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
5730ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns the number value
5731ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */
5732ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillarddouble
5733ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathCastBooleanToNumber(int val) {
5734ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    if (val)
5735ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	return(1.0);
5736ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    return(0.0);
5737ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard}
5738ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
5739ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/**
5740ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathCastStringToNumber:
5741ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @val:  a string
5742ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
5743ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts a string to its number value
5744ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
5745ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns the number value
5746ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */
5747ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillarddouble
5748ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathCastStringToNumber(const xmlChar * val) {
5749ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    return(xmlXPathStringEvalNumber(val));
5750ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard}
5751ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
5752ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/**
5753ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathCastNodeToNumber:
5754ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @node:  a node
5755ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
5756ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts a node to its number value
5757ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
5758ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns the number value
5759ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */
5760ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillarddouble
5761ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathCastNodeToNumber (xmlNodePtr node) {
5762ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    xmlChar *strval;
5763ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    double ret;
5764ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
5765ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    if (node == NULL)
5766ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	return(xmlXPathNAN);
5767ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    strval = xmlXPathCastNodeToString(node);
5768ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    if (strval == NULL)
5769ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	return(xmlXPathNAN);
5770ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    ret = xmlXPathCastStringToNumber(strval);
5771ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    xmlFree(strval);
5772ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
5773ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    return(ret);
5774ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard}
5775ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
5776ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/**
5777ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathCastNodeSetToNumber:
5778ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @ns:  a node-set
5779ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
5780ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts a node-set to its number value
5781ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
5782ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns the number value
5783ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */
5784ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillarddouble
5785ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathCastNodeSetToNumber (xmlNodeSetPtr ns) {
5786ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    xmlChar *str;
5787ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    double ret;
5788ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
5789ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    if (ns == NULL)
5790ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	return(xmlXPathNAN);
5791ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    str = xmlXPathCastNodeSetToString(ns);
5792ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    ret = xmlXPathCastStringToNumber(str);
5793ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    xmlFree(str);
5794ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    return(ret);
5795ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard}
5796ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
5797ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/**
5798ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathCastToNumber:
5799ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @val:  an XPath object
5800ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
5801ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts an XPath object to its number value
5802ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
5803ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns the number value
5804ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */
5805ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillarddouble
5806ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathCastToNumber(xmlXPathObjectPtr val) {
5807ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    double ret = 0.0;
5808ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
5809ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    if (val == NULL)
5810ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	return(xmlXPathNAN);
5811ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    switch (val->type) {
5812ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    case XPATH_UNDEFINED:
5813ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard#ifdef DEGUB_EXPR
5814ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	xmlGenericError(xmlGenericErrorContext, "NUMBER: undefined\n");
5815ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard#endif
5816ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	ret = xmlXPathNAN;
5817ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	break;
5818ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    case XPATH_NODESET:
58190c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack    case XPATH_XSLT_TREE:
5820ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	ret = xmlXPathCastNodeSetToNumber(val->nodesetval);
5821ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	break;
5822ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    case XPATH_STRING:
5823ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	ret = xmlXPathCastStringToNumber(val->stringval);
5824ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	break;
5825ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    case XPATH_NUMBER:
5826ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	ret = val->floatval;
5827ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	break;
5828ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    case XPATH_BOOLEAN:
5829ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	ret = xmlXPathCastBooleanToNumber(val->boolval);
5830ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	break;
5831ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    case XPATH_USERS:
5832ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    case XPATH_POINT:
5833ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    case XPATH_RANGE:
5834ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    case XPATH_LOCATIONSET:
5835ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	TODO;
5836ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	ret = xmlXPathNAN;
5837ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	break;
5838ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    }
5839ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    return(ret);
5840ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard}
5841ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
5842ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/**
5843ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathConvertNumber:
5844ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @val:  an XPath object
5845ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
5846ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts an existing object to its number() equivalent
5847ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
5848ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns the new object, the old one is freed (or the operation
5849ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *         is done directly on @val)
5850ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */
5851ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathObjectPtr
5852ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathConvertNumber(xmlXPathObjectPtr val) {
5853ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    xmlXPathObjectPtr ret;
5854ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
5855ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    if (val == NULL)
5856ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	return(xmlXPathNewFloat(0.0));
5857ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    if (val->type == XPATH_NUMBER)
5858ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	return(val);
5859ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    ret = xmlXPathNewFloat(xmlXPathCastToNumber(val));
5860ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    xmlXPathFreeObject(val);
5861ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    return(ret);
5862ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard}
5863ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
5864ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/**
5865ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathCastNumberToBoolean:
5866ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @val:  a number
5867ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
5868ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts a number to its boolean value
5869ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
5870ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns the boolean value
5871ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */
5872ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillardint
5873ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathCastNumberToBoolean (double val) {
5874cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard     if (xmlXPathIsNaN(val) || (val == 0.0))
5875ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	 return(0);
5876ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard     return(1);
5877ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard}
5878ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
5879ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/**
5880ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathCastStringToBoolean:
5881ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @val:  a string
5882ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
5883ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts a string to its boolean value
5884ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
5885ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns the boolean value
5886ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */
5887ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillardint
5888ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathCastStringToBoolean (const xmlChar *val) {
5889ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    if ((val == NULL) || (xmlStrlen(val) == 0))
5890ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	return(0);
5891ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    return(1);
5892ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard}
5893ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
5894ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/**
5895ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathCastNodeSetToBoolean:
5896ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @ns:  a node-set
5897ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
5898ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts a node-set to its boolean value
5899ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
5900ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns the boolean value
5901ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */
5902ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillardint
5903ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathCastNodeSetToBoolean (xmlNodeSetPtr ns) {
5904ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    if ((ns == NULL) || (ns->nodeNr == 0))
5905ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	return(0);
5906ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    return(1);
5907ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard}
5908ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
5909ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/**
59105e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard * xmlXPathCastToBoolean:
5911ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @val:  an XPath object
5912ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
5913ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts an XPath object to its boolean value
5914ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
5915ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns the boolean value
5916ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */
5917ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillardint
5918ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathCastToBoolean (xmlXPathObjectPtr val) {
5919ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    int ret = 0;
5920ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
5921ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    if (val == NULL)
5922ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	return(0);
5923ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    switch (val->type) {
5924ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    case XPATH_UNDEFINED:
5925ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard#ifdef DEBUG_EXPR
5926ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	xmlGenericError(xmlGenericErrorContext, "BOOLEAN: undefined\n");
5927ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard#endif
5928ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	ret = 0;
5929ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	break;
5930ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    case XPATH_NODESET:
59310c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack    case XPATH_XSLT_TREE:
5932ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	ret = xmlXPathCastNodeSetToBoolean(val->nodesetval);
5933ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	break;
5934ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    case XPATH_STRING:
5935ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	ret = xmlXPathCastStringToBoolean(val->stringval);
5936ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	break;
5937ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    case XPATH_NUMBER:
5938ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	ret = xmlXPathCastNumberToBoolean(val->floatval);
5939ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	break;
5940ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    case XPATH_BOOLEAN:
5941ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	ret = val->boolval;
5942ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	break;
5943ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    case XPATH_USERS:
5944ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    case XPATH_POINT:
5945ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    case XPATH_RANGE:
5946ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    case XPATH_LOCATIONSET:
5947ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	TODO;
5948ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	ret = 0;
5949ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	break;
5950ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    }
5951ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    return(ret);
5952ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard}
5953ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
5954ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
5955ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/**
5956ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathConvertBoolean:
5957ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @val:  an XPath object
5958ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
5959ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts an existing object to its boolean() equivalent
5960ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
5961ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns the new object, the old one is freed (or the operation
5962ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *         is done directly on @val)
5963ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */
5964ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathObjectPtr
5965ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathConvertBoolean(xmlXPathObjectPtr val) {
5966ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    xmlXPathObjectPtr ret;
5967ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
5968ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    if (val == NULL)
5969ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	return(xmlXPathNewBoolean(0));
5970ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    if (val->type == XPATH_BOOLEAN)
5971ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	return(val);
5972ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    ret = xmlXPathNewBoolean(xmlXPathCastToBoolean(val));
5973ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    xmlXPathFreeObject(val);
5974ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    return(ret);
5975ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard}
5976ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
59773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/************************************************************************
59783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *									*
59793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *		Routines to handle XPath contexts			*
59803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *									*
59813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ************************************************************************/
59823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
59833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
59843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNewContext:
59853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @doc:  the XML document
59863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
59873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Create a new xmlXPathContext
59883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
5989af43f63aaabf0dc4b4a070773875d0927da3d8a2Daniel Veillard * Returns the xmlXPathContext just allocated. The caller will need to free it.
59903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
59913473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathContextPtr
59923473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNewContext(xmlDocPtr doc) {
59933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathContextPtr ret;
59943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
59953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret = (xmlXPathContextPtr) xmlMalloc(sizeof(xmlXPathContext));
59963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ret == NULL) {
5997d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard        xmlXPathErrMemory(NULL, "creating context\n");
59983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(NULL);
59993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
60003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    memset(ret, 0 , (size_t) sizeof(xmlXPathContext));
60013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret->doc = doc;
60023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret->node = NULL;
60033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
60043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret->varHash = NULL;
60053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
60063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret->nb_types = 0;
60073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret->max_types = 0;
60083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret->types = NULL;
60093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
60103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret->funcHash = xmlHashCreate(0);
60113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
60123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret->nb_axis = 0;
60133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret->max_axis = 0;
60143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret->axis = NULL;
60153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
60163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret->nsHash = NULL;
60173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret->user = NULL;
60183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
60193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret->contextSize = -1;
60203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret->proximityPosition = -1;
60213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
6022a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#ifdef XP_DEFAULT_CACHE_ON
60235869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik    if (xmlXPathContextSetCache(ret, 1, -1, 0) == -1) {
6024a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	xmlXPathFreeContext(ret);
6025a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	return(NULL);
6026a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    }
6027a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#endif
6028a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
602945490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard    xmlXPathRegisterAllFunctions(ret);
6030a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
60313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(ret);
60323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
60333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
60343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
60353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathFreeContext:
60363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the context to free
60373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
60383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Free up an xmlXPathContext
60393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
60403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
60413473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathFreeContext(xmlXPathContextPtr ctxt) {
60427eca35fbaef6bd06074c4b978d381303609fcb0bDaniel Veillard    if (ctxt == NULL) return;
60437eca35fbaef6bd06074c4b978d381303609fcb0bDaniel Veillard
60445869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik    if (ctxt->cache != NULL)
60455869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik	xmlXPathFreeCache((xmlXPathContextCachePtr) ctxt->cache);
60463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathRegisteredNsCleanup(ctxt);
60473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathRegisteredFuncsCleanup(ctxt);
60483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathRegisteredVariablesCleanup(ctxt);
60497eca35fbaef6bd06074c4b978d381303609fcb0bDaniel Veillard    xmlResetError(&ctxt->lastError);
60503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlFree(ctxt);
60513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
60523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
60533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/************************************************************************
60543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *									*
60553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *		Routines to handle XPath parser contexts		*
60563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *									*
60573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ************************************************************************/
60583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
60593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define CHECK_CTXT(ctxt)						\
606045490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard    if (ctxt == NULL) {						\
6061f13f77f0e6a7876063d5fba15c096befb0827cedWilliam M. Brack	__xmlRaiseError(NULL, NULL, NULL,				\
6062f13f77f0e6a7876063d5fba15c096befb0827cedWilliam M. Brack		NULL, NULL, XML_FROM_XPATH,				\
6063f13f77f0e6a7876063d5fba15c096befb0827cedWilliam M. Brack		XML_ERR_INTERNAL_ERROR, XML_ERR_FATAL,			\
6064f13f77f0e6a7876063d5fba15c096befb0827cedWilliam M. Brack		__FILE__, __LINE__,					\
6065f13f77f0e6a7876063d5fba15c096befb0827cedWilliam M. Brack		NULL, NULL, NULL, 0, 0,					\
6066f13f77f0e6a7876063d5fba15c096befb0827cedWilliam M. Brack		"NULL context pointer\n");				\
6067f13f77f0e6a7876063d5fba15c096befb0827cedWilliam M. Brack	return(NULL);							\
60683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }									\
60693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
6070631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik#define CHECK_CTXT_NEG(ctxt)						\
607145490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard    if (ctxt == NULL) {						\
6072631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	__xmlRaiseError(NULL, NULL, NULL,				\
6073631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik		NULL, NULL, XML_FROM_XPATH,				\
6074631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik		XML_ERR_INTERNAL_ERROR, XML_ERR_FATAL,			\
6075631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik		__FILE__, __LINE__,					\
6076631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik		NULL, NULL, NULL, 0, 0,					\
6077631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik		"NULL context pointer\n");				\
6078631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	return(-1);							\
6079631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik    }									\
6080631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik
60813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
60823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define CHECK_CONTEXT(ctxt)						\
608357b2516af5e2e06c54750b6549723cf5b8edf8a4Daniel Veillard    if ((ctxt == NULL) || (ctxt->doc == NULL) ||			\
608445490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard        (ctxt->doc->children == NULL)) {				\
608557b2516af5e2e06c54750b6549723cf5b8edf8a4Daniel Veillard	xmlXPatherror(ctxt, __FILE__, __LINE__, XPATH_INVALID_CTXT);	\
6086ce682bc24b79f1dd29b781d4c17f9bf169ce7e32Daniel Veillard	return(NULL);							\
608757b2516af5e2e06c54750b6549723cf5b8edf8a4Daniel Veillard    }
60883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
60893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
60903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
60913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNewParserContext:
60923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @str:  the XPath expression
60933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath context
60943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
60953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Create a new xmlXPathParserContext
60963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
60973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the xmlXPathParserContext just allocated.
60983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
60993473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathParserContextPtr
61003473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNewParserContext(const xmlChar *str, xmlXPathContextPtr ctxt) {
61013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathParserContextPtr ret;
61023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
61033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret = (xmlXPathParserContextPtr) xmlMalloc(sizeof(xmlXPathParserContext));
61043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ret == NULL) {
6105d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard        xmlXPathErrMemory(ctxt, "creating parser context\n");
61063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(NULL);
61073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
61083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    memset(ret, 0 , (size_t) sizeof(xmlXPathParserContext));
61093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret->cur = ret->base = str;
61103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret->context = ctxt;
61113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
61129e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    ret->comp = xmlXPathNewCompExpr();
61139e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    if (ret->comp == NULL) {
61149e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	xmlFree(ret->valueTab);
61159e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	xmlFree(ret);
61169e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	return(NULL);
61179e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    }
61184773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard    if ((ctxt != NULL) && (ctxt->dict != NULL)) {
61194773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard        ret->comp->dict = ctxt->dict;
61204773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard	xmlDictReference(ret->comp->dict);
61214773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard    }
61229e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
61239e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    return(ret);
61249e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard}
61259e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
61269e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard/**
61279e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * xmlXPathCompParserContext:
61289e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * @comp:  the XPath compiled expression
61299e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * @ctxt:  the XPath context
61309e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard *
61319e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * Create a new xmlXPathParserContext when processing a compiled expression
61329e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard *
61339e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * Returns the xmlXPathParserContext just allocated.
61349e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard */
613556a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic xmlXPathParserContextPtr
61369e7160d45a18bfa26d708e22ba991f7670d0128bDaniel VeillardxmlXPathCompParserContext(xmlXPathCompExprPtr comp, xmlXPathContextPtr ctxt) {
61379e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    xmlXPathParserContextPtr ret;
61389e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
61399e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    ret = (xmlXPathParserContextPtr) xmlMalloc(sizeof(xmlXPathParserContext));
61409e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    if (ret == NULL) {
6141d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard        xmlXPathErrMemory(ctxt, "creating evaluation context\n");
61429e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	return(NULL);
61439e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    }
61449e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    memset(ret, 0 , (size_t) sizeof(xmlXPathParserContext));
61459e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
61463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    /* Allocate the value stack */
614745490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard    ret->valueTab = (xmlXPathObjectPtr *)
61483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor                     xmlMalloc(10 * sizeof(xmlXPathObjectPtr));
61499e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    if (ret->valueTab == NULL) {
61509e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	xmlFree(ret);
6151d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard	xmlXPathErrMemory(ctxt, "creating evaluation context\n");
61529e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	return(NULL);
61539e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    }
61543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret->valueNr = 0;
61553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret->valueMax = 10;
61563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret->value = NULL;
61579e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
6158fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard    ret->context = ctxt;
61599e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    ret->comp = comp;
61609e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
61613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(ret);
61623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
61633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
61643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
61653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathFreeParserContext:
61663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the context to free
61673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
61683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Free up an xmlXPathParserContext
61693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
61703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
61713473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathFreeParserContext(xmlXPathParserContextPtr ctxt) {
61723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ctxt->valueTab != NULL) {
61733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        xmlFree(ctxt->valueTab);
61743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
617556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard    if (ctxt->comp != NULL) {
617656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard#ifdef XPATH_STREAMING
617756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	if (ctxt->comp->stream != NULL) {
617856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	    xmlFreePatternList(ctxt->comp->stream);
617956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	    ctxt->comp->stream = NULL;
618056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	}
618156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard#endif
61829e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	xmlXPathFreeCompExpr(ctxt->comp);
618356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard    }
61843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlFree(ctxt);
61853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
61863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
61873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/************************************************************************
61883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *									*
61893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *		The implicit core function library			*
61903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *									*
61913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ************************************************************************/
61923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
61933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
619401c13b5be2d249ef66d86585adee87901bb8efa2Daniel Veillard * xmlXPathNodeValHash:
6195f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * @node:  a node pointer
6196f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard *
6197f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Function computing the beginning of the string value of the node,
6198f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * used to speed up comparisons
6199f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard *
6200f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Returns an int usable as a hash
6201f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */
6202f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillardstatic unsigned int
6203f06307e2c172284bb41376c396f757bdac9bdd19Daniel VeillardxmlXPathNodeValHash(xmlNodePtr node) {
6204f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    int len = 2;
6205f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    const xmlChar * string = NULL;
6206f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    xmlNodePtr tmp = NULL;
6207f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    unsigned int ret = 0;
6208f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
6209f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    if (node == NULL)
6210f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	return(0);
6211f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
62129adc0469d4691e798ea4ad59b84c874cdea8b38dDaniel Veillard    if (node->type == XML_DOCUMENT_NODE) {
62139adc0469d4691e798ea4ad59b84c874cdea8b38dDaniel Veillard	tmp = xmlDocGetRootElement((xmlDocPtr) node);
62149adc0469d4691e798ea4ad59b84c874cdea8b38dDaniel Veillard	if (tmp == NULL)
62159adc0469d4691e798ea4ad59b84c874cdea8b38dDaniel Veillard	    node = node->children;
62169adc0469d4691e798ea4ad59b84c874cdea8b38dDaniel Veillard	else
62179adc0469d4691e798ea4ad59b84c874cdea8b38dDaniel Veillard	    node = tmp;
62189adc0469d4691e798ea4ad59b84c874cdea8b38dDaniel Veillard
62199adc0469d4691e798ea4ad59b84c874cdea8b38dDaniel Veillard	if (node == NULL)
62209adc0469d4691e798ea4ad59b84c874cdea8b38dDaniel Veillard	    return(0);
62219adc0469d4691e798ea4ad59b84c874cdea8b38dDaniel Veillard    }
6222f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
6223f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    switch (node->type) {
6224f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	case XML_COMMENT_NODE:
6225f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	case XML_PI_NODE:
6226f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	case XML_CDATA_SECTION_NODE:
6227f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	case XML_TEXT_NODE:
6228f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	    string = node->content;
6229f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	    if (string == NULL)
6230f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard		return(0);
6231f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	    if (string[0] == 0)
6232f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard		return(0);
6233f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	    return(((unsigned int) string[0]) +
6234f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard		   (((unsigned int) string[1]) << 8));
6235f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	case XML_NAMESPACE_DECL:
6236f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	    string = ((xmlNsPtr)node)->href;
6237f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	    if (string == NULL)
6238f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard		return(0);
6239f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	    if (string[0] == 0)
6240f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard		return(0);
6241f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	    return(((unsigned int) string[0]) +
6242f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard		   (((unsigned int) string[1]) << 8));
6243f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	case XML_ATTRIBUTE_NODE:
6244f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	    tmp = ((xmlAttrPtr) node)->children;
6245f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	    break;
6246f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	case XML_ELEMENT_NODE:
6247f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	    tmp = node->children;
6248f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	    break;
6249f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	default:
6250f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	    return(0);
6251f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    }
6252f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    while (tmp != NULL) {
6253f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	switch (tmp->type) {
6254f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	    case XML_COMMENT_NODE:
6255f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	    case XML_PI_NODE:
6256f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	    case XML_CDATA_SECTION_NODE:
6257f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	    case XML_TEXT_NODE:
6258f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard		string = tmp->content;
6259f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard		break;
6260f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	    case XML_NAMESPACE_DECL:
6261f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard		string = ((xmlNsPtr)tmp)->href;
6262f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard		break;
6263f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	    default:
6264f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard		break;
6265f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	}
6266f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	if ((string != NULL) && (string[0] != 0)) {
6267f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	    if (len == 1) {
6268f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard		return(ret + (((unsigned int) string[0]) << 8));
6269f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	    }
6270f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	    if (string[1] == 0) {
6271f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard		len = 1;
6272f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard		ret = (unsigned int) string[0];
6273f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	    } else {
6274f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard		return(((unsigned int) string[0]) +
6275f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard		       (((unsigned int) string[1]) << 8));
6276f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	    }
6277f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	}
6278f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	/*
6279f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	 * Skip to next node
6280f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	 */
6281f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	if ((tmp->children != NULL) && (tmp->type != XML_DTD_NODE)) {
6282f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	    if (tmp->children->type != XML_ENTITY_DECL) {
6283f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard		tmp = tmp->children;
6284f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard		continue;
6285f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	    }
6286f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	}
6287f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	if (tmp == node)
6288f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	    break;
6289f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
6290f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	if (tmp->next != NULL) {
6291f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	    tmp = tmp->next;
6292f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	    continue;
6293f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	}
629445490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
6295f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	do {
6296f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	    tmp = tmp->parent;
6297f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	    if (tmp == NULL)
6298f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard		break;
6299f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	    if (tmp == node) {
6300f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard		tmp = NULL;
6301f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard		break;
6302f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	    }
6303f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	    if (tmp->next != NULL) {
6304f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard		tmp = tmp->next;
6305f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard		break;
6306f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	    }
6307f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	} while (tmp != NULL);
6308f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    }
6309f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    return(ret);
6310f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard}
6311f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
6312f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard/**
6313f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * xmlXPathStringHash:
6314f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * @string:  a string
6315f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard *
6316f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Function computing the beginning of the string value of the node,
6317f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * used to speed up comparisons
6318f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard *
6319f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Returns an int usable as a hash
6320f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */
6321f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillardstatic unsigned int
6322f06307e2c172284bb41376c396f757bdac9bdd19Daniel VeillardxmlXPathStringHash(const xmlChar * string) {
6323f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    if (string == NULL)
6324f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	return((unsigned int) 0);
6325f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    if (string[0] == 0)
6326f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	return(0);
6327f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    return(((unsigned int) string[0]) +
6328f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	   (((unsigned int) string[1]) << 8));
6329f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard}
6330f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
6331f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard/**
63323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathCompareNodeSetFloat:
63333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
63343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @inf:  less than (1) or greater than (0)
63353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @strict:  is the comparison strict
63363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @arg:  the node set
63373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @f:  the value
63383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
63393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the compare operation between a nodeset and a number
63403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *     @ns < @val    (1, 1, ...
63413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *     @ns <= @val   (1, 0, ...
63423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *     @ns > @val    (0, 1, ...
63433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *     @ns >= @val   (0, 0, ...
63443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
63453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * If one object to be compared is a node-set and the other is a number,
63463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * then the comparison will be true if and only if there is a node in the
63473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * node-set such that the result of performing the comparison on the number
63483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * to be compared and on the result of converting the string-value of that
63493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * node to a number using the number function is true.
63503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
63513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns 0 or 1 depending on the results of the test.
63523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
635356a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic int
63543473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathCompareNodeSetFloat(xmlXPathParserContextPtr ctxt, int inf, int strict,
63553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	                    xmlXPathObjectPtr arg, xmlXPathObjectPtr f) {
63563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    int i, ret = 0;
63573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlNodeSetPtr ns;
63583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlChar *str2;
63593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
63603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if ((f == NULL) || (arg == NULL) ||
63613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	((arg->type != XPATH_NODESET) && (arg->type != XPATH_XSLT_TREE))) {
6362a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	xmlXPathReleaseObject(ctxt->context, arg);
6363a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	xmlXPathReleaseObject(ctxt->context, f);
63643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        return(0);
63653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
63663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ns = arg->nodesetval;
6367911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard    if (ns != NULL) {
6368911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard	for (i = 0;i < ns->nodeNr;i++) {
6369ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	     str2 = xmlXPathCastNodeToString(ns->nodeTab[i]);
6370911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard	     if (str2 != NULL) {
6371911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard		 valuePush(ctxt,
6372a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik			   xmlXPathCacheNewString(ctxt->context, str2));
6373911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard		 xmlFree(str2);
6374911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard		 xmlXPathNumberFunction(ctxt, 1);
6375a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		 valuePush(ctxt, xmlXPathCacheObjectCopy(ctxt->context, f));
6376911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard		 ret = xmlXPathCompareValues(ctxt, inf, strict);
6377911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard		 if (ret)
6378911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard		     break;
6379911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard	     }
6380911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard	}
63813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
6382a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathReleaseObject(ctxt->context, arg);
6383a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathReleaseObject(ctxt->context, f);
63843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(ret);
63853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
63863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
63873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
63883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathCompareNodeSetString:
63893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
63903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @inf:  less than (1) or greater than (0)
63913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @strict:  is the comparison strict
63923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @arg:  the node set
63933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @s:  the value
63943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
63953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the compare operation between a nodeset and a string
63963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *     @ns < @val    (1, 1, ...
63973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *     @ns <= @val   (1, 0, ...
63983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *     @ns > @val    (0, 1, ...
63993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *     @ns >= @val   (0, 0, ...
64003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
64013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * If one object to be compared is a node-set and the other is a string,
64023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * then the comparison will be true if and only if there is a node in
64033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the node-set such that the result of performing the comparison on the
64043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * string-value of the node and the other string is true.
64053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
64063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns 0 or 1 depending on the results of the test.
64073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
640856a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic int
64093473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathCompareNodeSetString(xmlXPathParserContextPtr ctxt, int inf, int strict,
64103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	                    xmlXPathObjectPtr arg, xmlXPathObjectPtr s) {
64113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    int i, ret = 0;
64123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlNodeSetPtr ns;
64133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlChar *str2;
64143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
64153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if ((s == NULL) || (arg == NULL) ||
64163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	((arg->type != XPATH_NODESET) && (arg->type != XPATH_XSLT_TREE))) {
6417a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	xmlXPathReleaseObject(ctxt->context, arg);
6418a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	xmlXPathReleaseObject(ctxt->context, s);
64193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        return(0);
64203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
64213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ns = arg->nodesetval;
6422911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard    if (ns != NULL) {
6423911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard	for (i = 0;i < ns->nodeNr;i++) {
6424ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	     str2 = xmlXPathCastNodeToString(ns->nodeTab[i]);
6425911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard	     if (str2 != NULL) {
6426911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard		 valuePush(ctxt,
6427a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik			   xmlXPathCacheNewString(ctxt->context, str2));
6428911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard		 xmlFree(str2);
6429a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		 valuePush(ctxt, xmlXPathCacheObjectCopy(ctxt->context, s));
6430911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard		 ret = xmlXPathCompareValues(ctxt, inf, strict);
6431911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard		 if (ret)
6432911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard		     break;
6433911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard	     }
6434911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard	}
64353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
6436a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathReleaseObject(ctxt->context, arg);
6437a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathReleaseObject(ctxt->context, s);
64383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(ret);
64393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
64403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
64413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
64423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathCompareNodeSets:
6443ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @inf:  less than (1) or greater than (0)
64443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @strict:  is the comparison strict
6445cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * @arg1:  the first node set object
64463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @arg2:  the second node set object
64473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
64483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the compare operation on nodesets:
64493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
64503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * If both objects to be compared are node-sets, then the comparison
64513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * will be true if and only if there is a node in the first node-set
64523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * and a node in the second node-set such that the result of performing
645345490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard * the comparison on the string-values of the two nodes is true.
64543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * ....
64553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * When neither object to be compared is a node-set and the operator
64563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * is <=, <, >= or >, then the objects are compared by converting both
64573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * objects to numbers and comparing the numbers according to IEEE 754.
64583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * ....
64593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The number function converts its argument to a number as follows:
64603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *  - a string that consists of optional whitespace followed by an
64613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *    optional minus sign followed by a Number followed by whitespace
64623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *    is converted to the IEEE 754 number that is nearest (according
64633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *    to the IEEE 754 round-to-nearest rule) to the mathematical value
64643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *    represented by the string; any other string is converted to NaN
64653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
64663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Conclusion all nodes need to be converted first to their string value
646745490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard * and then the comparison must be done when possible
64683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
646956a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic int
647056a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel VeillardxmlXPathCompareNodeSets(int inf, int strict,
64713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	                xmlXPathObjectPtr arg1, xmlXPathObjectPtr arg2) {
64723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    int i, j, init = 0;
64733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    double val1;
64743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    double *values2;
64753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    int ret = 0;
64763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlNodeSetPtr ns1;
64773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlNodeSetPtr ns2;
64783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
64793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if ((arg1 == NULL) ||
64804dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard	((arg1->type != XPATH_NODESET) && (arg1->type != XPATH_XSLT_TREE))) {
64814dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard	xmlXPathFreeObject(arg2);
64823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        return(0);
64834dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard    }
64843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if ((arg2 == NULL) ||
64854dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard	((arg2->type != XPATH_NODESET) && (arg2->type != XPATH_XSLT_TREE))) {
64864dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard	xmlXPathFreeObject(arg1);
64874dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard	xmlXPathFreeObject(arg2);
64883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        return(0);
64894dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard    }
64903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
64913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ns1 = arg1->nodesetval;
64923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ns2 = arg2->nodesetval;
64933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
6494d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard    if ((ns1 == NULL) || (ns1->nodeNr <= 0)) {
64954dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard	xmlXPathFreeObject(arg1);
64964dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard	xmlXPathFreeObject(arg2);
64973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(0);
64984dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard    }
6499d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard    if ((ns2 == NULL) || (ns2->nodeNr <= 0)) {
65004dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard	xmlXPathFreeObject(arg1);
65014dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard	xmlXPathFreeObject(arg2);
65023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(0);
65034dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard    }
65043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
65053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    values2 = (double *) xmlMalloc(ns2->nodeNr * sizeof(double));
65063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (values2 == NULL) {
6507d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard        xmlXPathErrMemory(NULL, "comparing nodesets\n");
65084dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard	xmlXPathFreeObject(arg1);
65094dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard	xmlXPathFreeObject(arg2);
65103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(0);
65113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
65123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    for (i = 0;i < ns1->nodeNr;i++) {
6513ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	val1 = xmlXPathCastNodeToNumber(ns1->nodeTab[i]);
6514cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard	if (xmlXPathIsNaN(val1))
65153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    continue;
65163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	for (j = 0;j < ns2->nodeNr;j++) {
65173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    if (init == 0) {
6518ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard		values2[j] = xmlXPathCastNodeToNumber(ns2->nodeTab[j]);
65193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    }
6520cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard	    if (xmlXPathIsNaN(values2[j]))
65213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		continue;
652245490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	    if (inf && strict)
65233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		ret = (val1 < values2[j]);
65243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    else if (inf && !strict)
65253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		ret = (val1 <= values2[j]);
65263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    else if (!inf && strict)
65273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		ret = (val1 > values2[j]);
65283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    else if (!inf && !strict)
65293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		ret = (val1 >= values2[j]);
65303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    if (ret)
65313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		break;
65323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
65333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (ret)
65343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    break;
65353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	init = 1;
65363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
65373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlFree(values2);
65384dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard    xmlXPathFreeObject(arg1);
65394dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard    xmlXPathFreeObject(arg2);
65403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(ret);
65413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
65423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
65433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
65443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathCompareNodeSetValue:
65453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
65463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @inf:  less than (1) or greater than (0)
65473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @strict:  is the comparison strict
65483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @arg:  the node set
65493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val:  the value
65503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
65513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the compare operation between a nodeset and a value
65523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *     @ns < @val    (1, 1, ...
65533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *     @ns <= @val   (1, 0, ...
65543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *     @ns > @val    (0, 1, ...
65553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *     @ns >= @val   (0, 0, ...
65563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
65573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * If one object to be compared is a node-set and the other is a boolean,
65583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * then the comparison will be true if and only if the result of performing
65593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the comparison on the boolean and on the result of converting
65603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the node-set to a boolean using the boolean function is true.
65613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
65623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns 0 or 1 depending on the results of the test.
65633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
656456a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic int
65653473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathCompareNodeSetValue(xmlXPathParserContextPtr ctxt, int inf, int strict,
65663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	                    xmlXPathObjectPtr arg, xmlXPathObjectPtr val) {
65673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if ((val == NULL) || (arg == NULL) ||
65683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	((arg->type != XPATH_NODESET) && (arg->type != XPATH_XSLT_TREE)))
65693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        return(0);
65703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
65713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    switch(val->type) {
65723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        case XPATH_NUMBER:
65733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    return(xmlXPathCompareNodeSetFloat(ctxt, inf, strict, arg, val));
65743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        case XPATH_NODESET:
65753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        case XPATH_XSLT_TREE:
657656a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillard	    return(xmlXPathCompareNodeSets(inf, strict, arg, val));
65773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        case XPATH_STRING:
65783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    return(xmlXPathCompareNodeSetString(ctxt, inf, strict, arg, val));
65793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        case XPATH_BOOLEAN:
65803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    valuePush(ctxt, arg);
65813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    xmlXPathBooleanFunction(ctxt, 1);
65823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    valuePush(ctxt, val);
65833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    return(xmlXPathCompareValues(ctxt, inf, strict));
65843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	default:
65853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    TODO
65863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
65873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(0);
65883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
65893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
65903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
659101c13b5be2d249ef66d86585adee87901bb8efa2Daniel Veillard * xmlXPathEqualNodeSetString:
65923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @arg:  the nodeset object argument
65933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @str:  the string to compare to.
65940c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack * @neq:  flag to show whether for '=' (0) or '!=' (1)
65953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
65963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the equal operation on XPath objects content: @arg1 == @arg2
65973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * If one object to be compared is a node-set and the other is a string,
65983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * then the comparison will be true if and only if there is a node in
65993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the node-set such that the result of performing the comparison on the
66003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * string-value of the node and the other string is true.
66013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
66023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns 0 or 1 depending on the results of the test.
66033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
660456a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic int
66050c022ad8234a9228288c651f5e6a9bce7efcd789William M. BrackxmlXPathEqualNodeSetString(xmlXPathObjectPtr arg, const xmlChar * str, int neq)
6606f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard{
66073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    int i;
66083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlNodeSetPtr ns;
66093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlChar *str2;
6610f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    unsigned int hash;
66113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
66123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if ((str == NULL) || (arg == NULL) ||
6613f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        ((arg->type != XPATH_NODESET) && (arg->type != XPATH_XSLT_TREE)))
6614f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        return (0);
66153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ns = arg->nodesetval;
6616c125a721a4b7856f5356334137d467f95e6bf4b2William M. Brack    /*
6617c125a721a4b7856f5356334137d467f95e6bf4b2William M. Brack     * A NULL nodeset compared with a string is always false
6618c125a721a4b7856f5356334137d467f95e6bf4b2William M. Brack     * (since there is no node equal, and no node not equal)
6619c125a721a4b7856f5356334137d467f95e6bf4b2William M. Brack     */
6620c125a721a4b7856f5356334137d467f95e6bf4b2William M. Brack    if ((ns == NULL) || (ns->nodeNr <= 0) )
6621f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        return (0);
6622c125a721a4b7856f5356334137d467f95e6bf4b2William M. Brack    hash = xmlXPathStringHash(str);
6623f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    for (i = 0; i < ns->nodeNr; i++) {
6624f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        if (xmlXPathNodeValHash(ns->nodeTab[i]) == hash) {
6625f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            str2 = xmlNodeGetContent(ns->nodeTab[i]);
6626f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            if ((str2 != NULL) && (xmlStrEqual(str, str2))) {
6627f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                xmlFree(str2);
66280c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		if (neq)
66290c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		    continue;
6630f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                return (1);
66319adc0469d4691e798ea4ad59b84c874cdea8b38dDaniel Veillard	    } else if ((str2 == NULL) && (xmlStrEqual(str, BAD_CAST ""))) {
66329adc0469d4691e798ea4ad59b84c874cdea8b38dDaniel Veillard		if (neq)
66339adc0469d4691e798ea4ad59b84c874cdea8b38dDaniel Veillard		    continue;
66349adc0469d4691e798ea4ad59b84c874cdea8b38dDaniel Veillard                return (1);
66350c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack            } else if (neq) {
66360c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		if (str2 != NULL)
66370c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		    xmlFree(str2);
66380c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		return (1);
66390c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	    }
6640f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            if (str2 != NULL)
6641f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                xmlFree(str2);
66420c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack        } else if (neq)
66430c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	    return (1);
66443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
6645f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    return (0);
66463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
66473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
66483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
664901c13b5be2d249ef66d86585adee87901bb8efa2Daniel Veillard * xmlXPathEqualNodeSetFloat:
66503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @arg:  the nodeset object argument
66513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @f:  the float to compare to
66520c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack * @neq:  flag to show whether to compare '=' (0) or '!=' (1)
66533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
66543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the equal operation on XPath objects content: @arg1 == @arg2
66553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * If one object to be compared is a node-set and the other is a number,
66563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * then the comparison will be true if and only if there is a node in
66573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the node-set such that the result of performing the comparison on the
66583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * number to be compared and on the result of converting the string-value
66593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * of that node to a number using the number function is true.
66603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
66613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns 0 or 1 depending on the results of the test.
66623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
666356a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic int
66640c022ad8234a9228288c651f5e6a9bce7efcd789William M. BrackxmlXPathEqualNodeSetFloat(xmlXPathParserContextPtr ctxt,
66650c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack    xmlXPathObjectPtr arg, double f, int neq) {
66660c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack  int i, ret=0;
66670c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack  xmlNodeSetPtr ns;
66680c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack  xmlChar *str2;
66690c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack  xmlXPathObjectPtr val;
66700c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack  double v;
66713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
66723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if ((arg == NULL) ||
66733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	((arg->type != XPATH_NODESET) && (arg->type != XPATH_XSLT_TREE)))
66743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        return(0);
66753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
66760c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack    ns = arg->nodesetval;
66770c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack    if (ns != NULL) {
66780c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	for (i=0;i<ns->nodeNr;i++) {
66790c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	    str2 = xmlXPathCastNodeToString(ns->nodeTab[i]);
66800c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	    if (str2 != NULL) {
6681a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		valuePush(ctxt, xmlXPathCacheNewString(ctxt->context, str2));
66820c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		xmlFree(str2);
66830c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		xmlXPathNumberFunction(ctxt, 1);
66840c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		val = valuePop(ctxt);
66850c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		v = val->floatval;
6686a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		xmlXPathReleaseObject(ctxt->context, val);
66870c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		if (!xmlXPathIsNaN(v)) {
66880c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		    if ((!neq) && (v==f)) {
66890c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack			ret = 1;
66900c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack			break;
66910c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		    } else if ((neq) && (v!=f)) {
66920c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack			ret = 1;
66930c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack			break;
66940c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		    }
669532f0f717d1e7854d87e03b659e772fa48ec9f91aWilliam M. Brack		} else {	/* NaN is unequal to any value */
669632f0f717d1e7854d87e03b659e772fa48ec9f91aWilliam M. Brack		    if (neq)
669732f0f717d1e7854d87e03b659e772fa48ec9f91aWilliam M. Brack			ret = 1;
66980c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		}
66990c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	    }
67000c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	}
67010c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack    }
67020c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack
67030c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack    return(ret);
67043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
67053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
67063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
67073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
670801c13b5be2d249ef66d86585adee87901bb8efa2Daniel Veillard * xmlXPathEqualNodeSets:
67093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @arg1:  first nodeset object argument
67103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @arg2:  second nodeset object argument
67110c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack * @neq:   flag to show whether to test '=' (0) or '!=' (1)
67123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
67130c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack * Implement the equal / not equal operation on XPath nodesets:
67140c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack * @arg1 == @arg2  or  @arg1 != @arg2
67153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * If both objects to be compared are node-sets, then the comparison
67163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * will be true if and only if there is a node in the first node-set and
67173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * a node in the second node-set such that the result of performing the
67183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * comparison on the string-values of the two nodes is true.
67193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
67203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * (needless to say, this is a costly operation)
67213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
67223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns 0 or 1 depending on the results of the test.
67233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
672456a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic int
67250c022ad8234a9228288c651f5e6a9bce7efcd789William M. BrackxmlXPathEqualNodeSets(xmlXPathObjectPtr arg1, xmlXPathObjectPtr arg2, int neq) {
67263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    int i, j;
6727f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    unsigned int *hashs1;
6728f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    unsigned int *hashs2;
67293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlChar **values1;
67303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlChar **values2;
67313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    int ret = 0;
67323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlNodeSetPtr ns1;
67333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlNodeSetPtr ns2;
67343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
67353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if ((arg1 == NULL) ||
67363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	((arg1->type != XPATH_NODESET) && (arg1->type != XPATH_XSLT_TREE)))
67373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        return(0);
67383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if ((arg2 == NULL) ||
67393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	((arg2->type != XPATH_NODESET) && (arg2->type != XPATH_XSLT_TREE)))
67403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        return(0);
67413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
67423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ns1 = arg1->nodesetval;
67433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ns2 = arg2->nodesetval;
67443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
6745911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard    if ((ns1 == NULL) || (ns1->nodeNr <= 0))
67463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(0);
6747911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard    if ((ns2 == NULL) || (ns2->nodeNr <= 0))
67483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(0);
67493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
67503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    /*
67510c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack     * for equal, check if there is a node pertaining to both sets
67523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor     */
67530c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack    if (neq == 0)
67540c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	for (i = 0;i < ns1->nodeNr;i++)
67550c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	    for (j = 0;j < ns2->nodeNr;j++)
67560c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		if (ns1->nodeTab[i] == ns2->nodeTab[j])
67570c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		    return(1);
67583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
67593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    values1 = (xmlChar **) xmlMalloc(ns1->nodeNr * sizeof(xmlChar *));
6760d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard    if (values1 == NULL) {
6761d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard        xmlXPathErrMemory(NULL, "comparing nodesets\n");
67623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(0);
6763d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard    }
6764f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    hashs1 = (unsigned int *) xmlMalloc(ns1->nodeNr * sizeof(unsigned int));
6765f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    if (hashs1 == NULL) {
6766d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard        xmlXPathErrMemory(NULL, "comparing nodesets\n");
6767f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	xmlFree(values1);
6768f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	return(0);
6769f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    }
67703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    memset(values1, 0, ns1->nodeNr * sizeof(xmlChar *));
67713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    values2 = (xmlChar **) xmlMalloc(ns2->nodeNr * sizeof(xmlChar *));
67723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (values2 == NULL) {
6773d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard        xmlXPathErrMemory(NULL, "comparing nodesets\n");
6774f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	xmlFree(hashs1);
67753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	xmlFree(values1);
67763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(0);
67773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
6778f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    hashs2 = (unsigned int *) xmlMalloc(ns2->nodeNr * sizeof(unsigned int));
6779f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    if (hashs2 == NULL) {
6780d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard        xmlXPathErrMemory(NULL, "comparing nodesets\n");
6781f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	xmlFree(hashs1);
6782f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	xmlFree(values1);
6783f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	xmlFree(values2);
6784f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	return(0);
6785f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    }
67863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    memset(values2, 0, ns2->nodeNr * sizeof(xmlChar *));
67873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    for (i = 0;i < ns1->nodeNr;i++) {
6788f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	hashs1[i] = xmlXPathNodeValHash(ns1->nodeTab[i]);
67893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	for (j = 0;j < ns2->nodeNr;j++) {
67903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    if (i == 0)
6791f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard		hashs2[j] = xmlXPathNodeValHash(ns2->nodeTab[j]);
67920c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	    if (hashs1[i] != hashs2[j]) {
67930c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		if (neq) {
67940c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		    ret = 1;
67950c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		    break;
67960c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		}
67970c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	    }
67980c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	    else {
6799f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard		if (values1[i] == NULL)
6800f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard		    values1[i] = xmlNodeGetContent(ns1->nodeTab[i]);
6801f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard		if (values2[j] == NULL)
6802f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard		    values2[j] = xmlNodeGetContent(ns2->nodeTab[j]);
68030c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		ret = xmlStrEqual(values1[i], values2[j]) ^ neq;
6804f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard		if (ret)
6805f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard		    break;
6806f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	    }
68073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
68083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (ret)
68093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    break;
68103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
68113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    for (i = 0;i < ns1->nodeNr;i++)
68123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (values1[i] != NULL)
68133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    xmlFree(values1[i]);
68143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    for (j = 0;j < ns2->nodeNr;j++)
68153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (values2[j] != NULL)
68163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    xmlFree(values2[j]);
68173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlFree(values1);
68183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlFree(values2);
6819f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    xmlFree(hashs1);
6820f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    xmlFree(hashs2);
68213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(ret);
68223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
68233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
68240c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brackstatic int
68250c022ad8234a9228288c651f5e6a9bce7efcd789William M. BrackxmlXPathEqualValuesCommon(xmlXPathParserContextPtr ctxt,
68260c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack  xmlXPathObjectPtr arg1, xmlXPathObjectPtr arg2) {
68273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    int ret = 0;
68280c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack    /*
68290c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack     *At this point we are assured neither arg1 nor arg2
68300c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack     *is a nodeset, so we can just pick the appropriate routine.
68310c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack     */
68323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    switch (arg1->type) {
68333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        case XPATH_UNDEFINED:
68343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_EXPR
68353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    xmlGenericError(xmlGenericErrorContext,
68363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    "Equal: undefined\n");
68373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif
68383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    break;
68393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        case XPATH_BOOLEAN:
68403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    switch (arg2->type) {
68413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	        case XPATH_UNDEFINED:
68423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_EXPR
68433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    xmlGenericError(xmlGenericErrorContext,
68443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor			    "Equal: undefined\n");
68453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif
68463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    break;
68473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		case XPATH_BOOLEAN:
68483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_EXPR
68493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    xmlGenericError(xmlGenericErrorContext,
68503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor			    "Equal: %d boolean %d \n",
68513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor			    arg1->boolval, arg2->boolval);
68523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif
68533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    ret = (arg1->boolval == arg2->boolval);
68543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    break;
68553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		case XPATH_NUMBER:
6856ef61d208503e41688f4bf86f6e9023c70e65829bWilliam M. Brack		    ret = (arg1->boolval ==
6857ef61d208503e41688f4bf86f6e9023c70e65829bWilliam M. Brack			   xmlXPathCastNumberToBoolean(arg2->floatval));
68583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    break;
68593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		case XPATH_STRING:
68603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    if ((arg2->stringval == NULL) ||
68613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor			(arg2->stringval[0] == 0)) ret = 0;
686245490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard		    else
68633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor			ret = 1;
68643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    ret = (arg1->boolval == ret);
68653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    break;
68663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		case XPATH_USERS:
68673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		case XPATH_POINT:
68683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		case XPATH_RANGE:
68693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		case XPATH_LOCATIONSET:
68703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    TODO
68713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    break;
68720c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		case XPATH_NODESET:
68730c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		case XPATH_XSLT_TREE:
68740c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		    break;
68753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    }
68763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    break;
68773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        case XPATH_NUMBER:
68783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    switch (arg2->type) {
68793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	        case XPATH_UNDEFINED:
68803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_EXPR
68813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    xmlGenericError(xmlGenericErrorContext,
68823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor			    "Equal: undefined\n");
68833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif
68843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    break;
68853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		case XPATH_BOOLEAN:
6886ef61d208503e41688f4bf86f6e9023c70e65829bWilliam M. Brack		    ret = (arg2->boolval==
6887ef61d208503e41688f4bf86f6e9023c70e65829bWilliam M. Brack			   xmlXPathCastNumberToBoolean(arg1->floatval));
68883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    break;
68893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		case XPATH_STRING:
68903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    valuePush(ctxt, arg2);
68913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    xmlXPathNumberFunction(ctxt, 1);
68923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    arg2 = valuePop(ctxt);
68933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    /* no break on purpose */
68943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		case XPATH_NUMBER:
6895d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard		    /* Hand check NaN and Infinity equalities */
6896081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack		    if (xmlXPathIsNaN(arg1->floatval) ||
689745490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard			    xmlXPathIsNaN(arg2->floatval)) {
689821458c85e209cd2621ac3eadfee075ae2dc0121dDaniel Veillard		        ret = 0;
6899d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard		    } else if (xmlXPathIsInf(arg1->floatval) == 1) {
6900d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard		        if (xmlXPathIsInf(arg2->floatval) == 1)
6901d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard			    ret = 1;
6902d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard			else
6903d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard			    ret = 0;
6904d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard		    } else if (xmlXPathIsInf(arg1->floatval) == -1) {
6905d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard			if (xmlXPathIsInf(arg2->floatval) == -1)
6906d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard			    ret = 1;
6907d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard			else
6908d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard			    ret = 0;
6909d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard		    } else if (xmlXPathIsInf(arg2->floatval) == 1) {
6910d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard			if (xmlXPathIsInf(arg1->floatval) == 1)
6911d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard			    ret = 1;
6912d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard			else
6913d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard			    ret = 0;
6914d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard		    } else if (xmlXPathIsInf(arg2->floatval) == -1) {
6915d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard			if (xmlXPathIsInf(arg1->floatval) == -1)
6916d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard			    ret = 1;
6917d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard			else
6918d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard			    ret = 0;
691921458c85e209cd2621ac3eadfee075ae2dc0121dDaniel Veillard		    } else {
692021458c85e209cd2621ac3eadfee075ae2dc0121dDaniel Veillard		        ret = (arg1->floatval == arg2->floatval);
692121458c85e209cd2621ac3eadfee075ae2dc0121dDaniel Veillard		    }
69223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    break;
69233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		case XPATH_USERS:
69243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		case XPATH_POINT:
69253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		case XPATH_RANGE:
69263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		case XPATH_LOCATIONSET:
69273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    TODO
69283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    break;
69290c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		case XPATH_NODESET:
69300c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		case XPATH_XSLT_TREE:
69310c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		    break;
69323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    }
69333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    break;
69343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        case XPATH_STRING:
69353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    switch (arg2->type) {
69363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	        case XPATH_UNDEFINED:
69373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_EXPR
69383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    xmlGenericError(xmlGenericErrorContext,
69393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor			    "Equal: undefined\n");
69403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif
69413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    break;
69423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		case XPATH_BOOLEAN:
69433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    if ((arg1->stringval == NULL) ||
69443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor			(arg1->stringval[0] == 0)) ret = 0;
694545490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard		    else
69463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor			ret = 1;
69473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    ret = (arg2->boolval == ret);
69483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    break;
69493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		case XPATH_STRING:
69503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    ret = xmlStrEqual(arg1->stringval, arg2->stringval);
69513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    break;
69523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		case XPATH_NUMBER:
69533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    valuePush(ctxt, arg1);
69543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    xmlXPathNumberFunction(ctxt, 1);
69553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    arg1 = valuePop(ctxt);
6956d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard		    /* Hand check NaN and Infinity equalities */
6957081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack		    if (xmlXPathIsNaN(arg1->floatval) ||
695845490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard			    xmlXPathIsNaN(arg2->floatval)) {
695921458c85e209cd2621ac3eadfee075ae2dc0121dDaniel Veillard		        ret = 0;
6960d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard		    } else if (xmlXPathIsInf(arg1->floatval) == 1) {
6961d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard			if (xmlXPathIsInf(arg2->floatval) == 1)
6962d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard			    ret = 1;
6963d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard			else
6964d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard			    ret = 0;
6965d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard		    } else if (xmlXPathIsInf(arg1->floatval) == -1) {
6966d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard			if (xmlXPathIsInf(arg2->floatval) == -1)
6967d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard			    ret = 1;
6968d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard			else
6969d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard			    ret = 0;
6970d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard		    } else if (xmlXPathIsInf(arg2->floatval) == 1) {
6971d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard			if (xmlXPathIsInf(arg1->floatval) == 1)
6972d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard			    ret = 1;
6973d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard			else
6974d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard			    ret = 0;
6975d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard		    } else if (xmlXPathIsInf(arg2->floatval) == -1) {
6976d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard			if (xmlXPathIsInf(arg1->floatval) == -1)
6977d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard			    ret = 1;
6978d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard			else
6979d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard			    ret = 0;
698021458c85e209cd2621ac3eadfee075ae2dc0121dDaniel Veillard		    } else {
698121458c85e209cd2621ac3eadfee075ae2dc0121dDaniel Veillard		        ret = (arg1->floatval == arg2->floatval);
698221458c85e209cd2621ac3eadfee075ae2dc0121dDaniel Veillard		    }
69833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    break;
69843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		case XPATH_USERS:
69853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		case XPATH_POINT:
69863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		case XPATH_RANGE:
69873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		case XPATH_LOCATIONSET:
69883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    TODO
69893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    break;
69900c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		case XPATH_NODESET:
69910c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		case XPATH_XSLT_TREE:
69920c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		    break;
69933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    }
69943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    break;
69953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        case XPATH_USERS:
69963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XPATH_POINT:
69973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XPATH_RANGE:
69983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XPATH_LOCATIONSET:
69993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    TODO
70003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    break;
70010c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	case XPATH_NODESET:
70020c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	case XPATH_XSLT_TREE:
70030c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	    break;
70043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
7005a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathReleaseObject(ctxt->context, arg1);
7006a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathReleaseObject(ctxt->context, arg2);
70073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(ret);
70083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
70093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
70100c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack/**
70110c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack * xmlXPathEqualValues:
70120c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack * @ctxt:  the XPath Parser context
70130c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack *
70140c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack * Implement the equal operation on XPath objects content: @arg1 == @arg2
70150c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack *
70160c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack * Returns 0 or 1 depending on the results of the test.
70170c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack */
70180c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brackint
70190c022ad8234a9228288c651f5e6a9bce7efcd789William M. BrackxmlXPathEqualValues(xmlXPathParserContextPtr ctxt) {
70200c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack    xmlXPathObjectPtr arg1, arg2, argtmp;
70210c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack    int ret = 0;
70220c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack
70236128c01ca6a5c1d67970b44cd11aa95a392d8a2dDaniel Veillard    if ((ctxt == NULL) || (ctxt->context == NULL)) return(0);
702445490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard    arg2 = valuePop(ctxt);
70250c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack    arg1 = valuePop(ctxt);
70260c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack    if ((arg1 == NULL) || (arg2 == NULL)) {
70270c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	if (arg1 != NULL)
7028a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathReleaseObject(ctxt->context, arg1);
70290c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	else
7030a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathReleaseObject(ctxt->context, arg2);
70310c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	XP_ERROR0(XPATH_INVALID_OPERAND);
70320c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack    }
70330c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack
70340c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack    if (arg1 == arg2) {
70350c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack#ifdef DEBUG_EXPR
70360c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack        xmlGenericError(xmlGenericErrorContext,
70370c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		"Equal: by pointer\n");
70380c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack#endif
70392c19a7bf2ee0f78485840cac50f2a989f5efe476William M. Brack	xmlXPathFreeObject(arg1);
70400c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack        return(1);
70410c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack    }
70420c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack
70430c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack    /*
70440c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack     *If either argument is a nodeset, it's a 'special case'
70450c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack     */
70460c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack    if ((arg2->type == XPATH_NODESET) || (arg2->type == XPATH_XSLT_TREE) ||
70470c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack      (arg1->type == XPATH_NODESET) || (arg1->type == XPATH_XSLT_TREE)) {
70480c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	/*
70490c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	 *Hack it to assure arg1 is the nodeset
70500c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	 */
70510c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	if ((arg1->type != XPATH_NODESET) && (arg1->type != XPATH_XSLT_TREE)) {
70520c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		argtmp = arg2;
70530c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		arg2 = arg1;
70540c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		arg1 = argtmp;
70550c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	}
70560c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	switch (arg2->type) {
70570c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	    case XPATH_UNDEFINED:
70580c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack#ifdef DEBUG_EXPR
70590c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		xmlGenericError(xmlGenericErrorContext,
70600c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack			"Equal: undefined\n");
70610c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack#endif
70620c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		break;
70630c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	    case XPATH_NODESET:
70640c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	    case XPATH_XSLT_TREE:
70650c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		ret = xmlXPathEqualNodeSets(arg1, arg2, 0);
70660c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		break;
70670c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	    case XPATH_BOOLEAN:
70680c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		if ((arg1->nodesetval == NULL) ||
70690c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		  (arg1->nodesetval->nodeNr == 0)) ret = 0;
707045490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard		else
70710c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		    ret = 1;
70720c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		ret = (ret == arg2->boolval);
70730c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		break;
70740c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	    case XPATH_NUMBER:
70750c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		ret = xmlXPathEqualNodeSetFloat(ctxt, arg1, arg2->floatval, 0);
70760c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		break;
70770c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	    case XPATH_STRING:
70780c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		ret = xmlXPathEqualNodeSetString(arg1, arg2->stringval, 0);
70790c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		break;
70800c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	    case XPATH_USERS:
70810c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	    case XPATH_POINT:
70820c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	    case XPATH_RANGE:
70830c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	    case XPATH_LOCATIONSET:
70840c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		TODO
70850c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		break;
70860c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	}
7087a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	xmlXPathReleaseObject(ctxt->context, arg1);
7088a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	xmlXPathReleaseObject(ctxt->context, arg2);
70890c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	return(ret);
70900c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack    }
70910c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack
70920c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack    return (xmlXPathEqualValuesCommon(ctxt, arg1, arg2));
70930c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack}
70940c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack
70950c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack/**
70960c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack * xmlXPathNotEqualValues:
70970c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack * @ctxt:  the XPath Parser context
70980c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack *
70990c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack * Implement the equal operation on XPath objects content: @arg1 == @arg2
71000c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack *
71010c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack * Returns 0 or 1 depending on the results of the test.
71020c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack */
71030c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brackint
71040c022ad8234a9228288c651f5e6a9bce7efcd789William M. BrackxmlXPathNotEqualValues(xmlXPathParserContextPtr ctxt) {
71050c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack    xmlXPathObjectPtr arg1, arg2, argtmp;
71060c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack    int ret = 0;
71070c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack
71086128c01ca6a5c1d67970b44cd11aa95a392d8a2dDaniel Veillard    if ((ctxt == NULL) || (ctxt->context == NULL)) return(0);
710945490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard    arg2 = valuePop(ctxt);
71100c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack    arg1 = valuePop(ctxt);
71110c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack    if ((arg1 == NULL) || (arg2 == NULL)) {
71120c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	if (arg1 != NULL)
7113a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathReleaseObject(ctxt->context, arg1);
71140c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	else
7115a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathReleaseObject(ctxt->context, arg2);
71160c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	XP_ERROR0(XPATH_INVALID_OPERAND);
71170c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack    }
71180c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack
71190c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack    if (arg1 == arg2) {
71200c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack#ifdef DEBUG_EXPR
71210c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack        xmlGenericError(xmlGenericErrorContext,
71220c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		"NotEqual: by pointer\n");
71230c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack#endif
7124a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	xmlXPathReleaseObject(ctxt->context, arg1);
71250c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack        return(0);
71260c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack    }
71270c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack
71280c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack    /*
71290c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack     *If either argument is a nodeset, it's a 'special case'
71300c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack     */
71310c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack    if ((arg2->type == XPATH_NODESET) || (arg2->type == XPATH_XSLT_TREE) ||
71320c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack      (arg1->type == XPATH_NODESET) || (arg1->type == XPATH_XSLT_TREE)) {
71330c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	/*
71340c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	 *Hack it to assure arg1 is the nodeset
71350c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	 */
71360c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	if ((arg1->type != XPATH_NODESET) && (arg1->type != XPATH_XSLT_TREE)) {
71370c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		argtmp = arg2;
71380c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		arg2 = arg1;
71390c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		arg1 = argtmp;
71400c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	}
71410c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	switch (arg2->type) {
71420c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	    case XPATH_UNDEFINED:
71430c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack#ifdef DEBUG_EXPR
71440c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		xmlGenericError(xmlGenericErrorContext,
71450c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack			"NotEqual: undefined\n");
71460c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack#endif
71470c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		break;
71480c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	    case XPATH_NODESET:
71490c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	    case XPATH_XSLT_TREE:
71500c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		ret = xmlXPathEqualNodeSets(arg1, arg2, 1);
71510c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		break;
71520c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	    case XPATH_BOOLEAN:
71530c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		if ((arg1->nodesetval == NULL) ||
71540c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		  (arg1->nodesetval->nodeNr == 0)) ret = 0;
715545490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard		else
71560c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		    ret = 1;
7157ef61d208503e41688f4bf86f6e9023c70e65829bWilliam M. Brack		ret = (ret != arg2->boolval);
71580c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		break;
71590c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	    case XPATH_NUMBER:
71600c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		ret = xmlXPathEqualNodeSetFloat(ctxt, arg1, arg2->floatval, 1);
71610c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		break;
71620c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	    case XPATH_STRING:
71630c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		ret = xmlXPathEqualNodeSetString(arg1, arg2->stringval,1);
71640c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		break;
71650c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	    case XPATH_USERS:
71660c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	    case XPATH_POINT:
71670c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	    case XPATH_RANGE:
71680c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	    case XPATH_LOCATIONSET:
71690c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		TODO
71700c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		break;
71710c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	}
7172a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	xmlXPathReleaseObject(ctxt->context, arg1);
7173a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	xmlXPathReleaseObject(ctxt->context, arg2);
71740c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	return(ret);
71750c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack    }
71760c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack
71770c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack    return (!xmlXPathEqualValuesCommon(ctxt, arg1, arg2));
71780c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack}
71793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
71803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
71813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathCompareValues:
71823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
71833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @inf:  less than (1) or greater than (0)
71843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @strict:  is the comparison strict
71853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
718645490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard * Implement the compare operation on XPath objects:
71873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *     @arg1 < @arg2    (1, 1, ...
71883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *     @arg1 <= @arg2   (1, 0, ...
71893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *     @arg1 > @arg2    (0, 1, ...
71903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *     @arg1 >= @arg2   (0, 0, ...
71913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
71923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * When neither object to be compared is a node-set and the operator is
71933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * <=, <, >=, >, then the objects are compared by converted both objects
71943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * to numbers and comparing the numbers according to IEEE 754. The <
71953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * comparison will be true if and only if the first number is less than the
71963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * second number. The <= comparison will be true if and only if the first
71973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * number is less than or equal to the second number. The > comparison
71983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * will be true if and only if the first number is greater than the second
71993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * number. The >= comparison will be true if and only if the first number
72003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * is greater than or equal to the second number.
72013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
7202cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * Returns 1 if the comparison succeeded, 0 if it failed
72033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
72043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorint
72053473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathCompareValues(xmlXPathParserContextPtr ctxt, int inf, int strict) {
7206d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard    int ret = 0, arg1i = 0, arg2i = 0;
72073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathObjectPtr arg1, arg2;
72083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
72096128c01ca6a5c1d67970b44cd11aa95a392d8a2dDaniel Veillard    if ((ctxt == NULL) || (ctxt->context == NULL)) return(0);
721045490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard    arg2 = valuePop(ctxt);
72113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    arg1 = valuePop(ctxt);
72120c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack    if ((arg1 == NULL) || (arg2 == NULL)) {
72130c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	if (arg1 != NULL)
7214a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathReleaseObject(ctxt->context, arg1);
72150c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	else
7216a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathReleaseObject(ctxt->context, arg2);
72173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	XP_ERROR0(XPATH_INVALID_OPERAND);
72183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
72193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
72200c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack    if ((arg2->type == XPATH_NODESET) || (arg2->type == XPATH_XSLT_TREE) ||
72210c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack      (arg1->type == XPATH_NODESET) || (arg1->type == XPATH_XSLT_TREE)) {
7222d6e347e865b473f06fd431be926183c77596194aWilliam M. Brack	/*
7223d6e347e865b473f06fd431be926183c77596194aWilliam M. Brack	 * If either argument is a XPATH_NODESET or XPATH_XSLT_TREE the two arguments
7224d6e347e865b473f06fd431be926183c77596194aWilliam M. Brack	 * are not freed from within this routine; they will be freed from the
7225d6e347e865b473f06fd431be926183c77596194aWilliam M. Brack	 * called routine, e.g. xmlXPathCompareNodeSets or xmlXPathCompareNodeSetValue
7226d6e347e865b473f06fd431be926183c77596194aWilliam M. Brack	 */
72270c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	if (((arg2->type == XPATH_NODESET) || (arg2->type == XPATH_XSLT_TREE)) &&
72280c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	  ((arg1->type == XPATH_NODESET) || (arg1->type == XPATH_XSLT_TREE))){
722956a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillard	    ret = xmlXPathCompareNodeSets(inf, strict, arg1, arg2);
72303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	} else {
72310c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	    if ((arg1->type == XPATH_NODESET) || (arg1->type == XPATH_XSLT_TREE)) {
72324af6b6e801346d1c832cf19b7c3833a831871db2Daniel Veillard		ret = xmlXPathCompareNodeSetValue(ctxt, inf, strict,
72334af6b6e801346d1c832cf19b7c3833a831871db2Daniel Veillard			                          arg1, arg2);
72343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    } else {
72354af6b6e801346d1c832cf19b7c3833a831871db2Daniel Veillard		ret = xmlXPathCompareNodeSetValue(ctxt, !inf, strict,
72364af6b6e801346d1c832cf19b7c3833a831871db2Daniel Veillard			                          arg2, arg1);
72373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    }
72383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
72393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(ret);
72403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
72413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
72423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (arg1->type != XPATH_NUMBER) {
72433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	valuePush(ctxt, arg1);
72443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	xmlXPathNumberFunction(ctxt, 1);
72453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	arg1 = valuePop(ctxt);
72463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
72473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (arg1->type != XPATH_NUMBER) {
72483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	xmlXPathFreeObject(arg1);
72493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	xmlXPathFreeObject(arg2);
72503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	XP_ERROR0(XPATH_INVALID_OPERAND);
72513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
72523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (arg2->type != XPATH_NUMBER) {
72533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	valuePush(ctxt, arg2);
72543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	xmlXPathNumberFunction(ctxt, 1);
72553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	arg2 = valuePop(ctxt);
72563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
72573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (arg2->type != XPATH_NUMBER) {
7258a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	xmlXPathReleaseObject(ctxt->context, arg1);
7259a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	xmlXPathReleaseObject(ctxt->context, arg2);
72603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	XP_ERROR0(XPATH_INVALID_OPERAND);
72613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
72623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    /*
72633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor     * Add tests for infinity and nan
72643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor     * => feedback on 3.4 for Inf and NaN
72653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor     */
7266d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard    /* Hand check NaN and Infinity comparisons */
726721458c85e209cd2621ac3eadfee075ae2dc0121dDaniel Veillard    if (xmlXPathIsNaN(arg1->floatval) || xmlXPathIsNaN(arg2->floatval)) {
7268d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard	ret=0;
726921458c85e209cd2621ac3eadfee075ae2dc0121dDaniel Veillard    } else {
7270d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard	arg1i=xmlXPathIsInf(arg1->floatval);
7271d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard	arg2i=xmlXPathIsInf(arg2->floatval);
7272d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard	if (inf && strict) {
7273d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard	    if ((arg1i == -1 && arg2i != -1) ||
7274d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard		(arg2i == 1 && arg1i != 1)) {
7275d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard		ret = 1;
7276d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard	    } else if (arg1i == 0 && arg2i == 0) {
7277d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard		ret = (arg1->floatval < arg2->floatval);
7278d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard	    } else {
7279d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard		ret = 0;
7280d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard	    }
7281d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard	}
7282d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard	else if (inf && !strict) {
7283d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard	    if (arg1i == -1 || arg2i == 1) {
7284d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard		ret = 1;
7285d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard	    } else if (arg1i == 0 && arg2i == 0) {
7286d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard		ret = (arg1->floatval <= arg2->floatval);
7287d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard	    } else {
7288d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard		ret = 0;
7289d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard	    }
7290d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard	}
7291d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard	else if (!inf && strict) {
7292d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard	    if ((arg1i == 1 && arg2i != 1) ||
7293d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard		(arg2i == -1 && arg1i != -1)) {
7294d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard		ret = 1;
7295d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard	    } else if (arg1i == 0 && arg2i == 0) {
7296d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard		ret = (arg1->floatval > arg2->floatval);
7297d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard	    } else {
7298d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard		ret = 0;
7299d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard	    }
7300d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard	}
7301d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard	else if (!inf && !strict) {
7302d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard	    if (arg1i == 1 || arg2i == -1) {
7303d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard		ret = 1;
7304d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard	    } else if (arg1i == 0 && arg2i == 0) {
7305d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard		ret = (arg1->floatval >= arg2->floatval);
7306d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard	    } else {
7307d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard		ret = 0;
7308d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard	    }
7309d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard	}
731021458c85e209cd2621ac3eadfee075ae2dc0121dDaniel Veillard    }
7311a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathReleaseObject(ctxt->context, arg1);
7312a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathReleaseObject(ctxt->context, arg2);
73133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(ret);
73143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
73153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
73163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
73173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathValueFlipSign:
73183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
73193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
73203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the unary - operation on an XPath object
73213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The numeric operators convert their operands to numbers as if
73223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * by calling the number function.
73233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
73243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
73253473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathValueFlipSign(xmlXPathParserContextPtr ctxt) {
7326a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard    if ((ctxt == NULL) || (ctxt->context == NULL)) return;
7327ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    CAST_TO_NUMBER;
7328ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    CHECK_TYPE(XPATH_NUMBER);
7329eca82810f0fb81f3e9936d2018347e1e19de513aDaniel Veillard    if (xmlXPathIsNaN(ctxt->value->floatval))
7330eca82810f0fb81f3e9936d2018347e1e19de513aDaniel Veillard        ctxt->value->floatval=xmlXPathNAN;
7331eca82810f0fb81f3e9936d2018347e1e19de513aDaniel Veillard    else if (xmlXPathIsInf(ctxt->value->floatval) == 1)
7332eca82810f0fb81f3e9936d2018347e1e19de513aDaniel Veillard        ctxt->value->floatval=xmlXPathNINF;
7333eca82810f0fb81f3e9936d2018347e1e19de513aDaniel Veillard    else if (xmlXPathIsInf(ctxt->value->floatval) == -1)
7334eca82810f0fb81f3e9936d2018347e1e19de513aDaniel Veillard        ctxt->value->floatval=xmlXPathPINF;
7335eca82810f0fb81f3e9936d2018347e1e19de513aDaniel Veillard    else if (ctxt->value->floatval == 0) {
73365fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard        if (xmlXPathGetSign(ctxt->value->floatval) == 0)
73375fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard	    ctxt->value->floatval = xmlXPathNZERO;
73385fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard	else
73395fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard	    ctxt->value->floatval = 0;
73405fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard    }
73415fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard    else
73425fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard        ctxt->value->floatval = - ctxt->value->floatval;
73433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
73443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
73453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
73463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathAddValues:
73473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
73483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
73493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the add operation on XPath objects:
73503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The numeric operators convert their operands to numbers as if
73513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * by calling the number function.
73523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
73533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
73543473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathAddValues(xmlXPathParserContextPtr ctxt) {
73553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathObjectPtr arg;
73563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    double val;
73573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
7358ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    arg = valuePop(ctxt);
7359ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    if (arg == NULL)
7360ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	XP_ERROR(XPATH_INVALID_OPERAND);
7361ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    val = xmlXPathCastToNumber(arg);
7362a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathReleaseObject(ctxt->context, arg);
7363ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    CAST_TO_NUMBER;
7364ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    CHECK_TYPE(XPATH_NUMBER);
7365ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    ctxt->value->floatval += val;
73663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
73673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
73683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
73693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathSubValues:
73703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
73713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
7372cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * Implement the subtraction operation on XPath objects:
73733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The numeric operators convert their operands to numbers as if
73743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * by calling the number function.
73753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
73763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
73773473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathSubValues(xmlXPathParserContextPtr ctxt) {
73783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathObjectPtr arg;
73793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    double val;
73803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
7381ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    arg = valuePop(ctxt);
7382ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    if (arg == NULL)
7383ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	XP_ERROR(XPATH_INVALID_OPERAND);
7384ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    val = xmlXPathCastToNumber(arg);
7385a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathReleaseObject(ctxt->context, arg);
7386ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    CAST_TO_NUMBER;
7387ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    CHECK_TYPE(XPATH_NUMBER);
7388ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    ctxt->value->floatval -= val;
73893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
73903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
73913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
73923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathMultValues:
73933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
73943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
73953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the multiply operation on XPath objects:
73963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The numeric operators convert their operands to numbers as if
73973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * by calling the number function.
73983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
73993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
74003473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathMultValues(xmlXPathParserContextPtr ctxt) {
74013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathObjectPtr arg;
74023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    double val;
74033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
7404ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    arg = valuePop(ctxt);
7405ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    if (arg == NULL)
7406ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	XP_ERROR(XPATH_INVALID_OPERAND);
7407ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    val = xmlXPathCastToNumber(arg);
7408a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathReleaseObject(ctxt->context, arg);
7409ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    CAST_TO_NUMBER;
7410ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    CHECK_TYPE(XPATH_NUMBER);
7411ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    ctxt->value->floatval *= val;
74123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
74133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
74143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
74153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathDivValues:
74163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
74173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
74183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the div operation on XPath objects @arg1 / @arg2:
74193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The numeric operators convert their operands to numbers as if
74203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * by calling the number function.
74213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
74223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
74233473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathDivValues(xmlXPathParserContextPtr ctxt) {
74243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathObjectPtr arg;
74253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    double val;
74263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
7427ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    arg = valuePop(ctxt);
7428ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    if (arg == NULL)
7429ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	XP_ERROR(XPATH_INVALID_OPERAND);
7430ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    val = xmlXPathCastToNumber(arg);
7431a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathReleaseObject(ctxt->context, arg);
7432ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    CAST_TO_NUMBER;
7433ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    CHECK_TYPE(XPATH_NUMBER);
7434eca82810f0fb81f3e9936d2018347e1e19de513aDaniel Veillard    if (xmlXPathIsNaN(val) || xmlXPathIsNaN(ctxt->value->floatval))
7435eca82810f0fb81f3e9936d2018347e1e19de513aDaniel Veillard	ctxt->value->floatval = xmlXPathNAN;
7436eca82810f0fb81f3e9936d2018347e1e19de513aDaniel Veillard    else if (val == 0 && xmlXPathGetSign(val) != 0) {
74375fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard	if (ctxt->value->floatval == 0)
74385fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard	    ctxt->value->floatval = xmlXPathNAN;
74395fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard	else if (ctxt->value->floatval > 0)
74405fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard	    ctxt->value->floatval = xmlXPathNINF;
74415fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard	else if (ctxt->value->floatval < 0)
74425fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard	    ctxt->value->floatval = xmlXPathPINF;
74435fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard    }
74445fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard    else if (val == 0) {
74455f4b5999b4eeda2ca68e6d9f54a3c534a8474b38Daniel Veillard	if (ctxt->value->floatval == 0)
74465f4b5999b4eeda2ca68e6d9f54a3c534a8474b38Daniel Veillard	    ctxt->value->floatval = xmlXPathNAN;
74475f4b5999b4eeda2ca68e6d9f54a3c534a8474b38Daniel Veillard	else if (ctxt->value->floatval > 0)
74485f4b5999b4eeda2ca68e6d9f54a3c534a8474b38Daniel Veillard	    ctxt->value->floatval = xmlXPathPINF;
74495f4b5999b4eeda2ca68e6d9f54a3c534a8474b38Daniel Veillard	else if (ctxt->value->floatval < 0)
74505f4b5999b4eeda2ca68e6d9f54a3c534a8474b38Daniel Veillard	    ctxt->value->floatval = xmlXPathNINF;
745145490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard    } else
74525f4b5999b4eeda2ca68e6d9f54a3c534a8474b38Daniel Veillard	ctxt->value->floatval /= val;
74533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
74543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
74553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
74563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathModValues:
74573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
74583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
74593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the mod operation on XPath objects: @arg1 / @arg2
74603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The numeric operators convert their operands to numbers as if
74613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * by calling the number function.
74623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
74633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
74643473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathModValues(xmlXPathParserContextPtr ctxt) {
74653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathObjectPtr arg;
7466fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard    double arg1, arg2;
74673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
7468ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    arg = valuePop(ctxt);
7469ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    if (arg == NULL)
7470ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	XP_ERROR(XPATH_INVALID_OPERAND);
74715fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard    arg2 = xmlXPathCastToNumber(arg);
7472a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathReleaseObject(ctxt->context, arg);
7473ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    CAST_TO_NUMBER;
7474ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    CHECK_TYPE(XPATH_NUMBER);
74755fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard    arg1 = ctxt->value->floatval;
7476268fd1bc97f79b43290041cfda2287fb0b0ef2d6Daniel Veillard    if (arg2 == 0)
7477268fd1bc97f79b43290041cfda2287fb0b0ef2d6Daniel Veillard	ctxt->value->floatval = xmlXPathNAN;
74785fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard    else {
7479fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard	ctxt->value->floatval = fmod(arg1, arg2);
74805fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard    }
74813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
74823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
74833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/************************************************************************
74843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *									*
74853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *		The traversal functions					*
74863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *									*
74873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ************************************************************************/
74883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
74893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/*
74903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * A traversal function enumerates nodes along an axis.
74913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Initially it must be called with NULL, and it indicates
74923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * termination on the axis by returning NULL.
74933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
74943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylortypedef xmlNodePtr (*xmlXPathTraversalFunction)
74953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor                    (xmlXPathParserContextPtr ctxt, xmlNodePtr cur);
74963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
7497df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik/*
7498df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik * xmlXPathTraversalFunctionExt:
7499df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik * A traversal function enumerates nodes along an axis.
7500df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik * Initially it must be called with NULL, and it indicates
7501df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik * termination on the axis by returning NULL.
7502df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik * The context node of the traversal is specified via @contextNode.
7503df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik */
7504df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchciktypedef xmlNodePtr (*xmlXPathTraversalFunctionExt)
7505df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik                    (xmlNodePtr cur, xmlNodePtr contextNode);
7506df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik
75079bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik/*
75089bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik * xmlXPathNodeSetMergeFunction:
75099bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik * Used for merging node sets in xmlXPathCollectAndTest().
75109bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik */
75119bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchciktypedef xmlNodeSetPtr (*xmlXPathNodeSetMergeFunction)
75129bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		    (xmlNodeSetPtr, xmlNodeSetPtr, int);
75139bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik
7514df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik
75153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
75163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNextSelf:
75173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
75183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur:  the current node in the traversal
75193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
75203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Traversal function for the "self" direction
75213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The self axis contains just the context node itself
75223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
75233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the next element following that axis
75243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
75253473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNodePtr
75263473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNextSelf(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
7527a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard    if ((ctxt == NULL) || (ctxt->context == NULL)) return(NULL);
75283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (cur == NULL)
75293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        return(ctxt->context->node);
75303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(NULL);
75313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
75323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
75333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
75343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNextChild:
75353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
75363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur:  the current node in the traversal
75373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
75383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Traversal function for the "child" direction
75393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The child axis contains the children of the context node in document order.
75403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
75413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the next element following that axis
75423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
75433473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNodePtr
75443473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNextChild(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
7545a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard    if ((ctxt == NULL) || (ctxt->context == NULL)) return(NULL);
75463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (cur == NULL) {
75473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (ctxt->context->node == NULL) return(NULL);
75483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	switch (ctxt->context->node->type) {
75493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_ELEMENT_NODE:
75503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_TEXT_NODE:
75513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_CDATA_SECTION_NODE:
75523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_ENTITY_REF_NODE:
75533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_ENTITY_NODE:
75543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_PI_NODE:
75553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_COMMENT_NODE:
75563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_NOTATION_NODE:
75573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_DTD_NODE:
75583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		return(ctxt->context->node->children);
75593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_DOCUMENT_NODE:
75603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_DOCUMENT_TYPE_NODE:
75613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_DOCUMENT_FRAG_NODE:
75623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_HTML_DOCUMENT_NODE:
7563eae522a0d8aa9f830d2e447f29b504030dbb6bbdDaniel Veillard#ifdef LIBXML_DOCB_ENABLED
7564eae522a0d8aa9f830d2e447f29b504030dbb6bbdDaniel Veillard	    case XML_DOCB_DOCUMENT_NODE:
75653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif
75663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		return(((xmlDocPtr) ctxt->context->node)->children);
75673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    case XML_ELEMENT_DECL:
75683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    case XML_ATTRIBUTE_DECL:
75693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    case XML_ENTITY_DECL:
75703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_ATTRIBUTE_NODE:
75713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    case XML_NAMESPACE_DECL:
75723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    case XML_XINCLUDE_START:
75733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    case XML_XINCLUDE_END:
75743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		return(NULL);
75753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
75763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(NULL);
75773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
75783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if ((cur->type == XML_DOCUMENT_NODE) ||
75793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        (cur->type == XML_HTML_DOCUMENT_NODE))
75803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(NULL);
75813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(cur->next);
75823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
75833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
75843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
758575af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik * xmlXPathNextChildElement:
758675af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik * @ctxt:  the XPath Parser context
758775af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik * @cur:  the current node in the traversal
758875af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik *
758975af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik * Traversal function for the "child" direction and nodes of type element.
759075af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik * The child axis contains the children of the context node in document order.
759175af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik *
759275af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik * Returns the next element following that axis
759375af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik */
759475af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcikstatic xmlNodePtr
759575af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. BuchcikxmlXPathNextChildElement(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
759675af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik    if ((ctxt == NULL) || (ctxt->context == NULL)) return(NULL);
759775af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik    if (cur == NULL) {
759875af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik	cur = ctxt->context->node;
759975af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik	if (cur == NULL) return(NULL);
760075af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik	/*
760175af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik	* Get the first element child.
760275af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik	*/
760375af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik	switch (cur->type) {
760475af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik            case XML_ELEMENT_NODE:
760575af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik	    case XML_DOCUMENT_FRAG_NODE:
760675af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik	    case XML_ENTITY_REF_NODE: /* URGENT TODO: entify-refs as well? */
760775af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik            case XML_ENTITY_NODE:
760875af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik		cur = cur->children;
760975af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik		if (cur != NULL) {
761075af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik		    if (cur->type == XML_ELEMENT_NODE)
761175af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik			return(cur);
761275af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik		    do {
761375af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik			cur = cur->next;
761475af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik		    } while ((cur != NULL) &&
761575af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik			(cur->type != XML_ELEMENT_NODE));
761675af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik		    return(cur);
761775af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik		}
761875af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik		return(NULL);
761975af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik            case XML_DOCUMENT_NODE:
762075af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik            case XML_HTML_DOCUMENT_NODE:
762175af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik#ifdef LIBXML_DOCB_ENABLED
762275af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik	    case XML_DOCB_DOCUMENT_NODE:
762375af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik#endif
762475af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik		return(xmlDocGetRootElement((xmlDocPtr) cur));
762575af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik	    default:
762675af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik		return(NULL);
762775af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik	}
762875af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik	return(NULL);
762975af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik    }
763075af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik    /*
763175af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik    * Get the next sibling element node.
763275af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik    */
763375af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik    switch (cur->type) {
763475af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik	case XML_ELEMENT_NODE:
763575af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik	case XML_TEXT_NODE:
763675af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik	case XML_ENTITY_REF_NODE:
763775af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik	case XML_ENTITY_NODE:
763875af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik	case XML_CDATA_SECTION_NODE:
763975af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik	case XML_PI_NODE:
764075af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik	case XML_COMMENT_NODE:
764175af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik	case XML_XINCLUDE_END:
764275af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik	    break;
764375af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik	/* case XML_DTD_NODE: */ /* URGENT TODO: DTD-node as well? */
764475af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik	default:
764575af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik	    return(NULL);
764675af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik    }
764775af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik    if (cur->next != NULL) {
764875af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik	if (cur->next->type == XML_ELEMENT_NODE)
764975af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik	    return(cur->next);
765075af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik	cur = cur->next;
765175af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik	do {
765275af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik	    cur = cur->next;
765375af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik	} while ((cur != NULL) && (cur->type != XML_ELEMENT_NODE));
765475af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik	return(cur);
765575af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik    }
765675af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik    return(NULL);
765775af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik}
765875af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik
765975af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik/**
7660df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik * xmlXPathNextDescendantOrSelfElemParent:
7661df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik * @ctxt:  the XPath Parser context
7662df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik * @cur:  the current node in the traversal
7663df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik *
7664df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik * Traversal function for the "descendant-or-self" axis.
7665df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik * Additionally it returns only nodes which can be parents of
7666df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik * element nodes.
7667df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik *
7668df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik *
7669df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik * Returns the next element following that axis
7670df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik */
7671df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcikstatic xmlNodePtr
7672df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. BuchcikxmlXPathNextDescendantOrSelfElemParent(xmlNodePtr cur,
7673df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik				       xmlNodePtr contextNode)
7674df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik{
7675df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik    if (cur == NULL) {
7676df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik	if (contextNode == NULL)
7677df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik	    return(NULL);
7678df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik	switch (contextNode->type) {
7679df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik	    case XML_ELEMENT_NODE:
7680df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik	    case XML_XINCLUDE_START:
7681df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik	    case XML_DOCUMENT_FRAG_NODE:
7682df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik	    case XML_DOCUMENT_NODE:
7683df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik#ifdef LIBXML_DOCB_ENABLED
7684df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik	    case XML_DOCB_DOCUMENT_NODE:
7685df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik#endif
768645490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	    case XML_HTML_DOCUMENT_NODE:
7687df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		return(contextNode);
7688df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik	    default:
768945490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard		return(NULL);
7690df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik	}
7691df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik	return(NULL);
7692df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik    } else {
7693df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik	xmlNodePtr start = cur;
7694df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik
7695df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik	while (cur != NULL) {
7696df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik	    switch (cur->type) {
7697df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		case XML_ELEMENT_NODE:
7698df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		/* TODO: OK to have XInclude here? */
7699df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		case XML_XINCLUDE_START:
770045490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard		case XML_DOCUMENT_FRAG_NODE:
7701df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		    if (cur != start)
7702df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik			return(cur);
7703df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		    if (cur->children != NULL) {
7704df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik			cur = cur->children;
7705df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik			continue;
7706df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		    }
7707df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		    break;
7708df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		/* Not sure if we need those here. */
7709df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		case XML_DOCUMENT_NODE:
771017970a72caf1347025f2cc01eb6a1d7142b50d7cDaniel Veillard#ifdef LIBXML_DOCB_ENABLED
7711df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		case XML_DOCB_DOCUMENT_NODE:
7712df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik#endif
7713df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		case XML_HTML_DOCUMENT_NODE:
7714df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		    if (cur != start)
7715df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik			return(cur);
7716df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		    return(xmlDocGetRootElement((xmlDocPtr) cur));
7717df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		default:
7718df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		    break;
771945490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	    }
772045490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
7721df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchciknext_sibling:
7722df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik	    if ((cur == NULL) || (cur == contextNode))
772345490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard		return(NULL);
7724df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik	    if (cur->next != NULL) {
772545490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard		cur = cur->next;
7726df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik	    } else {
7727df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		cur = cur->parent;
7728df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		goto next_sibling;
7729df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik	    }
7730df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik	}
7731df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik    }
7732df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik    return(NULL);
773345490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard}
7734df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik
7735df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik/**
77363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNextDescendant:
77373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
77383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur:  the current node in the traversal
77393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
77403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Traversal function for the "descendant" direction
77413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the descendant axis contains the descendants of the context node in document
77423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * order; a descendant is a child or a child of a child and so on.
77433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
77443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the next element following that axis
77453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
77463473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNodePtr
77473473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNextDescendant(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
7748a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard    if ((ctxt == NULL) || (ctxt->context == NULL)) return(NULL);
77493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (cur == NULL) {
77503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (ctxt->context->node == NULL)
77513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    return(NULL);
77523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if ((ctxt->context->node->type == XML_ATTRIBUTE_NODE) ||
77533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    (ctxt->context->node->type == XML_NAMESPACE_DECL))
77543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    return(NULL);
77553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
77563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        if (ctxt->context->node == (xmlNodePtr) ctxt->context->doc)
77573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    return(ctxt->context->doc->children);
77583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        return(ctxt->context->node->children);
77593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
77603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
7761567e1b48e8664163894742d5674c24baa4282f9eDaniel Veillard    if (cur->children != NULL) {
776268e9e74af85ebbc30781787f247c361bc85adfa0Daniel Veillard	/*
776368e9e74af85ebbc30781787f247c361bc85adfa0Daniel Veillard	 * Do not descend on entities declarations
776468e9e74af85ebbc30781787f247c361bc85adfa0Daniel Veillard	 */
776545490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	if (cur->children->type != XML_ENTITY_DECL) {
776668e9e74af85ebbc30781787f247c361bc85adfa0Daniel Veillard	    cur = cur->children;
776768e9e74af85ebbc30781787f247c361bc85adfa0Daniel Veillard	    /*
776868e9e74af85ebbc30781787f247c361bc85adfa0Daniel Veillard	     * Skip DTDs
776968e9e74af85ebbc30781787f247c361bc85adfa0Daniel Veillard	     */
777068e9e74af85ebbc30781787f247c361bc85adfa0Daniel Veillard	    if (cur->type != XML_DTD_NODE)
777168e9e74af85ebbc30781787f247c361bc85adfa0Daniel Veillard		return(cur);
777268e9e74af85ebbc30781787f247c361bc85adfa0Daniel Veillard	}
7773567e1b48e8664163894742d5674c24baa4282f9eDaniel Veillard    }
7774567e1b48e8664163894742d5674c24baa4282f9eDaniel Veillard
7775567e1b48e8664163894742d5674c24baa4282f9eDaniel Veillard    if (cur == ctxt->context->node) return(NULL);
7776567e1b48e8664163894742d5674c24baa4282f9eDaniel Veillard
777768e9e74af85ebbc30781787f247c361bc85adfa0Daniel Veillard    while (cur->next != NULL) {
777868e9e74af85ebbc30781787f247c361bc85adfa0Daniel Veillard	cur = cur->next;
777968e9e74af85ebbc30781787f247c361bc85adfa0Daniel Veillard	if ((cur->type != XML_ENTITY_DECL) &&
778068e9e74af85ebbc30781787f247c361bc85adfa0Daniel Veillard	    (cur->type != XML_DTD_NODE))
778168e9e74af85ebbc30781787f247c361bc85adfa0Daniel Veillard	    return(cur);
778268e9e74af85ebbc30781787f247c361bc85adfa0Daniel Veillard    }
778345490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
77843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    do {
77853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        cur = cur->parent;
778611ce4004d86bb4b317c48b7d5124ba33e40e10f5Daniel Veillard	if (cur == NULL) break;
77873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (cur == ctxt->context->node) return(NULL);
77883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (cur->next != NULL) {
77893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    cur = cur->next;
77903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    return(cur);
77913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
77923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    } while (cur != NULL);
77933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(cur);
77943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
77953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
77963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
77973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNextDescendantOrSelf:
77983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
77993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur:  the current node in the traversal
78003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
78013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Traversal function for the "descendant-or-self" direction
78023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the descendant-or-self axis contains the context node and the descendants
78033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * of the context node in document order; thus the context node is the first
78043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * node on the axis, and the first child of the context node is the second node
78053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * on the axis
78063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
78073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the next element following that axis
78083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
78093473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNodePtr
78103473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNextDescendantOrSelf(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
7811a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard    if ((ctxt == NULL) || (ctxt->context == NULL)) return(NULL);
78123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (cur == NULL) {
78133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (ctxt->context->node == NULL)
78143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    return(NULL);
78153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if ((ctxt->context->node->type == XML_ATTRIBUTE_NODE) ||
78163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    (ctxt->context->node->type == XML_NAMESPACE_DECL))
78173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    return(NULL);
78183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        return(ctxt->context->node);
78193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
78203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
78213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(xmlXPathNextDescendant(ctxt, cur));
78223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
78233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
78243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
78253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNextParent:
78263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
78273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur:  the current node in the traversal
78283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
78293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Traversal function for the "parent" direction
78303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The parent axis contains the parent of the context node, if there is one.
78313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
78323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the next element following that axis
78333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
78343473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNodePtr
78353473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNextParent(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
7836a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard    if ((ctxt == NULL) || (ctxt->context == NULL)) return(NULL);
78373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    /*
78383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor     * the parent of an attribute or namespace node is the element
78393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor     * to which the attribute or namespace node is attached
78403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor     * Namespace handling !!!
78413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor     */
78423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (cur == NULL) {
78433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (ctxt->context->node == NULL) return(NULL);
78443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	switch (ctxt->context->node->type) {
78453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_ELEMENT_NODE:
78463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_TEXT_NODE:
78473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_CDATA_SECTION_NODE:
78483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_ENTITY_REF_NODE:
78493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_ENTITY_NODE:
78503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_PI_NODE:
78513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_COMMENT_NODE:
78523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_NOTATION_NODE:
78533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_DTD_NODE:
78543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    case XML_ELEMENT_DECL:
78553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    case XML_ATTRIBUTE_DECL:
78563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    case XML_XINCLUDE_START:
78573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    case XML_XINCLUDE_END:
78583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    case XML_ENTITY_DECL:
78593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		if (ctxt->context->node->parent == NULL)
78603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    return((xmlNodePtr) ctxt->context->doc);
78618e7e1c00ce5cc3ce959833b888c50ed9fd9d5aaeDaniel Veillard		if ((ctxt->context->node->parent->type == XML_ELEMENT_NODE) &&
7862652d8a949447833405cc0805f4b7ff1179e59ed2Daniel Veillard		    ((ctxt->context->node->parent->name[0] == ' ') ||
7863652d8a949447833405cc0805f4b7ff1179e59ed2Daniel Veillard		     (xmlStrEqual(ctxt->context->node->parent->name,
7864652d8a949447833405cc0805f4b7ff1179e59ed2Daniel Veillard				 BAD_CAST "fake node libxslt"))))
78658e7e1c00ce5cc3ce959833b888c50ed9fd9d5aaeDaniel Veillard		    return(NULL);
78663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		return(ctxt->context->node->parent);
78673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_ATTRIBUTE_NODE: {
78683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		xmlAttrPtr att = (xmlAttrPtr) ctxt->context->node;
78693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
78703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		return(att->parent);
78713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    }
78723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_DOCUMENT_NODE:
78733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_DOCUMENT_TYPE_NODE:
78743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_DOCUMENT_FRAG_NODE:
78753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_HTML_DOCUMENT_NODE:
7876eae522a0d8aa9f830d2e447f29b504030dbb6bbdDaniel Veillard#ifdef LIBXML_DOCB_ENABLED
7877eae522a0d8aa9f830d2e447f29b504030dbb6bbdDaniel Veillard	    case XML_DOCB_DOCUMENT_NODE:
78783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif
78793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor                return(NULL);
7880044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard	    case XML_NAMESPACE_DECL: {
7881044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard		xmlNsPtr ns = (xmlNsPtr) ctxt->context->node;
788245490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
7883044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard		if ((ns->next != NULL) &&
7884044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard		    (ns->next->type != XML_NAMESPACE_DECL))
7885044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard		    return((xmlNodePtr) ns->next);
78863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor                return(NULL);
7887044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard	    }
78883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
78893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
78903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(NULL);
78913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
78923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
78933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
78943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNextAncestor:
78953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
78963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur:  the current node in the traversal
78973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
78983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Traversal function for the "ancestor" direction
78993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the ancestor axis contains the ancestors of the context node; the ancestors
79003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * of the context node consist of the parent of context node and the parent's
79013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * parent and so on; the nodes are ordered in reverse document order; thus the
79023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * parent is the first node on the axis, and the parent's parent is the second
79033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * node on the axis
79043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
79053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the next element following that axis
79063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
79073473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNodePtr
79083473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNextAncestor(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
7909a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard    if ((ctxt == NULL) || (ctxt->context == NULL)) return(NULL);
79103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    /*
79113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor     * the parent of an attribute or namespace node is the element
79123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor     * to which the attribute or namespace node is attached
79133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor     * !!!!!!!!!!!!!
79143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor     */
79153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (cur == NULL) {
79163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (ctxt->context->node == NULL) return(NULL);
79173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	switch (ctxt->context->node->type) {
79183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_ELEMENT_NODE:
79193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_TEXT_NODE:
79203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_CDATA_SECTION_NODE:
79213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_ENTITY_REF_NODE:
79223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_ENTITY_NODE:
79233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_PI_NODE:
79243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_COMMENT_NODE:
79253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    case XML_DTD_NODE:
79263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    case XML_ELEMENT_DECL:
79273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    case XML_ATTRIBUTE_DECL:
79283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    case XML_ENTITY_DECL:
79293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_NOTATION_NODE:
79303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    case XML_XINCLUDE_START:
79313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    case XML_XINCLUDE_END:
79323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		if (ctxt->context->node->parent == NULL)
79333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    return((xmlNodePtr) ctxt->context->doc);
79348e7e1c00ce5cc3ce959833b888c50ed9fd9d5aaeDaniel Veillard		if ((ctxt->context->node->parent->type == XML_ELEMENT_NODE) &&
7935652d8a949447833405cc0805f4b7ff1179e59ed2Daniel Veillard		    ((ctxt->context->node->parent->name[0] == ' ') ||
7936652d8a949447833405cc0805f4b7ff1179e59ed2Daniel Veillard		     (xmlStrEqual(ctxt->context->node->parent->name,
7937652d8a949447833405cc0805f4b7ff1179e59ed2Daniel Veillard				 BAD_CAST "fake node libxslt"))))
79388e7e1c00ce5cc3ce959833b888c50ed9fd9d5aaeDaniel Veillard		    return(NULL);
79393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		return(ctxt->context->node->parent);
79403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_ATTRIBUTE_NODE: {
794156a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillard		xmlAttrPtr tmp = (xmlAttrPtr) ctxt->context->node;
79423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
794356a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillard		return(tmp->parent);
79443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    }
79453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_DOCUMENT_NODE:
79463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_DOCUMENT_TYPE_NODE:
79473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_DOCUMENT_FRAG_NODE:
79483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_HTML_DOCUMENT_NODE:
7949eae522a0d8aa9f830d2e447f29b504030dbb6bbdDaniel Veillard#ifdef LIBXML_DOCB_ENABLED
7950eae522a0d8aa9f830d2e447f29b504030dbb6bbdDaniel Veillard	    case XML_DOCB_DOCUMENT_NODE:
79513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif
79523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor                return(NULL);
7953044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard	    case XML_NAMESPACE_DECL: {
7954044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard		xmlNsPtr ns = (xmlNsPtr) ctxt->context->node;
795545490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
7956044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard		if ((ns->next != NULL) &&
7957044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard		    (ns->next->type != XML_NAMESPACE_DECL))
7958044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard		    return((xmlNodePtr) ns->next);
7959081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack		/* Bad, how did that namespace end up here ? */
79603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor                return(NULL);
7961044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard	    }
79623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
79633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(NULL);
79643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
79653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (cur == ctxt->context->doc->children)
79663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return((xmlNodePtr) ctxt->context->doc);
79673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (cur == (xmlNodePtr) ctxt->context->doc)
79683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(NULL);
79693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    switch (cur->type) {
79703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XML_ELEMENT_NODE:
79713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XML_TEXT_NODE:
79723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XML_CDATA_SECTION_NODE:
79733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XML_ENTITY_REF_NODE:
79743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XML_ENTITY_NODE:
79753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XML_PI_NODE:
79763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XML_COMMENT_NODE:
79773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XML_NOTATION_NODE:
79783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XML_DTD_NODE:
79793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        case XML_ELEMENT_DECL:
79803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        case XML_ATTRIBUTE_DECL:
79813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        case XML_ENTITY_DECL:
79823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XML_XINCLUDE_START:
79833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XML_XINCLUDE_END:
79848e7e1c00ce5cc3ce959833b888c50ed9fd9d5aaeDaniel Veillard	    if (cur->parent == NULL)
79858e7e1c00ce5cc3ce959833b888c50ed9fd9d5aaeDaniel Veillard		return(NULL);
79868e7e1c00ce5cc3ce959833b888c50ed9fd9d5aaeDaniel Veillard	    if ((cur->parent->type == XML_ELEMENT_NODE) &&
7987652d8a949447833405cc0805f4b7ff1179e59ed2Daniel Veillard		((cur->parent->name[0] == ' ') ||
7988652d8a949447833405cc0805f4b7ff1179e59ed2Daniel Veillard		 (xmlStrEqual(cur->parent->name,
7989652d8a949447833405cc0805f4b7ff1179e59ed2Daniel Veillard			      BAD_CAST "fake node libxslt"))))
79908e7e1c00ce5cc3ce959833b888c50ed9fd9d5aaeDaniel Veillard		return(NULL);
79913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    return(cur->parent);
79923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XML_ATTRIBUTE_NODE: {
79933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    xmlAttrPtr att = (xmlAttrPtr) ctxt->context->node;
79943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
79953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    return(att->parent);
79963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
7997dffd5c8dbc7b9052db7ae69dce419a96e22acc68Aleksey Sanin	case XML_NAMESPACE_DECL: {
7998dffd5c8dbc7b9052db7ae69dce419a96e22acc68Aleksey Sanin	    xmlNsPtr ns = (xmlNsPtr) ctxt->context->node;
799945490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
8000dffd5c8dbc7b9052db7ae69dce419a96e22acc68Aleksey Sanin	    if ((ns->next != NULL) &&
8001dffd5c8dbc7b9052db7ae69dce419a96e22acc68Aleksey Sanin	        (ns->next->type != XML_NAMESPACE_DECL))
8002dffd5c8dbc7b9052db7ae69dce419a96e22acc68Aleksey Sanin	        return((xmlNodePtr) ns->next);
8003081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack	    /* Bad, how did that namespace end up here ? */
8004dffd5c8dbc7b9052db7ae69dce419a96e22acc68Aleksey Sanin            return(NULL);
8005dffd5c8dbc7b9052db7ae69dce419a96e22acc68Aleksey Sanin	}
80063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XML_DOCUMENT_NODE:
80073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XML_DOCUMENT_TYPE_NODE:
80083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XML_DOCUMENT_FRAG_NODE:
80093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XML_HTML_DOCUMENT_NODE:
8010eae522a0d8aa9f830d2e447f29b504030dbb6bbdDaniel Veillard#ifdef LIBXML_DOCB_ENABLED
8011eae522a0d8aa9f830d2e447f29b504030dbb6bbdDaniel Veillard	case XML_DOCB_DOCUMENT_NODE:
80123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif
80133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    return(NULL);
80143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
80153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(NULL);
80163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
80173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
80183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
80193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNextAncestorOrSelf:
80203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
80213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur:  the current node in the traversal
80223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
80233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Traversal function for the "ancestor-or-self" direction
80243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * he ancestor-or-self axis contains the context node and ancestors of
80253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the context node in reverse document order; thus the context node is
80263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the first node on the axis, and the context node's parent the second;
80273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * parent here is defined the same as with the parent axis.
80283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
80293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the next element following that axis
80303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
80313473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNodePtr
80323473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNextAncestorOrSelf(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
8033a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard    if ((ctxt == NULL) || (ctxt->context == NULL)) return(NULL);
80343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (cur == NULL)
80353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        return(ctxt->context->node);
80363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(xmlXPathNextAncestor(ctxt, cur));
80373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
80383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
80393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
80403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNextFollowingSibling:
80413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
80423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur:  the current node in the traversal
80433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
80443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Traversal function for the "following-sibling" direction
80453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The following-sibling axis contains the following siblings of the context
80463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * node in document order.
80473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
80483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the next element following that axis
80493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
80503473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNodePtr
80513473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNextFollowingSibling(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
8052a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard    if ((ctxt == NULL) || (ctxt->context == NULL)) return(NULL);
80533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if ((ctxt->context->node->type == XML_ATTRIBUTE_NODE) ||
80543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	(ctxt->context->node->type == XML_NAMESPACE_DECL))
80553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(NULL);
80563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (cur == (xmlNodePtr) ctxt->context->doc)
80573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        return(NULL);
80583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (cur == NULL)
80593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        return(ctxt->context->node->next);
80603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(cur->next);
80613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
80623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
80633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
80643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNextPrecedingSibling:
80653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
80663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur:  the current node in the traversal
80673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
80683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Traversal function for the "preceding-sibling" direction
80693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The preceding-sibling axis contains the preceding siblings of the context
80703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * node in reverse document order; the first preceding sibling is first on the
80713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * axis; the sibling preceding that node is the second on the axis and so on.
80723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
80733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the next element following that axis
80743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
80753473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNodePtr
80763473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNextPrecedingSibling(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
8077a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard    if ((ctxt == NULL) || (ctxt->context == NULL)) return(NULL);
80783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if ((ctxt->context->node->type == XML_ATTRIBUTE_NODE) ||
80793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	(ctxt->context->node->type == XML_NAMESPACE_DECL))
80803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(NULL);
80813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (cur == (xmlNodePtr) ctxt->context->doc)
80823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        return(NULL);
80833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (cur == NULL)
80843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        return(ctxt->context->node->prev);
8085f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    if ((cur->prev != NULL) && (cur->prev->type == XML_DTD_NODE)) {
8086f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	cur = cur->prev;
8087f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	if (cur == NULL)
8088f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	    return(ctxt->context->node->prev);
8089f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    }
80903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(cur->prev);
80913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
80923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
80933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
80943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNextFollowing:
80953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
80963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur:  the current node in the traversal
80973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
80983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Traversal function for the "following" direction
80993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The following axis contains all nodes in the same document as the context
81003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * node that are after the context node in document order, excluding any
81013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * descendants and excluding attribute nodes and namespace nodes; the nodes
81023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * are ordered in document order
81033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
81043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the next element following that axis
81053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
81063473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNodePtr
81073473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNextFollowing(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
8108a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard    if ((ctxt == NULL) || (ctxt->context == NULL)) return(NULL);
81093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (cur != NULL && cur->children != NULL)
81103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        return cur->children ;
81113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (cur == NULL) cur = ctxt->context->node;
81123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (cur == NULL) return(NULL) ; /* ERROR */
81133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (cur->next != NULL) return(cur->next) ;
81143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    do {
81153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        cur = cur->parent;
811611ce4004d86bb4b317c48b7d5124ba33e40e10f5Daniel Veillard        if (cur == NULL) break;
81173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        if (cur == (xmlNodePtr) ctxt->context->doc) return(NULL);
81183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        if (cur->next != NULL) return(cur->next);
81193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    } while (cur != NULL);
81203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(cur);
81213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
81223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
81233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/*
81243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathIsAncestor:
81253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ancestor:  the ancestor node
81263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @node:  the current node
81273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
81283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Check that @ancestor is a @node's ancestor
81293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
81303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * returns 1 if @ancestor is a @node's ancestor, 0 otherwise.
81313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
81323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorstatic int
81333473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathIsAncestor(xmlNodePtr ancestor, xmlNodePtr node) {
81343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if ((ancestor == NULL) || (node == NULL)) return(0);
81353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    /* nodes need to be in the same document */
81363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ancestor->doc != node->doc) return(0);
81373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    /* avoid searching if ancestor or node is the root node */
81383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ancestor == (xmlNodePtr) node->doc) return(1);
81393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (node == (xmlNodePtr) ancestor->doc) return(0);
81403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    while (node->parent != NULL) {
81413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        if (node->parent == ancestor)
81423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            return(1);
81433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	node = node->parent;
81443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
81453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(0);
81463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
81473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
81483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
81493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNextPreceding:
81503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
81513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur:  the current node in the traversal
81523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
81533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Traversal function for the "preceding" direction
81543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the preceding axis contains all nodes in the same document as the context
81553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * node that are before the context node in document order, excluding any
81563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * ancestors and excluding attribute nodes and namespace nodes; the nodes are
81573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * ordered in reverse document order
81583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
81593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the next element following that axis
81603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
81613473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNodePtr
8162f06307e2c172284bb41376c396f757bdac9bdd19Daniel VeillardxmlXPathNextPreceding(xmlXPathParserContextPtr ctxt, xmlNodePtr cur)
8163f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard{
8164a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard    if ((ctxt == NULL) || (ctxt->context == NULL)) return(NULL);
8165f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    if (cur == NULL)
8166f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        cur = ctxt->context->node;
81673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (cur == NULL)
8168f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	return (NULL);
8169f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    if ((cur->prev != NULL) && (cur->prev->type == XML_DTD_NODE))
8170f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	cur = cur->prev;
81713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    do {
81723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        if (cur->prev != NULL) {
8173f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            for (cur = cur->prev; cur->last != NULL; cur = cur->last) ;
8174f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            return (cur);
81753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        }
81763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
81773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        cur = cur->parent;
8178f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        if (cur == NULL)
8179f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            return (NULL);
8180f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        if (cur == ctxt->context->doc->children)
8181f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            return (NULL);
81823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    } while (xmlXPathIsAncestor(cur, ctxt->context->node));
8183f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    return (cur);
8184f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard}
8185f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
8186f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard/**
8187f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * xmlXPathNextPrecedingInternal:
8188f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * @ctxt:  the XPath Parser context
8189f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * @cur:  the current node in the traversal
8190f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard *
8191f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Traversal function for the "preceding" direction
8192f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * the preceding axis contains all nodes in the same document as the context
8193f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * node that are before the context node in document order, excluding any
8194f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * ancestors and excluding attribute nodes and namespace nodes; the nodes are
8195f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * ordered in reverse document order
819645490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard * This is a faster implementation but internal only since it requires a
8197f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * state kept in the parser context: ctxt->ancestor.
8198f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard *
8199f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Returns the next element following that axis
8200f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */
8201f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillardstatic xmlNodePtr
8202f06307e2c172284bb41376c396f757bdac9bdd19Daniel VeillardxmlXPathNextPrecedingInternal(xmlXPathParserContextPtr ctxt,
8203f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                              xmlNodePtr cur)
8204f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard{
8205a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard    if ((ctxt == NULL) || (ctxt->context == NULL)) return(NULL);
8206f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    if (cur == NULL) {
8207f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        cur = ctxt->context->node;
8208f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        if (cur == NULL)
8209f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            return (NULL);
821040c22b472b3d24ecc2f5b843aa3fffad6ed5cf5eWilliam M. Brack	if (cur->type == XML_NAMESPACE_DECL)
821140c22b472b3d24ecc2f5b843aa3fffad6ed5cf5eWilliam M. Brack	    cur = (xmlNodePtr)((xmlNsPtr)cur)->next;
8212f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        ctxt->ancestor = cur->parent;
8213f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    }
8214f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    if ((cur->prev != NULL) && (cur->prev->type == XML_DTD_NODE))
8215f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	cur = cur->prev;
8216f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    while (cur->prev == NULL) {
8217f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        cur = cur->parent;
8218f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        if (cur == NULL)
8219f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            return (NULL);
8220f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        if (cur == ctxt->context->doc->children)
8221f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            return (NULL);
8222f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        if (cur != ctxt->ancestor)
8223f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            return (cur);
8224f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        ctxt->ancestor = cur->parent;
8225f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    }
8226f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    cur = cur->prev;
8227f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    while (cur->last != NULL)
8228f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        cur = cur->last;
8229f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    return (cur);
82303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
82313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
82323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
82333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNextNamespace:
82343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
82353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur:  the current attribute in the traversal
82363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
82373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Traversal function for the "namespace" direction
82383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the namespace axis contains the namespace nodes of the context node;
82393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the order of nodes on this axis is implementation-defined; the axis will
82403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * be empty unless the context node is an element
82413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
824220ee8c03107e5d5724765da513d595fdaf290dceDaniel Veillard * We keep the XML namespace node at the end of the list.
824320ee8c03107e5d5724765da513d595fdaf290dceDaniel Veillard *
82443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the next element following that axis
82453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
82463473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNodePtr
82473473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNextNamespace(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
8248a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard    if ((ctxt == NULL) || (ctxt->context == NULL)) return(NULL);
82493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ctxt->context->node->type != XML_ELEMENT_NODE) return(NULL);
8250fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard    if (ctxt->context->tmpNsList == NULL && cur != (xmlNodePtr) xmlXPathXMLNamespace) {
82517d7e37919fc6c7f257769c867122d885d2aae26fDaniel Veillard        if (ctxt->context->tmpNsList != NULL)
82527d7e37919fc6c7f257769c867122d885d2aae26fDaniel Veillard	    xmlFree(ctxt->context->tmpNsList);
825345490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	ctxt->context->tmpNsList =
82543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    xmlGetNsList(ctxt->context->doc, ctxt->context->node);
82557d7e37919fc6c7f257769c867122d885d2aae26fDaniel Veillard	ctxt->context->tmpNsNr = 0;
8256fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard	if (ctxt->context->tmpNsList != NULL) {
8257fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard	    while (ctxt->context->tmpNsList[ctxt->context->tmpNsNr] != NULL) {
8258fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard		ctxt->context->tmpNsNr++;
8259fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard	    }
8260fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard	}
8261fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard	return((xmlNodePtr) xmlXPathXMLNamespace);
82627d7e37919fc6c7f257769c867122d885d2aae26fDaniel Veillard    }
8263fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard    if (ctxt->context->tmpNsNr > 0) {
8264fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard	return (xmlNodePtr)ctxt->context->tmpNsList[--ctxt->context->tmpNsNr];
8265fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard    } else {
8266fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard	if (ctxt->context->tmpNsList != NULL)
8267fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard	    xmlFree(ctxt->context->tmpNsList);
82687d7e37919fc6c7f257769c867122d885d2aae26fDaniel Veillard	ctxt->context->tmpNsList = NULL;
8269fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard	return(NULL);
82703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
82713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
82723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
82733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
82743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNextAttribute:
82753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
82763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur:  the current attribute in the traversal
82773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
82783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Traversal function for the "attribute" direction
82793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * TODO: support DTD inherited default attributes
82803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
82813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the next element following that axis
82823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
82833473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNodePtr
82843473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNextAttribute(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
8285a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard    if ((ctxt == NULL) || (ctxt->context == NULL)) return(NULL);
8286e470df7fdd3505c6232d6498f3b8834ebfce522dDaniel Veillard    if (ctxt->context->node == NULL)
8287e470df7fdd3505c6232d6498f3b8834ebfce522dDaniel Veillard	return(NULL);
8288e470df7fdd3505c6232d6498f3b8834ebfce522dDaniel Veillard    if (ctxt->context->node->type != XML_ELEMENT_NODE)
8289e470df7fdd3505c6232d6498f3b8834ebfce522dDaniel Veillard	return(NULL);
82903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (cur == NULL) {
82913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        if (ctxt->context->node == (xmlNodePtr) ctxt->context->doc)
82923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    return(NULL);
82933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        return((xmlNodePtr)ctxt->context->node->properties);
82943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
82953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return((xmlNodePtr)cur->next);
82963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
82973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
82983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/************************************************************************
82993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *									*
83003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *		NodeTest Functions					*
83013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *									*
83023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ************************************************************************/
83033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
83043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define IS_FUNCTION			200
83053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
8306d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard
8307d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard/************************************************************************
8308d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard *									*
8309d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard *		Implicit tree core function library			*
8310d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard *									*
8311d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard ************************************************************************/
8312d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard
83133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
8314d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * xmlXPathRoot:
83153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
83163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
8317d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * Initialize the context to the root of the document
83183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
8319d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillardvoid
8320d8df6c0e8c883e1d618388d266015dda36731440Daniel VeillardxmlXPathRoot(xmlXPathParserContextPtr ctxt) {
8321a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    if ((ctxt == NULL) || (ctxt->context == NULL))
8322a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	return;
8323d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard    ctxt->context->node = (xmlNodePtr) ctxt->context->doc;
8324a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    valuePush(ctxt, xmlXPathCacheNewNodeSet(ctxt->context,
8325a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	ctxt->context->node));
8326d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard}
83273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
8328d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard/************************************************************************
8329d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard *									*
8330d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard *		The explicit core function library			*
8331d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard *http://www.w3.org/Style/XSL/Group/1999/07/xpath-19990705.html#corelib	*
8332d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard *									*
8333d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard ************************************************************************/
83343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
8335d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard
8336d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard/**
8337d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * xmlXPathLastFunction:
8338d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * @ctxt:  the XPath Parser context
8339d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * @nargs:  the number of arguments
8340d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard *
8341d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * Implement the last() XPath function
8342d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard *    number last()
8343d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * The last function returns the number of nodes in the context node list.
8344d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard */
8345d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillardvoid
8346d8df6c0e8c883e1d618388d266015dda36731440Daniel VeillardxmlXPathLastFunction(xmlXPathParserContextPtr ctxt, int nargs) {
8347d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard    CHECK_ARITY(0);
8348d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard    if (ctxt->context->contextSize >= 0) {
8349a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	valuePush(ctxt,
8350a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathCacheNewFloat(ctxt->context,
8351a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		(double) ctxt->context->contextSize));
8352d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_EXPR
8353d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	xmlGenericError(xmlGenericErrorContext,
8354d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard		"last() : %d\n", ctxt->context->contextSize);
83553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif
8356d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard    } else {
8357d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	XP_ERROR(XPATH_INVALID_CTXT_SIZE);
83583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
8359d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard}
83603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
8361d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard/**
8362d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * xmlXPathPositionFunction:
8363d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * @ctxt:  the XPath Parser context
8364d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * @nargs:  the number of arguments
8365d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard *
8366d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * Implement the position() XPath function
8367d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard *    number position()
8368d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * The position function returns the position of the context node in the
8369cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * context node list. The first position is 1, and so the last position
8370d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * will be equal to last().
8371d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard */
8372d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillardvoid
8373d8df6c0e8c883e1d618388d266015dda36731440Daniel VeillardxmlXPathPositionFunction(xmlXPathParserContextPtr ctxt, int nargs) {
8374d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard    CHECK_ARITY(0);
8375d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard    if (ctxt->context->proximityPosition >= 0) {
8376d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	valuePush(ctxt,
8377a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	      xmlXPathCacheNewFloat(ctxt->context,
8378a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		(double) ctxt->context->proximityPosition));
8379d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_EXPR
8380d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	xmlGenericError(xmlGenericErrorContext, "position() : %d\n",
8381d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard		ctxt->context->proximityPosition);
83823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif
8383d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard    } else {
8384d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	XP_ERROR(XPATH_INVALID_CTXT_POSITION);
8385d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard    }
8386d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard}
83873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
83883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
83893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathCountFunction:
83903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
83913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs:  the number of arguments
83923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
83933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the count() XPath function
83943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *    number count(node-set)
83953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
83963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
83973473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathCountFunction(xmlXPathParserContextPtr ctxt, int nargs) {
83983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathObjectPtr cur;
83993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
84003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CHECK_ARITY(1);
840145490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard    if ((ctxt->value == NULL) ||
84023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	((ctxt->value->type != XPATH_NODESET) &&
84033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	 (ctxt->value->type != XPATH_XSLT_TREE)))
84043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	XP_ERROR(XPATH_INVALID_TYPE);
84053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    cur = valuePop(ctxt);
84063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
8407911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard    if ((cur == NULL) || (cur->nodesetval == NULL))
8408a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	valuePush(ctxt, xmlXPathCacheNewFloat(ctxt->context, (double) 0));
84090c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack    else if ((cur->type == XPATH_NODESET) || (cur->type == XPATH_XSLT_TREE)) {
8410a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	valuePush(ctxt, xmlXPathCacheNewFloat(ctxt->context,
8411a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    (double) cur->nodesetval->nodeNr));
8412fe70332f7f29f146a364c73450729a8b3274daeeDaniel Veillard    } else {
8413fe70332f7f29f146a364c73450729a8b3274daeeDaniel Veillard	if ((cur->nodesetval->nodeNr != 1) ||
8414fe70332f7f29f146a364c73450729a8b3274daeeDaniel Veillard	    (cur->nodesetval->nodeTab == NULL)) {
8415a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    valuePush(ctxt, xmlXPathCacheNewFloat(ctxt->context, (double) 0));
8416fe70332f7f29f146a364c73450729a8b3274daeeDaniel Veillard	} else {
8417fe70332f7f29f146a364c73450729a8b3274daeeDaniel Veillard	    xmlNodePtr tmp;
8418fe70332f7f29f146a364c73450729a8b3274daeeDaniel Veillard	    int i = 0;
8419fe70332f7f29f146a364c73450729a8b3274daeeDaniel Veillard
8420fe70332f7f29f146a364c73450729a8b3274daeeDaniel Veillard	    tmp = cur->nodesetval->nodeTab[0];
8421fe70332f7f29f146a364c73450729a8b3274daeeDaniel Veillard	    if (tmp != NULL) {
8422fe70332f7f29f146a364c73450729a8b3274daeeDaniel Veillard		tmp = tmp->children;
8423fe70332f7f29f146a364c73450729a8b3274daeeDaniel Veillard		while (tmp != NULL) {
8424fe70332f7f29f146a364c73450729a8b3274daeeDaniel Veillard		    tmp = tmp->next;
8425fe70332f7f29f146a364c73450729a8b3274daeeDaniel Veillard		    i++;
8426fe70332f7f29f146a364c73450729a8b3274daeeDaniel Veillard		}
8427fe70332f7f29f146a364c73450729a8b3274daeeDaniel Veillard	    }
8428a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    valuePush(ctxt, xmlXPathCacheNewFloat(ctxt->context, (double) i));
8429fe70332f7f29f146a364c73450729a8b3274daeeDaniel Veillard	}
8430fe70332f7f29f146a364c73450729a8b3274daeeDaniel Veillard    }
8431a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathReleaseObject(ctxt->context, cur);
84323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
84333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
84343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
8435ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathGetElementsByIds:
8436ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @doc:  the document
8437ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @ids:  a whitespace separated list of IDs
8438ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
8439ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Selects elements by their unique ID.
8440ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
8441ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns a node-set of selected elements.
8442ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */
8443ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillardstatic xmlNodeSetPtr
8444ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathGetElementsByIds (xmlDocPtr doc, const xmlChar *ids) {
8445ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    xmlNodeSetPtr ret;
8446ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    const xmlChar *cur = ids;
8447ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    xmlChar *ID;
8448ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    xmlAttrPtr attr;
8449ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    xmlNodePtr elem = NULL;
8450ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
84517a985a18c2fee0aa9b490792dd990b75506e3740Daniel Veillard    if (ids == NULL) return(NULL);
84527a985a18c2fee0aa9b490792dd990b75506e3740Daniel Veillard
8453ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    ret = xmlXPathNodeSetCreate(NULL);
8454f88d849a4e994c94c0d0814a4befb43c990ceebdDaniel Veillard    if (ret == NULL)
8455f88d849a4e994c94c0d0814a4befb43c990ceebdDaniel Veillard        return(ret);
8456ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
845776e95df05556c9610b564b14cf578c8f9e34c9c1William M. Brack    while (IS_BLANK_CH(*cur)) cur++;
8458ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    while (*cur != 0) {
845976e95df05556c9610b564b14cf578c8f9e34c9c1William M. Brack	while ((!IS_BLANK_CH(*cur)) && (*cur != 0))
8460e209b330558d170da195acb3a7618b0048d22c9eDaniel Veillard	    cur++;
8461ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
8462ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard        ID = xmlStrndup(ids, cur - ids);
8463e209b330558d170da195acb3a7618b0048d22c9eDaniel Veillard	if (ID != NULL) {
846468cb4b2498088cf920ed6c9490b134ce7f38909fDaniel Veillard	    /*
846568cb4b2498088cf920ed6c9490b134ce7f38909fDaniel Veillard	     * We used to check the fact that the value passed
846668cb4b2498088cf920ed6c9490b134ce7f38909fDaniel Veillard	     * was an NCName, but this generated much troubles for
846768cb4b2498088cf920ed6c9490b134ce7f38909fDaniel Veillard	     * me and Aleksey Sanin, people blatantly violated that
846868cb4b2498088cf920ed6c9490b134ce7f38909fDaniel Veillard	     * constaint, like Visa3D spec.
846968cb4b2498088cf920ed6c9490b134ce7f38909fDaniel Veillard	     * if (xmlValidateNCName(ID, 1) == 0)
847068cb4b2498088cf920ed6c9490b134ce7f38909fDaniel Veillard	     */
847168cb4b2498088cf920ed6c9490b134ce7f38909fDaniel Veillard	    attr = xmlGetID(doc, ID);
847268cb4b2498088cf920ed6c9490b134ce7f38909fDaniel Veillard	    if (attr != NULL) {
847368cb4b2498088cf920ed6c9490b134ce7f38909fDaniel Veillard		if (attr->type == XML_ATTRIBUTE_NODE)
847468cb4b2498088cf920ed6c9490b134ce7f38909fDaniel Veillard		    elem = attr->parent;
847568cb4b2498088cf920ed6c9490b134ce7f38909fDaniel Veillard		else if (attr->type == XML_ELEMENT_NODE)
847668cb4b2498088cf920ed6c9490b134ce7f38909fDaniel Veillard		    elem = (xmlNodePtr) attr;
847768cb4b2498088cf920ed6c9490b134ce7f38909fDaniel Veillard		else
847868cb4b2498088cf920ed6c9490b134ce7f38909fDaniel Veillard		    elem = NULL;
847968cb4b2498088cf920ed6c9490b134ce7f38909fDaniel Veillard		if (elem != NULL)
848068cb4b2498088cf920ed6c9490b134ce7f38909fDaniel Veillard		    xmlXPathNodeSetAdd(ret, elem);
8481e209b330558d170da195acb3a7618b0048d22c9eDaniel Veillard	    }
8482ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	    xmlFree(ID);
8483e209b330558d170da195acb3a7618b0048d22c9eDaniel Veillard	}
8484ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
848576e95df05556c9610b564b14cf578c8f9e34c9c1William M. Brack	while (IS_BLANK_CH(*cur)) cur++;
8486ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	ids = cur;
8487ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    }
8488ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    return(ret);
8489ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard}
8490ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
8491ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/**
84923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathIdFunction:
84933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
84943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs:  the number of arguments
84953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
84963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the id() XPath function
84973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *    node-set id(object)
84983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The id function selects elements by their unique ID
84993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * (see [5.2.1 Unique IDs]). When the argument to id is of type node-set,
85003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * then the result is the union of the result of applying id to the
85013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * string value of each of the nodes in the argument node-set. When the
85023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * argument to id is of any other type, the argument is converted to a
85033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * string as if by a call to the string function; the string is split
85043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * into a whitespace-separated list of tokens (whitespace is any sequence
85053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * of characters matching the production S); the result is a node-set
85063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * containing the elements in the same document as the context node that
85073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * have a unique ID equal to any of the tokens in the list.
85083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
85093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
85103473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathIdFunction(xmlXPathParserContextPtr ctxt, int nargs) {
8511ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    xmlChar *tokens;
8512ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    xmlNodeSetPtr ret;
8513ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    xmlXPathObjectPtr obj;
85143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
85153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CHECK_ARITY(1);
85163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    obj = valuePop(ctxt);
85173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (obj == NULL) XP_ERROR(XPATH_INVALID_OPERAND);
85180c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack    if ((obj->type == XPATH_NODESET) || (obj->type == XPATH_XSLT_TREE)) {
8519ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	xmlNodeSetPtr ns;
85203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	int i;
85213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
8522ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	ret = xmlXPathNodeSetCreate(NULL);
8523f88d849a4e994c94c0d0814a4befb43c990ceebdDaniel Veillard        /*
8524f88d849a4e994c94c0d0814a4befb43c990ceebdDaniel Veillard         * FIXME -- in an out-of-memory condition this will behave badly.
8525f88d849a4e994c94c0d0814a4befb43c990ceebdDaniel Veillard         * The solution is not clear -- we already popped an item from
8526f88d849a4e994c94c0d0814a4befb43c990ceebdDaniel Veillard         * ctxt, so the object is in a corrupt state.
8527f88d849a4e994c94c0d0814a4befb43c990ceebdDaniel Veillard         */
85283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
8529911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard	if (obj->nodesetval != NULL) {
8530911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard	    for (i = 0; i < obj->nodesetval->nodeNr; i++) {
8531ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard		tokens =
8532ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard		    xmlXPathCastNodeToString(obj->nodesetval->nodeTab[i]);
8533ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard		ns = xmlXPathGetElementsByIds(ctxt->context->doc, tokens);
8534ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard		ret = xmlXPathNodeSetMerge(ret, ns);
8535ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard		xmlXPathFreeNodeSet(ns);
8536ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard		if (tokens != NULL)
8537ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard		    xmlFree(tokens);
8538911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard	    }
85393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
8540a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	xmlXPathReleaseObject(ctxt->context, obj);
8541a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	valuePush(ctxt, xmlXPathCacheWrapNodeSet(ctxt->context, ret));
85423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return;
85433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
8544a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    obj = xmlXPathCacheConvertString(ctxt->context, obj);
8545ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    ret = xmlXPathGetElementsByIds(ctxt->context->doc, obj->stringval);
854645490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard    valuePush(ctxt, xmlXPathCacheWrapNodeSet(ctxt->context, ret));
8547a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathReleaseObject(ctxt->context, obj);
85483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return;
85493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
85503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
85513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
85523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathLocalNameFunction:
85533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
85543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs:  the number of arguments
85553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
85563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the local-name() XPath function
85573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *    string local-name(node-set?)
85583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The local-name function returns a string containing the local part
85593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * of the name of the node in the argument node-set that is first in
85603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * document order. If the node-set is empty or the first node has no
85613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * name, an empty string is returned. If the argument is omitted it
85623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * defaults to the context node.
85633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
85643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
85653473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathLocalNameFunction(xmlXPathParserContextPtr ctxt, int nargs) {
85663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathObjectPtr cur;
85673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
8568a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard    if (ctxt == NULL) return;
8569a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard
85703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (nargs == 0) {
8571a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	valuePush(ctxt, xmlXPathCacheNewNodeSet(ctxt->context,
8572a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    ctxt->context->node));
85733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	nargs = 1;
85743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
85753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
85763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CHECK_ARITY(1);
857745490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard    if ((ctxt->value == NULL) ||
85783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	((ctxt->value->type != XPATH_NODESET) &&
85793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	 (ctxt->value->type != XPATH_XSLT_TREE)))
85803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	XP_ERROR(XPATH_INVALID_TYPE);
85813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    cur = valuePop(ctxt);
85823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
8583911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard    if ((cur->nodesetval == NULL) || (cur->nodesetval->nodeNr == 0)) {
8584a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	valuePush(ctxt, xmlXPathCacheNewCString(ctxt->context, ""));
85853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    } else {
85863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	int i = 0; /* Should be first in document order !!!!! */
85873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	switch (cur->nodesetval->nodeTab[i]->type) {
85883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XML_ELEMENT_NODE:
85893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XML_ATTRIBUTE_NODE:
85903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XML_PI_NODE:
8591652d8a949447833405cc0805f4b7ff1179e59ed2Daniel Veillard	    if (cur->nodesetval->nodeTab[i]->name[0] == ' ')
8592a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		valuePush(ctxt, xmlXPathCacheNewCString(ctxt->context, ""));
8593652d8a949447833405cc0805f4b7ff1179e59ed2Daniel Veillard	    else
8594652d8a949447833405cc0805f4b7ff1179e59ed2Daniel Veillard		valuePush(ctxt,
8595a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		      xmlXPathCacheNewString(ctxt->context,
8596a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik			cur->nodesetval->nodeTab[i]->name));
85973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    break;
85983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XML_NAMESPACE_DECL:
8599a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    valuePush(ctxt, xmlXPathCacheNewString(ctxt->context,
86003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor			((xmlNsPtr)cur->nodesetval->nodeTab[i])->prefix));
86013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    break;
86023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	default:
8603a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    valuePush(ctxt, xmlXPathCacheNewCString(ctxt->context, ""));
86043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
86053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
8606a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathReleaseObject(ctxt->context, cur);
86073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
86083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
86093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
86103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNamespaceURIFunction:
86113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
86123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs:  the number of arguments
86133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
86143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the namespace-uri() XPath function
86153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *    string namespace-uri(node-set?)
86163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The namespace-uri function returns a string containing the
86173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * namespace URI of the expanded name of the node in the argument
86183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * node-set that is first in document order. If the node-set is empty,
86193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the first node has no name, or the expanded name has no namespace
86203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * URI, an empty string is returned. If the argument is omitted it
86213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * defaults to the context node.
86223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
86233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
86243473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNamespaceURIFunction(xmlXPathParserContextPtr ctxt, int nargs) {
86253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathObjectPtr cur;
86263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
8627a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard    if (ctxt == NULL) return;
8628a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard
86293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (nargs == 0) {
8630a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	valuePush(ctxt, xmlXPathCacheNewNodeSet(ctxt->context,
8631a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    ctxt->context->node));
86323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	nargs = 1;
86333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
86343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CHECK_ARITY(1);
863545490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard    if ((ctxt->value == NULL) ||
86363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	((ctxt->value->type != XPATH_NODESET) &&
86373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	 (ctxt->value->type != XPATH_XSLT_TREE)))
86383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	XP_ERROR(XPATH_INVALID_TYPE);
86393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    cur = valuePop(ctxt);
86403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
8641911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard    if ((cur->nodesetval == NULL) || (cur->nodesetval->nodeNr == 0)) {
8642a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	valuePush(ctxt, xmlXPathCacheNewCString(ctxt->context, ""));
86433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    } else {
86443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	int i = 0; /* Should be first in document order !!!!! */
86453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	switch (cur->nodesetval->nodeTab[i]->type) {
86463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XML_ELEMENT_NODE:
86473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XML_ATTRIBUTE_NODE:
86483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    if (cur->nodesetval->nodeTab[i]->ns == NULL)
8649a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		valuePush(ctxt, xmlXPathCacheNewCString(ctxt->context, ""));
86503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    else
8651a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		valuePush(ctxt, xmlXPathCacheNewString(ctxt->context,
86523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor			  cur->nodesetval->nodeTab[i]->ns->href));
86533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    break;
86543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	default:
8655a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    valuePush(ctxt, xmlXPathCacheNewCString(ctxt->context, ""));
86563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
86573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
8658a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathReleaseObject(ctxt->context, cur);
86593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
86603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
86613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
86623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNameFunction:
86633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
86643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs:  the number of arguments
86653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
86663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the name() XPath function
86673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *    string name(node-set?)
86683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The name function returns a string containing a QName representing
8669cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * the name of the node in the argument node-set that is first in document
86703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * order. The QName must represent the name with respect to the namespace
86713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * declarations in effect on the node whose name is being represented.
86723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Typically, this will be the form in which the name occurred in the XML
86733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * source. This need not be the case if there are namespace declarations
86743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * in effect on the node that associate multiple prefixes with the same
86753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * namespace. However, an implementation may include information about
86763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the original prefix in its representation of nodes; in this case, an
86773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * implementation can ensure that the returned string is always the same
86783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * as the QName used in the XML source. If the argument it omitted it
86793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * defaults to the context node.
86803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Libxml keep the original prefix so the "real qualified name" used is
86813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * returned.
86823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
868356a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic void
86840438375d2e6be47d0179826271081ae64df94f8bDaniel VeillardxmlXPathNameFunction(xmlXPathParserContextPtr ctxt, int nargs)
86850438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard{
86863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathObjectPtr cur;
86873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
86883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (nargs == 0) {
8689a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	valuePush(ctxt, xmlXPathCacheNewNodeSet(ctxt->context,
8690a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    ctxt->context->node));
86910438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard        nargs = 1;
86923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
86933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
86943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CHECK_ARITY(1);
86950438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard    if ((ctxt->value == NULL) ||
86960438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard        ((ctxt->value->type != XPATH_NODESET) &&
86970438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard         (ctxt->value->type != XPATH_XSLT_TREE)))
86980438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard        XP_ERROR(XPATH_INVALID_TYPE);
86993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    cur = valuePop(ctxt);
87003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
8701911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard    if ((cur->nodesetval == NULL) || (cur->nodesetval->nodeNr == 0)) {
8702a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik        valuePush(ctxt, xmlXPathCacheNewCString(ctxt->context, ""));
87033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    } else {
87040438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard        int i = 0;              /* Should be first in document order !!!!! */
87053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
87060438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard        switch (cur->nodesetval->nodeTab[i]->type) {
87070438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard            case XML_ELEMENT_NODE:
87080438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard            case XML_ATTRIBUTE_NODE:
8709652d8a949447833405cc0805f4b7ff1179e59ed2Daniel Veillard		if (cur->nodesetval->nodeTab[i]->name[0] == ' ')
8710a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    valuePush(ctxt,
8711a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik			xmlXPathCacheNewCString(ctxt->context, ""));
8712652d8a949447833405cc0805f4b7ff1179e59ed2Daniel Veillard		else if ((cur->nodesetval->nodeTab[i]->ns == NULL) ||
8713652d8a949447833405cc0805f4b7ff1179e59ed2Daniel Veillard                         (cur->nodesetval->nodeTab[i]->ns->prefix == NULL)) {
8714a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    valuePush(ctxt,
8715a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		        xmlXPathCacheNewString(ctxt->context,
8716a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik			    cur->nodesetval->nodeTab[i]->name));
8717652d8a949447833405cc0805f4b7ff1179e59ed2Daniel Veillard		} else {
8718c00cda8c065beba24706c9e8719f08e9de420274Daniel Veillard		    xmlChar *fullname;
871945490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
8720c00cda8c065beba24706c9e8719f08e9de420274Daniel Veillard		    fullname = xmlBuildQName(cur->nodesetval->nodeTab[i]->name,
8721c00cda8c065beba24706c9e8719f08e9de420274Daniel Veillard				     cur->nodesetval->nodeTab[i]->ns->prefix,
8722c00cda8c065beba24706c9e8719f08e9de420274Daniel Veillard				     NULL, 0);
8723c00cda8c065beba24706c9e8719f08e9de420274Daniel Veillard		    if (fullname == cur->nodesetval->nodeTab[i]->name)
8724c00cda8c065beba24706c9e8719f08e9de420274Daniel Veillard			fullname = xmlStrdup(cur->nodesetval->nodeTab[i]->name);
8725c00cda8c065beba24706c9e8719f08e9de420274Daniel Veillard		    if (fullname == NULL) {
8726c00cda8c065beba24706c9e8719f08e9de420274Daniel Veillard			XP_ERROR(XPATH_MEMORY_ERROR);
8727c00cda8c065beba24706c9e8719f08e9de420274Daniel Veillard		    }
8728a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    valuePush(ctxt, xmlXPathCacheWrapString(
8729a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik			ctxt->context, fullname));
87300438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard                }
87310438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard                break;
87320438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard            default:
8733a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		valuePush(ctxt, xmlXPathCacheNewNodeSet(ctxt->context,
8734a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    cur->nodesetval->nodeTab[i]));
87350438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard                xmlXPathLocalNameFunction(ctxt, 1);
87360438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard        }
87373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
8738a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathReleaseObject(ctxt->context, cur);
87393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
87403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
8741fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard
8742fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard/**
87433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathStringFunction:
87443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
87453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs:  the number of arguments
87463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
87473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the string() XPath function
87483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *    string string(object?)
8749081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack * The string function converts an object to a string as follows:
87503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *    - A node-set is converted to a string by returning the value of
87513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *      the node in the node-set that is first in document order.
87523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *      If the node-set is empty, an empty string is returned.
87533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *    - A number is converted to a string as follows
875445490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *      + NaN is converted to the string NaN
875545490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *      + positive zero is converted to the string 0
875645490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *      + negative zero is converted to the string 0
875745490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *      + positive infinity is converted to the string Infinity
875845490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *      + negative infinity is converted to the string -Infinity
87593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *      + if the number is an integer, the number is represented in
87603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *        decimal form as a Number with no decimal point and no leading
87613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *        zeros, preceded by a minus sign (-) if the number is negative
87623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *      + otherwise, the number is represented in decimal form as a
87633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *        Number including a decimal point with at least one digit
87643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *        before the decimal point and at least one digit after the
87653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *        decimal point, preceded by a minus sign (-) if the number
87663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *        is negative; there must be no leading zeros before the decimal
8767cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard *        point apart possibly from the one required digit immediately
87683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *        before the decimal point; beyond the one required digit
87693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *        after the decimal point there must be as many, but only as
87703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *        many, more digits as are needed to uniquely distinguish the
87713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *        number from all other IEEE 754 numeric values.
87723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *    - The boolean false value is converted to the string false.
87733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *      The boolean true value is converted to the string true.
87743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
87753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * If the argument is omitted, it defaults to a node-set with the
87763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * context node as its only member.
87773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
87783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
87793473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathStringFunction(xmlXPathParserContextPtr ctxt, int nargs) {
87803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathObjectPtr cur;
87813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
8782a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard    if (ctxt == NULL) return;
87833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (nargs == 0) {
8784a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    valuePush(ctxt,
8785a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	xmlXPathCacheWrapString(ctxt->context,
8786a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathCastNodeToString(ctxt->context->node)));
8787ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	return;
87883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
87893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
87903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CHECK_ARITY(1);
87913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    cur = valuePop(ctxt);
87923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (cur == NULL) XP_ERROR(XPATH_INVALID_OPERAND);
8793a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    valuePush(ctxt, xmlXPathCacheConvertString(ctxt->context, cur));
87943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
87953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
87963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
87973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathStringLengthFunction:
87983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
87993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs:  the number of arguments
88003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
88013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the string-length() XPath function
88023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *    number string-length(string?)
88033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The string-length returns the number of characters in the string
88043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * (see [3.6 Strings]). If the argument is omitted, it defaults to
88053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the context node converted to a string, in other words the value
88063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * of the context node.
88073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
88083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
88093473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathStringLengthFunction(xmlXPathParserContextPtr ctxt, int nargs) {
88103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathObjectPtr cur;
88113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
88123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (nargs == 0) {
8813a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard        if ((ctxt == NULL) || (ctxt->context == NULL))
8814a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard	    return;
88153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (ctxt->context->node == NULL) {
8816a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    valuePush(ctxt, xmlXPathCacheNewFloat(ctxt->context, 0));
88173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	} else {
88183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    xmlChar *content;
88193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
8820ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	    content = xmlXPathCastNodeToString(ctxt->context->node);
8821a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    valuePush(ctxt, xmlXPathCacheNewFloat(ctxt->context,
8822a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		xmlUTF8Strlen(content)));
88233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    xmlFree(content);
88243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
88253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return;
88263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
88273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CHECK_ARITY(1);
88283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CAST_TO_STRING;
88293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CHECK_TYPE(XPATH_STRING);
88303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    cur = valuePop(ctxt);
8831a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    valuePush(ctxt, xmlXPathCacheNewFloat(ctxt->context,
883245490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	xmlUTF8Strlen(cur->stringval)));
8833a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathReleaseObject(ctxt->context, cur);
88343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
88353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
88363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
88373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathConcatFunction:
88383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
88393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs:  the number of arguments
88403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
88413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the concat() XPath function
88423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *    string concat(string, string, string*)
88433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The concat function returns the concatenation of its arguments.
88443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
88453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
88463473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathConcatFunction(xmlXPathParserContextPtr ctxt, int nargs) {
88473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathObjectPtr cur, newobj;
88483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlChar *tmp;
88493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
8850a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard    if (ctxt == NULL) return;
88513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (nargs < 2) {
88523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	CHECK_ARITY(2);
88533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
88543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
88553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CAST_TO_STRING;
88563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    cur = valuePop(ctxt);
88573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if ((cur == NULL) || (cur->type != XPATH_STRING)) {
8858a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	xmlXPathReleaseObject(ctxt->context, cur);
88593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return;
88603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
88613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    nargs--;
88623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
88633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    while (nargs > 0) {
88643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	CAST_TO_STRING;
88653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	newobj = valuePop(ctxt);
88663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if ((newobj == NULL) || (newobj->type != XPATH_STRING)) {
8867a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathReleaseObject(ctxt->context, newobj);
8868a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathReleaseObject(ctxt->context, cur);
88693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    XP_ERROR(XPATH_INVALID_TYPE);
88703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
88713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	tmp = xmlStrcat(newobj->stringval, cur->stringval);
88723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	newobj->stringval = cur->stringval;
88733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	cur->stringval = tmp;
8874a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	xmlXPathReleaseObject(ctxt->context, newobj);
88753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	nargs--;
88763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
88773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    valuePush(ctxt, cur);
88783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
88793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
88803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
88813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathContainsFunction:
88823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
88833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs:  the number of arguments
88843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
88853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the contains() XPath function
88863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *    boolean contains(string, string)
88873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The contains function returns true if the first argument string
88883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * contains the second argument string, and otherwise returns false.
88893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
88903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
88913473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathContainsFunction(xmlXPathParserContextPtr ctxt, int nargs) {
88923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathObjectPtr hay, needle;
88933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
88943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CHECK_ARITY(2);
88953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CAST_TO_STRING;
88963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CHECK_TYPE(XPATH_STRING);
88973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    needle = valuePop(ctxt);
88983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CAST_TO_STRING;
88993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    hay = valuePop(ctxt);
8900a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
89013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if ((hay == NULL) || (hay->type != XPATH_STRING)) {
8902a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	xmlXPathReleaseObject(ctxt->context, hay);
8903a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	xmlXPathReleaseObject(ctxt->context, needle);
89043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	XP_ERROR(XPATH_INVALID_TYPE);
89053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
89063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (xmlStrstr(hay->stringval, needle->stringval))
8907a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	valuePush(ctxt, xmlXPathCacheNewBoolean(ctxt->context, 1));
89083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    else
8909a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	valuePush(ctxt, xmlXPathCacheNewBoolean(ctxt->context, 0));
8910a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathReleaseObject(ctxt->context, hay);
8911a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathReleaseObject(ctxt->context, needle);
89123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
89133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
89143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
89153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathStartsWithFunction:
89163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
89173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs:  the number of arguments
89183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
89193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the starts-with() XPath function
89203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *    boolean starts-with(string, string)
89213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The starts-with function returns true if the first argument string
89223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * starts with the second argument string, and otherwise returns false.
89233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
89243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
89253473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathStartsWithFunction(xmlXPathParserContextPtr ctxt, int nargs) {
89263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathObjectPtr hay, needle;
89273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    int n;
89283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
89293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CHECK_ARITY(2);
89303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CAST_TO_STRING;
89313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CHECK_TYPE(XPATH_STRING);
89323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    needle = valuePop(ctxt);
89333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CAST_TO_STRING;
89343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    hay = valuePop(ctxt);
8935a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
89363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if ((hay == NULL) || (hay->type != XPATH_STRING)) {
8937a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	xmlXPathReleaseObject(ctxt->context, hay);
8938a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	xmlXPathReleaseObject(ctxt->context, needle);
89393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	XP_ERROR(XPATH_INVALID_TYPE);
89403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
89413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    n = xmlStrlen(needle->stringval);
89423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (xmlStrncmp(hay->stringval, needle->stringval, n))
8943a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik        valuePush(ctxt, xmlXPathCacheNewBoolean(ctxt->context, 0));
89443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    else
8945a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik        valuePush(ctxt, xmlXPathCacheNewBoolean(ctxt->context, 1));
8946a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathReleaseObject(ctxt->context, hay);
8947a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathReleaseObject(ctxt->context, needle);
89483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
89493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
89503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
89513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathSubstringFunction:
89523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
89533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs:  the number of arguments
89543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
89553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the substring() XPath function
89563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *    string substring(string, number, number?)
89573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The substring function returns the substring of the first argument
89583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * starting at the position specified in the second argument with
89593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * length specified in the third argument. For example,
89603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * substring("12345",2,3) returns "234". If the third argument is not
89613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * specified, it returns the substring starting at the position specified
89623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * in the second argument and continuing to the end of the string. For
89633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * example, substring("12345",2) returns "2345".  More precisely, each
89643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * character in the string (see [3.6 Strings]) is considered to have a
89653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * numeric position: the position of the first character is 1, the position
89663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * of the second character is 2 and so on. The returned substring contains
89673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * those characters for which the position of the character is greater than
89683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * or equal to the second argument and, if the third argument is specified,
89693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * less than the sum of the second and third arguments; the comparisons
89703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * and addition used for the above follow the standard IEEE 754 rules. Thus:
897145490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *  - substring("12345", 1.5, 2.6) returns "234"
897245490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *  - substring("12345", 0, 3) returns "12"
897345490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *  - substring("12345", 0 div 0, 3) returns ""
897445490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *  - substring("12345", 1, 0 div 0) returns ""
897545490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *  - substring("12345", -42, 1 div 0) returns "12345"
897645490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *  - substring("12345", -1 div 0, 1 div 0) returns ""
89773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
89783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
89793473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathSubstringFunction(xmlXPathParserContextPtr ctxt, int nargs) {
89803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathObjectPtr str, start, len;
898197ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard    double le=0, in;
898297ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard    int i, l, m;
89833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlChar *ret;
89843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
89853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (nargs < 2) {
89863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	CHECK_ARITY(2);
89873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
89883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (nargs > 3) {
89893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	CHECK_ARITY(3);
89903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
899197ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard    /*
899297ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard     * take care of possible last (position) argument
899397ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard    */
89943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (nargs == 3) {
89953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	CAST_TO_NUMBER;
89963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	CHECK_TYPE(XPATH_NUMBER);
89973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	len = valuePop(ctxt);
89983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	le = len->floatval;
8999a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	xmlXPathReleaseObject(ctxt->context, len);
90003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
900197ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard
90023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CAST_TO_NUMBER;
90033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CHECK_TYPE(XPATH_NUMBER);
90043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    start = valuePop(ctxt);
90053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    in = start->floatval;
9006a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathReleaseObject(ctxt->context, start);
90073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CAST_TO_STRING;
90083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CHECK_TYPE(XPATH_STRING);
90093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    str = valuePop(ctxt);
901097ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard    m = xmlUTF8Strlen((const unsigned char *)str->stringval);
901197ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard
901297ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard    /*
901397ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard     * If last pos not present, calculate last position
901497ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard    */
90159e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard    if (nargs != 3) {
90169e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard	le = (double)m;
901745490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	if (in < 1.0)
90189e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard	    in = 1.0;
90199e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard    }
902097ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard
902145490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard    /* Need to check for the special cases where either
90220eafdef9881c396ce4c014359d8f497cc088cfabDaniel Veillard     * the index is NaN, the length is NaN, or both
90230eafdef9881c396ce4c014359d8f497cc088cfabDaniel Veillard     * arguments are infinity (relying on Inf + -Inf = NaN)
902497ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard     */
90259e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard    if (!xmlXPathIsNaN(in + le) && !xmlXPathIsInf(in)) {
90260eafdef9881c396ce4c014359d8f497cc088cfabDaniel Veillard        /*
90279e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard         * To meet the requirements of the spec, the arguments
902845490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	 * must be converted to integer format before
90299e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard	 * initial index calculations are done
90300eafdef9881c396ce4c014359d8f497cc088cfabDaniel Veillard         *
90319e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard         * First we go to integer form, rounding up
90329e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard	 * and checking for special cases
90330eafdef9881c396ce4c014359d8f497cc088cfabDaniel Veillard         */
90340eafdef9881c396ce4c014359d8f497cc088cfabDaniel Veillard        i = (int) in;
90359e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard        if (((double)i)+0.5 <= in) i++;
90369e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard
90379e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard	if (xmlXPathIsInf(le) == 1) {
90389e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard	    l = m;
90399e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard	    if (i < 1)
90409e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard		i = 1;
90419e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard	}
90429e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard	else if (xmlXPathIsInf(le) == -1 || le < 0.0)
90439e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard	    l = 0;
90449e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard	else {
90459e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard	    l = (int) le;
90469e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard	    if (((double)l)+0.5 <= le) l++;
90479e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard	}
90480eafdef9881c396ce4c014359d8f497cc088cfabDaniel Veillard
90499e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard	/* Now we normalize inidices */
90509e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard        i -= 1;
90519e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard        l += i;
90529e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard        if (i < 0)
90539e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard            i = 0;
90549e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard        if (l > m)
90559e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard            l = m;
90563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
90570eafdef9881c396ce4c014359d8f497cc088cfabDaniel Veillard        /* number of chars to copy */
90580eafdef9881c396ce4c014359d8f497cc088cfabDaniel Veillard        l -= i;
90593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
90600eafdef9881c396ce4c014359d8f497cc088cfabDaniel Veillard        ret = xmlUTF8Strsub(str->stringval, i, l);
90610eafdef9881c396ce4c014359d8f497cc088cfabDaniel Veillard    }
90620eafdef9881c396ce4c014359d8f497cc088cfabDaniel Veillard    else {
90630eafdef9881c396ce4c014359d8f497cc088cfabDaniel Veillard        ret = NULL;
90640eafdef9881c396ce4c014359d8f497cc088cfabDaniel Veillard    }
90653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ret == NULL)
9066a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	valuePush(ctxt, xmlXPathCacheNewCString(ctxt->context, ""));
90673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    else {
9068a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	valuePush(ctxt, xmlXPathCacheNewString(ctxt->context, ret));
90693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	xmlFree(ret);
90703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
9071a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathReleaseObject(ctxt->context, str);
90723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
90733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
90743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
90753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathSubstringBeforeFunction:
90763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
90773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs:  the number of arguments
90783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
90793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the substring-before() XPath function
90803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *    string substring-before(string, string)
90813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The substring-before function returns the substring of the first
90823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * argument string that precedes the first occurrence of the second
90833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * argument string in the first argument string, or the empty string
90843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * if the first argument string does not contain the second argument
90853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * string. For example, substring-before("1999/04/01","/") returns 1999.
90863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
90873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
90883473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathSubstringBeforeFunction(xmlXPathParserContextPtr ctxt, int nargs) {
90893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  xmlXPathObjectPtr str;
90903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  xmlXPathObjectPtr find;
90913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  xmlBufferPtr target;
90923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  const xmlChar *point;
90933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  int offset;
909445490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
90953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  CHECK_ARITY(2);
90963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  CAST_TO_STRING;
90973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  find = valuePop(ctxt);
90983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  CAST_TO_STRING;
90993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  str = valuePop(ctxt);
910045490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
91013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  target = xmlBufferCreate();
91023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  if (target) {
91033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    point = xmlStrstr(str->stringval, find->stringval);
91043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (point) {
91053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor      offset = (int)(point - str->stringval);
91063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor      xmlBufferAdd(target, str->stringval, offset);
91073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
9108a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    valuePush(ctxt, xmlXPathCacheNewString(ctxt->context,
9109a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	xmlBufferContent(target)));
91103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlBufferFree(target);
91113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  }
9112a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik  xmlXPathReleaseObject(ctxt->context, str);
9113a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik  xmlXPathReleaseObject(ctxt->context, find);
91143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
91153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
91163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
91173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathSubstringAfterFunction:
91183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
91193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs:  the number of arguments
91203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
91213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the substring-after() XPath function
91223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *    string substring-after(string, string)
91233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The substring-after function returns the substring of the first
91243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * argument string that follows the first occurrence of the second
91253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * argument string in the first argument string, or the empty stringi
91263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * if the first argument string does not contain the second argument
91273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * string. For example, substring-after("1999/04/01","/") returns 04/01,
91283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * and substring-after("1999/04/01","19") returns 99/04/01.
91293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
91303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
91313473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathSubstringAfterFunction(xmlXPathParserContextPtr ctxt, int nargs) {
91323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  xmlXPathObjectPtr str;
91333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  xmlXPathObjectPtr find;
91343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  xmlBufferPtr target;
91353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  const xmlChar *point;
91363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  int offset;
913745490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
91383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  CHECK_ARITY(2);
91393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  CAST_TO_STRING;
91403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  find = valuePop(ctxt);
91413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  CAST_TO_STRING;
91423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  str = valuePop(ctxt);
914345490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
91443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  target = xmlBufferCreate();
91453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  if (target) {
91463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    point = xmlStrstr(str->stringval, find->stringval);
91473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (point) {
91483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor      offset = (int)(point - str->stringval) + xmlStrlen(find->stringval);
91493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor      xmlBufferAdd(target, &str->stringval[offset],
91503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		   xmlStrlen(str->stringval) - offset);
91513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
9152a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    valuePush(ctxt, xmlXPathCacheNewString(ctxt->context,
915345490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	xmlBufferContent(target)));
91543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlBufferFree(target);
91553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  }
9156a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik  xmlXPathReleaseObject(ctxt->context, str);
9157a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik  xmlXPathReleaseObject(ctxt->context, find);
91583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
91593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
91603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
91613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNormalizeFunction:
91623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
91633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs:  the number of arguments
91643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
91653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the normalize-space() XPath function
91663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *    string normalize-space(string?)
91673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The normalize-space function returns the argument string with white
91683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * space normalized by stripping leading and trailing whitespace
91693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * and replacing sequences of whitespace characters by a single
91703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * space. Whitespace characters are the same allowed by the S production
91713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * in XML. If the argument is omitted, it defaults to the context
91723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * node converted to a string, in other words the value of the context node.
91733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
91743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
91753473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNormalizeFunction(xmlXPathParserContextPtr ctxt, int nargs) {
91763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  xmlXPathObjectPtr obj = NULL;
91773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  xmlChar *source = NULL;
91783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  xmlBufferPtr target;
91793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  xmlChar blank;
918045490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
9181a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard  if (ctxt == NULL) return;
91823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  if (nargs == 0) {
91833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    /* Use current context node */
9184a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik      valuePush(ctxt,
9185a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	  xmlXPathCacheWrapString(ctxt->context,
9186a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathCastNodeToString(ctxt->context->node)));
91873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    nargs = 1;
91883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  }
91893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
91903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  CHECK_ARITY(1);
91913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  CAST_TO_STRING;
91923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  CHECK_TYPE(XPATH_STRING);
91933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  obj = valuePop(ctxt);
91943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  source = obj->stringval;
91953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
91963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  target = xmlBufferCreate();
91973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  if (target && source) {
919845490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
91993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    /* Skip leading whitespaces */
920076e95df05556c9610b564b14cf578c8f9e34c9c1William M. Brack    while (IS_BLANK_CH(*source))
92013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor      source++;
920245490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
92033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    /* Collapse intermediate whitespaces, and skip trailing whitespaces */
92043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    blank = 0;
92053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    while (*source) {
920676e95df05556c9610b564b14cf578c8f9e34c9c1William M. Brack      if (IS_BLANK_CH(*source)) {
920797ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard	blank = 0x20;
92083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor      } else {
92093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (blank) {
92103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	  xmlBufferAdd(target, &blank, 1);
92113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	  blank = 0;
92123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
92133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	xmlBufferAdd(target, source, 1);
92143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor      }
92153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor      source++;
92163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
9217a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    valuePush(ctxt, xmlXPathCacheNewString(ctxt->context,
9218a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	xmlBufferContent(target)));
92193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlBufferFree(target);
92203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  }
9221a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik  xmlXPathReleaseObject(ctxt->context, obj);
92223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
92233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
92243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
92253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathTranslateFunction:
92263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
92273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs:  the number of arguments
92283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
92293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the translate() XPath function
92303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *    string translate(string, string, string)
92313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The translate function returns the first argument string with
92323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * occurrences of characters in the second argument string replaced
92333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * by the character at the corresponding position in the third argument
92343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * string. For example, translate("bar","abc","ABC") returns the string
92353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * BAr. If there is a character in the second argument string with no
92363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * character at a corresponding position in the third argument string
92373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * (because the second argument string is longer than the third argument
92383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * string), then occurrences of that character in the first argument
92393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * string are removed. For example, translate("--aaa--","abc-","ABC")
92403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * returns "AAA". If a character occurs more than once in second
92413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * argument string, then the first occurrence determines the replacement
92423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * character. If the third argument string is longer than the second
92433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * argument string, then excess characters are ignored.
92443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
92453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
92463473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathTranslateFunction(xmlXPathParserContextPtr ctxt, int nargs) {
9247e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard    xmlXPathObjectPtr str;
9248e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard    xmlXPathObjectPtr from;
9249e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard    xmlXPathObjectPtr to;
9250e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard    xmlBufferPtr target;
925197ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard    int offset, max;
9252e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard    xmlChar ch;
9253b031cef5b537d8eda30f508627f08bc642bbd31dWilliam M. Brack    const xmlChar *point;
925497ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard    xmlChar *cptr;
92553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
9256e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard    CHECK_ARITY(3);
92573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
9258e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard    CAST_TO_STRING;
9259e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard    to = valuePop(ctxt);
9260e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard    CAST_TO_STRING;
9261e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard    from = valuePop(ctxt);
9262e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard    CAST_TO_STRING;
9263e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard    str = valuePop(ctxt);
92643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
9265e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard    target = xmlBufferCreate();
9266e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard    if (target) {
926797ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard	max = xmlUTF8Strlen(to->stringval);
926897ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard	for (cptr = str->stringval; (ch=*cptr); ) {
926997ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard	    offset = xmlUTF8Strloc(from->stringval, cptr);
927097ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard	    if (offset >= 0) {
927197ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard		if (offset < max) {
927297ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard		    point = xmlUTF8Strpos(to->stringval, offset);
927397ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard		    if (point)
927497ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard			xmlBufferAdd(target, point, xmlUTF8Strsize(point, 1));
927597ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard		}
927697ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard	    } else
927797ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard		xmlBufferAdd(target, cptr, xmlUTF8Strsize(cptr, 1));
927897ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard
927997ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard	    /* Step to next character in input */
928097ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard	    cptr++;
928197ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard	    if ( ch & 0x80 ) {
928297ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard		/* if not simple ascii, verify proper format */
928397ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard		if ( (ch & 0xc0) != 0xc0 ) {
928497ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard		    xmlGenericError(xmlGenericErrorContext,
928597ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard			"xmlXPathTranslateFunction: Invalid UTF8 string\n");
928697ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard		    break;
928797ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard		}
928897ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard		/* then skip over remaining bytes for this char */
928997ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard		while ( (ch <<= 1) & 0x80 )
929097ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard		    if ( (*cptr++ & 0xc0) != 0x80 ) {
929197ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard			xmlGenericError(xmlGenericErrorContext,
929297ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard			    "xmlXPathTranslateFunction: Invalid UTF8 string\n");
929397ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard			break;
929497ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard		    }
929597ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard		if (ch & 0x80) /* must have had error encountered */
929697ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard		    break;
929797ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard	    }
9298e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard	}
92993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
9300a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    valuePush(ctxt, xmlXPathCacheNewString(ctxt->context,
9301a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	xmlBufferContent(target)));
9302e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard    xmlBufferFree(target);
9303a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathReleaseObject(ctxt->context, str);
9304a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathReleaseObject(ctxt->context, from);
9305a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathReleaseObject(ctxt->context, to);
93063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
93073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
93083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
9309fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * xmlXPathBooleanFunction:
9310fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * @ctxt:  the XPath Parser context
9311fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * @nargs:  the number of arguments
9312fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard *
9313fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * Implement the boolean() XPath function
9314fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard *    boolean boolean(object)
9315081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack * The boolean function converts its argument to a boolean as follows:
9316fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard *    - a number is true if and only if it is neither positive or
9317fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard *      negative zero nor NaN
9318fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard *    - a node-set is true if and only if it is non-empty
9319fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard *    - a string is true if and only if its length is non-zero
9320fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard */
9321fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillardvoid
9322fbf8a2d0c8145b713099df63d174154a8442e60dDaniel VeillardxmlXPathBooleanFunction(xmlXPathParserContextPtr ctxt, int nargs) {
9323fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard    xmlXPathObjectPtr cur;
9324fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard
9325fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard    CHECK_ARITY(1);
9326fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard    cur = valuePop(ctxt);
9327fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard    if (cur == NULL) XP_ERROR(XPATH_INVALID_OPERAND);
9328a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    cur = xmlXPathCacheConvertBoolean(ctxt->context, cur);
9329fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard    valuePush(ctxt, cur);
93303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
93313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
93323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
93333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNotFunction:
93343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
93353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs:  the number of arguments
93363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
93373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the not() XPath function
93383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *    boolean not(boolean)
93393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The not function returns true if its argument is false,
93403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * and false otherwise.
93413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
93423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
93433473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNotFunction(xmlXPathParserContextPtr ctxt, int nargs) {
93443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CHECK_ARITY(1);
93453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CAST_TO_BOOLEAN;
93463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CHECK_TYPE(XPATH_BOOLEAN);
93473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ctxt->value->boolval = ! ctxt->value->boolval;
93483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
93493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
93503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
93513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathTrueFunction:
93523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
93533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs:  the number of arguments
93543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
93553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the true() XPath function
93563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *    boolean true()
93573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
93583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
93593473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathTrueFunction(xmlXPathParserContextPtr ctxt, int nargs) {
93603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CHECK_ARITY(0);
9361a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    valuePush(ctxt, xmlXPathCacheNewBoolean(ctxt->context, 1));
93623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
93633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
93643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
93653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathFalseFunction:
93663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
93673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs:  the number of arguments
93683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
93693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the false() XPath function
93703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *    boolean false()
93713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
93723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
93733473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathFalseFunction(xmlXPathParserContextPtr ctxt, int nargs) {
93743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CHECK_ARITY(0);
9375a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    valuePush(ctxt, xmlXPathCacheNewBoolean(ctxt->context, 0));
93763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
93773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
93783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
93793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathLangFunction:
93803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
93813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs:  the number of arguments
93823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
93833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the lang() XPath function
93843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *    boolean lang(string)
93853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The lang function returns true or false depending on whether the
93863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * language of the context node as specified by xml:lang attributes
93873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * is the same as or is a sublanguage of the language specified by
93883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the argument string. The language of the context node is determined
93893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * by the value of the xml:lang attribute on the context node, or, if
93903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the context node has no xml:lang attribute, by the value of the
93913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xml:lang attribute on the nearest ancestor of the context node that
93923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * has an xml:lang attribute. If there is no such attribute, then lang
93933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * returns false. If there is such an attribute, then lang returns
93943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * true if the attribute value is equal to the argument ignoring case,
93953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * or if there is some suffix starting with - such that the attribute
93963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * value is equal to the argument ignoring that suffix of the attribute
93973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * value and ignoring case.
93983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
93993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
94003473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathLangFunction(xmlXPathParserContextPtr ctxt, int nargs) {
94014ddaa56d7af6638c20a4446c47b02b299987be65Daniel Veillard    xmlXPathObjectPtr val = NULL;
94024ddaa56d7af6638c20a4446c47b02b299987be65Daniel Veillard    const xmlChar *theLang = NULL;
94033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    const xmlChar *lang;
94043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    int ret = 0;
94053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    int i;
94063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
94073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CHECK_ARITY(1);
94083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CAST_TO_STRING;
94093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CHECK_TYPE(XPATH_STRING);
94103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    val = valuePop(ctxt);
94113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    lang = val->stringval;
94123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    theLang = xmlNodeGetLang(ctxt->context->node);
94133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if ((theLang != NULL) && (lang != NULL)) {
94143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        for (i = 0;lang[i] != 0;i++)
94153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    if (toupper(lang[i]) != toupper(theLang[i]))
94163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	        goto not_equal;
94174ddaa56d7af6638c20a4446c47b02b299987be65Daniel Veillard	if ((theLang[i] == 0) || (theLang[i] == '-'))
94184ddaa56d7af6638c20a4446c47b02b299987be65Daniel Veillard	    ret = 1;
94193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
94203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylornot_equal:
94214ddaa56d7af6638c20a4446c47b02b299987be65Daniel Veillard    if (theLang != NULL)
94224ddaa56d7af6638c20a4446c47b02b299987be65Daniel Veillard	xmlFree((void *)theLang);
9423a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
9424a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathReleaseObject(ctxt->context, val);
9425a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    valuePush(ctxt, xmlXPathCacheNewBoolean(ctxt->context, ret));
94263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
94273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
94283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
94293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNumberFunction:
94303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
94313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs:  the number of arguments
94323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
94333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the number() XPath function
94343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *    number number(object?)
94353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
94363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
94373473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNumberFunction(xmlXPathParserContextPtr ctxt, int nargs) {
94383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathObjectPtr cur;
94393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    double res;
94403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
9441a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard    if (ctxt == NULL) return;
94423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (nargs == 0) {
94433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (ctxt->context->node == NULL) {
9444a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    valuePush(ctxt, xmlXPathCacheNewFloat(ctxt->context, 0.0));
94453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	} else {
94463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    xmlChar* content = xmlNodeGetContent(ctxt->context->node);
94473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
94483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    res = xmlXPathStringEvalNumber(content);
9449a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    valuePush(ctxt, xmlXPathCacheNewFloat(ctxt->context, res));
94503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    xmlFree(content);
94513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
94523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return;
94533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
94543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
94553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CHECK_ARITY(1);
94563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    cur = valuePop(ctxt);
9457a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    valuePush(ctxt, xmlXPathCacheConvertNumber(ctxt->context, cur));
94583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
94593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
94603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
94613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathSumFunction:
94623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
94633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs:  the number of arguments
94643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
94653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the sum() XPath function
94663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *    number sum(node-set)
94673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The sum function returns the sum of the values of the nodes in
94683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the argument node-set.
94693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
94703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
94713473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathSumFunction(xmlXPathParserContextPtr ctxt, int nargs) {
94723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathObjectPtr cur;
94733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    int i;
9474ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    double res = 0.0;
94753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
94763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CHECK_ARITY(1);
947745490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard    if ((ctxt->value == NULL) ||
94783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	((ctxt->value->type != XPATH_NODESET) &&
94793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	 (ctxt->value->type != XPATH_XSLT_TREE)))
94803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	XP_ERROR(XPATH_INVALID_TYPE);
94813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    cur = valuePop(ctxt);
94823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
9483081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack    if ((cur->nodesetval != NULL) && (cur->nodesetval->nodeNr != 0)) {
9484ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	for (i = 0; i < cur->nodesetval->nodeNr; i++) {
9485ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	    res += xmlXPathCastNodeToNumber(cur->nodesetval->nodeTab[i]);
94863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
94873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
9488a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    valuePush(ctxt, xmlXPathCacheNewFloat(ctxt->context, res));
9489a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathReleaseObject(ctxt->context, cur);
94903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
94913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
94923d426663629a53180f3f54282ba27f3d070eef24William M. Brack/*
94933d426663629a53180f3f54282ba27f3d070eef24William M. Brack * To assure working code on multiple platforms, we want to only depend
94943d426663629a53180f3f54282ba27f3d070eef24William M. Brack * upon the characteristic truncation of converting a floating point value
94953d426663629a53180f3f54282ba27f3d070eef24William M. Brack * to an integer.  Unfortunately, because of the different storage sizes
94963d426663629a53180f3f54282ba27f3d070eef24William M. Brack * of our internal floating point value (double) and integer (int), we
94973d426663629a53180f3f54282ba27f3d070eef24William M. Brack * can't directly convert (see bug 301162).  This macro is a messy
94983d426663629a53180f3f54282ba27f3d070eef24William M. Brack * 'workaround'
94993d426663629a53180f3f54282ba27f3d070eef24William M. Brack */
95003d426663629a53180f3f54282ba27f3d070eef24William M. Brack#define XTRUNC(f, v)            \
95013d426663629a53180f3f54282ba27f3d070eef24William M. Brack    f = fmod((v), INT_MAX);     \
95023d426663629a53180f3f54282ba27f3d070eef24William M. Brack    f = (v) - (f) + (double)((int)(f));
95033d426663629a53180f3f54282ba27f3d070eef24William M. Brack
95043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
95053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathFloorFunction:
95063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
95073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs:  the number of arguments
95083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
95093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the floor() XPath function
95103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *    number floor(number)
95113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The floor function returns the largest (closest to positive infinity)
95123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * number that is not greater than the argument and that is an integer.
95133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
95143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
95153473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathFloorFunction(xmlXPathParserContextPtr ctxt, int nargs) {
951656cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard    double f;
951756cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard
95183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CHECK_ARITY(1);
95193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CAST_TO_NUMBER;
95203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CHECK_TYPE(XPATH_NUMBER);
952156cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard
95223d426663629a53180f3f54282ba27f3d070eef24William M. Brack    XTRUNC(f, ctxt->value->floatval);
952356cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard    if (f != ctxt->value->floatval) {
952456cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard	if (ctxt->value->floatval > 0)
952556cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard	    ctxt->value->floatval = f;
952656cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard	else
952756cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard	    ctxt->value->floatval = f - 1;
952856cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard    }
95293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
95303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
95313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
95323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathCeilingFunction:
95333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
95343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs:  the number of arguments
95353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
95363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the ceiling() XPath function
95373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *    number ceiling(number)
95383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The ceiling function returns the smallest (closest to negative infinity)
95393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * number that is not less than the argument and that is an integer.
95403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
95413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
95423473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathCeilingFunction(xmlXPathParserContextPtr ctxt, int nargs) {
95433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    double f;
95443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
95453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CHECK_ARITY(1);
95463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CAST_TO_NUMBER;
95473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CHECK_TYPE(XPATH_NUMBER);
95483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
95493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#if 0
95503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ctxt->value->floatval = ceil(ctxt->value->floatval);
95513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#else
95523d426663629a53180f3f54282ba27f3d070eef24William M. Brack    XTRUNC(f, ctxt->value->floatval);
955356cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard    if (f != ctxt->value->floatval) {
955456cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard	if (ctxt->value->floatval > 0)
955556cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard	    ctxt->value->floatval = f + 1;
95565fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard	else {
95575fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard	    if (ctxt->value->floatval < 0 && f == 0)
95585fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard	        ctxt->value->floatval = xmlXPathNZERO;
95595fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard	    else
95605fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard	        ctxt->value->floatval = f;
95615fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard	}
95625fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard
956356cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard    }
95643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif
95653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
95663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
95673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
95683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathRoundFunction:
95693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
95703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs:  the number of arguments
95713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
95723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the round() XPath function
95733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *    number round(number)
95743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The round function returns the number that is closest to the
95753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * argument and that is an integer. If there are two such numbers,
95763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * then the one that is even is returned.
95773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
95783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
95793473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathRoundFunction(xmlXPathParserContextPtr ctxt, int nargs) {
95803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    double f;
95813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
95823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CHECK_ARITY(1);
95833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CAST_TO_NUMBER;
95843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CHECK_TYPE(XPATH_NUMBER);
95853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
9586cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard    if ((xmlXPathIsNaN(ctxt->value->floatval)) ||
9587cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard	(xmlXPathIsInf(ctxt->value->floatval) == 1) ||
9588cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard	(xmlXPathIsInf(ctxt->value->floatval) == -1) ||
95893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	(ctxt->value->floatval == 0.0))
95903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return;
95913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
95923d426663629a53180f3f54282ba27f3d070eef24William M. Brack    XTRUNC(f, ctxt->value->floatval);
959356cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard    if (ctxt->value->floatval < 0) {
959456cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard	if (ctxt->value->floatval < f - 0.5)
959556cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard	    ctxt->value->floatval = f - 1;
959645490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	else
959756cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard	    ctxt->value->floatval = f;
95985fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard	if (ctxt->value->floatval == 0)
95995fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard	    ctxt->value->floatval = xmlXPathNZERO;
960056cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard    } else {
960156cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard	if (ctxt->value->floatval < f + 0.5)
960256cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard	    ctxt->value->floatval = f;
960345490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	else
960456cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard	    ctxt->value->floatval = f + 1;
960556cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard    }
96063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
96073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
96083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/************************************************************************
96093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *									*
96103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *			The Parser					*
96113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *									*
96123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ************************************************************************/
96133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
96143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/*
9615081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack * a few forward declarations since we use a recursive call based
96163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * implementation.
96173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
96185691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcikstatic void xmlXPathCompileExpr(xmlXPathParserContextPtr ctxt, int sort);
9619d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillardstatic void xmlXPathCompPredicate(xmlXPathParserContextPtr ctxt, int filter);
9620afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void xmlXPathCompLocationPath(xmlXPathParserContextPtr ctxt);
9621afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void xmlXPathCompRelativeLocationPath(xmlXPathParserContextPtr ctxt);
96222156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillardstatic xmlChar * xmlXPathParseNameComplex(xmlXPathParserContextPtr ctxt,
96232156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard	                                  int qualified);
96243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
96253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
962661d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard * xmlXPathCurrentChar:
962761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard * @ctxt:  the XPath parser context
962861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard * @cur:  pointer to the beginning of the char
962961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard * @len:  pointer to the length of the char read
963061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard *
9631cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * The current char value, if using UTF-8 this may actually span multiple
963261d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard * bytes in the input buffer.
963361d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard *
963460087f30f3b4cf21de48f39181736e7d71e7a661Daniel Veillard * Returns the current char value and its length
963561d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard */
963661d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard
963761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillardstatic int
963861d80a2822b2678dee885ac2850295cc96277c63Daniel VeillardxmlXPathCurrentChar(xmlXPathParserContextPtr ctxt, int *len) {
963961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard    unsigned char c;
964061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard    unsigned int val;
964161d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard    const xmlChar *cur;
964261d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard
964361d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard    if (ctxt == NULL)
964461d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	return(0);
964561d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard    cur = ctxt->cur;
964661d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard
964761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard    /*
964861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard     * We are supposed to handle UTF8, check it's valid
964961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard     * From rfc2044: encoding of the Unicode values on UTF-8:
965061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard     *
965161d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard     * UCS-4 range (hex.)           UTF-8 octet sequence (binary)
965261d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard     * 0000 0000-0000 007F   0xxxxxxx
965361d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard     * 0000 0080-0000 07FF   110xxxxx 10xxxxxx
965445490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard     * 0000 0800-0000 FFFF   1110xxxx 10xxxxxx 10xxxxxx
965561d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard     *
965661d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard     * Check for the 0x110000 limit too
965761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard     */
965861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard    c = *cur;
965961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard    if (c & 0x80) {
966061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	if ((cur[1] & 0xc0) != 0x80)
966161d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	    goto encoding_error;
966261d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	if ((c & 0xe0) == 0xe0) {
966361d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard
966461d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	    if ((cur[2] & 0xc0) != 0x80)
966561d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard		goto encoding_error;
966661d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	    if ((c & 0xf0) == 0xf0) {
966761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard		if (((c & 0xf8) != 0xf0) ||
966861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard		    ((cur[3] & 0xc0) != 0x80))
966961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard		    goto encoding_error;
967061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard		/* 4-byte code */
967161d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard		*len = 4;
967261d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard		val = (cur[0] & 0x7) << 18;
967361d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard		val |= (cur[1] & 0x3f) << 12;
967461d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard		val |= (cur[2] & 0x3f) << 6;
967561d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard		val |= cur[3] & 0x3f;
967661d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	    } else {
967761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	      /* 3-byte code */
967861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard		*len = 3;
967961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard		val = (cur[0] & 0xf) << 12;
968061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard		val |= (cur[1] & 0x3f) << 6;
968161d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard		val |= cur[2] & 0x3f;
968261d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	    }
968361d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	} else {
968461d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	  /* 2-byte code */
968561d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	    *len = 2;
968661d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	    val = (cur[0] & 0x1f) << 6;
968761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	    val |= cur[1] & 0x3f;
968861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	}
968961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	if (!IS_CHAR(val)) {
969061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	    XP_ERROR0(XPATH_INVALID_CHAR_ERROR);
969145490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	}
969261d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	return(val);
969361d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard    } else {
969461d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	/* 1-byte code */
969561d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	*len = 1;
969661d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	return((int) *cur);
969761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard    }
969861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillardencoding_error:
969961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard    /*
9700081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack     * If we detect an UTF8 error that probably means that the
9701081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack     * input encoding didn't get properly advertised in the
970261d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard     * declaration header. Report the error and switch the encoding
970361d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard     * to ISO-Latin-1 (if you don't like this policy, just declare the
970461d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard     * encoding !)
970561d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard     */
970642596ad20cdf1925dd79ea801cbe598b6e7b7aecDaniel Veillard    *len = 0;
970761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard    XP_ERROR0(XPATH_ENCODING_ERROR);
970861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard}
970961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard
971061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard/**
97113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathParseNCName:
97123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
97133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
97143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * parse an XML namespace non qualified name.
97153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
97163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [NS 3] NCName ::= (Letter | '_') (NCNameChar)*
97173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
97183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [NS 4] NCNameChar ::= Letter | Digit | '.' | '-' | '_' |
97193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *                       CombiningChar | Extender
97203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
97213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the namespace name or NULL
97223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
97233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
97243473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlChar *
97253473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathParseNCName(xmlXPathParserContextPtr ctxt) {
97262156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard    const xmlChar *in;
97272156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard    xmlChar *ret;
97282156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard    int count = 0;
97293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
9730a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard    if ((ctxt == NULL) || (ctxt->cur == NULL)) return(NULL);
97312156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard    /*
97322156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard     * Accelerator for simple ASCII names
97332156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard     */
97342156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard    in = ctxt->cur;
97352156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard    if (((*in >= 0x61) && (*in <= 0x7A)) ||
97362156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard	((*in >= 0x41) && (*in <= 0x5A)) ||
97372156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard	(*in == '_')) {
97382156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard	in++;
97392156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard	while (((*in >= 0x61) && (*in <= 0x7A)) ||
97402156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard	       ((*in >= 0x41) && (*in <= 0x5A)) ||
97412156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard	       ((*in >= 0x30) && (*in <= 0x39)) ||
97429a89a8ab80bc021deec9da7d79bda20995c4e78dDaniel Veillard	       (*in == '_') || (*in == '.') ||
97439a89a8ab80bc021deec9da7d79bda20995c4e78dDaniel Veillard	       (*in == '-'))
97442156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard	    in++;
97452156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard	if ((*in == ' ') || (*in == '>') || (*in == '/') ||
97462156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard            (*in == '[') || (*in == ']') || (*in == ':') ||
97472156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard            (*in == '@') || (*in == '*')) {
97482156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard	    count = in - ctxt->cur;
97492156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard	    if (count == 0)
97502156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard		return(NULL);
97512156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard	    ret = xmlStrndup(ctxt->cur, count);
97522156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard	    ctxt->cur = in;
97532156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard	    return(ret);
97542156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard	}
97552156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard    }
97562156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard    return(xmlXPathParseNameComplex(ctxt, 0));
97573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
97583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
97592156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard
97603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
97613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathParseQName:
97623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
976345490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard * @prefix:  a xmlChar **
97643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
97653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * parse an XML qualified name
97663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
97673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [NS 5] QName ::= (Prefix ':')? LocalPart
97683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
97693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [NS 6] Prefix ::= NCName
97703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
97713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [NS 7] LocalPart ::= NCName
97723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
97733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the function returns the local part, and prefix is updated
97743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *   to get the Prefix if any.
97753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
97763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
977756a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic xmlChar *
97783473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathParseQName(xmlXPathParserContextPtr ctxt, xmlChar **prefix) {
97793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlChar *ret = NULL;
97803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
97813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    *prefix = NULL;
97823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret = xmlXPathParseNCName(ctxt);
9783074f37e7ebd5e76ceb584a89745a9e84df5b3be2Daniel Veillard    if (ret && CUR == ':') {
97843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        *prefix = ret;
97853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	NEXT;
97863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	ret = xmlXPathParseNCName(ctxt);
97873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
97883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(ret);
97893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
97903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
97913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
97923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathParseName:
97933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
97943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
97953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * parse an XML name
97963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
97973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [4] NameChar ::= Letter | Digit | '.' | '-' | '_' | ':' |
97983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *                  CombiningChar | Extender
97993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
98003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [5] Name ::= (Letter | '_' | ':') (NameChar)*
98013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
98023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the namespace name or NULL
98033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
98043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
98053473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlChar *
98063473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathParseName(xmlXPathParserContextPtr ctxt) {
980761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard    const xmlChar *in;
980861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard    xmlChar *ret;
980961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard    int count = 0;
98103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
9811a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard    if ((ctxt == NULL) || (ctxt->cur == NULL)) return(NULL);
981261d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard    /*
981361d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard     * Accelerator for simple ASCII names
981461d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard     */
981561d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard    in = ctxt->cur;
981661d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard    if (((*in >= 0x61) && (*in <= 0x7A)) ||
981761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	((*in >= 0x41) && (*in <= 0x5A)) ||
981861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	(*in == '_') || (*in == ':')) {
981961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	in++;
982061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	while (((*in >= 0x61) && (*in <= 0x7A)) ||
982161d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	       ((*in >= 0x41) && (*in <= 0x5A)) ||
982261d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	       ((*in >= 0x30) && (*in <= 0x39)) ||
982376d66f416d2d0d5db4a09d212b4e43087e9cdae7Daniel Veillard	       (*in == '_') || (*in == '-') ||
982476d66f416d2d0d5db4a09d212b4e43087e9cdae7Daniel Veillard	       (*in == ':') || (*in == '.'))
982561d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	    in++;
982676d66f416d2d0d5db4a09d212b4e43087e9cdae7Daniel Veillard	if ((*in > 0) && (*in < 0x80)) {
982761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	    count = in - ctxt->cur;
982861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	    ret = xmlStrndup(ctxt->cur, count);
982961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	    ctxt->cur = in;
983061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	    return(ret);
983161d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	}
983261d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard    }
98332156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard    return(xmlXPathParseNameComplex(ctxt, 1));
983461d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard}
98353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
983661d80a2822b2678dee885ac2850295cc96277c63Daniel Veillardstatic xmlChar *
98372156a56bcbf5d83fb3d694123be01beebf84d273Daniel VeillardxmlXPathParseNameComplex(xmlXPathParserContextPtr ctxt, int qualified) {
983861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard    xmlChar buf[XML_MAX_NAMELEN + 5];
983961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard    int len = 0, l;
984061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard    int c;
98413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
984261d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard    /*
984361d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard     * Handler for more complex cases
984461d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard     */
984561d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard    c = CUR_CHAR(l);
984661d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard    if ((c == ' ') || (c == '>') || (c == '/') || /* accelerators */
98472156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard        (c == '[') || (c == ']') || (c == '@') || /* accelerators */
98482156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard        (c == '*') || /* accelerators */
984961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	(!IS_LETTER(c) && (c != '_') &&
98502156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard         ((qualified) && (c != ':')))) {
985161d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	return(NULL);
985261d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard    }
98533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
985461d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard    while ((c != ' ') && (c != '>') && (c != '/') && /* test bigname.xml */
985561d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	   ((IS_LETTER(c)) || (IS_DIGIT(c)) ||
985661d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard            (c == '.') || (c == '-') ||
985745490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	    (c == '_') || ((qualified) && (c == ':')) ||
985861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	    (IS_COMBINING(c)) ||
985961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	    (IS_EXTENDER(c)))) {
986061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	COPY_BUF(l,buf,len,c);
986161d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	NEXTL(l);
986261d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	c = CUR_CHAR(l);
986361d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	if (len >= XML_MAX_NAMELEN) {
986461d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	    /*
986561d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	     * Okay someone managed to make a huge name, so he's ready to pay
986661d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	     * for the processing speed.
986761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	     */
986861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	    xmlChar *buffer;
986961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	    int max = len * 2;
987045490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
98713c908dca479ed50dca24b8593bca90e40dbde6b8Daniel Veillard	    buffer = (xmlChar *) xmlMallocAtomic(max * sizeof(xmlChar));
987261d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	    if (buffer == NULL) {
987324505b0f5c872c5afb6da5093565e5a6e09ca541Daniel Veillard		XP_ERRORNULL(XPATH_MEMORY_ERROR);
987461d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	    }
987561d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	    memcpy(buffer, buf, len);
987661d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	    while ((IS_LETTER(c)) || (IS_DIGIT(c)) || /* test bigname.xml */
987761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard		   (c == '.') || (c == '-') ||
987845490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard		   (c == '_') || ((qualified) && (c == ':')) ||
987961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard		   (IS_COMBINING(c)) ||
988061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard		   (IS_EXTENDER(c))) {
988161d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard		if (len + 10 > max) {
988261d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard		    max *= 2;
988361d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard		    buffer = (xmlChar *) xmlRealloc(buffer,
988461d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard			                            max * sizeof(xmlChar));
988561d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard		    if (buffer == NULL) {
988624505b0f5c872c5afb6da5093565e5a6e09ca541Daniel Veillard			XP_ERRORNULL(XPATH_MEMORY_ERROR);
988761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard		    }
988861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard		}
988961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard		COPY_BUF(l,buffer,len,c);
989061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard		NEXTL(l);
989161d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard		c = CUR_CHAR(l);
989261d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	    }
989361d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	    buffer[len] = 0;
989461d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	    return(buffer);
989561d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	}
989661d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard    }
98972156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard    if (len == 0)
98982156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard	return(NULL);
989961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard    return(xmlStrndup(buf, len));
990061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard}
99013cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard
99023cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard#define MAX_FRAC 20
99033cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard
9904372a445479b859bd0fe24df54e9b3db34d113d5aWilliam M. Brack/*
9905372a445479b859bd0fe24df54e9b3db34d113d5aWilliam M. Brack * These are used as divisors for the fractional part of a number.
9906372a445479b859bd0fe24df54e9b3db34d113d5aWilliam M. Brack * Since the table includes 1.0 (representing '0' fractional digits),
9907372a445479b859bd0fe24df54e9b3db34d113d5aWilliam M. Brack * it must be dimensioned at MAX_FRAC+1 (bug 133921)
9908372a445479b859bd0fe24df54e9b3db34d113d5aWilliam M. Brack */
9909372a445479b859bd0fe24df54e9b3db34d113d5aWilliam M. Brackstatic double my_pow10[MAX_FRAC+1] = {
99103cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard    1.0, 10.0, 100.0, 1000.0, 10000.0,
99113cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard    100000.0, 1000000.0, 10000000.0, 100000000.0, 1000000000.0,
99123cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard    10000000000.0, 100000000000.0, 1000000000000.0, 10000000000000.0,
99133cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard    100000000000000.0,
99143cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard    1000000000000000.0, 10000000000000000.0, 100000000000000000.0,
9915372a445479b859bd0fe24df54e9b3db34d113d5aWilliam M. Brack    1000000000000000000.0, 10000000000000000000.0, 100000000000000000000.0
99163cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard};
99173cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard
99183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
99193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathStringEvalNumber:
99203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @str:  A string to scan
99213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
992270a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese *  [30a]  Float  ::= Number ('e' Digits?)?
992370a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese *
99243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *  [30]   Number ::=   Digits ('.' Digits?)?
992545490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *                    | '.' Digits
99263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *  [31]   Digits ::=   [0-9]+
99273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
9928afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile a Number in the string
99293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * In complement of the Number expression, this function also handles
99303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * negative values : '-' Number.
99313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
99323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the double value.
99333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
99343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylordouble
99353473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathStringEvalNumber(const xmlChar *str) {
99363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    const xmlChar *cur = str;
99377b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard    double ret;
9938b06c61455f86758511aa050a06ff1bbd33f8c3c3Daniel Veillard    int ok = 0;
99393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    int isneg = 0;
994070a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese    int exponent = 0;
994170a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese    int is_exponent_negative = 0;
9942b06c61455f86758511aa050a06ff1bbd33f8c3c3Daniel Veillard#ifdef __GNUC__
9943b06c61455f86758511aa050a06ff1bbd33f8c3c3Daniel Veillard    unsigned long tmp = 0;
99447b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard    double temp;
9945b06c61455f86758511aa050a06ff1bbd33f8c3c3Daniel Veillard#endif
9946eca82810f0fb81f3e9936d2018347e1e19de513aDaniel Veillard    if (cur == NULL) return(0);
994776e95df05556c9610b564b14cf578c8f9e34c9c1William M. Brack    while (IS_BLANK_CH(*cur)) cur++;
99483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if ((*cur != '.') && ((*cur < '0') || (*cur > '9')) && (*cur != '-')) {
99493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        return(xmlXPathNAN);
99503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
99513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (*cur == '-') {
99523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	isneg = 1;
99533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	cur++;
99543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
9955b06c61455f86758511aa050a06ff1bbd33f8c3c3Daniel Veillard
9956b06c61455f86758511aa050a06ff1bbd33f8c3c3Daniel Veillard#ifdef __GNUC__
9957d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard    /*
99587b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard     * tmp/temp is a workaround against a gcc compiler bug
99597b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard     * http://veillard.com/gcc.bug
9960d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard     */
99617b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard    ret = 0;
99623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    while ((*cur >= '0') && (*cur <= '9')) {
99637b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard	ret = ret * 10;
99647b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard	tmp = (*cur - '0');
99653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	ok = 1;
99663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	cur++;
99677b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard	temp = (double) tmp;
99687b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard	ret = ret + temp;
99693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
9970b06c61455f86758511aa050a06ff1bbd33f8c3c3Daniel Veillard#else
99717b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard    ret = 0;
9972b06c61455f86758511aa050a06ff1bbd33f8c3c3Daniel Veillard    while ((*cur >= '0') && (*cur <= '9')) {
9973b06c61455f86758511aa050a06ff1bbd33f8c3c3Daniel Veillard	ret = ret * 10 + (*cur - '0');
9974b06c61455f86758511aa050a06ff1bbd33f8c3c3Daniel Veillard	ok = 1;
9975b06c61455f86758511aa050a06ff1bbd33f8c3c3Daniel Veillard	cur++;
9976b06c61455f86758511aa050a06ff1bbd33f8c3c3Daniel Veillard    }
9977b06c61455f86758511aa050a06ff1bbd33f8c3c3Daniel Veillard#endif
9978d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard
99793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (*cur == '.') {
99803cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard	int v, frac = 0;
99813cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard	double fraction = 0;
99823cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard
99833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        cur++;
99843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (((*cur < '0') || (*cur > '9')) && (!ok)) {
99853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    return(xmlXPathNAN);
99863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
99873cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard	while (((*cur >= '0') && (*cur <= '9')) && (frac < MAX_FRAC)) {
99883cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard	    v = (*cur - '0');
99893cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard	    fraction = fraction * 10 + v;
99903cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard	    frac = frac + 1;
99913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    cur++;
99923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
99933cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard	fraction /= my_pow10[frac];
99943cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard	ret = ret + fraction;
99953cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard	while ((*cur >= '0') && (*cur <= '9'))
99963cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard	    cur++;
99973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
999870a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese    if ((*cur == 'e') || (*cur == 'E')) {
999970a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese      cur++;
1000070a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese      if (*cur == '-') {
1000170a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese	is_exponent_negative = 1;
1000270a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese	cur++;
100039912705b82cbf3fbff43e19dd95dd0a6ec494d2dWilliam M. Brack      } else if (*cur == '+') {
100049912705b82cbf3fbff43e19dd95dd0a6ec494d2dWilliam M. Brack        cur++;
1000570a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese      }
1000670a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese      while ((*cur >= '0') && (*cur <= '9')) {
1000770a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese	exponent = exponent * 10 + (*cur - '0');
1000870a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese	cur++;
1000970a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese      }
1001070a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese    }
1001176e95df05556c9610b564b14cf578c8f9e34c9c1William M. Brack    while (IS_BLANK_CH(*cur)) cur++;
100123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (*cur != 0) return(xmlXPathNAN);
100133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (isneg) ret = -ret;
1001470a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese    if (is_exponent_negative) exponent = -exponent;
1001570a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese    ret *= pow(10.0, (double)exponent);
100163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(ret);
100173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
100183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
100193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
10020afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompNumber:
100213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
100223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
100233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *  [30]   Number ::=   Digits ('.' Digits?)?
1002445490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *                    | '.' Digits
100253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *  [31]   Digits ::=   [0-9]+
100263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
10027afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile a Number, then push it on the stack
100283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
100293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
10030afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void
10031d79bcd1b36412a7996ace1900ab613e38a609b60Daniel VeillardxmlXPathCompNumber(xmlXPathParserContextPtr ctxt)
10032d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard{
100333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    double ret = 0.0;
100343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    double mult = 1;
100357b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard    int ok = 0;
1003670a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese    int exponent = 0;
1003770a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese    int is_exponent_negative = 0;
100387b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard#ifdef __GNUC__
100397b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard    unsigned long tmp = 0;
100407b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard    double temp;
100417b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard#endif
100423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
100433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CHECK_ERROR;
100443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if ((CUR != '.') && ((CUR < '0') || (CUR > '9'))) {
100453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        XP_ERROR(XPATH_NUMBER_ERROR);
100463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
100477b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard#ifdef __GNUC__
10048d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard    /*
100497b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard     * tmp/temp is a workaround against a gcc compiler bug
100507b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard     * http://veillard.com/gcc.bug
10051d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard     */
100527b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard    ret = 0;
100533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    while ((CUR >= '0') && (CUR <= '9')) {
100547b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard	ret = ret * 10;
100557b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard	tmp = (CUR - '0');
10056d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard        ok = 1;
10057d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard        NEXT;
100587b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard	temp = (double) tmp;
100597b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard	ret = ret + temp;
100603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
100617b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard#else
100627b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard    ret = 0;
100637b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard    while ((CUR >= '0') && (CUR <= '9')) {
100647b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard	ret = ret * 10 + (CUR - '0');
100657b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard	ok = 1;
100667b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard	NEXT;
100677b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard    }
100687b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard#endif
100693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (CUR == '.') {
100703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        NEXT;
10071d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard        if (((CUR < '0') || (CUR > '9')) && (!ok)) {
10072d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard            XP_ERROR(XPATH_NUMBER_ERROR);
10073d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard        }
10074d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard        while ((CUR >= '0') && (CUR <= '9')) {
10075d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard            mult /= 10;
10076d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard            ret = ret + (CUR - '0') * mult;
10077d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard            NEXT;
10078d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard        }
100793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
1008070a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese    if ((CUR == 'e') || (CUR == 'E')) {
10081d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard        NEXT;
10082d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard        if (CUR == '-') {
10083d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard            is_exponent_negative = 1;
10084d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard            NEXT;
100859912705b82cbf3fbff43e19dd95dd0a6ec494d2dWilliam M. Brack        } else if (CUR == '+') {
100869912705b82cbf3fbff43e19dd95dd0a6ec494d2dWilliam M. Brack	    NEXT;
100879912705b82cbf3fbff43e19dd95dd0a6ec494d2dWilliam M. Brack	}
10088d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard        while ((CUR >= '0') && (CUR <= '9')) {
10089d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard            exponent = exponent * 10 + (CUR - '0');
10090d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard            NEXT;
10091d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard        }
10092d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard        if (is_exponent_negative)
10093d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard            exponent = -exponent;
10094d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard        ret *= pow(10.0, (double) exponent);
1009570a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese    }
100969e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    PUSH_LONG_EXPR(XPATH_OP_VALUE, XPATH_NUMBER, 0, 0,
10097a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik                   xmlXPathCacheNewFloat(ctxt->context, ret), NULL);
100983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
100993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
101003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
10101fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * xmlXPathParseLiteral:
10102fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * @ctxt:  the XPath Parser context
10103fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard *
10104fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * Parse a Literal
10105fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard *
10106fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard *  [29]   Literal ::=   '"' [^"]* '"'
10107fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard *                    | "'" [^']* "'"
10108fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard *
10109fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * Returns the value found or NULL in case of error
10110fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard */
10111fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillardstatic xmlChar *
10112fbf8a2d0c8145b713099df63d174154a8442e60dDaniel VeillardxmlXPathParseLiteral(xmlXPathParserContextPtr ctxt) {
10113fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard    const xmlChar *q;
10114fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard    xmlChar *ret = NULL;
10115fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard
10116fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard    if (CUR == '"') {
10117fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard        NEXT;
10118fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard	q = CUR_PTR;
1011976e95df05556c9610b564b14cf578c8f9e34c9c1William M. Brack	while ((IS_CHAR_CH(CUR)) && (CUR != '"'))
10120fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard	    NEXT;
1012176e95df05556c9610b564b14cf578c8f9e34c9c1William M. Brack	if (!IS_CHAR_CH(CUR)) {
1012224505b0f5c872c5afb6da5093565e5a6e09ca541Daniel Veillard	    XP_ERRORNULL(XPATH_UNFINISHED_LITERAL_ERROR);
10123fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard	} else {
10124fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard	    ret = xmlStrndup(q, CUR_PTR - q);
10125fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard	    NEXT;
10126fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard        }
10127fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard    } else if (CUR == '\'') {
10128fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard        NEXT;
10129fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard	q = CUR_PTR;
1013076e95df05556c9610b564b14cf578c8f9e34c9c1William M. Brack	while ((IS_CHAR_CH(CUR)) && (CUR != '\''))
10131fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard	    NEXT;
1013276e95df05556c9610b564b14cf578c8f9e34c9c1William M. Brack	if (!IS_CHAR_CH(CUR)) {
1013324505b0f5c872c5afb6da5093565e5a6e09ca541Daniel Veillard	    XP_ERRORNULL(XPATH_UNFINISHED_LITERAL_ERROR);
10134fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard	} else {
10135fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard	    ret = xmlStrndup(q, CUR_PTR - q);
10136fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard	    NEXT;
10137fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard        }
10138fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard    } else {
1013924505b0f5c872c5afb6da5093565e5a6e09ca541Daniel Veillard	XP_ERRORNULL(XPATH_START_LITERAL_ERROR);
10140fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard    }
10141fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard    return(ret);
10142fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard}
10143fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard
10144fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard/**
10145afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompLiteral:
101463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
101473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
101483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Parse a Literal and push it on the stack.
101493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
101503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *  [29]   Literal ::=   '"' [^"]* '"'
101513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *                    | "'" [^']* "'"
101523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
10153afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * TODO: xmlXPathCompLiteral memory allocation could be improved.
101543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
10155afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void
10156afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompLiteral(xmlXPathParserContextPtr ctxt) {
101573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    const xmlChar *q;
101583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlChar *ret = NULL;
101593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
101603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (CUR == '"') {
101613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        NEXT;
101623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	q = CUR_PTR;
1016376e95df05556c9610b564b14cf578c8f9e34c9c1William M. Brack	while ((IS_CHAR_CH(CUR)) && (CUR != '"'))
101643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    NEXT;
1016576e95df05556c9610b564b14cf578c8f9e34c9c1William M. Brack	if (!IS_CHAR_CH(CUR)) {
101663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    XP_ERROR(XPATH_UNFINISHED_LITERAL_ERROR);
101673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	} else {
101683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    ret = xmlStrndup(q, CUR_PTR - q);
101693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    NEXT;
101703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        }
101713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    } else if (CUR == '\'') {
101723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        NEXT;
101733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	q = CUR_PTR;
1017476e95df05556c9610b564b14cf578c8f9e34c9c1William M. Brack	while ((IS_CHAR_CH(CUR)) && (CUR != '\''))
101753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    NEXT;
1017676e95df05556c9610b564b14cf578c8f9e34c9c1William M. Brack	if (!IS_CHAR_CH(CUR)) {
101773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    XP_ERROR(XPATH_UNFINISHED_LITERAL_ERROR);
101783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	} else {
101793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    ret = xmlStrndup(q, CUR_PTR - q);
101803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    NEXT;
101813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        }
101823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    } else {
101833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	XP_ERROR(XPATH_START_LITERAL_ERROR);
101843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
101853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ret == NULL) return;
101869e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    PUSH_LONG_EXPR(XPATH_OP_VALUE, XPATH_STRING, 0, 0,
10187a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	           xmlXPathCacheNewString(ctxt->context, ret), NULL);
101883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlFree(ret);
101893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
101903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
101913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
10192afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompVariableReference:
101933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
101943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
101953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Parse a VariableReference, evaluate it and push it on the stack.
101963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
101973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The variable bindings consist of a mapping from variable names
10198081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack * to variable values. The value of a variable is an object, which can be
101993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * of any of the types that are possible for the value of an expression,
102003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * and may also be of additional types not specified here.
102013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
102023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Early evaluation is possible since:
102033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The variable bindings [...] used to evaluate a subexpression are
1020445490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard * always the same as those used to evaluate the containing expression.
102053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
1020645490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *  [36]   VariableReference ::=   '$' QName
102073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
10208afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void
10209afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompVariableReference(xmlXPathParserContextPtr ctxt) {
102103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlChar *name;
102113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlChar *prefix;
102123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
102133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    SKIP_BLANKS;
102143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (CUR != '$') {
102153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	XP_ERROR(XPATH_VARIABLE_REF_ERROR);
102163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
102173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    NEXT;
102183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    name = xmlXPathParseQName(ctxt, &prefix);
102193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (name == NULL) {
102203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	XP_ERROR(XPATH_VARIABLE_REF_ERROR);
102213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
10222fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard    ctxt->comp->last = -1;
102239e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    PUSH_LONG_EXPR(XPATH_OP_VARIABLE, 0, 0, 0,
102249e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	           name, prefix);
102253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    SKIP_BLANKS;
10226b3d1491b69060f8a67516b9a3ef12617adf88954Daniel Veillard    if ((ctxt->context != NULL) && (ctxt->context->flags & XML_XPATH_NOVAR)) {
10227b3d1491b69060f8a67516b9a3ef12617adf88954Daniel Veillard	XP_ERROR(XPATH_UNDEF_VARIABLE_ERROR);
10228b3d1491b69060f8a67516b9a3ef12617adf88954Daniel Veillard    }
102293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
102303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
102313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
102323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathIsNodeType:
102333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @name:  a name string
102343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
102353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Is the name given a NodeType one.
102363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
102373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *  [38]   NodeType ::=   'comment'
102383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *                    | 'text'
102393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *                    | 'processing-instruction'
102403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *                    | 'node'
102413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
102423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns 1 if true 0 otherwise
102433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
102443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorint
102453473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathIsNodeType(const xmlChar *name) {
102463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (name == NULL)
102473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(0);
102483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
102491971ee2698cb84c7699c96d3302f00e20d42c0d3Daniel Veillard    if (xmlStrEqual(name, BAD_CAST "node"))
102503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(1);
102513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (xmlStrEqual(name, BAD_CAST "text"))
102523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(1);
102531971ee2698cb84c7699c96d3302f00e20d42c0d3Daniel Veillard    if (xmlStrEqual(name, BAD_CAST "comment"))
102543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(1);
102551971ee2698cb84c7699c96d3302f00e20d42c0d3Daniel Veillard    if (xmlStrEqual(name, BAD_CAST "processing-instruction"))
102563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(1);
102573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(0);
102583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
102593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
102603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
10261afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompFunctionCall:
102623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
102633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
102643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *  [16]   FunctionCall ::=   FunctionName '(' ( Argument ( ',' Argument)*)? ')'
1026545490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *  [17]   Argument ::=   Expr
102663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
10267afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile a function call, the evaluation of all arguments are
102683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * pushed on the stack
102693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
10270afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void
10271afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompFunctionCall(xmlXPathParserContextPtr ctxt) {
102723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlChar *name;
102733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlChar *prefix;
102743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    int nbargs = 0;
102755691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik    int sort = 1;
102763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
102773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    name = xmlXPathParseQName(ctxt, &prefix);
102783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (name == NULL) {
10279074f37e7ebd5e76ceb584a89745a9e84df5b3be2Daniel Veillard	xmlFree(prefix);
102803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	XP_ERROR(XPATH_EXPR_ERROR);
102813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
102823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    SKIP_BLANKS;
102833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_EXPR
102843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (prefix == NULL)
102853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	xmlGenericError(xmlGenericErrorContext, "Calling function %s\n",
102863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor			name);
102873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    else
102883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	xmlGenericError(xmlGenericErrorContext, "Calling function %s:%s\n",
102893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor			prefix, name);
102903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif
102913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
102923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (CUR != '(') {
102933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	XP_ERROR(XPATH_EXPR_ERROR);
102943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
102953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    NEXT;
102963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    SKIP_BLANKS;
102973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
102985691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik    /*
102995691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik    * Optimization for count(): we don't need the node-set to be sorted.
103005691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik    */
103015691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik    if ((prefix == NULL) && (name[0] == 'c') &&
103025691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	xmlStrEqual(name, BAD_CAST "count"))
103035691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik    {
103045691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	sort = 0;
103055691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik    }
103069e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    ctxt->comp->last = -1;
1030771f9d7310c1f8c587f518ec685b1448160df7336Daniel Veillard    if (CUR != ')') {
1030871f9d7310c1f8c587f518ec685b1448160df7336Daniel Veillard	while (CUR != 0) {
1030971f9d7310c1f8c587f518ec685b1448160df7336Daniel Veillard	    int op1 = ctxt->comp->last;
1031071f9d7310c1f8c587f518ec685b1448160df7336Daniel Veillard	    ctxt->comp->last = -1;
103115691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    xmlXPathCompileExpr(ctxt, sort);
10312074f37e7ebd5e76ceb584a89745a9e84df5b3be2Daniel Veillard	    if (ctxt->error != XPATH_EXPRESSION_OK) {
10313074f37e7ebd5e76ceb584a89745a9e84df5b3be2Daniel Veillard		xmlFree(name);
10314074f37e7ebd5e76ceb584a89745a9e84df5b3be2Daniel Veillard		xmlFree(prefix);
10315074f37e7ebd5e76ceb584a89745a9e84df5b3be2Daniel Veillard		return;
10316074f37e7ebd5e76ceb584a89745a9e84df5b3be2Daniel Veillard	    }
1031771f9d7310c1f8c587f518ec685b1448160df7336Daniel Veillard	    PUSH_BINARY_EXPR(XPATH_OP_ARG, op1, ctxt->comp->last, 0, 0);
1031871f9d7310c1f8c587f518ec685b1448160df7336Daniel Veillard	    nbargs++;
1031971f9d7310c1f8c587f518ec685b1448160df7336Daniel Veillard	    if (CUR == ')') break;
1032071f9d7310c1f8c587f518ec685b1448160df7336Daniel Veillard	    if (CUR != ',') {
1032171f9d7310c1f8c587f518ec685b1448160df7336Daniel Veillard		XP_ERROR(XPATH_EXPR_ERROR);
1032271f9d7310c1f8c587f518ec685b1448160df7336Daniel Veillard	    }
1032371f9d7310c1f8c587f518ec685b1448160df7336Daniel Veillard	    NEXT;
1032471f9d7310c1f8c587f518ec685b1448160df7336Daniel Veillard	    SKIP_BLANKS;
103253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
103263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
103279e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    PUSH_LONG_EXPR(XPATH_OP_FUNCTION, nbargs, 0, 0,
103289e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	           name, prefix);
103293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    NEXT;
103303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    SKIP_BLANKS;
103313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
103323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
103333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
10334afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompPrimaryExpr:
103353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
103363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
1033745490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *  [15]   PrimaryExpr ::=   VariableReference
103383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *                | '(' Expr ')'
1033945490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *                | Literal
1034045490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *                | Number
1034145490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *                | FunctionCall
103423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
10343afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile a primary expression.
103443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
10345afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void
10346afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompPrimaryExpr(xmlXPathParserContextPtr ctxt) {
103473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    SKIP_BLANKS;
10348afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard    if (CUR == '$') xmlXPathCompVariableReference(ctxt);
103493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    else if (CUR == '(') {
103503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	NEXT;
103513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	SKIP_BLANKS;
103525691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	xmlXPathCompileExpr(ctxt, 1);
1035350fe8b1732048003f47b32b009507fe6cdecd39fAleksey Sanin	CHECK_ERROR;
103543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (CUR != ')') {
103553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    XP_ERROR(XPATH_EXPR_ERROR);
103563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
103573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	NEXT;
103583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	SKIP_BLANKS;
10359d1757abcb891e01a9017f4aad041cc306d0d467bWilliam M. Brack    } else if (IS_ASCII_DIGIT(CUR) || (CUR == '.' && IS_ASCII_DIGIT(NXT(1)))) {
10360afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard	xmlXPathCompNumber(ctxt);
103613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    } else if ((CUR == '\'') || (CUR == '"')) {
10362afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard	xmlXPathCompLiteral(ctxt);
103633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    } else {
10364afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard	xmlXPathCompFunctionCall(ctxt);
103653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
103663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    SKIP_BLANKS;
103673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
103683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
103693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
10370afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompFilterExpr:
103713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
103723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
1037345490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *  [20]   FilterExpr ::=   PrimaryExpr
1037445490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *               | FilterExpr Predicate
103753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
10376afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile a filter expression.
103773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Square brackets are used to filter expressions in the same way that
103783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * they are used in location paths. It is an error if the expression to
103793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * be filtered does not evaluate to a node-set. The context node list
103803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * used for evaluating the expression in square brackets is the node-set
103813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * to be filtered listed in document order.
103823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
103833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
10384afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void
10385afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompFilterExpr(xmlXPathParserContextPtr ctxt) {
10386afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard    xmlXPathCompPrimaryExpr(ctxt);
103873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CHECK_ERROR;
103883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    SKIP_BLANKS;
1038945490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
103903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    while (CUR == '[') {
10391d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	xmlXPathCompPredicate(ctxt, 1);
103923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	SKIP_BLANKS;
103933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
103943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
1039545490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
103963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
103973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
103983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
103993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathScanName:
104003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
104013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
104023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Trickery: parse an XML name but without consuming the input flow
104033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Needed to avoid insanity in the parser state.
104043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
104053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [4] NameChar ::= Letter | Digit | '.' | '-' | '_' | ':' |
104063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *                  CombiningChar | Extender
104073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
104083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [5] Name ::= (Letter | '_' | ':') (NameChar)*
104093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
104103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [6] Names ::= Name (S Name)*
104113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
104123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the Name parsed or NULL
104133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
104143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
1041556a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic xmlChar *
104163473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathScanName(xmlXPathParserContextPtr ctxt) {
10417032268145fad72bbf00c944c1f6a067e5da4a1e0Daniel Veillard    int len = 0, l;
10418032268145fad72bbf00c944c1f6a067e5da4a1e0Daniel Veillard    int c;
10419032268145fad72bbf00c944c1f6a067e5da4a1e0Daniel Veillard    const xmlChar *cur;
10420032268145fad72bbf00c944c1f6a067e5da4a1e0Daniel Veillard    xmlChar *ret;
104213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
10422032268145fad72bbf00c944c1f6a067e5da4a1e0Daniel Veillard    cur = ctxt->cur;
10423032268145fad72bbf00c944c1f6a067e5da4a1e0Daniel Veillard
10424032268145fad72bbf00c944c1f6a067e5da4a1e0Daniel Veillard    c = CUR_CHAR(l);
10425032268145fad72bbf00c944c1f6a067e5da4a1e0Daniel Veillard    if ((c == ' ') || (c == '>') || (c == '/') || /* accelerators */
10426032268145fad72bbf00c944c1f6a067e5da4a1e0Daniel Veillard	(!IS_LETTER(c) && (c != '_') &&
10427032268145fad72bbf00c944c1f6a067e5da4a1e0Daniel Veillard         (c != ':'))) {
104283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(NULL);
104293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
104303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
10431032268145fad72bbf00c944c1f6a067e5da4a1e0Daniel Veillard    while ((c != ' ') && (c != '>') && (c != '/') && /* test bigname.xml */
10432032268145fad72bbf00c944c1f6a067e5da4a1e0Daniel Veillard	   ((IS_LETTER(c)) || (IS_DIGIT(c)) ||
10433032268145fad72bbf00c944c1f6a067e5da4a1e0Daniel Veillard            (c == '.') || (c == '-') ||
1043445490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	    (c == '_') || (c == ':') ||
10435032268145fad72bbf00c944c1f6a067e5da4a1e0Daniel Veillard	    (IS_COMBINING(c)) ||
10436032268145fad72bbf00c944c1f6a067e5da4a1e0Daniel Veillard	    (IS_EXTENDER(c)))) {
10437032268145fad72bbf00c944c1f6a067e5da4a1e0Daniel Veillard	len += l;
10438032268145fad72bbf00c944c1f6a067e5da4a1e0Daniel Veillard	NEXTL(l);
10439032268145fad72bbf00c944c1f6a067e5da4a1e0Daniel Veillard	c = CUR_CHAR(l);
104403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
10441032268145fad72bbf00c944c1f6a067e5da4a1e0Daniel Veillard    ret = xmlStrndup(cur, ctxt->cur - cur);
10442032268145fad72bbf00c944c1f6a067e5da4a1e0Daniel Veillard    ctxt->cur = cur;
10443032268145fad72bbf00c944c1f6a067e5da4a1e0Daniel Veillard    return(ret);
104443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
104453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
104463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
10447afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompPathExpr:
104483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
104493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
1045045490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *  [19]   PathExpr ::=   LocationPath
1045145490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *               | FilterExpr
1045245490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *               | FilterExpr '/' RelativeLocationPath
1045345490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *               | FilterExpr '//' RelativeLocationPath
104543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
10455afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile a path expression.
104563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The / operator and // operators combine an arbitrary expression
104573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * and a relative location path. It is an error if the expression
104583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * does not evaluate to a node-set.
104593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The / operator does composition in the same way as when / is
104603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * used in a location path. As in location paths, // is short for
104613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * /descendant-or-self::node()/.
104623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
104633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
10464afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void
10465afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompPathExpr(xmlXPathParserContextPtr ctxt) {
104663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    int lc = 1;           /* Should we branch to LocationPath ?         */
104673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlChar *name = NULL; /* we may have to preparse a name to find out */
104683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
104693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    SKIP_BLANKS;
1047045490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard    if ((CUR == '$') || (CUR == '(') ||
1047145490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	(IS_ASCII_DIGIT(CUR)) ||
10472d1757abcb891e01a9017f4aad041cc306d0d467bWilliam M. Brack        (CUR == '\'') || (CUR == '"') ||
10473d1757abcb891e01a9017f4aad041cc306d0d467bWilliam M. Brack	(CUR == '.' && IS_ASCII_DIGIT(NXT(1)))) {
104743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	lc = 0;
104753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    } else if (CUR == '*') {
104763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	/* relative or absolute location path */
104773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	lc = 1;
104783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    } else if (CUR == '/') {
104793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	/* relative or absolute location path */
104803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	lc = 1;
104813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    } else if (CUR == '@') {
104823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	/* relative abbreviated attribute location path */
104833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	lc = 1;
104843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    } else if (CUR == '.') {
104853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	/* relative abbreviated attribute location path */
104863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	lc = 1;
104873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    } else {
104883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	/*
104893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	 * Problem is finding if we have a name here whether it's:
104903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	 *   - a nodetype
104913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	 *   - a function call in which case it's followed by '('
104923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	 *   - an axis in which case it's followed by ':'
104933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	 *   - a element name
104943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	 * We do an a priori analysis here rather than having to
104953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	 * maintain parsed token content through the recursive function
10496081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack	 * calls. This looks uglier but makes the code easier to
104973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	 * read/write/debug.
104983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	 */
104993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	SKIP_BLANKS;
105003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	name = xmlXPathScanName(ctxt);
105013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if ((name != NULL) && (xmlStrstr(name, (xmlChar *) "::") != NULL)) {
105023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_STEP
105033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    xmlGenericError(xmlGenericErrorContext,
105043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    "PathExpr: Axis\n");
105053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif
105063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    lc = 1;
105073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    xmlFree(name);
105083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	} else if (name != NULL) {
105093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    int len =xmlStrlen(name);
105103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
1051145490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
105123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    while (NXT(len) != 0) {
105133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		if (NXT(len) == '/') {
105143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    /* element name */
105153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_STEP
105163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    xmlGenericError(xmlGenericErrorContext,
105173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor			    "PathExpr: AbbrRelLocation\n");
105183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif
105193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    lc = 1;
105203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    break;
1052176e95df05556c9610b564b14cf578c8f9e34c9c1William M. Brack		} else if (IS_BLANK_CH(NXT(len))) {
1052278637da0ea1c833dfdfad87a9aa5bea14510d08aWilliam M. Brack		    /* ignore blanks */
1052378637da0ea1c833dfdfad87a9aa5bea14510d08aWilliam M. Brack		    ;
105243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		} else if (NXT(len) == ':') {
105253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_STEP
105263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    xmlGenericError(xmlGenericErrorContext,
105273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor			    "PathExpr: AbbrRelLocation\n");
105283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif
105293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    lc = 1;
105303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    break;
105313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		} else if ((NXT(len) == '(')) {
105323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    /* Note Type or Function */
105333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    if (xmlXPathIsNodeType(name)) {
105343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_STEP
105353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		        xmlGenericError(xmlGenericErrorContext,
105363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor				"PathExpr: Type search\n");
105373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif
105383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor			lc = 1;
105393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    } else {
105403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_STEP
105413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		        xmlGenericError(xmlGenericErrorContext,
105423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor				"PathExpr: function call\n");
105433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif
105443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor			lc = 0;
105453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    }
105463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor                    break;
105473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		} else if ((NXT(len) == '[')) {
105483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    /* element name */
105493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_STEP
105503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    xmlGenericError(xmlGenericErrorContext,
105513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor			    "PathExpr: AbbrRelLocation\n");
105523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif
105533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    lc = 1;
105543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    break;
105553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		} else if ((NXT(len) == '<') || (NXT(len) == '>') ||
105563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor			   (NXT(len) == '=')) {
105573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    lc = 1;
105583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    break;
105593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		} else {
105603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    lc = 1;
105613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    break;
105623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		}
105633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		len++;
105643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    }
105653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    if (NXT(len) == 0) {
105663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_STEP
105673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		xmlGenericError(xmlGenericErrorContext,
105683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor			"PathExpr: AbbrRelLocation\n");
105693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif
105703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		/* element name */
105713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		lc = 1;
105723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    }
105733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    xmlFree(name);
105743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	} else {
10575081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack	    /* make sure all cases are covered explicitly */
105763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    XP_ERROR(XPATH_EXPR_ERROR);
105773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
1057845490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard    }
105793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
105803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (lc) {
105819e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	if (CUR == '/') {
105829e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    PUSH_LEAVE_EXPR(XPATH_OP_ROOT, 0, 0);
105839e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	} else {
105849e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    PUSH_LEAVE_EXPR(XPATH_OP_NODE, 0, 0);
105853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
10586afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard	xmlXPathCompLocationPath(ctxt);
105873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    } else {
10588afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard	xmlXPathCompFilterExpr(ctxt);
105893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	CHECK_ERROR;
105903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if ((CUR == '/') && (NXT(1) == '/')) {
105913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    SKIP(2);
105923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    SKIP_BLANKS;
105939e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
105949e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    PUSH_LONG_EXPR(XPATH_OP_COLLECT, AXIS_DESCENDANT_OR_SELF,
105959e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    NODE_TEST_TYPE, NODE_TYPE_NODE, NULL, NULL);
105969e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    PUSH_UNARY_EXPR(XPATH_OP_RESET, ctxt->comp->last, 1, 0);
105979e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
10598afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard	    xmlXPathCompRelativeLocationPath(ctxt);
105993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	} else if (CUR == '/') {
10600afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard	    xmlXPathCompRelativeLocationPath(ctxt);
106013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
106023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
106033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    SKIP_BLANKS;
106043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
106053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
106063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
10607afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompUnionExpr:
106083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
106093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
1061045490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *  [18]   UnionExpr ::=   PathExpr
1061145490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *               | UnionExpr '|' PathExpr
106123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
10613afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile an union expression.
106143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
106153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
10616afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void
10617afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompUnionExpr(xmlXPathParserContextPtr ctxt) {
10618afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard    xmlXPathCompPathExpr(ctxt);
106193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CHECK_ERROR;
106203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    SKIP_BLANKS;
106213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    while (CUR == '|') {
106229e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	int op1 = ctxt->comp->last;
106239e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	PUSH_LEAVE_EXPR(XPATH_OP_NODE, 0, 0);
106243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
106253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	NEXT;
106263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	SKIP_BLANKS;
10627afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard	xmlXPathCompPathExpr(ctxt);
106283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
106299e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	PUSH_BINARY_EXPR(XPATH_OP_UNION, op1, ctxt->comp->last, 0, 0);
106309e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
106313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	SKIP_BLANKS;
106323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
106333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
106343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
106353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
10636afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompUnaryExpr:
106373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
106383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
1063945490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *  [27]   UnaryExpr ::=   UnionExpr
1064045490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *                   | '-' UnaryExpr
106413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
10642afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile an unary expression.
106433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
106443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
10645afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void
10646afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompUnaryExpr(xmlXPathParserContextPtr ctxt) {
106473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    int minus = 0;
106489e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    int found = 0;
106493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
106503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    SKIP_BLANKS;
1065168d7b67ada0941ad7e1d02602f48de4015a67af3Daniel Veillard    while (CUR == '-') {
1065268d7b67ada0941ad7e1d02602f48de4015a67af3Daniel Veillard        minus = 1 - minus;
106539e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	found = 1;
106543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	NEXT;
106553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	SKIP_BLANKS;
106563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
106579e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
10658afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard    xmlXPathCompUnionExpr(ctxt);
106593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CHECK_ERROR;
106609e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    if (found) {
106619e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	if (minus)
106629e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    PUSH_UNARY_EXPR(XPATH_OP_PLUS, ctxt->comp->last, 2, 0);
106639e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	else
106649e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    PUSH_UNARY_EXPR(XPATH_OP_PLUS, ctxt->comp->last, 3, 0);
106653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
106663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
106673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
106683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
10669afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompMultiplicativeExpr:
106703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
106713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
1067245490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *  [26]   MultiplicativeExpr ::=   UnaryExpr
1067345490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *                   | MultiplicativeExpr MultiplyOperator UnaryExpr
1067445490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *                   | MultiplicativeExpr 'div' UnaryExpr
1067545490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *                   | MultiplicativeExpr 'mod' UnaryExpr
106763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *  [34]   MultiplyOperator ::=   '*'
106773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
10678afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile an Additive expression.
106793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
106803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
10681afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void
10682afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompMultiplicativeExpr(xmlXPathParserContextPtr ctxt) {
10683afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard    xmlXPathCompUnaryExpr(ctxt);
106843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CHECK_ERROR;
106853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    SKIP_BLANKS;
1068645490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard    while ((CUR == '*') ||
106873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor           ((CUR == 'd') && (NXT(1) == 'i') && (NXT(2) == 'v')) ||
106883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor           ((CUR == 'm') && (NXT(1) == 'o') && (NXT(2) == 'd'))) {
106893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	int op = -1;
106909e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	int op1 = ctxt->comp->last;
106913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
106923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        if (CUR == '*') {
106933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    op = 0;
106943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    NEXT;
106953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	} else if (CUR == 'd') {
106963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    op = 1;
106973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    SKIP(3);
106983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	} else if (CUR == 'm') {
106993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    op = 2;
107003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    SKIP(3);
107013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
107023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	SKIP_BLANKS;
10703afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard        xmlXPathCompUnaryExpr(ctxt);
107043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	CHECK_ERROR;
107059e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	PUSH_BINARY_EXPR(XPATH_OP_MULT, op1, ctxt->comp->last, op, 0);
107063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	SKIP_BLANKS;
107073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
107083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
107093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
107103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
10711afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompAdditiveExpr:
107123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
107133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
1071445490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *  [25]   AdditiveExpr ::=   MultiplicativeExpr
1071545490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *                   | AdditiveExpr '+' MultiplicativeExpr
1071645490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *                   | AdditiveExpr '-' MultiplicativeExpr
107173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
10718afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile an Additive expression.
107193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
107203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
10721afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void
10722afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompAdditiveExpr(xmlXPathParserContextPtr ctxt) {
107239e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
10724afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard    xmlXPathCompMultiplicativeExpr(ctxt);
107253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CHECK_ERROR;
107263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    SKIP_BLANKS;
107273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    while ((CUR == '+') || (CUR == '-')) {
107283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	int plus;
107299e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	int op1 = ctxt->comp->last;
107303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
107313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        if (CUR == '+') plus = 1;
107323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	else plus = 0;
107333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	NEXT;
107343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	SKIP_BLANKS;
10735afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard        xmlXPathCompMultiplicativeExpr(ctxt);
107363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	CHECK_ERROR;
107379e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	PUSH_BINARY_EXPR(XPATH_OP_PLUS, op1, ctxt->comp->last, plus, 0);
107383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	SKIP_BLANKS;
107393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
107403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
107413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
107423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
10743afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompRelationalExpr:
107443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
107453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
1074645490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *  [24]   RelationalExpr ::=   AdditiveExpr
1074745490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *                 | RelationalExpr '<' AdditiveExpr
1074845490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *                 | RelationalExpr '>' AdditiveExpr
1074945490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *                 | RelationalExpr '<=' AdditiveExpr
1075045490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *                 | RelationalExpr '>=' AdditiveExpr
107513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
107523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *  A <= B > C is allowed ? Answer from James, yes with
107533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *  (AdditiveExpr <= AdditiveExpr) > AdditiveExpr
107543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *  which is basically what got implemented.
107553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
10756afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile a Relational expression, then push the result
107573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * on the stack
107583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
107593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
10760afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void
10761afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompRelationalExpr(xmlXPathParserContextPtr ctxt) {
10762afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard    xmlXPathCompAdditiveExpr(ctxt);
107633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CHECK_ERROR;
107643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    SKIP_BLANKS;
107653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    while ((CUR == '<') ||
107663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor           (CUR == '>') ||
107673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor           ((CUR == '<') && (NXT(1) == '=')) ||
107683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor           ((CUR == '>') && (NXT(1) == '='))) {
107699e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	int inf, strict;
107709e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	int op1 = ctxt->comp->last;
107713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
107723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        if (CUR == '<') inf = 1;
107733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	else inf = 0;
107743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (NXT(1) == '=') strict = 0;
107753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	else strict = 1;
107763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	NEXT;
107773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (!strict) NEXT;
107783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	SKIP_BLANKS;
10779afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard        xmlXPathCompAdditiveExpr(ctxt);
107803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	CHECK_ERROR;
107819e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	PUSH_BINARY_EXPR(XPATH_OP_CMP, op1, ctxt->comp->last, inf, strict);
107823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	SKIP_BLANKS;
107833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
107843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
107853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
107863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
10787afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompEqualityExpr:
107883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
107893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
1079045490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *  [23]   EqualityExpr ::=   RelationalExpr
1079145490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *                 | EqualityExpr '=' RelationalExpr
1079245490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *                 | EqualityExpr '!=' RelationalExpr
107933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
107943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *  A != B != C is allowed ? Answer from James, yes with
107953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *  (RelationalExpr = RelationalExpr) = RelationalExpr
107963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *  (RelationalExpr != RelationalExpr) != RelationalExpr
107973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *  which is basically what got implemented.
107983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
10799afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile an Equality expression.
108003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
108013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
10802afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void
10803afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompEqualityExpr(xmlXPathParserContextPtr ctxt) {
10804afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard    xmlXPathCompRelationalExpr(ctxt);
108053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CHECK_ERROR;
108063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    SKIP_BLANKS;
108073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    while ((CUR == '=') || ((CUR == '!') && (NXT(1) == '='))) {
108089e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	int eq;
108099e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	int op1 = ctxt->comp->last;
108103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
108113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        if (CUR == '=') eq = 1;
108123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	else eq = 0;
108133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	NEXT;
108143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (!eq) NEXT;
108153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	SKIP_BLANKS;
10816afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard        xmlXPathCompRelationalExpr(ctxt);
108173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	CHECK_ERROR;
108189e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	PUSH_BINARY_EXPR(XPATH_OP_EQUAL, op1, ctxt->comp->last, eq, 0);
108193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	SKIP_BLANKS;
108203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
108213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
108223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
108233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
10824afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompAndExpr:
108253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
108263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
1082745490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *  [22]   AndExpr ::=   EqualityExpr
1082845490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *                 | AndExpr 'and' EqualityExpr
108293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
10830afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile an AND expression.
108313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
108323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
10833afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void
10834afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompAndExpr(xmlXPathParserContextPtr ctxt) {
10835afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard    xmlXPathCompEqualityExpr(ctxt);
108363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CHECK_ERROR;
108373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    SKIP_BLANKS;
108383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    while ((CUR == 'a') && (NXT(1) == 'n') && (NXT(2) == 'd')) {
108399e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	int op1 = ctxt->comp->last;
108403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        SKIP(3);
108413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	SKIP_BLANKS;
10842afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard        xmlXPathCompEqualityExpr(ctxt);
108433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	CHECK_ERROR;
108449e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	PUSH_BINARY_EXPR(XPATH_OP_AND, op1, ctxt->comp->last, 0, 0);
108453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	SKIP_BLANKS;
108463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
108473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
108483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
108493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
10850591b4be0fe1986b5e71d54c5c063493987ef4285Daniel Veillard * xmlXPathCompileExpr:
108513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
108523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
1085345490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *  [14]   Expr ::=   OrExpr
1085445490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *  [21]   OrExpr ::=   AndExpr
1085545490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *                 | OrExpr 'or' AndExpr
108563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
10857afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Parse and compile an expression
108583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
10859afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void
108605691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. BuchcikxmlXPathCompileExpr(xmlXPathParserContextPtr ctxt, int sort) {
10861afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard    xmlXPathCompAndExpr(ctxt);
108623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CHECK_ERROR;
108633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    SKIP_BLANKS;
108643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    while ((CUR == 'o') && (NXT(1) == 'r')) {
108659e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	int op1 = ctxt->comp->last;
108663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        SKIP(2);
108673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	SKIP_BLANKS;
10868afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard        xmlXPathCompAndExpr(ctxt);
108693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	CHECK_ERROR;
108709e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	PUSH_BINARY_EXPR(XPATH_OP_OR, op1, ctxt->comp->last, 0, 0);
108719e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	op1 = ctxt->comp->nbStep;
108723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	SKIP_BLANKS;
108733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
108745691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik    if ((sort) && (ctxt->comp->steps[ctxt->comp->last].op != XPATH_OP_VALUE)) {
108759e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	/* more ops could be optimized too */
108765691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	/*
108775691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	* This is the main place to eliminate sorting for
108785691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	* operations which don't require a sorted node-set.
108795691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	* E.g. count().
108805691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	*/
108819e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	PUSH_UNARY_EXPR(XPATH_OP_SORT, ctxt->comp->last , 0, 0);
108829e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    }
108833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
108843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
108853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
10886afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompPredicate:
108873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
10888d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * @filter:  act as a filter
108893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
108903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *  [8]   Predicate ::=   '[' PredicateExpr ']'
1089145490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *  [9]   PredicateExpr ::=   Expr
108923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
10893afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile a predicate expression
108949e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard */
10895afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void
10896d8df6c0e8c883e1d618388d266015dda36731440Daniel VeillardxmlXPathCompPredicate(xmlXPathParserContextPtr ctxt, int filter) {
108979e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    int op1 = ctxt->comp->last;
108989e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
108999e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    SKIP_BLANKS;
109009e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    if (CUR != '[') {
109019e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	XP_ERROR(XPATH_INVALID_PREDICATE_ERROR);
109029e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    }
109039e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    NEXT;
109049e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    SKIP_BLANKS;
109059e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
109069e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    ctxt->comp->last = -1;
10907631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik    /*
10908631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik    * This call to xmlXPathCompileExpr() will deactivate sorting
10909631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik    * of the predicate result.
10910631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik    * TODO: Sorting is still activated for filters, since I'm not
10911631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik    *  sure if needed. Normally sorting should not be needed, since
10912631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik    *  a filter can only diminish the number of items in a sequence,
10913631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik    *  but won't change its order; so if the initial sequence is sorted,
10914631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik    *  subsequent sorting is not needed.
10915631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik    */
10916631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik    if (! filter)
10917631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	xmlXPathCompileExpr(ctxt, 0);
10918631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik    else
10919631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	xmlXPathCompileExpr(ctxt, 1);
109209e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    CHECK_ERROR;
109219e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
109229e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    if (CUR != ']') {
109239e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	XP_ERROR(XPATH_INVALID_PREDICATE_ERROR);
109249e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    }
109259e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
10926d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard    if (filter)
10927d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	PUSH_BINARY_EXPR(XPATH_OP_FILTER, op1, ctxt->comp->last, 0, 0);
10928d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard    else
10929d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	PUSH_BINARY_EXPR(XPATH_OP_PREDICATE, op1, ctxt->comp->last, 0, 0);
109309e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
109319e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    NEXT;
109329e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    SKIP_BLANKS;
109339e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard}
109349e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
109359e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard/**
10936afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompNodeTest:
109373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
109383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @test:  pointer to a xmlXPathTestVal
109393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @type:  pointer to a xmlXPathTypeVal
109403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @prefix:  placeholder for a possible name prefix
109413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
109423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [7] NodeTest ::=   NameTest
109433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *		    | NodeType '(' ')'
109443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *		    | 'processing-instruction' '(' Literal ')'
109453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
109463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [37] NameTest ::=  '*'
109473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *		    | NCName ':' '*'
109483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *		    | QName
109493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [38] NodeType ::= 'comment'
109503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *		   | 'text'
109513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *		   | 'processing-instruction'
109523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *		   | 'node'
109533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
10954081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack * Returns the name found and updates @test, @type and @prefix appropriately
109553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
1095656a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic xmlChar *
10957afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompNodeTest(xmlXPathParserContextPtr ctxt, xmlXPathTestVal *test,
10958afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard	             xmlXPathTypeVal *type, const xmlChar **prefix,
10959afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard		     xmlChar *name) {
109603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    int blanks;
109613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
109623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if ((test == NULL) || (type == NULL) || (prefix == NULL)) {
109633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	STRANGE;
109643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(NULL);
109653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
1096678637da0ea1c833dfdfad87a9aa5bea14510d08aWilliam M. Brack    *type = (xmlXPathTypeVal) 0;
1096778637da0ea1c833dfdfad87a9aa5bea14510d08aWilliam M. Brack    *test = (xmlXPathTestVal) 0;
109683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    *prefix = NULL;
109693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    SKIP_BLANKS;
109703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
109713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if ((name == NULL) && (CUR == '*')) {
109723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	/*
109733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	 * All elements
109743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	 */
109753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	NEXT;
109763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	*test = NODE_TEST_ALL;
109773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(NULL);
109783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
109793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
109803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (name == NULL)
109813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	name = xmlXPathParseNCName(ctxt);
109823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (name == NULL) {
1098324505b0f5c872c5afb6da5093565e5a6e09ca541Daniel Veillard	XP_ERRORNULL(XPATH_EXPR_ERROR);
109843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
109853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
1098676e95df05556c9610b564b14cf578c8f9e34c9c1William M. Brack    blanks = IS_BLANK_CH(CUR);
109873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    SKIP_BLANKS;
109883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (CUR == '(') {
109893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	NEXT;
109903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	/*
109913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	 * NodeType or PI search
109923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	 */
109933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (xmlStrEqual(name, BAD_CAST "comment"))
109943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    *type = NODE_TYPE_COMMENT;
109953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	else if (xmlStrEqual(name, BAD_CAST "node"))
109963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    *type = NODE_TYPE_NODE;
109973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	else if (xmlStrEqual(name, BAD_CAST "processing-instruction"))
109983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    *type = NODE_TYPE_PI;
109993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	else if (xmlStrEqual(name, BAD_CAST "text"))
110003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    *type = NODE_TYPE_TEXT;
110013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	else {
110023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    if (name != NULL)
110033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		xmlFree(name);
1100424505b0f5c872c5afb6da5093565e5a6e09ca541Daniel Veillard	    XP_ERRORNULL(XPATH_EXPR_ERROR);
110053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
110063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
110073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	*test = NODE_TEST_TYPE;
1100845490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
110093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	SKIP_BLANKS;
110103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (*type == NODE_TYPE_PI) {
110113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    /*
110123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	     * Specific case: search a PI by name.
110133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	     */
110143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    if (name != NULL)
110153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		xmlFree(name);
1101682e4971dc2f470c9b6f19cf8b15ff32781067167Daniel Veillard	    name = NULL;
1101782e4971dc2f470c9b6f19cf8b15ff32781067167Daniel Veillard	    if (CUR != ')') {
1101882e4971dc2f470c9b6f19cf8b15ff32781067167Daniel Veillard		name = xmlXPathParseLiteral(ctxt);
1101924505b0f5c872c5afb6da5093565e5a6e09ca541Daniel Veillard		CHECK_ERROR NULL;
11020ed23b7dc73f6c1146701ece20ed3f03d68366516Daniel Veillard		*test = NODE_TEST_PI;
1102182e4971dc2f470c9b6f19cf8b15ff32781067167Daniel Veillard		SKIP_BLANKS;
1102282e4971dc2f470c9b6f19cf8b15ff32781067167Daniel Veillard	    }
110233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
110243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (CUR != ')') {
110253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    if (name != NULL)
110263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		xmlFree(name);
1102724505b0f5c872c5afb6da5093565e5a6e09ca541Daniel Veillard	    XP_ERRORNULL(XPATH_UNCLOSED_ERROR);
110283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
110293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	NEXT;
110303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(name);
110313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
110323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    *test = NODE_TEST_NAME;
110333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if ((!blanks) && (CUR == ':')) {
110343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	NEXT;
110353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
110363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	/*
11037fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard	 * Since currently the parser context don't have a
11038fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard	 * namespace list associated:
11039fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard	 * The namespace name for this prefix can be computed
11040fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard	 * only at evaluation time. The compilation is done
11041fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard	 * outside of any context.
110423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	 */
11043fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard#if 0
110443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	*prefix = xmlXPathNsLookup(ctxt->context, name);
110453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (name != NULL)
110463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    xmlFree(name);
110473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (*prefix == NULL) {
110483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    XP_ERROR0(XPATH_UNDEF_PREFIX_ERROR);
110493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
11050fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard#else
11051fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard	*prefix = name;
11052fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard#endif
110533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
110543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (CUR == '*') {
110553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    /*
110563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	     * All elements
110573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	     */
110583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    NEXT;
110593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    *test = NODE_TEST_ALL;
110603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    return(NULL);
110613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
110623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
110633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	name = xmlXPathParseNCName(ctxt);
110643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (name == NULL) {
1106524505b0f5c872c5afb6da5093565e5a6e09ca541Daniel Veillard	    XP_ERRORNULL(XPATH_EXPR_ERROR);
110663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
110673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
110683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(name);
110693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
110703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
110713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
110723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathIsAxisName:
110733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @name:  a preparsed name token
110743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
110753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [6] AxisName ::=   'ancestor'
110763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *                  | 'ancestor-or-self'
110773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *                  | 'attribute'
110783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *                  | 'child'
110793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *                  | 'descendant'
110803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *                  | 'descendant-or-self'
110813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *                  | 'following'
110823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *                  | 'following-sibling'
110833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *                  | 'namespace'
110843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *                  | 'parent'
110853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *                  | 'preceding'
110863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *                  | 'preceding-sibling'
110873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *                  | 'self'
110883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
110893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the axis or 0
110903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
1109156a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic xmlXPathAxisVal
110923473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathIsAxisName(const xmlChar *name) {
1109378637da0ea1c833dfdfad87a9aa5bea14510d08aWilliam M. Brack    xmlXPathAxisVal ret = (xmlXPathAxisVal) 0;
110943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    switch (name[0]) {
110953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case 'a':
110963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    if (xmlStrEqual(name, BAD_CAST "ancestor"))
110973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		ret = AXIS_ANCESTOR;
110983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    if (xmlStrEqual(name, BAD_CAST "ancestor-or-self"))
110993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		ret = AXIS_ANCESTOR_OR_SELF;
111003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    if (xmlStrEqual(name, BAD_CAST "attribute"))
111013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		ret = AXIS_ATTRIBUTE;
111023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    break;
111033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case 'c':
111043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    if (xmlStrEqual(name, BAD_CAST "child"))
111053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		ret = AXIS_CHILD;
111063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    break;
111073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case 'd':
111083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    if (xmlStrEqual(name, BAD_CAST "descendant"))
111093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		ret = AXIS_DESCENDANT;
111103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    if (xmlStrEqual(name, BAD_CAST "descendant-or-self"))
111113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		ret = AXIS_DESCENDANT_OR_SELF;
111123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    break;
111133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case 'f':
111143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    if (xmlStrEqual(name, BAD_CAST "following"))
111153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		ret = AXIS_FOLLOWING;
111163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    if (xmlStrEqual(name, BAD_CAST "following-sibling"))
111173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		ret = AXIS_FOLLOWING_SIBLING;
111183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    break;
111193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case 'n':
111203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    if (xmlStrEqual(name, BAD_CAST "namespace"))
111213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		ret = AXIS_NAMESPACE;
111223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    break;
111233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case 'p':
111243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    if (xmlStrEqual(name, BAD_CAST "parent"))
111253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		ret = AXIS_PARENT;
111263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    if (xmlStrEqual(name, BAD_CAST "preceding"))
111273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		ret = AXIS_PRECEDING;
111283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    if (xmlStrEqual(name, BAD_CAST "preceding-sibling"))
111293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		ret = AXIS_PRECEDING_SIBLING;
111303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    break;
111313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case 's':
111323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    if (xmlStrEqual(name, BAD_CAST "self"))
111333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		ret = AXIS_SELF;
111343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    break;
111353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
111363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(ret);
111373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
111383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
111393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
11140afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompStep:
111413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
111423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
111433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [4] Step ::=   AxisSpecifier NodeTest Predicate*
1114445490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *                  | AbbreviatedStep
111453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
111463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [12] AbbreviatedStep ::=   '.' | '..'
111473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
111483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [5] AxisSpecifier ::= AxisName '::'
111493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *                  | AbbreviatedAxisSpecifier
111503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
111513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [13] AbbreviatedAxisSpecifier ::= '@'?
111523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
111533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Modified for XPtr range support as:
111543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
111553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *  [4xptr] Step ::= AxisSpecifier NodeTest Predicate*
111563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *                     | AbbreviatedStep
111573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *                     | 'range-to' '(' Expr ')' Predicate*
111583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
11159afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile one step in a Location Path
111603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * A location step of . is short for self::node(). This is
111613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * particularly useful in conjunction with //. For example, the
111623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * location path .//para is short for
111633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * self::node()/descendant-or-self::node()/child::para
111643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * and so will select all para descendant elements of the context
111653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * node.
111663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Similarly, a location step of .. is short for parent::node().
111673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * For example, ../title is short for parent::node()/child::title
111683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * and so will select the title children of the parent of the context
111693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * node.
111703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
11171afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void
11172afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompStep(xmlXPathParserContextPtr ctxt) {
11173fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard#ifdef LIBXML_XPTR_ENABLED
11174fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard    int rangeto = 0;
11175fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard    int op2 = -1;
11176fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard#endif
11177fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard
111783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    SKIP_BLANKS;
111793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if ((CUR == '.') && (NXT(1) == '.')) {
111803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	SKIP(2);
111813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	SKIP_BLANKS;
111829e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	PUSH_LONG_EXPR(XPATH_OP_COLLECT, AXIS_PARENT,
111839e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    NODE_TEST_TYPE, NODE_TYPE_NODE, NULL, NULL);
111843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    } else if (CUR == '.') {
111853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	NEXT;
111863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	SKIP_BLANKS;
111873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    } else {
111883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	xmlChar *name = NULL;
111893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	const xmlChar *prefix = NULL;
11190aac7c68e87d00732b319698723de1ec43252fb01Daniel Veillard	xmlXPathTestVal test = (xmlXPathTestVal) 0;
1119178637da0ea1c833dfdfad87a9aa5bea14510d08aWilliam M. Brack	xmlXPathAxisVal axis = (xmlXPathAxisVal) 0;
11192aac7c68e87d00732b319698723de1ec43252fb01Daniel Veillard	xmlXPathTypeVal type = (xmlXPathTypeVal) 0;
11193d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	int op1;
111943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
111953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	/*
111963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	 * The modification needed for XPointer change to the production
111973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	 */
111983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef LIBXML_XPTR_ENABLED
11199fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard	if (ctxt->xptr) {
112003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    name = xmlXPathParseNCName(ctxt);
112013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    if ((name != NULL) && (xmlStrEqual(name, BAD_CAST "range-to"))) {
11202fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard                op2 = ctxt->comp->last;
112033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		xmlFree(name);
112043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		SKIP_BLANKS;
112053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		if (CUR != '(') {
112063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    XP_ERROR(XPATH_EXPR_ERROR);
112073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		}
112083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		NEXT;
112093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		SKIP_BLANKS;
112103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
112115691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		xmlXPathCompileExpr(ctxt, 1);
11212fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard		/* PUSH_BINARY_EXPR(XPATH_OP_RANGETO, op2, ctxt->comp->last, 0, 0); */
112133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		CHECK_ERROR;
112143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
112153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		SKIP_BLANKS;
112163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		if (CUR != ')') {
112173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    XP_ERROR(XPATH_EXPR_ERROR);
112183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		}
112193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		NEXT;
11220fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard		rangeto = 1;
112213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		goto eval_predicates;
112223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    }
112233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
112243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif
112252156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard	if (CUR == '*') {
112262156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard	    axis = AXIS_CHILD;
112272156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard	} else {
112282156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard	    if (name == NULL)
112292156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard		name = xmlXPathParseNCName(ctxt);
112302156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard	    if (name != NULL) {
112312156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard		axis = xmlXPathIsAxisName(name);
112322156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard		if (axis != 0) {
112332156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard		    SKIP_BLANKS;
112342156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard		    if ((CUR == ':') && (NXT(1) == ':')) {
112352156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard			SKIP(2);
112362156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard			xmlFree(name);
112372156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard			name = NULL;
112382156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard		    } else {
112392156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard			/* an element name can conflict with an axis one :-\ */
112402156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard			axis = AXIS_CHILD;
112412156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard		    }
112423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		} else {
112433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    axis = AXIS_CHILD;
112443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		}
112452156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard	    } else if (CUR == '@') {
112462156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard		NEXT;
112472156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard		axis = AXIS_ATTRIBUTE;
112483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    } else {
112492156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard		axis = AXIS_CHILD;
112503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    }
112513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
112523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
112533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	CHECK_ERROR;
112543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
11255afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard	name = xmlXPathCompNodeTest(ctxt, &test, &type, &prefix, name);
112563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (test == 0)
112573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    return;
112583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
11259ed6c54971fdb7fa37c183b1a36c2e581c750984bDaniel Veillard        if ((prefix != NULL) && (ctxt->context != NULL) &&
11260ed6c54971fdb7fa37c183b1a36c2e581c750984bDaniel Veillard	    (ctxt->context->flags & XML_XPATH_CHECKNS)) {
11261ed6c54971fdb7fa37c183b1a36c2e581c750984bDaniel Veillard	    if (xmlXPathNsLookup(ctxt->context, prefix) == NULL) {
11262ed6c54971fdb7fa37c183b1a36c2e581c750984bDaniel Veillard		xmlXPathErr(ctxt, XPATH_UNDEF_PREFIX_ERROR);
11263ed6c54971fdb7fa37c183b1a36c2e581c750984bDaniel Veillard	    }
11264ed6c54971fdb7fa37c183b1a36c2e581c750984bDaniel Veillard	}
112653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_STEP
112663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	xmlGenericError(xmlGenericErrorContext,
112673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		"Basis : computing new set\n");
112683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif
112699e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
112703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_STEP
112713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	xmlGenericError(xmlGenericErrorContext, "Basis : ");
11272fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard	if (ctxt->value == NULL)
11273fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard	    xmlGenericError(xmlGenericErrorContext, "no value\n");
11274fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard	else if (ctxt->value->nodesetval == NULL)
11275fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard	    xmlGenericError(xmlGenericErrorContext, "Empty\n");
11276fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard	else
11277fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard	    xmlGenericErrorContextNodeSet(stdout, ctxt->value->nodesetval);
112783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif
112793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
112805bb9ccd56a812b65e94e71477389be7826203649Daniel Veillard#ifdef LIBXML_XPTR_ENABLED
112813473f88a7abdf4e585e267288fb77e898c580d2bOwen Tayloreval_predicates:
112825bb9ccd56a812b65e94e71477389be7826203649Daniel Veillard#endif
11283d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	op1 = ctxt->comp->last;
11284d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	ctxt->comp->last = -1;
11285d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard
112863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	SKIP_BLANKS;
112873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	while (CUR == '[') {
11288d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	    xmlXPathCompPredicate(ctxt, 0);
112893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
11290d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard
11291fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard#ifdef LIBXML_XPTR_ENABLED
11292fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard	if (rangeto) {
11293fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard	    PUSH_BINARY_EXPR(XPATH_OP_RANGETO, op2, op1, 0, 0);
11294fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard	} else
11295fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard#endif
11296fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard	    PUSH_FULL_EXPR(XPATH_OP_COLLECT, op1, ctxt->comp->last, axis,
11297fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard			   test, type, (void *)prefix, (void *)name);
11298d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard
112993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
113003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_STEP
113013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlGenericError(xmlGenericErrorContext, "Step : ");
11302fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard    if (ctxt->value == NULL)
11303fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard	xmlGenericError(xmlGenericErrorContext, "no value\n");
11304fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard    else if (ctxt->value->nodesetval == NULL)
11305fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard	xmlGenericError(xmlGenericErrorContext, "Empty\n");
11306fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard    else
11307fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard	xmlGenericErrorContextNodeSet(xmlGenericErrorContext,
11308fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard		ctxt->value->nodesetval);
113093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif
113103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
113113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
113123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
11313afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompRelativeLocationPath:
113143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
113153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
1131645490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *  [3]   RelativeLocationPath ::=   Step
1131745490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *                     | RelativeLocationPath '/' Step
1131845490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *                     | AbbreviatedRelativeLocationPath
1131945490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *  [11]  AbbreviatedRelativeLocationPath ::=   RelativeLocationPath '//' Step
113203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
11321afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile a relative location path.
113223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
11323afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void
11324afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompRelativeLocationPath
113253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor(xmlXPathParserContextPtr ctxt) {
113263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    SKIP_BLANKS;
113273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if ((CUR == '/') && (NXT(1) == '/')) {
113283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	SKIP(2);
113293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	SKIP_BLANKS;
113309e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	PUSH_LONG_EXPR(XPATH_OP_COLLECT, AXIS_DESCENDANT_OR_SELF,
113319e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		         NODE_TEST_TYPE, NODE_TYPE_NODE, NULL, NULL);
113323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    } else if (CUR == '/') {
113333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    NEXT;
113343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	SKIP_BLANKS;
113353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
11336afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard    xmlXPathCompStep(ctxt);
113373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    SKIP_BLANKS;
113383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    while (CUR == '/') {
113393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if ((CUR == '/') && (NXT(1) == '/')) {
113403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    SKIP(2);
113413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    SKIP_BLANKS;
113429e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    PUSH_LONG_EXPR(XPATH_OP_COLLECT, AXIS_DESCENDANT_OR_SELF,
113433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor			     NODE_TEST_TYPE, NODE_TYPE_NODE, NULL, NULL);
11344afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard	    xmlXPathCompStep(ctxt);
113453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	} else if (CUR == '/') {
113463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    NEXT;
113473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    SKIP_BLANKS;
11348afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard	    xmlXPathCompStep(ctxt);
113493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
113503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	SKIP_BLANKS;
113513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
113523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
113533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
113543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
11355afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompLocationPath:
113563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
113573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
1135845490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *  [1]   LocationPath ::=   RelativeLocationPath
1135945490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *                     | AbsoluteLocationPath
113603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *  [2]   AbsoluteLocationPath ::=   '/' RelativeLocationPath?
1136145490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *                     | AbbreviatedAbsoluteLocationPath
1136245490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *  [10]   AbbreviatedAbsoluteLocationPath ::=
1136345490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *                           '//' RelativeLocationPath
113643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
11365afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile a location path
11366afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard *
113673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * // is short for /descendant-or-self::node()/. For example,
113683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * //para is short for /descendant-or-self::node()/child::para and
113693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * so will select any para element in the document (even a para element
113703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * that is a document element will be selected by //para since the
113713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * document element node is a child of the root node); div//para is
113723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * short for div/descendant-or-self::node()/child::para and so will
113733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * select all para descendants of div children.
113743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
11375afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void
11376afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompLocationPath(xmlXPathParserContextPtr ctxt) {
113773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    SKIP_BLANKS;
113783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (CUR != '/') {
11379afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard        xmlXPathCompRelativeLocationPath(ctxt);
113803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    } else {
113813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	while (CUR == '/') {
113823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    if ((CUR == '/') && (NXT(1) == '/')) {
113833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		SKIP(2);
113843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		SKIP_BLANKS;
113859e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		PUSH_LONG_EXPR(XPATH_OP_COLLECT, AXIS_DESCENDANT_OR_SELF,
113869e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard			     NODE_TEST_TYPE, NODE_TYPE_NODE, NULL, NULL);
11387afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard		xmlXPathCompRelativeLocationPath(ctxt);
113883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    } else if (CUR == '/') {
113893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		NEXT;
11390608ad0791b3b35072c8021ea4f66cf9d700394b9Daniel Veillard		SKIP_BLANKS;
11391608ad0791b3b35072c8021ea4f66cf9d700394b9Daniel Veillard		if ((CUR != 0 ) &&
11392d1757abcb891e01a9017f4aad041cc306d0d467bWilliam M. Brack		    ((IS_ASCII_LETTER(CUR)) || (CUR == '_') || (CUR == '.') ||
11393608ad0791b3b35072c8021ea4f66cf9d700394b9Daniel Veillard		     (CUR == '@') || (CUR == '*')))
11394afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard		    xmlXPathCompRelativeLocationPath(ctxt);
113953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    }
113963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
113973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
113983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
113993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
114009e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard/************************************************************************
114019e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard *									*
1140245490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *		XPath precompiled expression evaluation			*
114039e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard *									*
114049e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard ************************************************************************/
114059e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
11406f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillardstatic int
11407d8df6c0e8c883e1d618388d266015dda36731440Daniel VeillardxmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op);
11408d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard
11409d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP
114109bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcikstatic void
11411074f37e7ebd5e76ceb584a89745a9e84df5b3be2Daniel VeillardxmlXPathDebugDumpStepAxis(xmlXPathStepOpPtr op,
114129bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik			  int nbNodes)
114139bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik{
11414f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    xmlGenericError(xmlGenericErrorContext, "new step : ");
11415074f37e7ebd5e76ceb584a89745a9e84df5b3be2Daniel Veillard    switch (op->value) {
11416d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard        case AXIS_ANCESTOR:
11417f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            xmlGenericError(xmlGenericErrorContext, "axis 'ancestors' ");
11418f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            break;
11419d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard        case AXIS_ANCESTOR_OR_SELF:
11420f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            xmlGenericError(xmlGenericErrorContext,
11421f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                            "axis 'ancestors-or-self' ");
11422f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            break;
11423d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard        case AXIS_ATTRIBUTE:
11424f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            xmlGenericError(xmlGenericErrorContext, "axis 'attributes' ");
11425f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            break;
11426d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard        case AXIS_CHILD:
11427f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            xmlGenericError(xmlGenericErrorContext, "axis 'child' ");
11428f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            break;
11429d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard        case AXIS_DESCENDANT:
11430f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            xmlGenericError(xmlGenericErrorContext, "axis 'descendant' ");
11431f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            break;
11432d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard        case AXIS_DESCENDANT_OR_SELF:
11433f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            xmlGenericError(xmlGenericErrorContext,
11434f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                            "axis 'descendant-or-self' ");
11435f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            break;
11436d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard        case AXIS_FOLLOWING:
11437f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            xmlGenericError(xmlGenericErrorContext, "axis 'following' ");
11438f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            break;
11439d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard        case AXIS_FOLLOWING_SIBLING:
11440f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            xmlGenericError(xmlGenericErrorContext,
11441f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                            "axis 'following-siblings' ");
11442f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            break;
11443d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard        case AXIS_NAMESPACE:
11444f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            xmlGenericError(xmlGenericErrorContext, "axis 'namespace' ");
11445f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            break;
11446d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard        case AXIS_PARENT:
11447f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            xmlGenericError(xmlGenericErrorContext, "axis 'parent' ");
11448f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            break;
11449d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard        case AXIS_PRECEDING:
11450f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            xmlGenericError(xmlGenericErrorContext, "axis 'preceding' ");
11451f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            break;
11452d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard        case AXIS_PRECEDING_SIBLING:
11453f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            xmlGenericError(xmlGenericErrorContext,
11454f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                            "axis 'preceding-sibling' ");
11455f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            break;
11456d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard        case AXIS_SELF:
11457f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            xmlGenericError(xmlGenericErrorContext, "axis 'self' ");
11458f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            break;
11459d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard    }
11460d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard    xmlGenericError(xmlGenericErrorContext,
114619bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	" context contains %d nodes\n", nbNodes);
11462074f37e7ebd5e76ceb584a89745a9e84df5b3be2Daniel Veillard    switch (op->value2) {
11463f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        case NODE_TEST_NONE:
11464f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            xmlGenericError(xmlGenericErrorContext,
11465f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                            "           searching for none !!!\n");
11466f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            break;
11467f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        case NODE_TEST_TYPE:
11468f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            xmlGenericError(xmlGenericErrorContext,
11469074f37e7ebd5e76ceb584a89745a9e84df5b3be2Daniel Veillard                            "           searching for type %d\n", op->value3);
11470f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            break;
11471f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        case NODE_TEST_PI:
11472f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            xmlGenericError(xmlGenericErrorContext,
11473f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                            "           searching for PI !!!\n");
11474f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            break;
11475f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        case NODE_TEST_ALL:
11476f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            xmlGenericError(xmlGenericErrorContext,
11477f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                            "           searching for *\n");
11478f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            break;
11479f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        case NODE_TEST_NS:
11480f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            xmlGenericError(xmlGenericErrorContext,
11481f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                            "           searching for namespace %s\n",
11482074f37e7ebd5e76ceb584a89745a9e84df5b3be2Daniel Veillard                            op->value5);
11483f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            break;
11484f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        case NODE_TEST_NAME:
11485f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            xmlGenericError(xmlGenericErrorContext,
11486074f37e7ebd5e76ceb584a89745a9e84df5b3be2Daniel Veillard                            "           searching for name %s\n", op->value5);
11487074f37e7ebd5e76ceb584a89745a9e84df5b3be2Daniel Veillard            if (op->value4)
11488f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                xmlGenericError(xmlGenericErrorContext,
11489074f37e7ebd5e76ceb584a89745a9e84df5b3be2Daniel Veillard                                "           with namespace %s\n", op->value4);
11490f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            break;
11491d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard    }
11492d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard    xmlGenericError(xmlGenericErrorContext, "Testing : ");
114939bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik}
114949bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik#endif /* DEBUG_STEP */
11495df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik
114969bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcikstatic int
114979bca933a6e39bae6dd8952825528270f006c97dfKasimier T. BuchcikxmlXPathCompOpEvalPredicate(xmlXPathParserContextPtr ctxt,
114989bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik			    xmlXPathStepOpPtr op,
114999bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik			    xmlNodeSetPtr set,
115009bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik			    int contextSize,
115019bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik			    int hasNsNodes)
115029bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik{
115039bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    if (op->ch1 != -1) {
115049bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	xmlXPathCompExprPtr comp = ctxt->comp;
115059bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	/*
115069bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	* Process inner predicates first.
115079bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	*/
115089bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	if (comp->steps[op->ch1].op != XPATH_OP_PREDICATE) {
11509df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik	    /*
115109bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    * TODO: raise an internal error.
11511df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik	    */
115129bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	}
115139bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	contextSize = xmlXPathCompOpEvalPredicate(ctxt,
115149bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    &comp->steps[op->ch1], set, contextSize, hasNsNodes);
115159bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	CHECK_ERROR0;
115169bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	if (contextSize <= 0)
115179bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    return(0);
1151845490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard    }
115199bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    if (op->ch2 != -1) {
115209bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	xmlXPathContextPtr xpctxt = ctxt->context;
115219bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	xmlNodePtr contextNode, oldContextNode;
115229bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	xmlDocPtr oldContextDoc;
11523631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	int i, res, contextPos = 0, newContextSize;
115249bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	xmlXPathStepOpPtr exprOp;
115259bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	xmlXPathObjectPtr contextObj = NULL, exprRes = NULL;
115269bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik
115279bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik#ifdef LIBXML_XPTR_ENABLED
115289bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	/*
115299bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	* URGENT TODO: Check the following:
115309bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	*  We don't expect location sets if evaluating prediates, right?
115319bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	*  Only filters should expect location sets, right?
115329bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	*/
115339bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik#endif
115349bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	/*
115359bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	* SPEC XPath 1.0:
115369bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	*  "For each node in the node-set to be filtered, the
115379bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	*  PredicateExpr is evaluated with that node as the
115389bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	*  context node, with the number of nodes in the
115399bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	*  node-set as the context size, and with the proximity
115409bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	*  position of the node in the node-set with respect to
115419bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	*  the axis as the context position;"
115429bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	* @oldset is the node-set" to be filtered.
115439bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	*
115449bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	* SPEC XPath 1.0:
115459bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	*  "only predicates change the context position and
115469bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	*  context size (see [2.4 Predicates])."
115479bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	* Example:
115489bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	*   node-set  context pos
115499bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	*    nA         1
115509bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	*    nB         2
115519bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	*    nC         3
115529bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	*   After applying predicate [position() > 1] :
115539bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	*   node-set  context pos
115549bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	*    nB         1
115559bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	*    nC         2
115569bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	*/
115579bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	oldContextNode = xpctxt->node;
115589bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	oldContextDoc = xpctxt->doc;
115599bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	/*
115609bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	* Get the expression of this predicate.
115619bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	*/
1156245490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	exprOp = &ctxt->comp->steps[op->ch2];
115639bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	newContextSize = 0;
115649bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	for (i = 0; i < set->nodeNr; i++) {
115659bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    if (set->nodeTab[i] == NULL)
11566df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		continue;
115679bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik
115689bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    contextNode = set->nodeTab[i];
115699bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    xpctxt->node = contextNode;
115709bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    xpctxt->contextSize = contextSize;
115719bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    xpctxt->proximityPosition = ++contextPos;
1157245490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
1157345490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	    /*
115749bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    * Also set the xpath document in case things like
115759bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    * key() are evaluated in the predicate.
115769bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    */
115779bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    if ((contextNode->type != XML_NAMESPACE_DECL) &&
115789bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		(contextNode->doc != NULL))
115799bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		xpctxt->doc = contextNode->doc;
11580df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik	    /*
115819bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    * Evaluate the predicate expression with 1 context node
115829bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    * at a time; this node is packaged into a node set; this
115839bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    * node set is handed over to the evaluation mechanism.
11584df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik	    */
115859bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    if (contextObj == NULL)
115869bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		contextObj = xmlXPathCacheNewNodeSet(xpctxt, contextNode);
115879bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    else
115889bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		xmlXPathNodeSetAddUnique(contextObj->nodesetval,
115899bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		    contextNode);
11590df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik
115919bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    valuePush(ctxt, contextObj);
115929bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik
11593324c75b3c3edffcd30e7afa2a32f0d83d928b10dKasimier T. Buchcik	    res = xmlXPathCompOpEvalToBoolean(ctxt, exprOp, 1);
11594631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik
115950bcec06d4c261ccff8bdc9111618e6938cb5855fWilliam M. Brack	    if ((ctxt->error != XPATH_EXPRESSION_OK) || (res == -1)) {
115960bcec06d4c261ccff8bdc9111618e6938cb5855fWilliam M. Brack		xmlXPathNodeSetClear(set, hasNsNodes);
115970bcec06d4c261ccff8bdc9111618e6938cb5855fWilliam M. Brack		newContextSize = 0;
115980bcec06d4c261ccff8bdc9111618e6938cb5855fWilliam M. Brack		goto evaluation_exit;
115990bcec06d4c261ccff8bdc9111618e6938cb5855fWilliam M. Brack	    }
11600631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik
11601631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    if (res != 0) {
11602631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik		newContextSize++;
11603631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    } else {
116049bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		/*
116059bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		* Remove the entry from the initial node set.
116069bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		*/
116079bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		set->nodeTab[i] = NULL;
116089bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		if (contextNode->type == XML_NAMESPACE_DECL)
116099bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		    xmlXPathNodeSetFreeNs((xmlNsPtr) contextNode);
1161075af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik	    }
116119bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    if (ctxt->value == contextObj) {
116129bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		/*
116139bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		* Don't free the temporary XPath object holding the
116149bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		* context node, in order to avoid massive recreation
116159bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		* inside this loop.
116169bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		*/
116179bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		valuePop(ctxt);
116189bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		xmlXPathNodeSetClear(contextObj->nodesetval, hasNsNodes);
116199bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    } else {
116209bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		/*
116219bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		* TODO: The object was lost in the evaluation machinery.
116229bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		*  Can this happen? Maybe in internal-error cases.
116239bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		*/
116249bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		contextObj = NULL;
1162575af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik	    }
116269bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	}
11627f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
116289bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	if (contextObj != NULL) {
116299bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    if (ctxt->value == contextObj)
116309bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		valuePop(ctxt);
116319bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    xmlXPathReleaseObject(xpctxt, contextObj);
1163245490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	}
116330bcec06d4c261ccff8bdc9111618e6938cb5855fWilliam M. Brackevaluation_exit:
116349bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	if (exprRes != NULL)
116359bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    xmlXPathReleaseObject(ctxt->context, exprRes);
116369bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	/*
116379bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	* Reset/invalidate the context.
116389bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	*/
116399bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	xpctxt->node = oldContextNode;
116409bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	xpctxt->doc = oldContextDoc;
116419bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	xpctxt->contextSize = -1;
116429bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	xpctxt->proximityPosition = -1;
116439bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	return(newContextSize);
116449bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    }
116459bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    return(contextSize);
116469bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik}
11647f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
116489bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcikstatic int
116499bca933a6e39bae6dd8952825528270f006c97dfKasimier T. BuchcikxmlXPathCompOpEvalPositionalPredicate(xmlXPathParserContextPtr ctxt,
116509bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik				      xmlXPathStepOpPtr op,
116519bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik				      xmlNodeSetPtr set,
116529bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik				      int contextSize,
116539bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik				      int minPos,
116549bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik				      int maxPos,
116559bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik				      int hasNsNodes)
116569bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik{
116579bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    if (op->ch1 != -1) {
116589bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	xmlXPathCompExprPtr comp = ctxt->comp;
116599bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	if (comp->steps[op->ch1].op != XPATH_OP_PREDICATE) {
116609bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    /*
116619bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    * TODO: raise an internal error.
116629bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    */
116639bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	}
116649bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	contextSize = xmlXPathCompOpEvalPredicate(ctxt,
116659bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    &comp->steps[op->ch1], set, contextSize, hasNsNodes);
116669bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	CHECK_ERROR0;
116679bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	if (contextSize <= 0)
116689bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    return(0);
116699bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    }
116709bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    /*
116719bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    * Check if the node set contains a sufficient number of nodes for
116729bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    * the requested range.
116739bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    */
116749bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    if (contextSize < minPos) {
116759bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	xmlXPathNodeSetClear(set, hasNsNodes);
116769bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	return(0);
116779bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    }
116789bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    if (op->ch2 == -1) {
116799bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	/*
116809bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	* TODO: Can this ever happen?
116819bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	*/
116829bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	return (contextSize);
116839bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    } else {
116849bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	xmlDocPtr oldContextDoc;
11685631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	int i, pos = 0, newContextSize = 0, contextPos = 0, res;
116869bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	xmlXPathStepOpPtr exprOp;
116879bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	xmlXPathObjectPtr contextObj = NULL, exprRes = NULL;
116889bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	xmlNodePtr oldContextNode, contextNode = NULL;
116899bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	xmlXPathContextPtr xpctxt = ctxt->context;
11690f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
116919bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik#ifdef LIBXML_XPTR_ENABLED
116929bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    /*
116939bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    * URGENT TODO: Check the following:
116949bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    *  We don't expect location sets if evaluating prediates, right?
116959bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    *  Only filters should expect location sets, right?
116969bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	*/
116979bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik#endif /* LIBXML_XPTR_ENABLED */
11698f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
116999bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	/*
117009bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	* Save old context.
117019bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	*/
117029bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	oldContextNode = xpctxt->node;
117039bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	oldContextDoc = xpctxt->doc;
117049bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	/*
117059bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	* Get the expression of this predicate.
117069bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	*/
117079bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	exprOp = &ctxt->comp->steps[op->ch2];
117089bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	for (i = 0; i < set->nodeNr; i++) {
117099bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    if (set->nodeTab[i] == NULL)
117109bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		continue;
11711a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
117129bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    contextNode = set->nodeTab[i];
117139bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    xpctxt->node = contextNode;
117149bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    xpctxt->contextSize = contextSize;
117159bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    xpctxt->proximityPosition = ++contextPos;
1171645490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
1171775af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik	    /*
117189bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    * Initialize the new set.
117199bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    * Also set the xpath document in case things like
117209bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    * key() evaluation are attempted on the predicate
1172175af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik	    */
117229bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    if ((contextNode->type != XML_NAMESPACE_DECL) &&
117239bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		(contextNode->doc != NULL))
117249bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		xpctxt->doc = contextNode->doc;
117259bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    /*
117269bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    * Evaluate the predicate expression with 1 context node
117279bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    * at a time; this node is packaged into a node set; this
117289bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    * node set is handed over to the evaluation mechanism.
1172975af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik	    */
117309bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    if (contextObj == NULL)
117319bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		contextObj = xmlXPathCacheNewNodeSet(xpctxt, contextNode);
1173275af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik	    else
117339bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		xmlXPathNodeSetAddUnique(contextObj->nodesetval,
117349bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		    contextNode);
117359bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik
117369bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    valuePush(ctxt, contextObj);
11737324c75b3c3edffcd30e7afa2a32f0d83d928b10dKasimier T. Buchcik	    res = xmlXPathCompOpEvalToBoolean(ctxt, exprOp, 1);
1173845490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
11739f179456d0f82225ef32196d4947a565bed1b59cbWilliam M. Brack	    if ((ctxt->error != XPATH_EXPRESSION_OK) || (res == -1)) {
11740f179456d0f82225ef32196d4947a565bed1b59cbWilliam M. Brack	        xmlXPathObjectPtr tmp;
11741f179456d0f82225ef32196d4947a565bed1b59cbWilliam M. Brack		/* pop the result */
11742f179456d0f82225ef32196d4947a565bed1b59cbWilliam M. Brack		tmp = valuePop(ctxt);
11743f179456d0f82225ef32196d4947a565bed1b59cbWilliam M. Brack		xmlXPathReleaseObject(xpctxt, tmp);
11744f179456d0f82225ef32196d4947a565bed1b59cbWilliam M. Brack		/* then pop off contextObj, which will be freed later */
11745f179456d0f82225ef32196d4947a565bed1b59cbWilliam M. Brack		valuePop(ctxt);
117469bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		goto evaluation_error;
11747f179456d0f82225ef32196d4947a565bed1b59cbWilliam M. Brack	    }
11748631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik
11749631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    if (res)
117509bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		pos++;
11751631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik
11752631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    if (res && (pos >= minPos) && (pos <= maxPos)) {
117539bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		/*
117549bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		* Fits in the requested range.
117559bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		*/
117569bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		newContextSize++;
117579bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		if (minPos == maxPos) {
117589bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		    /*
117599bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		    * Only 1 node was requested.
117609bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		    */
117619bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		    if (contextNode->type == XML_NAMESPACE_DECL) {
117629bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik			/*
117639bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik			* As always: take care of those nasty
117649bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik			* namespace nodes.
117659bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik			*/
117669bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik			set->nodeTab[i] = NULL;
117679bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		    }
117689bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		    xmlXPathNodeSetClear(set, hasNsNodes);
117699bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		    set->nodeNr = 1;
1177045490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard		    set->nodeTab[0] = contextNode;
117719bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		    goto evaluation_exit;
1177245490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard		}
117739bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		if (pos == maxPos) {
117749bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		    /*
117759bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		    * We are done.
117769bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		    */
117779bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		    xmlXPathNodeSetClearFromPos(set, i +1, hasNsNodes);
117789bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		    goto evaluation_exit;
117799bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		}
117809bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    } else {
117819bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		/*
117829bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		* Remove the entry from the initial node set.
117839bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		*/
117849bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		set->nodeTab[i] = NULL;
117859bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		if (contextNode->type == XML_NAMESPACE_DECL)
117869bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		    xmlXPathNodeSetFreeNs((xmlNsPtr) contextNode);
117879bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    }
117889bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    if (exprRes != NULL) {
117899bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		xmlXPathReleaseObject(ctxt->context, exprRes);
117909bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		exprRes = NULL;
117919bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    }
117929bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    if (ctxt->value == contextObj) {
117939bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		/*
117949bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		* Don't free the temporary XPath object holding the
117959bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		* context node, in order to avoid massive recreation
117969bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		* inside this loop.
117979bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		*/
117989bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		valuePop(ctxt);
117999bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		xmlXPathNodeSetClear(contextObj->nodesetval, hasNsNodes);
118009bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    } else {
118019bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		/*
118029bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		* The object was lost in the evaluation machinery.
118039bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		* Can this happen? Maybe in case of internal-errors.
118049bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		*/
118059bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		contextObj = NULL;
118069bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    }
118079bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	}
118089bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	goto evaluation_exit;
118099bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik
118109bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcikevaluation_error:
118119bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	xmlXPathNodeSetClear(set, hasNsNodes);
118129bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	newContextSize = 0;
118139bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik
118149bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcikevaluation_exit:
118159bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	if (contextObj != NULL) {
118169bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    if (ctxt->value == contextObj)
118179bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		valuePop(ctxt);
118189bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    xmlXPathReleaseObject(xpctxt, contextObj);
118199bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	}
118209bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	if (exprRes != NULL)
118219bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    xmlXPathReleaseObject(ctxt->context, exprRes);
118229bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	/*
118239bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	* Reset/invalidate the context.
118249bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	*/
118259bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	xpctxt->node = oldContextNode;
118269bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	xpctxt->doc = oldContextDoc;
118279bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	xpctxt->contextSize = -1;
118289bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	xpctxt->proximityPosition = -1;
118299bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	return(newContextSize);
11830d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard    }
118319bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    return(contextSize);
118329bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik}
118339bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik
118349bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcikstatic int
118359bca933a6e39bae6dd8952825528270f006c97dfKasimier T. BuchcikxmlXPathIsPositionalPredicate(xmlXPathParserContextPtr ctxt,
1183645490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard			    xmlXPathStepOpPtr op,
118379bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik			    int *maxPos)
118389bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik{
118399bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik
118409bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    xmlXPathStepOpPtr exprOp;
11841df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik
1184275af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik    /*
118439bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    * BIG NOTE: This is not intended for XPATH_OP_FILTER yet!
1184475af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik    */
1184545490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
118469bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    /*
118479bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    * If not -1, then ch1 will point to:
118489bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    * 1) For predicates (XPATH_OP_PREDICATE):
118499bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    *    - an inner predicate operator
118509bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    * 2) For filters (XPATH_OP_FILTER):
118519bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    *    - an inner filter operater OR
118529bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    *    - an expression selecting the node set.
118539bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    *      E.g. "key('a', 'b')" or "(//foo | //bar)".
1185445490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard    */
118559bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    if ((op->op != XPATH_OP_PREDICATE) && (op->op != XPATH_OP_FILTER))
118569bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	return(0);
11857df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik
118589bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    if (op->ch2 != -1) {
118599bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	exprOp = &ctxt->comp->steps[op->ch2];
1186045490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard    } else
118619bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	return(0);
11862a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
118639bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    if ((exprOp != NULL) &&
118649bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	(exprOp->op == XPATH_OP_VALUE) &&
118659bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	(exprOp->value4 != NULL) &&
118669bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	(((xmlXPathObjectPtr) exprOp->value4)->type == XPATH_NUMBER))
118679bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    {
11868df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik	/*
118699bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	* We have a "[n]" predicate here.
118709bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	* TODO: Unfortunately this simplistic test here is not
118719bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	* able to detect a position() predicate in compound
118729bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	* expressions like "[@attr = 'a" and position() = 1],
118739bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	* and even not the usage of position() in
118749bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	* "[position() = 1]"; thus - obviously - a position-range,
118759bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	* like it "[position() < 5]", is also not detected.
118769bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	* Maybe we could rewrite the AST to ease the optimization.
11877df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik	*/
118789bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	*maxPos = (int) ((xmlXPathObjectPtr) exprOp->value4)->floatval;
1187945490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
118809bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	if (((xmlXPathObjectPtr) exprOp->value4)->floatval ==
118819bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    (float) *maxPos)
1188245490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	{
118839bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    return(1);
118849bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	}
1188575af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik    }
118869bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    return(0);
11887d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard}
11888d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard
11889f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillardstatic int
118909bca933a6e39bae6dd8952825528270f006c97dfKasimier T. BuchcikxmlXPathNodeCollectAndTest(xmlXPathParserContextPtr ctxt,
118919bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik                           xmlXPathStepOpPtr op,
11892631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik			   xmlNodePtr * first, xmlNodePtr * last,
11893631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik			   int toBool)
11894f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard{
118959bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik
118969bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik#define XP_TEST_HIT \
118979bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    if (hasAxisRange != 0) { \
118989bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	if (++pos == maxPos) { \
118999bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    addNode(seq, cur); \
119009bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	goto axis_range_end; } \
11901631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik    } else { \
11902631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	addNode(seq, cur); \
11903631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	if (breakOnFirstHit) goto first_hit; }
119049bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik
119059bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik#define XP_TEST_HIT_NS \
119069bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    if (hasAxisRange != 0) { \
119079bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	if (++pos == maxPos) { \
119089bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    hasNsNodes = 1; \
119099bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    xmlXPathNodeSetAddNs(seq, xpctxt->node, (xmlNsPtr) cur); \
119109bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	goto axis_range_end; } \
119119bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    } else { \
119129bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	hasNsNodes = 1; \
119139bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	xmlXPathNodeSetAddNs(seq, \
11914631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	xpctxt->node, (xmlNsPtr) cur); \
11915631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	if (breakOnFirstHit) goto first_hit; }
119169bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik
1191778637da0ea1c833dfdfad87a9aa5bea14510d08aWilliam M. Brack    xmlXPathAxisVal axis = (xmlXPathAxisVal) op->value;
1191878637da0ea1c833dfdfad87a9aa5bea14510d08aWilliam M. Brack    xmlXPathTestVal test = (xmlXPathTestVal) op->value2;
1191978637da0ea1c833dfdfad87a9aa5bea14510d08aWilliam M. Brack    xmlXPathTypeVal type = (xmlXPathTypeVal) op->value3;
11920f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    const xmlChar *prefix = op->value4;
11921f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    const xmlChar *name = op->value5;
11922f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    const xmlChar *URI = NULL;
11923f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
119249bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik#ifdef DEBUG_STEP
119259bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    int nbMatches = 0, prevMatches = 0;
119269bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik#endif
119279bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    int total = 0, hasNsNodes = 0;
119289bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    /* The popped object holding the context nodes */
119299bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    xmlXPathObjectPtr obj;
119309bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    /* The set of context nodes for the node tests */
119319bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    xmlNodeSetPtr contextSeq;
119329bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    int contextIdx;
119339bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    xmlNodePtr contextNode;
119349bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    /* The context node for a compound traversal */
119359bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    xmlNodePtr outerContextNode;
119369bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    /* The final resulting node set wrt to all context nodes */
119379bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    xmlNodeSetPtr outSeq;
119389bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    /*
119399bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    * The temporary resulting node set wrt 1 context node.
119409bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    * Used to feed predicate evaluation.
119419bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    */
119429bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    xmlNodeSetPtr seq;
1194345490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard    xmlNodePtr cur;
119449bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    /* First predicate operator */
119459bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    xmlXPathStepOpPtr predOp;
119469bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    int maxPos; /* The requested position() (when a "[n]" predicate) */
119479bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    int hasPredicateRange, hasAxisRange, pos, size, newSize;
11948631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik    int breakOnFirstHit;
119499bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik
11950f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    xmlXPathTraversalFunction next = NULL;
119519bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    /* compound axis traversal */
119529bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    xmlXPathTraversalFunctionExt outerNext = NULL;
11953f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    void (*addNode) (xmlNodeSetPtr, xmlNodePtr);
119549bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    xmlXPathNodeSetMergeFunction mergeAndClear;
1195545490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard    xmlNodePtr oldContextNode;
119569bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    xmlXPathContextPtr xpctxt = ctxt->context;
11957df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik
11958f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
11959f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    CHECK_TYPE0(XPATH_NODESET);
11960f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    obj = valuePop(ctxt);
119619bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    /*
119629bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    * Setup namespaces.
119639bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    */
11964f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    if (prefix != NULL) {
11965df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik        URI = xmlXPathNsLookup(xpctxt, prefix);
119662c19a7bf2ee0f78485840cac50f2a989f5efe476William M. Brack        if (URI == NULL) {
119679bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    xmlXPathReleaseObject(xpctxt, obj);
11968f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            XP_ERROR0(XPATH_UNDEF_PREFIX_ERROR);
119692c19a7bf2ee0f78485840cac50f2a989f5efe476William M. Brack	}
1197045490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard    }
119719bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    /*
119729bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    * Setup axis.
119739bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    *
119749bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    * MAYBE FUTURE TODO: merging optimizations:
119759bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    * - If the nodes to be traversed wrt to the initial nodes and
119769bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    *   the current axis cannot overlap, then we could avoid searching
119779bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    *   for duplicates during the merge.
119789bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    *   But the question is how/when to evaluate if they cannot overlap.
119799bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    *   Example: if we know that for two initial nodes, the one is
119809bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    *   not in the ancestor-or-self axis of the other, then we could safely
119819bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    *   avoid a duplicate-aware merge, if the axis to be traversed is e.g.
119829bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    *   the descendant-or-self axis.
119839bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    */
119849bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    addNode = xmlXPathNodeSetAdd;
119859bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    mergeAndClear = xmlXPathNodeSetMergeAndClear;
11986f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    switch (axis) {
11987f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        case AXIS_ANCESTOR:
11988f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            first = NULL;
11989f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            next = xmlXPathNextAncestor;
11990f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            break;
11991f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        case AXIS_ANCESTOR_OR_SELF:
11992f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            first = NULL;
11993f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            next = xmlXPathNextAncestorOrSelf;
11994f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            break;
11995f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        case AXIS_ATTRIBUTE:
11996f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            first = NULL;
11997f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	    last = NULL;
11998f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            next = xmlXPathNextAttribute;
119999bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    mergeAndClear = xmlXPathNodeSetMergeAndClearNoDupls;
12000f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            break;
12001f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        case AXIS_CHILD:
12002f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	    last = NULL;
12003df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik	    if (op->rewriteType == XP_REWRITE_DOS_CHILD_ELEM) {
12004df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		/*
12005df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		* This iterator will give us only nodes which can
12006df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		* hold element nodes.
12007df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		*/
1200845490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard		outerNext = xmlXPathNextDescendantOrSelfElemParent;
1200945490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	    }
120109bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    if (((test == NODE_TEST_NAME) || (test == NODE_TEST_ALL)) &&
120119bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		(type == NODE_TYPE_NODE))
120129bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    {
12013df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		/*
12014df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		* Optimization if an element node type is 'element'.
12015df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		*/
12016df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		next = xmlXPathNextChildElement;
12017df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik	    } else
120189bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		next = xmlXPathNextChild;
120199bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    mergeAndClear = xmlXPathNodeSetMergeAndClearNoDupls;
12020f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            break;
12021f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        case AXIS_DESCENDANT:
12022f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	    last = NULL;
12023f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            next = xmlXPathNextDescendant;
12024f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            break;
12025f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        case AXIS_DESCENDANT_OR_SELF:
12026f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	    last = NULL;
12027f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            next = xmlXPathNextDescendantOrSelf;
12028f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            break;
12029f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        case AXIS_FOLLOWING:
12030f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	    last = NULL;
12031f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            next = xmlXPathNextFollowing;
12032f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            break;
12033f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        case AXIS_FOLLOWING_SIBLING:
12034f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	    last = NULL;
12035f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            next = xmlXPathNextFollowingSibling;
12036f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            break;
12037f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        case AXIS_NAMESPACE:
12038f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            first = NULL;
120399bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    last = NULL;
12040f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            next = (xmlXPathTraversalFunction) xmlXPathNextNamespace;
120419bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    mergeAndClear = xmlXPathNodeSetMergeAndClearNoDupls;
12042f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            break;
12043f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        case AXIS_PARENT:
12044f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            first = NULL;
12045f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            next = xmlXPathNextParent;
12046f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            break;
12047f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        case AXIS_PRECEDING:
12048f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            first = NULL;
12049f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            next = xmlXPathNextPrecedingInternal;
12050f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            break;
12051f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        case AXIS_PRECEDING_SIBLING:
12052f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            first = NULL;
12053f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            next = xmlXPathNextPrecedingSibling;
12054f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            break;
12055f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        case AXIS_SELF:
12056f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            first = NULL;
12057f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	    last = NULL;
12058f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            next = xmlXPathNextSelf;
120599bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    mergeAndClear = xmlXPathNodeSetMergeAndClearNoDupls;
12060f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            break;
12061f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    }
120629bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik
120639bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik#ifdef DEBUG_STEP
12064074f37e7ebd5e76ceb584a89745a9e84df5b3be2Daniel Veillard    xmlXPathDebugDumpStepAxis(op,
12065074f37e7ebd5e76ceb584a89745a9e84df5b3be2Daniel Veillard	(obj->nodesetval != NULL) ? obj->nodesetval->nodeNr : 0);
120669bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik#endif
120679bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik
120682c19a7bf2ee0f78485840cac50f2a989f5efe476William M. Brack    if (next == NULL) {
1206945490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	xmlXPathReleaseObject(xpctxt, obj);
12070f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        return(0);
1207145490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard    }
120729bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    contextSeq = obj->nodesetval;
120739bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    if ((contextSeq == NULL) || (contextSeq->nodeNr <= 0)) {
120749bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	xmlXPathReleaseObject(xpctxt, obj);
120759bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik        valuePush(ctxt, xmlXPathCacheWrapNodeSet(xpctxt, NULL));
12076f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        return(0);
1207745490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard    }
120789bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    /*
120799bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    * Predicate optimization ---------------------------------------------
120809bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    * If this step has a last predicate, which contains a position(),
120819bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    * then we'll optimize (although not exactly "position()", but only
120829bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    * the  short-hand form, i.e., "[n]".
120839bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    *
120849bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    * Example - expression "/foo[parent::bar][1]":
1208545490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard    *
120869bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    * COLLECT 'child' 'name' 'node' foo    -- op (we are here)
120879bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    *   ROOT                               -- op->ch1
120889bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    *   PREDICATE                          -- op->ch2 (predOp)
120899bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    *     PREDICATE                          -- predOp->ch1 = [parent::bar]
120909bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    *       SORT
120919bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    *         COLLECT  'parent' 'name' 'node' bar
120929bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    *           NODE
120939bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    *     ELEM Object is a number : 1        -- predOp->ch2 = [1]
120949bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    *
120959bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    */
120969bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    maxPos = 0;
120979bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    predOp = NULL;
120989bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    hasPredicateRange = 0;
120999bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    hasAxisRange = 0;
121009bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    if (op->ch2 != -1) {
121019bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	/*
121029bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	* There's at least one predicate. 16 == XPATH_OP_PREDICATE
121039bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	*/
121049bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	predOp = &ctxt->comp->steps[op->ch2];
121059bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	if (xmlXPathIsPositionalPredicate(ctxt, predOp, &maxPos)) {
121069bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    if (predOp->ch1 != -1) {
121079bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		/*
121089bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		* Use the next inner predicate operator.
121099bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		*/
121109bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		predOp = &ctxt->comp->steps[predOp->ch1];
121119bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		hasPredicateRange = 1;
121129bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    } else {
121139bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		/*
121149bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		* There's no other predicate than the [n] predicate.
121159bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		*/
121169bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		predOp = NULL;
121179bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		hasAxisRange = 1;
1211845490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	    }
121199bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	}
12120f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    }
12121631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik    breakOnFirstHit = ((toBool) && (predOp == NULL)) ? 1 : 0;
121229bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    /*
121239bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    * Axis traversal -----------------------------------------------------
121249bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    */
12125f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    /*
12126f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard     * 2.3 Node Tests
1212745490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard     *  - For the attribute axis, the principal node type is attribute.
121289bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik     *  - For the namespace axis, the principal node type is namespace.
121299bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik     *  - For other axes, the principal node type is element.
12130f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard     *
12131f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard     * A node test * is true for any node of the
12132cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard     * principal node type. For example, child::* will
12133f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard     * select all element children of the context node
12134f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard     */
12135df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik    oldContextNode = xpctxt->node;
12136df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik    addNode = xmlXPathNodeSetAddUnique;
121379bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    outSeq = NULL;
121389bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    seq = NULL;
121399bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    outerContextNode = NULL;
12140df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik    contextNode = NULL;
121419bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    contextIdx = 0;
121429bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik
12143df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik
121449bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    while ((contextIdx < contextSeq->nodeNr) || (contextNode != NULL)) {
121459bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	if (outerNext != NULL) {
12146df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik	    /*
12147df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik	    * This is a compound traversal.
12148df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik	    */
12149df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik	    if (contextNode == NULL) {
12150df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		/*
121519bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		* Set the context for the outer traversal.
12152df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		*/
121539bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		outerContextNode = contextSeq->nodeTab[contextIdx++];
121549bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		contextNode = outerNext(NULL, outerContextNode);
12155df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik	    } else
121569bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		contextNode = outerNext(contextNode, outerContextNode);
12157df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik	    if (contextNode == NULL)
12158df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		continue;
12159df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik	    /*
12160df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik	    * Set the context for the main traversal.
12161df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik	    */
12162df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik	    xpctxt->node = contextNode;
12163df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik	} else
1216445490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	    xpctxt->node = contextSeq->nodeTab[contextIdx++];
1216545490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
121669bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	if (seq == NULL) {
121679bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    seq = xmlXPathNodeSetCreate(NULL);
121689bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    if (seq == NULL) {
121699bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		total = 0;
121709bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		goto error;
121719bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    }
121729bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	}
121739bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	/*
121749bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	* Traverse the axis and test the nodes.
121759bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	*/
121769bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	pos = 0;
121779bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	cur = NULL;
121789bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	hasNsNodes = 0;
12179f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        do {
12180f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            cur = next(ctxt, cur);
12181f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            if (cur == NULL)
12182f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                break;
12183df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik
121849bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    /*
121859bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    * QUESTION TODO: What does the "first" and "last" stuff do?
121869bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    */
12187631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik            if ((first != NULL) && (*first != NULL)) {
12188df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		if (*first == cur)
12189df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		    break;
12190631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik		if (((total % 256) == 0) &&
12191df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik#ifdef XP_OPTIMIZED_NON_ELEM_COMPARISON
12192df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		    (xmlXPathCmpNodesExt(*first, cur) >= 0))
12193df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik#else
12194631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik		    (xmlXPathCmpNodes(*first, cur) >= 0))
12195df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik#endif
12196df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		{
12197df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		    break;
12198df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		}
12199df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik	    }
12200631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    if ((last != NULL) && (*last != NULL)) {
12201df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		if (*last == cur)
12202df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		    break;
12203631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik		if (((total % 256) == 0) &&
12204df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik#ifdef XP_OPTIMIZED_NON_ELEM_COMPARISON
12205df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		    (xmlXPathCmpNodesExt(cur, *last) >= 0))
12206df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik#else
12207df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		    (xmlXPathCmpNodes(cur, *last) >= 0))
12208df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik#endif
12209df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		{
12210df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		    break;
12211df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		}
12212df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik	    }
12213df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik
12214df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik            total++;
122159bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik
122169bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik#ifdef DEBUG_STEP
122179bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik            xmlGenericError(xmlGenericErrorContext, " %s", cur->name);
122189bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik#endif
1221945490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
122209bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    switch (test) {
12221f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                case NODE_TEST_NONE:
12222df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		    total = 0;
12223df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik                    STRANGE
12224df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		    goto error;
12225f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                case NODE_TEST_TYPE:
122269bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		    /*
122279bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		    * TODO: Don't we need to use
122289bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		    *  xmlXPathNodeSetAddNs() for namespace nodes here?
122299bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		    *  Surprisingly, some c14n tests fail, if we do this.
122309bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		    */
122319bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		    if (type == NODE_TYPE_NODE) {
122329bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik			switch (cur->type) {
122339bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik			    case XML_DOCUMENT_NODE:
122349bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik			    case XML_HTML_DOCUMENT_NODE:
122359bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik#ifdef LIBXML_DOCB_ENABLED
122369bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik			    case XML_DOCB_DOCUMENT_NODE:
122379bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik#endif
1223845490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard			    case XML_ELEMENT_NODE:
122399bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik			    case XML_ATTRIBUTE_NODE:
122409bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik			    case XML_PI_NODE:
122419bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik			    case XML_COMMENT_NODE:
122429bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik			    case XML_CDATA_SECTION_NODE:
122439bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik			    case XML_TEXT_NODE:
122449bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik			    case XML_NAMESPACE_DECL:
122459bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik				XP_TEST_HIT
122469bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik				break;
122479bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik			    default:
122489bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik				break;
122499bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik			}
122509bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		    } else if (cur->type == type) {
12251889b76229b544ec2fe1a4996c8a3b0733f4fc828Kasimier T. Buchcik			if (type == XML_NAMESPACE_DECL)
12252889b76229b544ec2fe1a4996c8a3b0733f4fc828Kasimier T. Buchcik			    XP_TEST_HIT_NS
12253889b76229b544ec2fe1a4996c8a3b0733f4fc828Kasimier T. Buchcik			else
12254889b76229b544ec2fe1a4996c8a3b0733f4fc828Kasimier T. Buchcik			    XP_TEST_HIT
122559bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		    } else if ((type == NODE_TYPE_TEXT) &&
122569bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik			 (cur->type == XML_CDATA_SECTION_NODE))
122579bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		    {
122589bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik			XP_TEST_HIT
122599bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		    }
122609bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		    break;
12261f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                case NODE_TEST_PI:
122629bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik                    if ((cur->type == XML_PI_NODE) &&
122639bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik                        ((name == NULL) || xmlStrEqual(name, cur->name)))
122649bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		    {
122659bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik			XP_TEST_HIT
12266f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    }
12267f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    break;
12268f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                case NODE_TEST_ALL:
12269f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    if (axis == AXIS_ATTRIBUTE) {
122709bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik                        if (cur->type == XML_ATTRIBUTE_NODE)
122719bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik			{
122729bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik			    XP_TEST_HIT
12273f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        }
12274f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    } else if (axis == AXIS_NAMESPACE) {
122759bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik                        if (cur->type == XML_NAMESPACE_DECL)
122769bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik			{
122779bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik			    XP_TEST_HIT_NS
12278f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        }
12279f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    } else {
12280f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        if (cur->type == XML_ELEMENT_NODE) {
122819bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik                            if (prefix == NULL)
122829bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik			    {
122839bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik				XP_TEST_HIT
122849bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik
12285f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                            } else if ((cur->ns != NULL) &&
122869bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik				(xmlStrEqual(URI, cur->ns->href)))
122879bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik			    {
122889bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik				XP_TEST_HIT
12289f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                            }
12290f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        }
12291f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    }
12292f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    break;
12293f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                case NODE_TEST_NS:{
12294f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        TODO;
12295f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        break;
12296f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    }
12297f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                case NODE_TEST_NAME:
12298fe3970e09fc95a78eea09225e21ec24b69c1dc75Daniel Veillard                    if (axis == AXIS_ATTRIBUTE) {
12299fe3970e09fc95a78eea09225e21ec24b69c1dc75Daniel Veillard                        if (cur->type != XML_ATTRIBUTE_NODE)
12300fe3970e09fc95a78eea09225e21ec24b69c1dc75Daniel Veillard			    break;
12301fe3970e09fc95a78eea09225e21ec24b69c1dc75Daniel Veillard		    } else if (axis == AXIS_NAMESPACE) {
12302fe3970e09fc95a78eea09225e21ec24b69c1dc75Daniel Veillard                        if (cur->type != XML_NAMESPACE_DECL)
12303fe3970e09fc95a78eea09225e21ec24b69c1dc75Daniel Veillard			    break;
12304fe3970e09fc95a78eea09225e21ec24b69c1dc75Daniel Veillard		    } else {
12305fe3970e09fc95a78eea09225e21ec24b69c1dc75Daniel Veillard		        if (cur->type != XML_ELEMENT_NODE)
12306fe3970e09fc95a78eea09225e21ec24b69c1dc75Daniel Veillard			    break;
12307fe3970e09fc95a78eea09225e21ec24b69c1dc75Daniel Veillard		    }
12308f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    switch (cur->type) {
12309f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        case XML_ELEMENT_NODE:
12310f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                            if (xmlStrEqual(name, cur->name)) {
12311f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                                if (prefix == NULL) {
123129bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik                                    if (cur->ns == NULL)
123139bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik				    {
123149bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik					XP_TEST_HIT
12315f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                                    }
12316f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                                } else {
12317f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                                    if ((cur->ns != NULL) &&
123189bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik                                        (xmlStrEqual(URI, cur->ns->href)))
12319df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik				    {
123209bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik					XP_TEST_HIT
12321f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                                    }
12322f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                                }
12323f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                            }
12324f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                            break;
12325f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        case XML_ATTRIBUTE_NODE:{
12326f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                                xmlAttrPtr attr = (xmlAttrPtr) cur;
12327f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
12328f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                                if (xmlStrEqual(name, attr->name)) {
12329f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                                    if (prefix == NULL) {
12330f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                                        if ((attr->ns == NULL) ||
12331df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik                                            (attr->ns->prefix == NULL))
12332df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik					{
123339bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik					    XP_TEST_HIT
12334f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                                        }
12335f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                                    } else {
12336f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                                        if ((attr->ns != NULL) &&
12337f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                                            (xmlStrEqual(URI,
12338df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik					      attr->ns->href)))
12339df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik					{
123409bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik					    XP_TEST_HIT
12341f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                                        }
12342f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                                    }
12343f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                                }
12344f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                                break;
12345f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                            }
12346f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        case XML_NAMESPACE_DECL:
12347f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                            if (cur->type == XML_NAMESPACE_DECL) {
12348f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                                xmlNsPtr ns = (xmlNsPtr) cur;
12349f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
12350f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                                if ((ns->prefix != NULL) && (name != NULL)
123519bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik                                    && (xmlStrEqual(ns->prefix, name)))
123529bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik				{
123539bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik				    XP_TEST_HIT_NS
12354f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                                }
12355f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                            }
12356f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                            break;
12357f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        default:
12358f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                            break;
12359f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    }
12360f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    break;
123619bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    } /* switch(test) */
123629bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik        } while (cur != NULL);
12363df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik
123649bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	goto apply_predicates;
123659bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik
1236645490aebe7a60704e8ed850c498969858ab900eeDaniel Veillardaxis_range_end: /* ----------------------------------------------------- */
123679bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	/*
123689bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	* We have a "/foo[n]", and position() = n was reached.
123699bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	* Note that we can have as well "/foo/::parent::foo[1]", so
123709bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	* a duplicate-aware merge is still needed.
123719bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	* Merge with the result.
123729bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	*/
123739bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	if (outSeq == NULL) {
123749bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    outSeq = seq;
123759bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    seq = NULL;
123769bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	} else
12377631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    outSeq = mergeAndClear(outSeq, seq, 0);
12378631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	/*
12379631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	* Break if only a true/false result was requested.
12380631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	*/
12381631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	if (toBool)
12382631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    break;
123839bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	continue;
123849bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik
12385631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcikfirst_hit: /* ---------------------------------------------------------- */
12386631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	/*
12387631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	* Break if only a true/false result was requested and
12388631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	* no predicates existed and a node test succeeded.
12389631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	*/
12390631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	if (outSeq == NULL) {
12391631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    outSeq = seq;
12392631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    seq = NULL;
12393631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	} else
12394631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    outSeq = mergeAndClear(outSeq, seq, 0);
12395631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	break;
12396631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik
123979bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik#ifdef DEBUG_STEP
123989bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	if (seq != NULL)
123999bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    nbMatches += seq->nodeNr;
12400f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#endif
12401df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik
124029bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcikapply_predicates: /* --------------------------------------------------- */
124039bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik        /*
124049bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	* Apply predicates.
1240545490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	*/
124069bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik        if ((predOp != NULL) && (seq->nodeNr > 0)) {
124079bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    /*
124089bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    * E.g. when we have a "/foo[some expression][n]".
1240945490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	    */
124109bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    /*
124119bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    * QUESTION TODO: The old predicate evaluation took into
124129bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    *  account location-sets.
124139bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    *  (E.g. ctxt->value->type == XPATH_LOCATIONSET)
124149bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    *  Do we expect such a set here?
124159bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    *  All what I learned now from the evaluation semantics
124169bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    *  does not indicate that a location-set will be processed
124179bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    *  here, so this looks OK.
1241845490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	    */
124199bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    /*
124209bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    * Iterate over all predicates, starting with the outermost
124219bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    * predicate.
124229bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    * TODO: Problem: we cannot execute the inner predicates first
124239bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    *  since we cannot go back *up* the operator tree!
124249bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    *  Options we have:
124259bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    *  1) Use of recursive functions (like is it currently done
124269bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    *     via xmlXPathCompOpEval())
124279bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    *  2) Add a predicate evaluation information stack to the
124289bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    *     context struct
124299bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    *  3) Change the way the operators are linked; we need a
124309bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    *     "parent" field on xmlXPathStepOp
124319bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    *
124329bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    * For the moment, I'll try to solve this with a recursive
124339bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    * function: xmlXPathCompOpEvalPredicate().
1243445490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	    */
124359bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    size = seq->nodeNr;
124369bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    if (hasPredicateRange != 0)
124379bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		newSize = xmlXPathCompOpEvalPositionalPredicate(ctxt,
124389bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		    predOp, seq, size, maxPos, maxPos, hasNsNodes);
124399bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    else
124409bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		newSize = xmlXPathCompOpEvalPredicate(ctxt,
124419bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		    predOp, seq, size, hasNsNodes);
124429bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik
124439bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    if (ctxt->error != XPATH_EXPRESSION_OK) {
124449bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		total = 0;
124459bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		goto error;
124469bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    }
124479bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    /*
124489bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    * Add the filtered set of nodes to the result node set.
124499bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    */
124509bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    if (newSize == 0) {
124519bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		/*
124529bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		* The predicates filtered all nodes out.
124539bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		*/
124549bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		xmlXPathNodeSetClear(seq, hasNsNodes);
124559bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    } else if (seq->nodeNr > 0) {
124569bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		/*
124579bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		* Add to result set.
124589bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		*/
124599bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		if (outSeq == NULL) {
124609bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		    if (size != newSize) {
124619bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik			/*
124629bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik			* We need to merge and clear here, since
124639bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik			* the sequence will contained NULLed entries.
124649bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik			*/
124659bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik			outSeq = mergeAndClear(NULL, seq, 1);
124669bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		    } else {
124679bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik			outSeq = seq;
124689bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik			seq = NULL;
124699bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		    }
124709bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		} else
124719bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		    outSeq = mergeAndClear(outSeq, seq,
124729bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik			(size != newSize) ? 1: 0);
12473631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik		/*
12474631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik		* Break if only a true/false result was requested.
12475631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik		*/
12476631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik		if (toBool)
12477631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik		    break;
124789bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    }
124799bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik        } else if (seq->nodeNr > 0) {
124809bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    /*
124819bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    * Add to result set.
124829bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    */
124839bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    if (outSeq == NULL) {
124849bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		outSeq = seq;
124859bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		seq = NULL;
124869bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    } else {
124879bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		outSeq = mergeAndClear(outSeq, seq, 0);
124889bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    }
1248945490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	}
124909bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    }
12491df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik
124929bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcikerror:
124930ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard    if ((obj->boolval) && (obj->user != NULL)) {
124949bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	/*
124959bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	* QUESTION TODO: What does this do and why?
124969bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	* TODO: Do we have to do this also for the "error"
124979bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	* cleanup further down?
124989bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	*/
124990ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard	ctxt->value->boolval = 1;
125000ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard	ctxt->value->user = obj->user;
125010ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard	obj->user = NULL;
125020ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard	obj->boolval = 0;
125030ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard    }
12504df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik    xmlXPathReleaseObject(xpctxt, obj);
12505df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik
125069bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    /*
125079bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    * Ensure we return at least an emtpy set.
125089bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    */
125099bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    if (outSeq == NULL) {
125109bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	if ((seq != NULL) && (seq->nodeNr == 0))
125119bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    outSeq = seq;
125129bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	else
125139bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    outSeq = xmlXPathNodeSetCreate(NULL);
12514f88d849a4e994c94c0d0814a4befb43c990ceebdDaniel Veillard        /* XXX what if xmlXPathNodeSetCreate returned NULL here? */
125159bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    }
125169bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    if ((seq != NULL) && (seq != outSeq)) {
125179bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	 xmlXPathFreeNodeSet(seq);
1251845490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard    }
125199bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    /*
125209bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    * Hand over the result. Better to push the set also in
125219bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    * case of errors.
125229bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    */
125239bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    valuePush(ctxt, xmlXPathCacheWrapNodeSet(xpctxt, outSeq));
125249bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    /*
125259bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    * Reset the context node.
125269bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    */
12527df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik    xpctxt->node = oldContextNode;
125289bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik
125299bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik#ifdef DEBUG_STEP
125309bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    xmlGenericError(xmlGenericErrorContext,
125319bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	"\nExamined %d nodes, found %d nodes at that step\n",
125329bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	total, nbMatches);
125339bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik#endif
125349bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik
12535df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik    return(total);
12536f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard}
12537f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
125385691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcikstatic int
125395691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. BuchcikxmlXPathCompOpEvalFilterFirst(xmlXPathParserContextPtr ctxt,
125405691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik			      xmlXPathStepOpPtr op, xmlNodePtr * first);
125415691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik
12542f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard/**
12543f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * xmlXPathCompOpEvalFirst:
12544d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * @ctxt:  the XPath parser context with the compiled expression
12545d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * @op:  an XPath compiled operation
12546f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * @first:  the first elem found so far
12547d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard *
12548f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Evaluate the Precompiled XPath operation searching only the first
12549f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * element in document order
12550f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard *
12551f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Returns the number of examined objects.
12552d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard */
12553f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillardstatic int
12554f06307e2c172284bb41376c396f757bdac9bdd19Daniel VeillardxmlXPathCompOpEvalFirst(xmlXPathParserContextPtr ctxt,
12555f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        xmlXPathStepOpPtr op, xmlNodePtr * first)
12556f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard{
12557f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    int total = 0, cur;
12558d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard    xmlXPathCompExprPtr comp;
12559d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard    xmlXPathObjectPtr arg1, arg2;
12560d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard
12561556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard    CHECK_ERROR0;
12562d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard    comp = ctxt->comp;
12563d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard    switch (op->op) {
12564f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        case XPATH_OP_END:
12565f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            return (0);
12566f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        case XPATH_OP_UNION:
12567f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            total =
12568f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                xmlXPathCompOpEvalFirst(ctxt, &comp->steps[op->ch1],
12569f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                                        first);
12570556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard	    CHECK_ERROR0;
12571f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            if ((ctxt->value != NULL)
12572f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                && (ctxt->value->type == XPATH_NODESET)
12573f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                && (ctxt->value->nodesetval != NULL)
12574f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                && (ctxt->value->nodesetval->nodeNr >= 1)) {
12575f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                /*
12576f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                 * limit tree traversing to first node in the result
12577f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                 */
125785691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		/*
125795691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		* OPTIMIZE TODO: This implicitely sorts
125805691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		*  the result, even if not needed. E.g. if the argument
125815691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		*  of the count() function, no sorting is needed.
125825691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		* OPTIMIZE TODO: How do we know if the node-list wasn't
125835691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		*  aready sorted?
125845691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		*/
1258564f7e1a85fe9c973cf9b21cc0bd53efa6cc3dafcKasimier T. Buchcik		if (ctxt->value->nodesetval->nodeNr > 1)
1258664f7e1a85fe9c973cf9b21cc0bd53efa6cc3dafcKasimier T. Buchcik		    xmlXPathNodeSetSort(ctxt->value->nodesetval);
12587f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                *first = ctxt->value->nodesetval->nodeTab[0];
12588f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            }
12589f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            cur =
12590f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                xmlXPathCompOpEvalFirst(ctxt, &comp->steps[op->ch2],
12591f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                                        first);
12592556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard	    CHECK_ERROR0;
12593f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            CHECK_TYPE0(XPATH_NODESET);
12594f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            arg2 = valuePop(ctxt);
12595f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
12596f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            CHECK_TYPE0(XPATH_NODESET);
12597f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            arg1 = valuePop(ctxt);
12598f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
12599f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            arg1->nodesetval = xmlXPathNodeSetMerge(arg1->nodesetval,
12600f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                                                    arg2->nodesetval);
12601f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            valuePush(ctxt, arg1);
12602a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathReleaseObject(ctxt->context, arg2);
12603f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            /* optimizer */
12604f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	    if (total > cur)
12605f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard		xmlXPathCompSwap(op);
12606f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            return (total + cur);
12607f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        case XPATH_OP_ROOT:
12608f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            xmlXPathRoot(ctxt);
12609f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            return (0);
12610f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        case XPATH_OP_NODE:
12611f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            if (op->ch1 != -1)
12612f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
12613556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard	    CHECK_ERROR0;
12614f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            if (op->ch2 != -1)
12615f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
12616556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard	    CHECK_ERROR0;
12617a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    valuePush(ctxt, xmlXPathCacheNewNodeSet(ctxt->context,
12618a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		ctxt->context->node));
12619f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            return (total);
12620f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        case XPATH_OP_RESET:
12621f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            if (op->ch1 != -1)
12622f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
12623556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard	    CHECK_ERROR0;
12624f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            if (op->ch2 != -1)
12625f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
12626556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard	    CHECK_ERROR0;
12627f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            ctxt->context->node = NULL;
12628f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            return (total);
12629f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        case XPATH_OP_COLLECT:{
12630f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                if (op->ch1 == -1)
12631f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    return (total);
12632f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
12633f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                total = xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
12634556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard		CHECK_ERROR0;
12635f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
12636631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik                total += xmlXPathNodeCollectAndTest(ctxt, op, first, NULL, 0);
12637f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                return (total);
12638f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            }
12639f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        case XPATH_OP_VALUE:
12640f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            valuePush(ctxt,
12641a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik                      xmlXPathCacheObjectCopy(ctxt->context,
12642a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik			(xmlXPathObjectPtr) op->value4));
12643f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            return (0);
12644f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        case XPATH_OP_SORT:
12645f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            if (op->ch1 != -1)
12646f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                total +=
12647f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    xmlXPathCompOpEvalFirst(ctxt, &comp->steps[op->ch1],
12648f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                                            first);
12649556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard	    CHECK_ERROR0;
12650f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            if ((ctxt->value != NULL)
12651f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                && (ctxt->value->type == XPATH_NODESET)
126525691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik                && (ctxt->value->nodesetval != NULL)
126535691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		&& (ctxt->value->nodesetval->nodeNr > 1))
12654f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                xmlXPathNodeSetSort(ctxt->value->nodesetval);
12655f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            return (total);
126565691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik#ifdef XP_OPTIMIZED_FILTER_FIRST
126575691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	case XPATH_OP_FILTER:
126585691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik                total =+ xmlXPathCompOpEvalFilterFirst(ctxt, op, first);
126595691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik            return (total);
126605691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik#endif
12661f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        default:
12662f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            return (xmlXPathCompOpEval(ctxt, op));
12663f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    }
12664f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard}
1266542596ad20cdf1925dd79ea801cbe598b6e7b7aecDaniel Veillard
12666f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard/**
12667f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * xmlXPathCompOpEvalLast:
12668f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * @ctxt:  the XPath parser context with the compiled expression
12669f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * @op:  an XPath compiled operation
12670f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * @last:  the last elem found so far
12671f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard *
12672f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Evaluate the Precompiled XPath operation searching only the last
12673f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * element in document order
12674f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard *
12675081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack * Returns the number of nodes traversed
12676f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */
12677f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillardstatic int
12678f06307e2c172284bb41376c396f757bdac9bdd19Daniel VeillardxmlXPathCompOpEvalLast(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op,
12679f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                       xmlNodePtr * last)
12680f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard{
12681f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    int total = 0, cur;
12682f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    xmlXPathCompExprPtr comp;
12683f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    xmlXPathObjectPtr arg1, arg2;
12684ce4fc56e1b56253ae794b47515948f3bc3142024William M. Brack    xmlNodePtr bak;
12685ce4fc56e1b56253ae794b47515948f3bc3142024William M. Brack    xmlDocPtr bakd;
12686ce4fc56e1b56253ae794b47515948f3bc3142024William M. Brack    int pp;
12687ce4fc56e1b56253ae794b47515948f3bc3142024William M. Brack    int cs;
126889e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
12689556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard    CHECK_ERROR0;
12690f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    comp = ctxt->comp;
12691f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    switch (op->op) {
12692f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        case XPATH_OP_END:
12693f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            return (0);
12694f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        case XPATH_OP_UNION:
12695ce4fc56e1b56253ae794b47515948f3bc3142024William M. Brack	    bakd = ctxt->context->doc;
12696ce4fc56e1b56253ae794b47515948f3bc3142024William M. Brack	    bak = ctxt->context->node;
12697ce4fc56e1b56253ae794b47515948f3bc3142024William M. Brack	    pp = ctxt->context->proximityPosition;
12698ce4fc56e1b56253ae794b47515948f3bc3142024William M. Brack	    cs = ctxt->context->contextSize;
12699f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            total =
12700f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                xmlXPathCompOpEvalLast(ctxt, &comp->steps[op->ch1], last);
12701556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard	    CHECK_ERROR0;
12702f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            if ((ctxt->value != NULL)
12703f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                && (ctxt->value->type == XPATH_NODESET)
12704f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                && (ctxt->value->nodesetval != NULL)
12705f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                && (ctxt->value->nodesetval->nodeNr >= 1)) {
12706f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                /*
12707f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                 * limit tree traversing to first node in the result
12708f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                 */
1270964f7e1a85fe9c973cf9b21cc0bd53efa6cc3dafcKasimier T. Buchcik		if (ctxt->value->nodesetval->nodeNr > 1)
1271064f7e1a85fe9c973cf9b21cc0bd53efa6cc3dafcKasimier T. Buchcik		    xmlXPathNodeSetSort(ctxt->value->nodesetval);
12711f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                *last =
12712f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    ctxt->value->nodesetval->nodeTab[ctxt->value->
12713f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                                                     nodesetval->nodeNr -
12714f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                                                     1];
12715f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            }
12716ce4fc56e1b56253ae794b47515948f3bc3142024William M. Brack	    ctxt->context->doc = bakd;
12717ce4fc56e1b56253ae794b47515948f3bc3142024William M. Brack	    ctxt->context->node = bak;
12718ce4fc56e1b56253ae794b47515948f3bc3142024William M. Brack	    ctxt->context->proximityPosition = pp;
12719ce4fc56e1b56253ae794b47515948f3bc3142024William M. Brack	    ctxt->context->contextSize = cs;
12720f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            cur =
12721f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                xmlXPathCompOpEvalLast(ctxt, &comp->steps[op->ch2], last);
12722556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard	    CHECK_ERROR0;
12723f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            if ((ctxt->value != NULL)
12724f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                && (ctxt->value->type == XPATH_NODESET)
12725f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                && (ctxt->value->nodesetval != NULL)
1272664f7e1a85fe9c973cf9b21cc0bd53efa6cc3dafcKasimier T. Buchcik                && (ctxt->value->nodesetval->nodeNr >= 1)) { /* TODO: NOP ? */
12727f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            }
12728f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            CHECK_TYPE0(XPATH_NODESET);
12729f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            arg2 = valuePop(ctxt);
12730f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
12731f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            CHECK_TYPE0(XPATH_NODESET);
12732f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            arg1 = valuePop(ctxt);
12733f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
12734f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            arg1->nodesetval = xmlXPathNodeSetMerge(arg1->nodesetval,
12735f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                                                    arg2->nodesetval);
12736f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            valuePush(ctxt, arg1);
12737a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathReleaseObject(ctxt->context, arg2);
12738f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            /* optimizer */
12739f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	    if (total > cur)
12740f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard		xmlXPathCompSwap(op);
12741f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            return (total + cur);
12742f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        case XPATH_OP_ROOT:
12743f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            xmlXPathRoot(ctxt);
12744f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            return (0);
12745f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        case XPATH_OP_NODE:
12746f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            if (op->ch1 != -1)
12747f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
12748556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard	    CHECK_ERROR0;
12749f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            if (op->ch2 != -1)
12750f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
12751556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard	    CHECK_ERROR0;
12752a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    valuePush(ctxt, xmlXPathCacheNewNodeSet(ctxt->context,
12753a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		ctxt->context->node));
12754f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            return (total);
12755f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        case XPATH_OP_RESET:
12756f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            if (op->ch1 != -1)
12757f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
12758556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard	    CHECK_ERROR0;
12759f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            if (op->ch2 != -1)
12760f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
12761556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard	    CHECK_ERROR0;
12762f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            ctxt->context->node = NULL;
12763f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            return (total);
12764f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        case XPATH_OP_COLLECT:{
12765f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                if (op->ch1 == -1)
12766f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    return (0);
12767f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
12768f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
12769556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard		CHECK_ERROR0;
12770f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
12771631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik                total += xmlXPathNodeCollectAndTest(ctxt, op, NULL, last, 0);
12772f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                return (total);
12773f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            }
12774f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        case XPATH_OP_VALUE:
12775f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            valuePush(ctxt,
12776a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik                      xmlXPathCacheObjectCopy(ctxt->context,
12777a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik			(xmlXPathObjectPtr) op->value4));
12778f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            return (0);
12779f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        case XPATH_OP_SORT:
12780f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            if (op->ch1 != -1)
12781f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                total +=
12782f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    xmlXPathCompOpEvalLast(ctxt, &comp->steps[op->ch1],
12783f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                                           last);
12784556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard	    CHECK_ERROR0;
12785f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            if ((ctxt->value != NULL)
12786f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                && (ctxt->value->type == XPATH_NODESET)
1278764f7e1a85fe9c973cf9b21cc0bd53efa6cc3dafcKasimier T. Buchcik                && (ctxt->value->nodesetval != NULL)
1278864f7e1a85fe9c973cf9b21cc0bd53efa6cc3dafcKasimier T. Buchcik		&& (ctxt->value->nodesetval->nodeNr > 1))
12789f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                xmlXPathNodeSetSort(ctxt->value->nodesetval);
12790f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            return (total);
12791f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        default:
12792f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            return (xmlXPathCompOpEval(ctxt, op));
12793f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    }
12794f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard}
127959e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
127965691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik#ifdef XP_OPTIMIZED_FILTER_FIRST
127975691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcikstatic int
127985691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. BuchcikxmlXPathCompOpEvalFilterFirst(xmlXPathParserContextPtr ctxt,
127995691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik			      xmlXPathStepOpPtr op, xmlNodePtr * first)
128005691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik{
128015691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik    int total = 0;
1280245490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard    xmlXPathCompExprPtr comp;
128035691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik    xmlXPathObjectPtr res;
1280445490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard    xmlXPathObjectPtr obj;
128055691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik    xmlNodeSetPtr oldset;
128065691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik    xmlNodePtr oldnode;
128075691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik    xmlDocPtr oldDoc;
128085691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik    int i;
128095691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik
128105691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik    CHECK_ERROR0;
128115691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik    comp = ctxt->comp;
128125691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik    /*
128135691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik    * Optimization for ()[last()] selection i.e. the last elem
128145691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik    */
128155691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik    if ((op->ch1 != -1) && (op->ch2 != -1) &&
128165691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	(comp->steps[op->ch1].op == XPATH_OP_SORT) &&
128175691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	(comp->steps[op->ch2].op == XPATH_OP_SORT)) {
128185691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	int f = comp->steps[op->ch2].ch1;
1281945490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
128205691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	if ((f != -1) &&
128215691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    (comp->steps[f].op == XPATH_OP_FUNCTION) &&
128225691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    (comp->steps[f].value5 == NULL) &&
128235691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    (comp->steps[f].value == 0) &&
128245691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    (comp->steps[f].value4 != NULL) &&
128255691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    (xmlStrEqual
128265691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    (comp->steps[f].value4, BAD_CAST "last"))) {
128275691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    xmlNodePtr last = NULL;
1282845490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
128295691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    total +=
128305691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		xmlXPathCompOpEvalLast(ctxt,
128315691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		    &comp->steps[op->ch1],
128325691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		    &last);
128335691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    CHECK_ERROR0;
128345691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    /*
128355691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    * The nodeset should be in document order,
128365691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    * Keep only the last value
128375691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    */
128385691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    if ((ctxt->value != NULL) &&
128395691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		(ctxt->value->type == XPATH_NODESET) &&
128405691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		(ctxt->value->nodesetval != NULL) &&
128415691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		(ctxt->value->nodesetval->nodeTab != NULL) &&
128425691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		(ctxt->value->nodesetval->nodeNr > 1)) {
128435691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		ctxt->value->nodesetval->nodeTab[0] =
128445691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		    ctxt->value->nodesetval->nodeTab[ctxt->
128455691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		    value->
128465691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		    nodesetval->
128475691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		    nodeNr -
128485691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		    1];
128495691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		ctxt->value->nodesetval->nodeNr = 1;
128505691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		*first = *(ctxt->value->nodesetval->nodeTab);
128515691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    }
128525691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    return (total);
128535691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	}
128545691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik    }
1285545490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
128565691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik    if (op->ch1 != -1)
128575691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
128585691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik    CHECK_ERROR0;
128595691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik    if (op->ch2 == -1)
128605691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	return (total);
128615691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik    if (ctxt->value == NULL)
128625691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	return (total);
1286345490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
128645691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik#ifdef LIBXML_XPTR_ENABLED
128655691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik    oldnode = ctxt->context->node;
128665691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik    /*
128675691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik    * Hum are we filtering the result of an XPointer expression
128685691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik    */
128695691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik    if (ctxt->value->type == XPATH_LOCATIONSET) {
128705691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	xmlXPathObjectPtr tmp = NULL;
128715691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	xmlLocationSetPtr newlocset = NULL;
128725691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	xmlLocationSetPtr oldlocset;
1287345490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
128745691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	/*
128755691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	* Extract the old locset, and then evaluate the result of the
128765691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	* expression for all the element in the locset. use it to grow
128775691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	* up a new locset.
128785691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	*/
128795691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	CHECK_TYPE0(XPATH_LOCATIONSET);
128805691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	obj = valuePop(ctxt);
128815691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	oldlocset = obj->user;
128825691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	ctxt->context->node = NULL;
1288345490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
128845691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	if ((oldlocset == NULL) || (oldlocset->locNr == 0)) {
128855691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    ctxt->context->contextSize = 0;
128865691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    ctxt->context->proximityPosition = 0;
128875691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    if (op->ch2 != -1)
128885691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
128895691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    res = valuePop(ctxt);
12890a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    if (res != NULL) {
12891a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		xmlXPathReleaseObject(ctxt->context, res);
12892a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    }
128935691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    valuePush(ctxt, obj);
128945691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    CHECK_ERROR0;
128955691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    return (total);
128965691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	}
128975691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	newlocset = xmlXPtrLocationSetCreate(NULL);
1289845490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
128995691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	for (i = 0; i < oldlocset->locNr; i++) {
129005691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    /*
129015691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    * Run the evaluation with a node list made of a
129025691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    * single item in the nodelocset.
129035691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    */
129045691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    ctxt->context->node = oldlocset->locTab[i]->user;
129055691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    ctxt->context->contextSize = oldlocset->locNr;
129065691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    ctxt->context->proximityPosition = i + 1;
12907a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    if (tmp == NULL) {
12908a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		tmp = xmlXPathCacheNewNodeSet(ctxt->context,
12909a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    ctxt->context->node);
12910a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    } else {
12911a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		xmlXPathNodeSetAddUnique(tmp->nodesetval,
12912a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    ctxt->context->node);
1291345490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	    }
129145691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    valuePush(ctxt, tmp);
129155691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    if (op->ch2 != -1)
129165691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
129175691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    if (ctxt->error != XPATH_EXPRESSION_OK) {
129185691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		xmlXPathFreeObject(obj);
129195691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		return(0);
129205691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    }
129215691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    /*
129225691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    * The result of the evaluation need to be tested to
129235691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    * decided whether the filter succeeded or not
129245691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    */
129255691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    res = valuePop(ctxt);
129265691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    if (xmlXPathEvaluatePredicateResult(ctxt, res)) {
129275691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		xmlXPtrLocationSetAdd(newlocset,
12928a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    xmlXPathCacheObjectCopy(ctxt->context,
12929a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik			oldlocset->locTab[i]));
129305691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    }
129315691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    /*
129325691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    * Cleanup
129335691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    */
12934a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    if (res != NULL) {
12935a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		xmlXPathReleaseObject(ctxt->context, res);
12936a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    }
129375691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    if (ctxt->value == tmp) {
129385691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		valuePop(ctxt);
1293945490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard		xmlXPathNodeSetClear(tmp->nodesetval, 1);
129405691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		/*
12941a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		* REVISIT TODO: Don't create a temporary nodeset
12942a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		* for everly iteration.
129435691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		*/
12944a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		/* OLD: xmlXPathFreeObject(res); */
12945a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    } else
1294645490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard		tmp = NULL;
129475691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    ctxt->context->node = NULL;
129485691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    /*
129495691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    * Only put the first node in the result, then leave.
129505691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    */
129515691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    if (newlocset->locNr > 0) {
129525691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		*first = (xmlNodePtr) oldlocset->locTab[i]->user;
129535691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		break;
129545691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    }
129555691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	}
12956a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	if (tmp != NULL) {
12957a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathReleaseObject(ctxt->context, tmp);
12958a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	}
129595691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	/*
129605691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	* The result is used as the new evaluation locset.
129615691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	*/
12962a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	xmlXPathReleaseObject(ctxt->context, obj);
129635691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	ctxt->context->node = NULL;
129645691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	ctxt->context->contextSize = -1;
129655691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	ctxt->context->proximityPosition = -1;
129665691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	valuePush(ctxt, xmlXPtrWrapLocationSet(newlocset));
129675691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	ctxt->context->node = oldnode;
129685691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	return (total);
129695691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik    }
129705691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik#endif /* LIBXML_XPTR_ENABLED */
1297145490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
129725691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik    /*
129735691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik    * Extract the old set, and then evaluate the result of the
129745691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik    * expression for all the element in the set. use it to grow
129755691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik    * up a new set.
129765691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik    */
129775691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik    CHECK_TYPE0(XPATH_NODESET);
129785691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik    obj = valuePop(ctxt);
129795691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik    oldset = obj->nodesetval;
1298045490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
129815691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik    oldnode = ctxt->context->node;
129825691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik    oldDoc = ctxt->context->doc;
129835691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik    ctxt->context->node = NULL;
1298445490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
129855691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik    if ((oldset == NULL) || (oldset->nodeNr == 0)) {
129865691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	ctxt->context->contextSize = 0;
129875691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	ctxt->context->proximityPosition = 0;
129885691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	/* QUESTION TODO: Why was this code commented out?
129895691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    if (op->ch2 != -1)
129905691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		total +=
129915691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		    xmlXPathCompOpEval(ctxt,
129925691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik			&comp->steps[op->ch2]);
129935691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    CHECK_ERROR0;
129945691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    res = valuePop(ctxt);
129955691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    if (res != NULL)
129965691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		xmlXPathFreeObject(res);
129975691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	*/
129985691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	valuePush(ctxt, obj);
129995691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	ctxt->context->node = oldnode;
130005691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	CHECK_ERROR0;
130015691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik    } else {
130025691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	xmlNodeSetPtr newset;
130035691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	xmlXPathObjectPtr tmp = NULL;
130045691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	/*
130055691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	* Initialize the new set.
130065691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	* Also set the xpath document in case things like
130075691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	* key() evaluation are attempted on the predicate
1300845490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	*/
130095691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	newset = xmlXPathNodeSetCreate(NULL);
13010f88d849a4e994c94c0d0814a4befb43c990ceebdDaniel Veillard        /* XXX what if xmlXPathNodeSetCreate returned NULL? */
1301145490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
130125691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	for (i = 0; i < oldset->nodeNr; i++) {
130135691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    /*
130145691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    * Run the evaluation with a node list made of
130155691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    * a single item in the nodeset.
130165691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    */
130175691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    ctxt->context->node = oldset->nodeTab[i];
130185691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    if ((oldset->nodeTab[i]->type != XML_NAMESPACE_DECL) &&
130195691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		(oldset->nodeTab[i]->doc != NULL))
130205691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		ctxt->context->doc = oldset->nodeTab[i]->doc;
13021a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    if (tmp == NULL) {
13022a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		tmp = xmlXPathCacheNewNodeSet(ctxt->context,
13023a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    ctxt->context->node);
13024a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    } else {
13025a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		xmlXPathNodeSetAddUnique(tmp->nodesetval,
13026a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    ctxt->context->node);
130275691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    }
130285691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    valuePush(ctxt, tmp);
130295691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    ctxt->context->contextSize = oldset->nodeNr;
130305691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    ctxt->context->proximityPosition = i + 1;
130315691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    if (op->ch2 != -1)
130325691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
130335691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    if (ctxt->error != XPATH_EXPRESSION_OK) {
130345691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		xmlXPathFreeNodeSet(newset);
130355691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		xmlXPathFreeObject(obj);
130365691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		return(0);
1303745490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	    }
130385691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    /*
130395691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    * The result of the evaluation needs to be tested to
130405691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    * decide whether the filter succeeded or not
130415691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    */
130425691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    res = valuePop(ctxt);
130435691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    if (xmlXPathEvaluatePredicateResult(ctxt, res)) {
130445691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		xmlXPathNodeSetAdd(newset, oldset->nodeTab[i]);
1304545490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	    }
130465691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    /*
130475691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    * Cleanup
130485691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    */
13049a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    if (res != NULL) {
13050a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		xmlXPathReleaseObject(ctxt->context, res);
13051a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    }
130525691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    if (ctxt->value == tmp) {
130535691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		valuePop(ctxt);
130545691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		/*
13055a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		* Don't free the temporary nodeset
130565691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		* in order to avoid massive recreation inside this
130575691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		* loop.
13058a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		*/
130599bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		xmlXPathNodeSetClear(tmp->nodesetval, 1);
13060a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    } else
13061a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		tmp = NULL;
130625691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    ctxt->context->node = NULL;
130635691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    /*
130645691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    * Only put the first node in the result, then leave.
130655691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    */
130665691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    if (newset->nodeNr > 0) {
130675691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		*first = *(newset->nodeTab);
130685691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		break;
130695691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    }
130705691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	}
13071a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	if (tmp != NULL) {
13072a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathReleaseObject(ctxt->context, tmp);
13073a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	}
130745691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	/*
130755691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	* The result is used as the new evaluation set.
130765691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	*/
13077a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	xmlXPathReleaseObject(ctxt->context, obj);
130785691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	ctxt->context->node = NULL;
130795691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	ctxt->context->contextSize = -1;
130805691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	ctxt->context->proximityPosition = -1;
130815691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	/* may want to move this past the '}' later */
130825691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	ctxt->context->doc = oldDoc;
13083a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	valuePush(ctxt, xmlXPathCacheWrapNodeSet(ctxt->context, newset));
130845691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik    }
130855691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik    ctxt->context->node = oldnode;
130865691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik    return(total);
130875691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik}
130885691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik#endif /* XP_OPTIMIZED_FILTER_FIRST */
130895691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik
13090f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard/**
13091f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * xmlXPathCompOpEval:
13092f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * @ctxt:  the XPath parser context with the compiled expression
13093f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * @op:  an XPath compiled operation
13094f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard *
13095f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Evaluate the Precompiled XPath operation
13096081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack * Returns the number of nodes traversed
13097f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */
13098f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillardstatic int
13099f06307e2c172284bb41376c396f757bdac9bdd19Daniel VeillardxmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op)
13100f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard{
13101f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    int total = 0;
13102f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    int equal, ret;
13103f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    xmlXPathCompExprPtr comp;
13104f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    xmlXPathObjectPtr arg1, arg2;
131057089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard    xmlNodePtr bak;
131067089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard    xmlDocPtr bakd;
131076000af549b49464a3b1947fc582998a1c9ff7c79William M. Brack    int pp;
13108692092b5886073a8cd1c97bb7d57579e4a9cfc3fWilliam M. Brack    int cs;
131099e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
13110556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard    CHECK_ERROR0;
13111f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    comp = ctxt->comp;
13112f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    switch (op->op) {
13113f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        case XPATH_OP_END:
13114f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            return (0);
13115f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        case XPATH_OP_AND:
131167089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard	    bakd = ctxt->context->doc;
131177089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard	    bak = ctxt->context->node;
131186000af549b49464a3b1947fc582998a1c9ff7c79William M. Brack	    pp = ctxt->context->proximityPosition;
13119692092b5886073a8cd1c97bb7d57579e4a9cfc3fWilliam M. Brack	    cs = ctxt->context->contextSize;
13120f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
13121556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard	    CHECK_ERROR0;
13122f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            xmlXPathBooleanFunction(ctxt, 1);
13123f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            if ((ctxt->value == NULL) || (ctxt->value->boolval == 0))
13124f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                return (total);
13125f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            arg2 = valuePop(ctxt);
131267089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard	    ctxt->context->doc = bakd;
131277089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard	    ctxt->context->node = bak;
131286000af549b49464a3b1947fc582998a1c9ff7c79William M. Brack	    ctxt->context->proximityPosition = pp;
13129692092b5886073a8cd1c97bb7d57579e4a9cfc3fWilliam M. Brack	    ctxt->context->contextSize = cs;
13130f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
13131556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard	    if (ctxt->error) {
13132556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard		xmlXPathFreeObject(arg2);
13133556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard		return(0);
13134556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard	    }
13135f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            xmlXPathBooleanFunction(ctxt, 1);
13136f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            arg1 = valuePop(ctxt);
13137f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            arg1->boolval &= arg2->boolval;
13138f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            valuePush(ctxt, arg1);
13139a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathReleaseObject(ctxt->context, arg2);
13140f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            return (total);
13141f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        case XPATH_OP_OR:
131427089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard	    bakd = ctxt->context->doc;
131437089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard	    bak = ctxt->context->node;
131446000af549b49464a3b1947fc582998a1c9ff7c79William M. Brack	    pp = ctxt->context->proximityPosition;
13145692092b5886073a8cd1c97bb7d57579e4a9cfc3fWilliam M. Brack	    cs = ctxt->context->contextSize;
13146f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
13147556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard	    CHECK_ERROR0;
13148f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            xmlXPathBooleanFunction(ctxt, 1);
13149f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            if ((ctxt->value == NULL) || (ctxt->value->boolval == 1))
13150f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                return (total);
13151f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            arg2 = valuePop(ctxt);
131527089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard	    ctxt->context->doc = bakd;
131537089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard	    ctxt->context->node = bak;
131546000af549b49464a3b1947fc582998a1c9ff7c79William M. Brack	    ctxt->context->proximityPosition = pp;
13155692092b5886073a8cd1c97bb7d57579e4a9cfc3fWilliam M. Brack	    ctxt->context->contextSize = cs;
13156f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
13157556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard	    if (ctxt->error) {
13158556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard		xmlXPathFreeObject(arg2);
13159556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard		return(0);
13160556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard	    }
13161f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            xmlXPathBooleanFunction(ctxt, 1);
13162f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            arg1 = valuePop(ctxt);
13163f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            arg1->boolval |= arg2->boolval;
13164f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            valuePush(ctxt, arg1);
13165a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathReleaseObject(ctxt->context, arg2);
13166f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            return (total);
13167f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        case XPATH_OP_EQUAL:
131687089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard	    bakd = ctxt->context->doc;
131697089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard	    bak = ctxt->context->node;
131706000af549b49464a3b1947fc582998a1c9ff7c79William M. Brack	    pp = ctxt->context->proximityPosition;
13171692092b5886073a8cd1c97bb7d57579e4a9cfc3fWilliam M. Brack	    cs = ctxt->context->contextSize;
13172f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
13173556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard	    CHECK_ERROR0;
131747089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard	    ctxt->context->doc = bakd;
131757089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard	    ctxt->context->node = bak;
131766000af549b49464a3b1947fc582998a1c9ff7c79William M. Brack	    ctxt->context->proximityPosition = pp;
13177692092b5886073a8cd1c97bb7d57579e4a9cfc3fWilliam M. Brack	    ctxt->context->contextSize = cs;
13178f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
13179556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard	    CHECK_ERROR0;
131800c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	    if (op->value)
1318145490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard		equal = xmlXPathEqualValues(ctxt);
131820c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	    else
131830c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		equal = xmlXPathNotEqualValues(ctxt);
13184a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    valuePush(ctxt, xmlXPathCacheNewBoolean(ctxt->context, equal));
13185f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            return (total);
13186f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        case XPATH_OP_CMP:
131877089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard	    bakd = ctxt->context->doc;
131887089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard	    bak = ctxt->context->node;
131896000af549b49464a3b1947fc582998a1c9ff7c79William M. Brack	    pp = ctxt->context->proximityPosition;
13190692092b5886073a8cd1c97bb7d57579e4a9cfc3fWilliam M. Brack	    cs = ctxt->context->contextSize;
13191f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
13192556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard	    CHECK_ERROR0;
131937089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard	    ctxt->context->doc = bakd;
131947089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard	    ctxt->context->node = bak;
131956000af549b49464a3b1947fc582998a1c9ff7c79William M. Brack	    ctxt->context->proximityPosition = pp;
13196692092b5886073a8cd1c97bb7d57579e4a9cfc3fWilliam M. Brack	    ctxt->context->contextSize = cs;
13197f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
13198556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard	    CHECK_ERROR0;
13199f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            ret = xmlXPathCompareValues(ctxt, op->value, op->value2);
13200a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    valuePush(ctxt, xmlXPathCacheNewBoolean(ctxt->context, ret));
13201f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            return (total);
13202f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        case XPATH_OP_PLUS:
132037089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard	    bakd = ctxt->context->doc;
132047089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard	    bak = ctxt->context->node;
132056000af549b49464a3b1947fc582998a1c9ff7c79William M. Brack	    pp = ctxt->context->proximityPosition;
13206692092b5886073a8cd1c97bb7d57579e4a9cfc3fWilliam M. Brack	    cs = ctxt->context->contextSize;
13207f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
13208556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard	    CHECK_ERROR0;
132097089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard            if (op->ch2 != -1) {
132107089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard		ctxt->context->doc = bakd;
132117089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard		ctxt->context->node = bak;
132126000af549b49464a3b1947fc582998a1c9ff7c79William M. Brack		ctxt->context->proximityPosition = pp;
13213692092b5886073a8cd1c97bb7d57579e4a9cfc3fWilliam M. Brack		ctxt->context->contextSize = cs;
13214f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
132157089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard	    }
13216556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard	    CHECK_ERROR0;
13217f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            if (op->value == 0)
13218f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                xmlXPathSubValues(ctxt);
13219f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            else if (op->value == 1)
13220f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                xmlXPathAddValues(ctxt);
13221f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            else if (op->value == 2)
13222f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                xmlXPathValueFlipSign(ctxt);
13223f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            else if (op->value == 3) {
13224f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                CAST_TO_NUMBER;
13225f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                CHECK_TYPE0(XPATH_NUMBER);
13226f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            }
13227f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            return (total);
13228f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        case XPATH_OP_MULT:
132297089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard	    bakd = ctxt->context->doc;
132307089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard	    bak = ctxt->context->node;
132316000af549b49464a3b1947fc582998a1c9ff7c79William M. Brack	    pp = ctxt->context->proximityPosition;
13232692092b5886073a8cd1c97bb7d57579e4a9cfc3fWilliam M. Brack	    cs = ctxt->context->contextSize;
13233f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
13234556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard	    CHECK_ERROR0;
132357089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard	    ctxt->context->doc = bakd;
132367089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard	    ctxt->context->node = bak;
132376000af549b49464a3b1947fc582998a1c9ff7c79William M. Brack	    ctxt->context->proximityPosition = pp;
13238692092b5886073a8cd1c97bb7d57579e4a9cfc3fWilliam M. Brack	    ctxt->context->contextSize = cs;
13239f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
13240556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard	    CHECK_ERROR0;
13241f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            if (op->value == 0)
13242f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                xmlXPathMultValues(ctxt);
13243f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            else if (op->value == 1)
13244f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                xmlXPathDivValues(ctxt);
13245f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            else if (op->value == 2)
13246f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                xmlXPathModValues(ctxt);
13247f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            return (total);
13248f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        case XPATH_OP_UNION:
132497089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard	    bakd = ctxt->context->doc;
132507089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard	    bak = ctxt->context->node;
132516000af549b49464a3b1947fc582998a1c9ff7c79William M. Brack	    pp = ctxt->context->proximityPosition;
13252692092b5886073a8cd1c97bb7d57579e4a9cfc3fWilliam M. Brack	    cs = ctxt->context->contextSize;
13253f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
13254556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard	    CHECK_ERROR0;
132557089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard	    ctxt->context->doc = bakd;
132567089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard	    ctxt->context->node = bak;
132576000af549b49464a3b1947fc582998a1c9ff7c79William M. Brack	    ctxt->context->proximityPosition = pp;
13258692092b5886073a8cd1c97bb7d57579e4a9cfc3fWilliam M. Brack	    ctxt->context->contextSize = cs;
13259f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
13260556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard	    CHECK_ERROR0;
13261f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            CHECK_TYPE0(XPATH_NODESET);
13262f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            arg2 = valuePop(ctxt);
13263f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
13264f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            CHECK_TYPE0(XPATH_NODESET);
13265f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            arg1 = valuePop(ctxt);
13266f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
1326764f7e1a85fe9c973cf9b21cc0bd53efa6cc3dafcKasimier T. Buchcik	    if ((arg1->nodesetval == NULL) ||
1326864f7e1a85fe9c973cf9b21cc0bd53efa6cc3dafcKasimier T. Buchcik		((arg2->nodesetval != NULL) &&
1326964f7e1a85fe9c973cf9b21cc0bd53efa6cc3dafcKasimier T. Buchcik		 (arg2->nodesetval->nodeNr != 0)))
1327064f7e1a85fe9c973cf9b21cc0bd53efa6cc3dafcKasimier T. Buchcik	    {
1327164f7e1a85fe9c973cf9b21cc0bd53efa6cc3dafcKasimier T. Buchcik		arg1->nodesetval = xmlXPathNodeSetMerge(arg1->nodesetval,
1327264f7e1a85fe9c973cf9b21cc0bd53efa6cc3dafcKasimier T. Buchcik							arg2->nodesetval);
1327364f7e1a85fe9c973cf9b21cc0bd53efa6cc3dafcKasimier T. Buchcik	    }
1327464f7e1a85fe9c973cf9b21cc0bd53efa6cc3dafcKasimier T. Buchcik
13275f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            valuePush(ctxt, arg1);
13276a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathReleaseObject(ctxt->context, arg2);
13277f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            return (total);
13278f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        case XPATH_OP_ROOT:
13279f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            xmlXPathRoot(ctxt);
13280f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            return (total);
13281f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        case XPATH_OP_NODE:
13282f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            if (op->ch1 != -1)
13283f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
13284556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard	    CHECK_ERROR0;
13285f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            if (op->ch2 != -1)
13286f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
13287556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard	    CHECK_ERROR0;
13288a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    valuePush(ctxt, xmlXPathCacheNewNodeSet(ctxt->context,
13289a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		ctxt->context->node));
13290f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            return (total);
13291f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        case XPATH_OP_RESET:
13292f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            if (op->ch1 != -1)
13293f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
13294556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard	    CHECK_ERROR0;
13295f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            if (op->ch2 != -1)
13296f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
13297556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard	    CHECK_ERROR0;
13298f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            ctxt->context->node = NULL;
13299f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            return (total);
13300f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        case XPATH_OP_COLLECT:{
13301f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                if (op->ch1 == -1)
13302f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    return (total);
13303f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
13304f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
13305556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard		CHECK_ERROR0;
13306f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
13307631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik                total += xmlXPathNodeCollectAndTest(ctxt, op, NULL, NULL, 0);
13308f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                return (total);
13309f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            }
13310f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        case XPATH_OP_VALUE:
13311f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            valuePush(ctxt,
13312a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik                      xmlXPathCacheObjectCopy(ctxt->context,
13313a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik			(xmlXPathObjectPtr) op->value4));
13314f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            return (total);
13315f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        case XPATH_OP_VARIABLE:{
13316556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard		xmlXPathObjectPtr val;
13317556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard
13318f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                if (op->ch1 != -1)
13319f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    total +=
13320f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
13321556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard                if (op->value5 == NULL) {
13322556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard		    val = xmlXPathVariableLookup(ctxt->context, op->value4);
13323556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard		    if (val == NULL) {
13324556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard			ctxt->error = XPATH_UNDEF_VARIABLE_ERROR;
13325556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard			return(0);
13326556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard		    }
13327556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard                    valuePush(ctxt, val);
13328556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard		} else {
13329f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    const xmlChar *URI;
13330f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
13331f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    URI = xmlXPathNsLookup(ctxt->context, op->value5);
13332f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    if (URI == NULL) {
13333f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        xmlGenericError(xmlGenericErrorContext,
13334f63085de5e33a95e326d1d810fb18d979359012bDaniel Veillard            "xmlXPathCompOpEval: variable %s bound to undefined prefix %s\n",
13335f63085de5e33a95e326d1d810fb18d979359012bDaniel Veillard                                    (char *) op->value4, (char *)op->value5);
13336f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        return (total);
13337f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    }
13338556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard		    val = xmlXPathVariableLookupNS(ctxt->context,
13339556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard                                                       op->value4, URI);
13340556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard		    if (val == NULL) {
13341556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard			ctxt->error = XPATH_UNDEF_VARIABLE_ERROR;
13342556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard			return(0);
13343556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard		    }
13344556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard                    valuePush(ctxt, val);
13345f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                }
13346f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                return (total);
13347f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            }
13348f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        case XPATH_OP_FUNCTION:{
13349f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                xmlXPathFunction func;
13350f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                const xmlChar *oldFunc, *oldFuncURI;
13351556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard		int i;
13352f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
13353f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                if (op->ch1 != -1)
13354f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    total +=
13355f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
13356556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard		if (ctxt->valueNr < op->value) {
13357556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard		    xmlGenericError(xmlGenericErrorContext,
13358cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard			    "xmlXPathCompOpEval: parameter error\n");
13359556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard		    ctxt->error = XPATH_INVALID_OPERAND;
13360556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard		    return (total);
13361556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard		}
13362556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard		for (i = 0; i < op->value; i++)
13363556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard		    if (ctxt->valueTab[(ctxt->valueNr - 1) - i] == NULL) {
13364556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard			xmlGenericError(xmlGenericErrorContext,
13365cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard				"xmlXPathCompOpEval: parameter error\n");
13366556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard			ctxt->error = XPATH_INVALID_OPERAND;
13367556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard			return (total);
13368556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard		    }
13369f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                if (op->cache != NULL)
13370ad0e67c57f26f691fc120d5c5336cee9885cf324William M. Brack                    XML_CAST_FPTR(func) = op->cache;
13371f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                else {
13372f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    const xmlChar *URI = NULL;
13373f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
13374f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    if (op->value5 == NULL)
13375f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        func =
13376f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                            xmlXPathFunctionLookup(ctxt->context,
13377f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                                                   op->value4);
13378f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    else {
13379f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        URI = xmlXPathNsLookup(ctxt->context, op->value5);
13380f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        if (URI == NULL) {
13381f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                            xmlGenericError(xmlGenericErrorContext,
13382f63085de5e33a95e326d1d810fb18d979359012bDaniel Veillard            "xmlXPathCompOpEval: function %s bound to undefined prefix %s\n",
13383f63085de5e33a95e326d1d810fb18d979359012bDaniel Veillard                                    (char *)op->value4, (char *)op->value5);
13384f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                            return (total);
13385f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        }
13386f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        func = xmlXPathFunctionLookupNS(ctxt->context,
13387f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                                                        op->value4, URI);
13388f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    }
13389f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    if (func == NULL) {
13390f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        xmlGenericError(xmlGenericErrorContext,
13391f63085de5e33a95e326d1d810fb18d979359012bDaniel Veillard                                "xmlXPathCompOpEval: function %s not found\n",
13392f63085de5e33a95e326d1d810fb18d979359012bDaniel Veillard                                        (char *)op->value4);
13393f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        XP_ERROR0(XPATH_UNKNOWN_FUNC_ERROR);
13394f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    }
13395ad0e67c57f26f691fc120d5c5336cee9885cf324William M. Brack                    op->cache = XML_CAST_FPTR(func);
13396f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    op->cacheURI = (void *) URI;
13397f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                }
13398f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                oldFunc = ctxt->context->function;
13399f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                oldFuncURI = ctxt->context->functionURI;
13400f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                ctxt->context->function = op->value4;
13401f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                ctxt->context->functionURI = op->cacheURI;
13402f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                func(ctxt, op->value);
13403f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                ctxt->context->function = oldFunc;
13404f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                ctxt->context->functionURI = oldFuncURI;
13405f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                return (total);
13406f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            }
13407f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        case XPATH_OP_ARG:
13408088bf1163080cbbb72ba9d4a52ab08cc7c8ff6c7Daniel Veillard	    bakd = ctxt->context->doc;
13409088bf1163080cbbb72ba9d4a52ab08cc7c8ff6c7Daniel Veillard	    bak = ctxt->context->node;
13410645a924a9d50d8e0eced5dd7277214a65756c2e1William M. Brack	    pp = ctxt->context->proximityPosition;
13411645a924a9d50d8e0eced5dd7277214a65756c2e1William M. Brack	    cs = ctxt->context->contextSize;
13412f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            if (op->ch1 != -1)
13413f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
13414645a924a9d50d8e0eced5dd7277214a65756c2e1William M. Brack	    ctxt->context->contextSize = cs;
13415645a924a9d50d8e0eced5dd7277214a65756c2e1William M. Brack	    ctxt->context->proximityPosition = pp;
13416088bf1163080cbbb72ba9d4a52ab08cc7c8ff6c7Daniel Veillard	    ctxt->context->node = bak;
13417645a924a9d50d8e0eced5dd7277214a65756c2e1William M. Brack	    ctxt->context->doc = bakd;
13418556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard	    CHECK_ERROR0;
1341972ee48d55f9002544d011826e2897b5054b7e32cWilliam M. Brack            if (op->ch2 != -1) {
13420f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
1342172ee48d55f9002544d011826e2897b5054b7e32cWilliam M. Brack	        ctxt->context->doc = bakd;
1342272ee48d55f9002544d011826e2897b5054b7e32cWilliam M. Brack	        ctxt->context->node = bak;
1342372ee48d55f9002544d011826e2897b5054b7e32cWilliam M. Brack	        CHECK_ERROR0;
1342472ee48d55f9002544d011826e2897b5054b7e32cWilliam M. Brack	    }
13425f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            return (total);
13426f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        case XPATH_OP_PREDICATE:
13427f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        case XPATH_OP_FILTER:{
13428f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                xmlXPathObjectPtr res;
13429f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                xmlXPathObjectPtr obj, tmp;
13430f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                xmlNodeSetPtr newset = NULL;
13431f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                xmlNodeSetPtr oldset;
13432f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                xmlNodePtr oldnode;
134333794b9e84ac51072830a0b34d1ddd0378c0f7cb6William M. Brack		xmlDocPtr oldDoc;
13434f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                int i;
13435f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
13436f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                /*
13437f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                 * Optimization for ()[1] selection i.e. the first elem
13438f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                 */
13439f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                if ((op->ch1 != -1) && (op->ch2 != -1) &&
134405691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik#ifdef XP_OPTIMIZED_FILTER_FIRST
134415691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		    /*
134425691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		    * FILTER TODO: Can we assume that the inner processing
134435691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		    *  will result in an ordered list if we have an
134445691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		    *  XPATH_OP_FILTER?
134455691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		    *  What about an additional field or flag on
134465691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		    *  xmlXPathObject like @sorted ? This way we wouln'd need
134475691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		    *  to assume anything, so it would be more robust and
134485691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		    *  easier to optimize.
134495691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		    */
134505691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik                    ((comp->steps[op->ch1].op == XPATH_OP_SORT) || /* 18 */
134515691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		     (comp->steps[op->ch1].op == XPATH_OP_FILTER)) && /* 17 */
134525691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik#else
134535691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		    (comp->steps[op->ch1].op == XPATH_OP_SORT) &&
134545691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik#endif
134555691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik                    (comp->steps[op->ch2].op == XPATH_OP_VALUE)) { /* 12 */
13456f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    xmlXPathObjectPtr val;
13457f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
13458f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    val = comp->steps[op->ch2].value4;
13459f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    if ((val != NULL) && (val->type == XPATH_NUMBER) &&
13460f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        (val->floatval == 1.0)) {
13461f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        xmlNodePtr first = NULL;
13462f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
13463f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        total +=
13464f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                            xmlXPathCompOpEvalFirst(ctxt,
13465f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                                                    &comp->steps[op->ch1],
13466f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                                                    &first);
13467556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard			CHECK_ERROR0;
13468f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        /*
13469f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                         * The nodeset should be in document order,
13470f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                         * Keep only the first value
13471f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                         */
13472f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        if ((ctxt->value != NULL) &&
13473f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                            (ctxt->value->type == XPATH_NODESET) &&
13474f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                            (ctxt->value->nodesetval != NULL) &&
13475f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                            (ctxt->value->nodesetval->nodeNr > 1))
13476f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                            ctxt->value->nodesetval->nodeNr = 1;
13477f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        return (total);
13478f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    }
13479f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                }
13480f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                /*
13481f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                 * Optimization for ()[last()] selection i.e. the last elem
13482f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                 */
13483f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                if ((op->ch1 != -1) && (op->ch2 != -1) &&
13484f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    (comp->steps[op->ch1].op == XPATH_OP_SORT) &&
13485f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    (comp->steps[op->ch2].op == XPATH_OP_SORT)) {
13486f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    int f = comp->steps[op->ch2].ch1;
13487f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
13488f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    if ((f != -1) &&
13489f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        (comp->steps[f].op == XPATH_OP_FUNCTION) &&
13490f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        (comp->steps[f].value5 == NULL) &&
13491f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        (comp->steps[f].value == 0) &&
13492f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        (comp->steps[f].value4 != NULL) &&
13493f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        (xmlStrEqual
13494f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                         (comp->steps[f].value4, BAD_CAST "last"))) {
13495f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        xmlNodePtr last = NULL;
13496f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
13497f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        total +=
13498f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                            xmlXPathCompOpEvalLast(ctxt,
13499f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                                                   &comp->steps[op->ch1],
13500f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                                                   &last);
13501556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard			CHECK_ERROR0;
13502f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        /*
13503f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                         * The nodeset should be in document order,
13504f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                         * Keep only the last value
13505f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                         */
13506f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        if ((ctxt->value != NULL) &&
13507f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                            (ctxt->value->type == XPATH_NODESET) &&
13508f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                            (ctxt->value->nodesetval != NULL) &&
13509f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                            (ctxt->value->nodesetval->nodeTab != NULL) &&
13510f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                            (ctxt->value->nodesetval->nodeNr > 1)) {
13511f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                            ctxt->value->nodesetval->nodeTab[0] =
13512f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                                ctxt->value->nodesetval->nodeTab[ctxt->
13513f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                                                                 value->
13514f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                                                                 nodesetval->
13515f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                                                                 nodeNr -
13516f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                                                                 1];
13517f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                            ctxt->value->nodesetval->nodeNr = 1;
13518f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        }
13519f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        return (total);
13520f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    }
13521f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                }
13522df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		/*
13523df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		* Process inner predicates first.
13524df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		* Example "index[parent::book][1]":
13525df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		* ...
13526df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		*   PREDICATE   <-- we are here "[1]"
13527df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		*     PREDICATE <-- process "[parent::book]" first
13528df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		*       SORT
13529df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		*         COLLECT  'parent' 'name' 'node' book
13530df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		*           NODE
13531df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		*     ELEM Object is a number : 1
13532df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		*/
13533f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                if (op->ch1 != -1)
13534f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    total +=
13535f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
13536556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard		CHECK_ERROR0;
13537f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                if (op->ch2 == -1)
13538f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    return (total);
13539f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                if (ctxt->value == NULL)
13540f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    return (total);
13541f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
13542f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                oldnode = ctxt->context->node;
135439e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
13544f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#ifdef LIBXML_XPTR_ENABLED
13545f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                /*
13546f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                 * Hum are we filtering the result of an XPointer expression
13547f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                 */
13548f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                if (ctxt->value->type == XPATH_LOCATIONSET) {
13549f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    xmlLocationSetPtr newlocset = NULL;
13550f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    xmlLocationSetPtr oldlocset;
13551f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
13552f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    /*
13553f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                     * Extract the old locset, and then evaluate the result of the
13554f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                     * expression for all the element in the locset. use it to grow
13555f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                     * up a new locset.
13556f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                     */
13557f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    CHECK_TYPE0(XPATH_LOCATIONSET);
13558f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    obj = valuePop(ctxt);
13559f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    oldlocset = obj->user;
13560f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    ctxt->context->node = NULL;
13561f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
13562f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    if ((oldlocset == NULL) || (oldlocset->locNr == 0)) {
13563f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        ctxt->context->contextSize = 0;
13564f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        ctxt->context->proximityPosition = 0;
13565f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        if (op->ch2 != -1)
13566f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                            total +=
13567f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                                xmlXPathCompOpEval(ctxt,
13568f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                                                   &comp->steps[op->ch2]);
13569f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        res = valuePop(ctxt);
13570a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik                        if (res != NULL) {
13571a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik			    xmlXPathReleaseObject(ctxt->context, res);
13572a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik			}
13573f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        valuePush(ctxt, obj);
13574f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        CHECK_ERROR0;
13575f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        return (total);
13576f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    }
13577f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    newlocset = xmlXPtrLocationSetCreate(NULL);
13578f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
13579f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    for (i = 0; i < oldlocset->locNr; i++) {
13580f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        /*
13581f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                         * Run the evaluation with a node list made of a
13582f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                         * single item in the nodelocset.
13583f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                         */
13584f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        ctxt->context->node = oldlocset->locTab[i]->user;
13585f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        ctxt->context->contextSize = oldlocset->locNr;
13586f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        ctxt->context->proximityPosition = i + 1;
13587a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik			tmp = xmlXPathCacheNewNodeSet(ctxt->context,
13588a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik			    ctxt->context->node);
13589f7eb794c142e31ca895f2d7743f872a809e514abWilliam M. Brack                        valuePush(ctxt, tmp);
1359045490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
13591f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        if (op->ch2 != -1)
13592f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                            total +=
13593f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                                xmlXPathCompOpEval(ctxt,
13594f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                                                   &comp->steps[op->ch2]);
135952c19a7bf2ee0f78485840cac50f2a989f5efe476William M. Brack			if (ctxt->error != XPATH_EXPRESSION_OK) {
135962c19a7bf2ee0f78485840cac50f2a989f5efe476William M. Brack			    xmlXPathFreeObject(obj);
135972c19a7bf2ee0f78485840cac50f2a989f5efe476William M. Brack			    return(0);
135982c19a7bf2ee0f78485840cac50f2a989f5efe476William M. Brack			}
13599f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
13600f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        /*
13601f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                         * The result of the evaluation need to be tested to
13602f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                         * decided whether the filter succeeded or not
13603f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                         */
13604f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        res = valuePop(ctxt);
13605f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        if (xmlXPathEvaluatePredicateResult(ctxt, res)) {
13606f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                            xmlXPtrLocationSetAdd(newlocset,
13607f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                                                  xmlXPathObjectCopy
13608f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                                                  (oldlocset->locTab[i]));
13609f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        }
13610f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
13611f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        /*
13612f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                         * Cleanup
13613f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                         */
13614a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik                        if (res != NULL) {
13615a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik			    xmlXPathReleaseObject(ctxt->context, res);
13616a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik			}
13617f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        if (ctxt->value == tmp) {
13618f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                            res = valuePop(ctxt);
13619a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik			    xmlXPathReleaseObject(ctxt->context, res);
13620f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        }
13621f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
13622f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        ctxt->context->node = NULL;
13623f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    }
13624f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
13625f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    /*
13626f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                     * The result is used as the new evaluation locset.
13627f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                     */
13628a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    xmlXPathReleaseObject(ctxt->context, obj);
13629f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    ctxt->context->node = NULL;
13630f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    ctxt->context->contextSize = -1;
13631f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    ctxt->context->proximityPosition = -1;
13632f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    valuePush(ctxt, xmlXPtrWrapLocationSet(newlocset));
13633f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    ctxt->context->node = oldnode;
13634f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    return (total);
13635f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                }
136369e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard#endif /* LIBXML_XPTR_ENABLED */
136379e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
13638f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                /*
13639f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                 * Extract the old set, and then evaluate the result of the
13640f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                 * expression for all the element in the set. use it to grow
13641f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                 * up a new set.
13642f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                 */
13643f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                CHECK_TYPE0(XPATH_NODESET);
13644f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                obj = valuePop(ctxt);
13645f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                oldset = obj->nodesetval;
13646f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
13647f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                oldnode = ctxt->context->node;
136483794b9e84ac51072830a0b34d1ddd0378c0f7cb6William M. Brack		oldDoc = ctxt->context->doc;
13649f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                ctxt->context->node = NULL;
13650f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
13651f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                if ((oldset == NULL) || (oldset->nodeNr == 0)) {
13652f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    ctxt->context->contextSize = 0;
13653f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    ctxt->context->proximityPosition = 0;
136548fad8bff2c2e0b064a6d48d4eeb663804de5545fWilliam M. Brack/*
13655f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    if (op->ch2 != -1)
13656f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        total +=
13657f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                            xmlXPathCompOpEval(ctxt,
13658f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                                               &comp->steps[op->ch2]);
13659556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard		    CHECK_ERROR0;
13660f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    res = valuePop(ctxt);
13661f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    if (res != NULL)
13662f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        xmlXPathFreeObject(res);
136638fad8bff2c2e0b064a6d48d4eeb663804de5545fWilliam M. Brack*/
13664f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    valuePush(ctxt, obj);
13665f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    ctxt->context->node = oldnode;
13666f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    CHECK_ERROR0;
13667f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                } else {
136685691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		    tmp = NULL;
13669f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    /*
13670f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                     * Initialize the new set.
136713794b9e84ac51072830a0b34d1ddd0378c0f7cb6William M. Brack		     * Also set the xpath document in case things like
136723794b9e84ac51072830a0b34d1ddd0378c0f7cb6William M. Brack		     * key() evaluation are attempted on the predicate
13673f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                     */
13674f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    newset = xmlXPathNodeSetCreate(NULL);
13675df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		    /*
13676df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		    * SPEC XPath 1.0:
13677df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		    *  "For each node in the node-set to be filtered, the
13678df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		    *  PredicateExpr is evaluated with that node as the
13679df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		    *  context node, with the number of nodes in the
13680df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		    *  node-set as the context size, and with the proximity
13681df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		    *  position of the node in the node-set with respect to
13682df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		    *  the axis as the context position;"
13683df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		    * @oldset is the node-set" to be filtered.
13684df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		    *
13685df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		    * SPEC XPath 1.0:
13686df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		    *  "only predicates change the context position and
13687df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		    *  context size (see [2.4 Predicates])."
13688df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		    * Example:
13689df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		    *   node-set  context pos
13690df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		    *    nA         1
13691df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		    *    nB         2
13692df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		    *    nC         3
13693df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		    *   After applying predicate [position() > 1] :
13694df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		    *   node-set  context pos
13695df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		    *    nB         1
13696df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		    *    nC         2
13697df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		    *
13698df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		    * removed the first node in the node-set, then
1369945490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard		    * the context position of the
13700df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		    */
13701f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    for (i = 0; i < oldset->nodeNr; i++) {
13702f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        /*
13703f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                         * Run the evaluation with a node list made of
13704f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                         * a single item in the nodeset.
13705f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                         */
13706f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        ctxt->context->node = oldset->nodeTab[i];
137073794b9e84ac51072830a0b34d1ddd0378c0f7cb6William M. Brack			if ((oldset->nodeTab[i]->type != XML_NAMESPACE_DECL) &&
137083794b9e84ac51072830a0b34d1ddd0378c0f7cb6William M. Brack			    (oldset->nodeTab[i]->doc != NULL))
137093794b9e84ac51072830a0b34d1ddd0378c0f7cb6William M. Brack		            ctxt->context->doc = oldset->nodeTab[i]->doc;
13710a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik			if (tmp == NULL) {
13711a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik			    tmp = xmlXPathCacheNewNodeSet(ctxt->context,
13712a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik				ctxt->context->node);
13713a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik			} else {
13714a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik			    xmlXPathNodeSetAddUnique(tmp->nodesetval,
13715a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik				ctxt->context->node);
137165691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik			}
13717f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        valuePush(ctxt, tmp);
13718f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        ctxt->context->contextSize = oldset->nodeNr;
13719f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        ctxt->context->proximityPosition = i + 1;
13720df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik			/*
13721df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik			* Evaluate the predicate against the context node.
13722df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik			* Can/should we optimize position() predicates
13723df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik			* here (e.g. "[1]")?
13724df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik			*/
13725f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        if (op->ch2 != -1)
13726f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                            total +=
13727f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                                xmlXPathCompOpEval(ctxt,
13728f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                                                   &comp->steps[op->ch2]);
137292c19a7bf2ee0f78485840cac50f2a989f5efe476William M. Brack			if (ctxt->error != XPATH_EXPRESSION_OK) {
137302c19a7bf2ee0f78485840cac50f2a989f5efe476William M. Brack			    xmlXPathFreeNodeSet(newset);
137312c19a7bf2ee0f78485840cac50f2a989f5efe476William M. Brack			    xmlXPathFreeObject(obj);
137322c19a7bf2ee0f78485840cac50f2a989f5efe476William M. Brack			    return(0);
137332c19a7bf2ee0f78485840cac50f2a989f5efe476William M. Brack			}
13734f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
13735f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        /*
13736081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                         * The result of the evaluation needs to be tested to
13737081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                         * decide whether the filter succeeded or not
13738df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik                         */
13739df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik			/*
13740df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik			* OPTIMIZE TODO: Can we use
13741df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik			* xmlXPathNodeSetAdd*Unique()* instead?
13742df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik			*/
13743f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        res = valuePop(ctxt);
13744f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        if (xmlXPathEvaluatePredicateResult(ctxt, res)) {
13745f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                            xmlXPathNodeSetAdd(newset, oldset->nodeTab[i]);
13746f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        }
13747f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
13748f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        /*
13749f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                         * Cleanup
13750f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                         */
13751a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik                        if (res != NULL) {
13752a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik			    xmlXPathReleaseObject(ctxt->context, res);
13753a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik			}
13754f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        if (ctxt->value == tmp) {
137555691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik                            valuePop(ctxt);
1375645490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard			    xmlXPathNodeSetClear(tmp->nodesetval, 1);
137575691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik			    /*
13758df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik			    * Don't free the temporary nodeset
137595691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik			    * in order to avoid massive recreation inside this
137605691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik			    * loop.
13761df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik			    */
137625691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik                        } else
13763a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik			    tmp = NULL;
13764f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        ctxt->context->node = NULL;
13765f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    }
137665691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		    if (tmp != NULL)
13767a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik			xmlXPathReleaseObject(ctxt->context, tmp);
13768f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    /*
13769f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                     * The result is used as the new evaluation set.
13770f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                     */
13771a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    xmlXPathReleaseObject(ctxt->context, obj);
13772f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    ctxt->context->node = NULL;
13773f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    ctxt->context->contextSize = -1;
13774f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    ctxt->context->proximityPosition = -1;
137753794b9e84ac51072830a0b34d1ddd0378c0f7cb6William M. Brack		    /* may want to move this past the '}' later */
137763794b9e84ac51072830a0b34d1ddd0378c0f7cb6William M. Brack		    ctxt->context->doc = oldDoc;
13777a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    valuePush(ctxt,
13778a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik			xmlXPathCacheWrapNodeSet(ctxt->context, newset));
13779f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                }
13780f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                ctxt->context->node = oldnode;
13781f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                return (total);
13782f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            }
13783f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        case XPATH_OP_SORT:
13784f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            if (op->ch1 != -1)
13785f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
13786556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard	    CHECK_ERROR0;
13787f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            if ((ctxt->value != NULL) &&
13788f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                (ctxt->value->type == XPATH_NODESET) &&
1378964f7e1a85fe9c973cf9b21cc0bd53efa6cc3dafcKasimier T. Buchcik                (ctxt->value->nodesetval != NULL) &&
1379064f7e1a85fe9c973cf9b21cc0bd53efa6cc3dafcKasimier T. Buchcik		(ctxt->value->nodesetval->nodeNr > 1))
13791a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    {
13792f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                xmlXPathNodeSetSort(ctxt->value->nodesetval);
13793a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    }
13794f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            return (total);
137959e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard#ifdef LIBXML_XPTR_ENABLED
13796f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        case XPATH_OP_RANGETO:{
13797f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                xmlXPathObjectPtr range;
13798f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                xmlXPathObjectPtr res, obj;
13799f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                xmlXPathObjectPtr tmp;
13800081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                xmlLocationSetPtr newlocset = NULL;
13801081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack		    xmlLocationSetPtr oldlocset;
13802f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                xmlNodeSetPtr oldset;
1380372ee48d55f9002544d011826e2897b5054b7e32cWilliam M. Brack                int i, j;
13804f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
13805f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                if (op->ch1 != -1)
13806f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    total +=
13807f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
13808f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                if (op->ch2 == -1)
13809f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    return (total);
13810f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
13811081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                if (ctxt->value->type == XPATH_LOCATIONSET) {
13812081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                    /*
13813081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                     * Extract the old locset, and then evaluate the result of the
13814081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                     * expression for all the element in the locset. use it to grow
13815081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                     * up a new locset.
13816081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                     */
13817081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                    CHECK_TYPE0(XPATH_LOCATIONSET);
13818081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                    obj = valuePop(ctxt);
13819081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                    oldlocset = obj->user;
13820f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
13821081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                    if ((oldlocset == NULL) || (oldlocset->locNr == 0)) {
1382272ee48d55f9002544d011826e2897b5054b7e32cWilliam M. Brack		        ctxt->context->node = NULL;
13823081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                        ctxt->context->contextSize = 0;
13824081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                        ctxt->context->proximityPosition = 0;
13825081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                        total += xmlXPathCompOpEval(ctxt,&comp->steps[op->ch2]);
13826081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                        res = valuePop(ctxt);
13827a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik                        if (res != NULL) {
13828a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik			    xmlXPathReleaseObject(ctxt->context, res);
13829a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik			}
13830081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                        valuePush(ctxt, obj);
13831081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                        CHECK_ERROR0;
13832081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                        return (total);
13833081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                    }
13834081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                    newlocset = xmlXPtrLocationSetCreate(NULL);
13835f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
13836081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                    for (i = 0; i < oldlocset->locNr; i++) {
13837f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        /*
13838081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                         * Run the evaluation with a node list made of a
13839081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                         * single item in the nodelocset.
13840f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                         */
13841f7eb794c142e31ca895f2d7743f872a809e514abWilliam M. Brack                        ctxt->context->node = oldlocset->locTab[i]->user;
13842f7eb794c142e31ca895f2d7743f872a809e514abWilliam M. Brack                        ctxt->context->contextSize = oldlocset->locNr;
13843f7eb794c142e31ca895f2d7743f872a809e514abWilliam M. Brack                        ctxt->context->proximityPosition = i + 1;
13844a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik			tmp = xmlXPathCacheNewNodeSet(ctxt->context,
13845a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik			    ctxt->context->node);
13846f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        valuePush(ctxt, tmp);
13847f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
13848f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        if (op->ch2 != -1)
13849f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                            total +=
13850f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                                xmlXPathCompOpEval(ctxt,
13851f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                                                   &comp->steps[op->ch2]);
138522c19a7bf2ee0f78485840cac50f2a989f5efe476William M. Brack			if (ctxt->error != XPATH_EXPRESSION_OK) {
138532c19a7bf2ee0f78485840cac50f2a989f5efe476William M. Brack			    xmlXPathFreeObject(obj);
138542c19a7bf2ee0f78485840cac50f2a989f5efe476William M. Brack			    return(0);
138552c19a7bf2ee0f78485840cac50f2a989f5efe476William M. Brack			}
13856f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
13857f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        res = valuePop(ctxt);
1385872ee48d55f9002544d011826e2897b5054b7e32cWilliam M. Brack			if (res->type == XPATH_LOCATIONSET) {
1385945490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard			    xmlLocationSetPtr rloc =
1386072ee48d55f9002544d011826e2897b5054b7e32cWilliam M. Brack			        (xmlLocationSetPtr)res->user;
1386172ee48d55f9002544d011826e2897b5054b7e32cWilliam M. Brack			    for (j=0; j<rloc->locNr; j++) {
1386272ee48d55f9002544d011826e2897b5054b7e32cWilliam M. Brack			        range = xmlXPtrNewRange(
1386372ee48d55f9002544d011826e2897b5054b7e32cWilliam M. Brack				  oldlocset->locTab[i]->user,
1386472ee48d55f9002544d011826e2897b5054b7e32cWilliam M. Brack				  oldlocset->locTab[i]->index,
1386572ee48d55f9002544d011826e2897b5054b7e32cWilliam M. Brack				  rloc->locTab[j]->user2,
1386672ee48d55f9002544d011826e2897b5054b7e32cWilliam M. Brack				  rloc->locTab[j]->index2);
1386772ee48d55f9002544d011826e2897b5054b7e32cWilliam M. Brack				if (range != NULL) {
1386872ee48d55f9002544d011826e2897b5054b7e32cWilliam M. Brack				    xmlXPtrLocationSetAdd(newlocset, range);
1386972ee48d55f9002544d011826e2897b5054b7e32cWilliam M. Brack				}
1387072ee48d55f9002544d011826e2897b5054b7e32cWilliam M. Brack			    }
1387172ee48d55f9002544d011826e2897b5054b7e32cWilliam M. Brack			} else {
1387272ee48d55f9002544d011826e2897b5054b7e32cWilliam M. Brack			    range = xmlXPtrNewRangeNodeObject(
1387372ee48d55f9002544d011826e2897b5054b7e32cWilliam M. Brack				(xmlNodePtr)oldlocset->locTab[i]->user, res);
1387472ee48d55f9002544d011826e2897b5054b7e32cWilliam M. Brack                            if (range != NULL) {
1387572ee48d55f9002544d011826e2897b5054b7e32cWilliam M. Brack                                xmlXPtrLocationSetAdd(newlocset,range);
1387672ee48d55f9002544d011826e2897b5054b7e32cWilliam M. Brack			    }
13877f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        }
13878f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
13879f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        /*
13880f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                         * Cleanup
13881f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                         */
13882a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik                        if (res != NULL) {
13883a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik			    xmlXPathReleaseObject(ctxt->context, res);
13884a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik			}
13885f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        if (ctxt->value == tmp) {
13886f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                            res = valuePop(ctxt);
13887a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik			    xmlXPathReleaseObject(ctxt->context, res);
13888f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        }
13889f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
13890f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        ctxt->context->node = NULL;
13891f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    }
1389272ee48d55f9002544d011826e2897b5054b7e32cWilliam M. Brack		} else {	/* Not a location set */
13893081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                    CHECK_TYPE0(XPATH_NODESET);
13894081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                    obj = valuePop(ctxt);
13895081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                    oldset = obj->nodesetval;
13896081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                    ctxt->context->node = NULL;
13897081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack
13898081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                    newlocset = xmlXPtrLocationSetCreate(NULL);
13899081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack
13900081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                    if (oldset != NULL) {
13901081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                        for (i = 0; i < oldset->nodeNr; i++) {
13902081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                            /*
13903081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                             * Run the evaluation with a node list made of a single item
13904081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                             * in the nodeset.
13905081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                             */
13906081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                            ctxt->context->node = oldset->nodeTab[i];
13907a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik			    /*
13908a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik			    * OPTIMIZE TODO: Avoid recreation for every iteration.
13909a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik			    */
13910a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik			    tmp = xmlXPathCacheNewNodeSet(ctxt->context,
13911a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik				ctxt->context->node);
13912081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                            valuePush(ctxt, tmp);
13913081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack
13914081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                            if (op->ch2 != -1)
13915081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                                total +=
13916081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                                    xmlXPathCompOpEval(ctxt,
13917081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                                                   &comp->steps[op->ch2]);
139182c19a7bf2ee0f78485840cac50f2a989f5efe476William M. Brack			    if (ctxt->error != XPATH_EXPRESSION_OK) {
139192c19a7bf2ee0f78485840cac50f2a989f5efe476William M. Brack				xmlXPathFreeObject(obj);
139202c19a7bf2ee0f78485840cac50f2a989f5efe476William M. Brack				return(0);
139212c19a7bf2ee0f78485840cac50f2a989f5efe476William M. Brack			    }
13922081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack
13923081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                            res = valuePop(ctxt);
13924081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                            range =
13925081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                                xmlXPtrNewRangeNodeObject(oldset->nodeTab[i],
13926081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                                                      res);
13927081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                            if (range != NULL) {
13928081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                                xmlXPtrLocationSetAdd(newlocset, range);
13929081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                            }
13930081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack
13931081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                            /*
13932081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                             * Cleanup
13933081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                             */
13934a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik                            if (res != NULL) {
13935a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik				xmlXPathReleaseObject(ctxt->context, res);
13936a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik			    }
13937081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                            if (ctxt->value == tmp) {
13938081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                                res = valuePop(ctxt);
13939a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik				xmlXPathReleaseObject(ctxt->context, res);
13940081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                            }
13941081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack
13942081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                            ctxt->context->node = NULL;
13943081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                        }
13944081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                    }
13945f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                }
13946f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
13947f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                /*
13948f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                 * The result is used as the new evaluation set.
13949f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                 */
13950a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		xmlXPathReleaseObject(ctxt->context, obj);
13951f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                ctxt->context->node = NULL;
13952f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                ctxt->context->contextSize = -1;
13953f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                ctxt->context->proximityPosition = -1;
13954081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                valuePush(ctxt, xmlXPtrWrapLocationSet(newlocset));
13955f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                return (total);
13956f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            }
139579e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard#endif /* LIBXML_XPTR_ENABLED */
139589e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    }
139599e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    xmlGenericError(xmlGenericErrorContext,
13960f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    "XPath: unknown precompiled operation %d\n", op->op);
13961f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    return (total);
139629e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard}
139639e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
13964631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik/**
13965631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik * xmlXPathCompOpEvalToBoolean:
13966631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik * @ctxt:  the XPath parser context
13967631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik *
13968631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik * Evaluates if the expression evaluates to true.
13969631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik *
13970631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik * Returns 1 if true, 0 if false and -1 on API or internal errors.
13971631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik */
13972631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcikstatic int
13973631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. BuchcikxmlXPathCompOpEvalToBoolean(xmlXPathParserContextPtr ctxt,
13974324c75b3c3edffcd30e7afa2a32f0d83d928b10dKasimier T. Buchcik			    xmlXPathStepOpPtr op,
13975324c75b3c3edffcd30e7afa2a32f0d83d928b10dKasimier T. Buchcik			    int isPredicate)
13976631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik{
13977324c75b3c3edffcd30e7afa2a32f0d83d928b10dKasimier T. Buchcik    xmlXPathObjectPtr resObj = NULL;
13978631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik
13979631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcikstart:
13980631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik    /* comp = ctxt->comp; */
13981631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik    switch (op->op) {
13982631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik        case XPATH_OP_END:
13983631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik            return (0);
13984631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	case XPATH_OP_VALUE:
13985324c75b3c3edffcd30e7afa2a32f0d83d928b10dKasimier T. Buchcik	    resObj = (xmlXPathObjectPtr) op->value4;
139862bdb12ff9fdb69169604fdf544e1026b2459aca1Kasimier T. Buchcik	    if (isPredicate)
139872bdb12ff9fdb69169604fdf544e1026b2459aca1Kasimier T. Buchcik		return(xmlXPathEvaluatePredicateResult(ctxt, resObj));
139882bdb12ff9fdb69169604fdf544e1026b2459aca1Kasimier T. Buchcik	    return(xmlXPathCastToBoolean(resObj));
13989631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	case XPATH_OP_SORT:
13990631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    /*
13991631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    * We don't need sorting for boolean results. Skip this one.
13992631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    */
13993631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik            if (op->ch1 != -1) {
13994631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik		op = &ctxt->comp->steps[op->ch1];
13995631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik		goto start;
13996631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    }
13997631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    return(0);
13998324c75b3c3edffcd30e7afa2a32f0d83d928b10dKasimier T. Buchcik	case XPATH_OP_COLLECT:
13999631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    if (op->ch1 == -1)
14000631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik		return(0);
14001631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik
14002631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik            xmlXPathCompOpEval(ctxt, &ctxt->comp->steps[op->ch1]);
14003631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    if (ctxt->error != XPATH_EXPRESSION_OK)
14004631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik		return(-1);
14005631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik
14006631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik            xmlXPathNodeCollectAndTest(ctxt, op, NULL, NULL, 1);
14007631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    if (ctxt->error != XPATH_EXPRESSION_OK)
14008631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik		return(-1);
14009631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik
14010631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    resObj = valuePop(ctxt);
14011631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    if (resObj == NULL)
14012631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik		return(-1);
14013324c75b3c3edffcd30e7afa2a32f0d83d928b10dKasimier T. Buchcik	    break;
14014324c75b3c3edffcd30e7afa2a32f0d83d928b10dKasimier T. Buchcik	default:
14015631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    /*
14016631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    * Fallback to call xmlXPathCompOpEval().
14017631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    */
14018631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    xmlXPathCompOpEval(ctxt, op);
14019631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    if (ctxt->error != XPATH_EXPRESSION_OK)
14020631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik		return(-1);
1402145490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
14022631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    resObj = valuePop(ctxt);
14023631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    if (resObj == NULL)
140242bdb12ff9fdb69169604fdf544e1026b2459aca1Kasimier T. Buchcik		return(-1);
14025324c75b3c3edffcd30e7afa2a32f0d83d928b10dKasimier T. Buchcik	    break;
14026324c75b3c3edffcd30e7afa2a32f0d83d928b10dKasimier T. Buchcik    }
14027324c75b3c3edffcd30e7afa2a32f0d83d928b10dKasimier T. Buchcik
14028324c75b3c3edffcd30e7afa2a32f0d83d928b10dKasimier T. Buchcik    if (resObj) {
14029324c75b3c3edffcd30e7afa2a32f0d83d928b10dKasimier T. Buchcik	int res;
14030324c75b3c3edffcd30e7afa2a32f0d83d928b10dKasimier T. Buchcik
14031324c75b3c3edffcd30e7afa2a32f0d83d928b10dKasimier T. Buchcik	if (resObj->type == XPATH_BOOLEAN) {
14032324c75b3c3edffcd30e7afa2a32f0d83d928b10dKasimier T. Buchcik	    res = resObj->boolval;
14033324c75b3c3edffcd30e7afa2a32f0d83d928b10dKasimier T. Buchcik	} else if (isPredicate) {
14034631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    /*
14035324c75b3c3edffcd30e7afa2a32f0d83d928b10dKasimier T. Buchcik	    * For predicates a result of type "number" is handled
14036324c75b3c3edffcd30e7afa2a32f0d83d928b10dKasimier T. Buchcik	    * differently:
14037324c75b3c3edffcd30e7afa2a32f0d83d928b10dKasimier T. Buchcik	    * SPEC XPath 1.0:
14038324c75b3c3edffcd30e7afa2a32f0d83d928b10dKasimier T. Buchcik	    * "If the result is a number, the result will be converted
14039324c75b3c3edffcd30e7afa2a32f0d83d928b10dKasimier T. Buchcik	    *  to true if the number is equal to the context position
14040324c75b3c3edffcd30e7afa2a32f0d83d928b10dKasimier T. Buchcik	    *  and will be converted to false otherwise;"
14041631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    */
1404245490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	    res = xmlXPathEvaluatePredicateResult(ctxt, resObj);
14043324c75b3c3edffcd30e7afa2a32f0d83d928b10dKasimier T. Buchcik	} else {
14044324c75b3c3edffcd30e7afa2a32f0d83d928b10dKasimier T. Buchcik	    res = xmlXPathCastToBoolean(resObj);
14045631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	}
14046324c75b3c3edffcd30e7afa2a32f0d83d928b10dKasimier T. Buchcik	xmlXPathReleaseObject(ctxt->context, resObj);
14047324c75b3c3edffcd30e7afa2a32f0d83d928b10dKasimier T. Buchcik	return(res);
14048631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik    }
14049324c75b3c3edffcd30e7afa2a32f0d83d928b10dKasimier T. Buchcik
14050631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik    return(0);
14051631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik}
14052631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik
1405356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard#ifdef XPATH_STREAMING
1405456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard/**
1405556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard * xmlXPathRunStreamEval:
1405656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard * @ctxt:  the XPath parser context with the compiled expression
1405756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard *
1405856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard * Evaluate the Precompiled Streamable XPath expression in the given context.
1405956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard */
14060631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcikstatic int
14061631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. BuchcikxmlXPathRunStreamEval(xmlXPathContextPtr ctxt, xmlPatternPtr comp,
14062631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik		      xmlXPathObjectPtr *resultSeq, int toBool)
14063631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik{
14064f03a8cdacdce917d09972c65371953e8a57a2ac3Daniel Veillard    int max_depth, min_depth;
1406545490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard    int from_root;
1406656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard    int ret, depth;
1406797258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik    int eval_all_nodes;
1406812d37ab63441baf9e03db70168cc1d0d6f1c2373William M. Brack    xmlNodePtr cur = NULL, limit = NULL;
140698af1f0bb83cfc3f57fd5637dcfce28c95eb99638Kasimier T. Buchcik    xmlStreamCtxtPtr patstream = NULL;
1407045490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
1407145490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard    int nb_nodes = 0;
1407256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard
1407356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard    if ((ctxt == NULL) || (comp == NULL))
14074631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik        return(-1);
1407556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard    max_depth = xmlPatternMaxDepth(comp);
1407656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard    if (max_depth == -1)
14077631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik        return(-1);
1407856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard    if (max_depth == -2)
1407956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard        max_depth = 10000;
14080f03a8cdacdce917d09972c65371953e8a57a2ac3Daniel Veillard    min_depth = xmlPatternMinDepth(comp);
14081f03a8cdacdce917d09972c65371953e8a57a2ac3Daniel Veillard    if (min_depth == -1)
14082631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik        return(-1);
1408356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard    from_root = xmlPatternFromRoot(comp);
1408456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard    if (from_root < 0)
14085631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik        return(-1);
14086fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard#if 0
14087fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard    printf("stream eval: depth %d from root %d\n", max_depth, from_root);
14088fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard#endif
1408956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard
14090631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik    if (! toBool) {
14091631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	if (resultSeq == NULL)
14092631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    return(-1);
14093631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	*resultSeq = xmlXPathCacheNewNodeSet(ctxt, NULL);
14094631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	if (*resultSeq == NULL)
14095631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    return(-1);
14096631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik    }
1409745490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
14098f03a8cdacdce917d09972c65371953e8a57a2ac3Daniel Veillard    /*
140998af1f0bb83cfc3f57fd5637dcfce28c95eb99638Kasimier T. Buchcik     * handle the special cases of "/" amd "." being matched
14100f03a8cdacdce917d09972c65371953e8a57a2ac3Daniel Veillard     */
14101f03a8cdacdce917d09972c65371953e8a57a2ac3Daniel Veillard    if (min_depth == 0) {
14102f03a8cdacdce917d09972c65371953e8a57a2ac3Daniel Veillard	if (from_root) {
141038af1f0bb83cfc3f57fd5637dcfce28c95eb99638Kasimier T. Buchcik	    /* Select "/" */
14104631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    if (toBool)
14105631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik		return(1);
14106631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    xmlXPathNodeSetAddUnique((*resultSeq)->nodesetval,
14107631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik		(xmlNodePtr) ctxt->doc);
14108f03a8cdacdce917d09972c65371953e8a57a2ac3Daniel Veillard	} else {
141098af1f0bb83cfc3f57fd5637dcfce28c95eb99638Kasimier T. Buchcik	    /* Select "self::node()" */
14110631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    if (toBool)
14111631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik		return(1);
14112631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    xmlXPathNodeSetAddUnique((*resultSeq)->nodesetval, ctxt->node);
14113f03a8cdacdce917d09972c65371953e8a57a2ac3Daniel Veillard	}
14114f03a8cdacdce917d09972c65371953e8a57a2ac3Daniel Veillard    }
14115f03a8cdacdce917d09972c65371953e8a57a2ac3Daniel Veillard    if (max_depth == 0) {
14116631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	return(0);
1411756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard    }
14118f03a8cdacdce917d09972c65371953e8a57a2ac3Daniel Veillard
1411956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard    if (from_root) {
1412012d37ab63441baf9e03db70168cc1d0d6f1c2373William M. Brack        cur = (xmlNodePtr)ctxt->doc;
1412156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard    } else if (ctxt->node != NULL) {
1412256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard        switch (ctxt->node->type) {
1412356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard            case XML_ELEMENT_NODE:
1412456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard            case XML_DOCUMENT_NODE:
1412556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard            case XML_DOCUMENT_FRAG_NODE:
1412656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard            case XML_HTML_DOCUMENT_NODE:
1412756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard#ifdef LIBXML_DOCB_ENABLED
1412856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard            case XML_DOCB_DOCUMENT_NODE:
1412956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard#endif
1413056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	        cur = ctxt->node;
1413156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard		break;
1413256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard            case XML_ATTRIBUTE_NODE:
1413356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard            case XML_TEXT_NODE:
1413456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard            case XML_CDATA_SECTION_NODE:
1413556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard            case XML_ENTITY_REF_NODE:
1413656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard            case XML_ENTITY_NODE:
1413756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard            case XML_PI_NODE:
1413856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard            case XML_COMMENT_NODE:
1413956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard            case XML_NOTATION_NODE:
1414056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard            case XML_DTD_NODE:
1414156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard            case XML_DOCUMENT_TYPE_NODE:
1414256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard            case XML_ELEMENT_DECL:
1414356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard            case XML_ATTRIBUTE_DECL:
1414456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard            case XML_ENTITY_DECL:
1414556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard            case XML_NAMESPACE_DECL:
1414656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard            case XML_XINCLUDE_START:
1414756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard            case XML_XINCLUDE_END:
1414856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard		break;
1414956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	}
1415056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	limit = cur;
1415156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard    }
14152631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik    if (cur == NULL) {
14153631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik        return(0);
14154631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik    }
1415556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard
1415656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard    patstream = xmlPatternGetStreamCtxt(comp);
1415756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard    if (patstream == NULL) {
14158631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	/*
14159631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	* QUESTION TODO: Is this an error?
14160631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	*/
14161631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	return(0);
1416256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard    }
1416356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard
1416497258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik    eval_all_nodes = xmlStreamWantsAnyNode(patstream);
1416597258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik
1416656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard    if (from_root) {
1416756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	ret = xmlStreamPush(patstream, NULL, NULL);
1416856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	if (ret < 0) {
1416956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	} else if (ret == 1) {
14170631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    if (toBool)
141718af1f0bb83cfc3f57fd5637dcfce28c95eb99638Kasimier T. Buchcik		goto return_1;
14172631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    xmlXPathNodeSetAddUnique((*resultSeq)->nodesetval, cur);
1417356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	}
1417456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard    }
1417556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard    depth = 0;
1417656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard    goto scan_children;
1417756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillardnext_node:
14178d3ff7ef6d3247872b1231718bdf1773c16d88806Daniel Veillard    do {
1417956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard        nb_nodes++;
1418097258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik
1418197258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik	switch (cur->type) {
1418297258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik	    case XML_ELEMENT_NODE:
1418397258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik	    case XML_TEXT_NODE:
1418497258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik	    case XML_CDATA_SECTION_NODE:
1418597258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik	    case XML_COMMENT_NODE:
14186631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    case XML_PI_NODE:
1418797258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik		if (cur->type == XML_ELEMENT_NODE) {
1418897258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik		    ret = xmlStreamPush(patstream, cur->name,
1418956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard				(cur->ns ? cur->ns->href : NULL));
14190631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik		} else if (eval_all_nodes)
1419197258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik		    ret = xmlStreamPushNode(patstream, NULL, NULL, cur->type);
1419297258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik		else
1419397258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik		    break;
1419445490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
1419597258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik		if (ret < 0) {
1419697258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik		    /* NOP. */
1419797258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik		} else if (ret == 1) {
14198631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik		    if (toBool)
141998af1f0bb83cfc3f57fd5637dcfce28c95eb99638Kasimier T. Buchcik			goto return_1;
14200631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik		    xmlXPathNodeSetAddUnique((*resultSeq)->nodesetval, cur);
1420197258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik		}
1420297258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik		if ((cur->children == NULL) || (depth >= max_depth)) {
1420397258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik		    ret = xmlStreamPop(patstream);
1420497258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik		    while (cur->next != NULL) {
1420597258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik			cur = cur->next;
1420697258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik			if ((cur->type != XML_ENTITY_DECL) &&
1420797258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik			    (cur->type != XML_DTD_NODE))
1420897258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik			    goto next_node;
1420997258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik		    }
1421097258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik		}
1421197258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik	    default:
1421297258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik		break;
14213631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	}
14214631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik
1421556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillardscan_children:
1421656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	if ((cur->children != NULL) && (depth < max_depth)) {
1421756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	    /*
1421845490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	     * Do not descend on entities declarations
1421956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	     */
1422056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	    if (cur->children->type != XML_ENTITY_DECL) {
1422156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard		cur = cur->children;
1422256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard		depth++;
1422356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard		/*
1422456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard		 * Skip DTDs
1422556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard		 */
1422656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard		if (cur->type != XML_DTD_NODE)
1422756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard		    continue;
1422856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	    }
1422956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	}
1423056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard
1423156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	if (cur == limit)
1423256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	    break;
1423356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard
1423456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	while (cur->next != NULL) {
1423556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	    cur = cur->next;
1423656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	    if ((cur->type != XML_ENTITY_DECL) &&
1423756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard		(cur->type != XML_DTD_NODE))
1423856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard		goto next_node;
1423956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	}
1424045490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
1424156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	do {
1424256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	    cur = cur->parent;
1424356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	    depth--;
1424456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	    if ((cur == NULL) || (cur == limit))
1424556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	        goto done;
1424697258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik	    if (cur->type == XML_ELEMENT_NODE) {
1424797258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik		ret = xmlStreamPop(patstream);
14248631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    } else if ((eval_all_nodes) &&
1424997258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik		((cur->type == XML_TEXT_NODE) ||
1425097258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik		 (cur->type == XML_CDATA_SECTION_NODE) ||
1425197258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik		 (cur->type == XML_COMMENT_NODE) ||
1425297258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik		 (cur->type == XML_PI_NODE)))
1425397258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik	    {
1425497258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik		ret = xmlStreamPop(patstream);
1425597258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik	    }
1425656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	    if (cur->next != NULL) {
1425756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard		cur = cur->next;
1425856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard		break;
1425956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	    }
1426056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	} while (cur != NULL);
1426156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard
1426256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard    } while ((cur != NULL) && (depth >= 0));
14263631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik
1426456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillarddone:
14265631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik
14266fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard#if 0
14267fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard    printf("stream eval: checked %d nodes selected %d\n",
14268631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik           nb_nodes, retObj->nodesetval->nodeNr);
14269fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard#endif
14270631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik
142718af1f0bb83cfc3f57fd5637dcfce28c95eb99638Kasimier T. Buchcik    if (patstream)
142728af1f0bb83cfc3f57fd5637dcfce28c95eb99638Kasimier T. Buchcik	xmlFreeStreamCtxt(patstream);
14273631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik    return(0);
142748af1f0bb83cfc3f57fd5637dcfce28c95eb99638Kasimier T. Buchcik
142758af1f0bb83cfc3f57fd5637dcfce28c95eb99638Kasimier T. Buchcikreturn_1:
142768af1f0bb83cfc3f57fd5637dcfce28c95eb99638Kasimier T. Buchcik    if (patstream)
142778af1f0bb83cfc3f57fd5637dcfce28c95eb99638Kasimier T. Buchcik	xmlFreeStreamCtxt(patstream);
142788af1f0bb83cfc3f57fd5637dcfce28c95eb99638Kasimier T. Buchcik    return(1);
1427956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard}
1428056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard#endif /* XPATH_STREAMING */
1428156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard
142829e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard/**
142839e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * xmlXPathRunEval:
142849e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * @ctxt:  the XPath parser context with the compiled expression
14285631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik * @toBool:  evaluate to a boolean result
142869e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard *
142879e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * Evaluate the Precompiled XPath expression in the given context.
142889e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard */
14289631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcikstatic int
14290631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. BuchcikxmlXPathRunEval(xmlXPathParserContextPtr ctxt, int toBool)
14291631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik{
142929e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    xmlXPathCompExprPtr comp;
142939e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
142949e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    if ((ctxt == NULL) || (ctxt->comp == NULL))
14295631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	return(-1);
142969e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
142979e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    if (ctxt->valueTab == NULL) {
142989e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	/* Allocate the value stack */
1429945490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	ctxt->valueTab = (xmlXPathObjectPtr *)
143009e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard			 xmlMalloc(10 * sizeof(xmlXPathObjectPtr));
143019e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	if (ctxt->valueTab == NULL) {
14302d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard	    xmlXPathPErrMemory(ctxt, "creating evaluation context\n");
143039e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    xmlFree(ctxt);
143049e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	}
143059e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	ctxt->valueNr = 0;
143069e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	ctxt->valueMax = 10;
143079e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	ctxt->value = NULL;
143089e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    }
1430956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard#ifdef XPATH_STREAMING
1431056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard    if (ctxt->comp->stream) {
14311631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	int res;
14312631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik
14313631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	if (toBool) {
14314631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    /*
14315631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    * Evaluation to boolean result.
14316631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    */
14317631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    res = xmlXPathRunStreamEval(ctxt->context,
14318631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik		ctxt->comp->stream, NULL, 1);
14319631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    if (res != -1)
14320631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik		return(res);
14321631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	} else {
1432245490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	    xmlXPathObjectPtr resObj = NULL;
14323631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik
14324631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    /*
14325631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    * Evaluation to a sequence.
14326631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    */
14327631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    res = xmlXPathRunStreamEval(ctxt->context,
14328631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik		ctxt->comp->stream, &resObj, 0);
14329631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik
14330631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    if ((res != -1) && (resObj != NULL)) {
14331631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik		valuePush(ctxt, resObj);
14332631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik		return(0);
14333631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    }
14334631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    if (resObj != NULL)
1433545490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard		xmlXPathReleaseObject(ctxt->context, resObj);
1433656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	}
14337631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	/*
14338631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	* QUESTION TODO: This falls back to normal XPath evaluation
14339631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	* if res == -1. Is this intended?
14340631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	*/
1434156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard    }
1434256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard#endif
143439e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    comp = ctxt->comp;
14344631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik    if (comp->last < 0) {
1434529b6f76c5326616aed5dcff9cb55145137863e97Aleksey Sanin	xmlGenericError(xmlGenericErrorContext,
1434629b6f76c5326616aed5dcff9cb55145137863e97Aleksey Sanin	    "xmlXPathRunEval: last is less than zero\n");
14347631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	return(-1);
1434829b6f76c5326616aed5dcff9cb55145137863e97Aleksey Sanin    }
14349631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik    if (toBool)
14350324c75b3c3edffcd30e7afa2a32f0d83d928b10dKasimier T. Buchcik	return(xmlXPathCompOpEvalToBoolean(ctxt,
14351324c75b3c3edffcd30e7afa2a32f0d83d928b10dKasimier T. Buchcik	    &comp->steps[comp->last], 0));
14352631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik    else
14353631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	xmlXPathCompOpEval(ctxt, &comp->steps[comp->last]);
14354631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik
14355631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik    return(0);
143569e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard}
143579e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
14358afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard/************************************************************************
14359afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard *									*
1436045490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *			Public interfaces				*
14361afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard *									*
14362afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard ************************************************************************/
14363afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard
14364afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard/**
14365fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * xmlXPathEvalPredicate:
14366fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * @ctxt:  the XPath context
14367fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * @res:  the Predicate Expression evaluation result
14368fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard *
14369fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * Evaluate a predicate result for the current node.
14370fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * A PredicateExpr is evaluated by evaluating the Expr and converting
14371fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * the result to a boolean. If the result is a number, the result will
14372fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * be converted to true if the number is equal to the position of the
14373fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * context node in the context node list (as returned by the position
14374fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * function) and will be converted to false otherwise; if the result
14375fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * is not a number, then the result will be converted as if by a call
1437645490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard * to the boolean function.
14377fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard *
14378cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * Returns 1 if predicate is true, 0 otherwise
14379fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard */
14380fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillardint
14381fbf8a2d0c8145b713099df63d174154a8442e60dDaniel VeillardxmlXPathEvalPredicate(xmlXPathContextPtr ctxt, xmlXPathObjectPtr res) {
14382ce682bc24b79f1dd29b781d4c17f9bf169ce7e32Daniel Veillard    if ((ctxt == NULL) || (res == NULL)) return(0);
14383fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard    switch (res->type) {
14384fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard        case XPATH_BOOLEAN:
14385fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard	    return(res->boolval);
14386fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard        case XPATH_NUMBER:
14387fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard	    return(res->floatval == ctxt->proximityPosition);
14388fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard        case XPATH_NODESET:
14389fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard        case XPATH_XSLT_TREE:
14390d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	    if (res->nodesetval == NULL)
14391d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard		return(0);
14392fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard	    return(res->nodesetval->nodeNr != 0);
14393fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard        case XPATH_STRING:
14394fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard	    return((res->stringval != NULL) &&
14395fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard	           (xmlStrlen(res->stringval) != 0));
14396fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard        default:
14397fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard	    STRANGE
14398fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard    }
14399fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard    return(0);
14400fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard}
14401fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard
14402fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard/**
14403afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathEvaluatePredicateResult:
14404afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * @ctxt:  the XPath Parser context
14405afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * @res:  the Predicate Expression evaluation result
14406afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard *
14407afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Evaluate a predicate result for the current node.
14408afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * A PredicateExpr is evaluated by evaluating the Expr and converting
14409afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * the result to a boolean. If the result is a number, the result will
14410afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * be converted to true if the number is equal to the position of the
14411afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * context node in the context node list (as returned by the position
14412afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * function) and will be converted to false otherwise; if the result
14413afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * is not a number, then the result will be converted as if by a call
1441445490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard * to the boolean function.
14415afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard *
14416cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * Returns 1 if predicate is true, 0 otherwise
14417afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard */
14418afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardint
1441945490aebe7a60704e8ed850c498969858ab900eeDaniel VeillardxmlXPathEvaluatePredicateResult(xmlXPathParserContextPtr ctxt,
14420afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard                                xmlXPathObjectPtr res) {
14421ce682bc24b79f1dd29b781d4c17f9bf169ce7e32Daniel Veillard    if ((ctxt == NULL) || (res == NULL)) return(0);
14422afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard    switch (res->type) {
14423afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard        case XPATH_BOOLEAN:
14424afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard	    return(res->boolval);
14425afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard        case XPATH_NUMBER:
144269ea6231ecef04c848b688355b8f7532dd5e4c6f8Daniel Veillard#if defined(__BORLANDC__) || (defined(_MSC_VER) && (_MSC_VER == 1200))
144277c4eb63bb01d754b17860cd7dc2ab2fef81f6a08Daniel Veillard	    return((res->floatval == ctxt->context->proximityPosition) &&
144287c4eb63bb01d754b17860cd7dc2ab2fef81f6a08Daniel Veillard	           (!xmlXPathIsNaN(res->floatval))); /* MSC pbm Mark Vakoc !*/
144292582a338bff77569b5aadbba8f40e1f3862d090dDaniel Veillard#else
14430afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard	    return(res->floatval == ctxt->context->proximityPosition);
144312582a338bff77569b5aadbba8f40e1f3862d090dDaniel Veillard#endif
14432afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard        case XPATH_NODESET:
14433afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard        case XPATH_XSLT_TREE:
1443473639a73c5a51c3739595f54c338bb531c1319c2Daniel Veillard	    if (res->nodesetval == NULL)
14435911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard		return(0);
14436afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard	    return(res->nodesetval->nodeNr != 0);
14437afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard        case XPATH_STRING:
14438631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    return((res->stringval != NULL) && (res->stringval[0] != 0));
14439081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack#ifdef LIBXML_XPTR_ENABLED
14440081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack	case XPATH_LOCATIONSET:{
14441081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack	    xmlLocationSetPtr ptr = res->user;
14442081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack	    if (ptr == NULL)
14443081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack	        return(0);
14444081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack	    return (ptr->locNr != 0);
14445081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack	    }
14446081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack#endif
14447afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard        default:
14448afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard	    STRANGE
14449afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard    }
14450afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard    return(0);
14451afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard}
14452afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard
1445356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard#ifdef XPATH_STREAMING
1445456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard/**
1445556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard * xmlXPathTryStreamCompile:
1445656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard * @ctxt: an XPath context
1445756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard * @str:  the XPath expression
1445856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard *
1445956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard * Try to compile the XPath expression as a streamable subset.
1446056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard *
1446156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard * Returns the compiled expression or NULL if failed to compile.
1446256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard */
1446356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillardstatic xmlXPathCompExprPtr
1446456de87ee0d147d04a041eb1ec95048566375bc3fDaniel VeillardxmlXPathTryStreamCompile(xmlXPathContextPtr ctxt, const xmlChar *str) {
1446556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard    /*
1446656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard     * Optimization: use streaming patterns when the XPath expression can
1446756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard     * be compiled to a stream lookup
1446856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard     */
1446956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard    xmlPatternPtr stream;
1447056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard    xmlXPathCompExprPtr comp;
1447156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard    xmlDictPtr dict = NULL;
1447256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard    const xmlChar **namespaces = NULL;
1447356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard    xmlNsPtr ns;
1447456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard    int i, j;
1447556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard
1447656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard    if ((!xmlStrchr(str, '[')) && (!xmlStrchr(str, '(')) &&
1447756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard        (!xmlStrchr(str, '@'))) {
144781f33c4d61f3cc9820643ef726b373ec3044bcac3Daniel Veillard	const xmlChar *tmp;
144791f33c4d61f3cc9820643ef726b373ec3044bcac3Daniel Veillard
144801f33c4d61f3cc9820643ef726b373ec3044bcac3Daniel Veillard	/*
144816ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik	 * We don't try to handle expressions using the verbose axis
144826ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik	 * specifiers ("::"), just the simplied form at this point.
144836ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik	 * Additionally, if there is no list of namespaces available and
144846ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik	 *  there's a ":" in the expression, indicating a prefixed QName,
144856ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik	 *  then we won't try to compile either. xmlPatterncompile() needs
144866ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik	 *  to have a list of namespaces at compilation time in order to
144876ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik	 *  compile prefixed name tests.
144881f33c4d61f3cc9820643ef726b373ec3044bcac3Daniel Veillard	 */
144891f33c4d61f3cc9820643ef726b373ec3044bcac3Daniel Veillard	tmp = xmlStrchr(str, ':');
144906ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik	if ((tmp != NULL) &&
144916ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik	    ((ctxt == NULL) || (ctxt->nsNr == 0) || (tmp[1] == ':')))
1449245490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	    return(NULL);
144931f33c4d61f3cc9820643ef726b373ec3044bcac3Daniel Veillard
1449456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	if (ctxt != NULL) {
1449556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	    dict = ctxt->dict;
1449656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	    if (ctxt->nsNr > 0) {
14497dbfe05aff4d242e31fcd7621a4901a6fa10b988eDaniel Veillard		namespaces = xmlMalloc(2 * (ctxt->nsNr + 1) * sizeof(xmlChar*));
1449856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard		if (namespaces == NULL) {
1449956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard		    xmlXPathErrMemory(ctxt, "allocating namespaces array\n");
1450056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard		    return(NULL);
1450156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard		}
1450256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard		for (i = 0, j = 0; (j < ctxt->nsNr); j++) {
1450356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard		    ns = ctxt->namespaces[j];
1450456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard		    namespaces[i++] = ns->href;
1450556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard		    namespaces[i++] = ns->prefix;
1450656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard		}
1450756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard		namespaces[i++] = NULL;
1450856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard		namespaces[i++] = NULL;
1450956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	    }
1451056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	}
1451156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard
14512ea152c05b3f3d9e47b282b88ffdb16fcb8c779c1William M. Brack	stream = xmlPatterncompile(str, dict, XML_PATTERN_XPATH,
14513ea152c05b3f3d9e47b282b88ffdb16fcb8c779c1William M. Brack			&namespaces[0]);
145146ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik	if (namespaces != NULL) {
145156ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik	    xmlFree((xmlChar **)namespaces);
1451645490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	}
1451756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	if ((stream != NULL) && (xmlPatternStreamable(stream) == 1)) {
1451856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	    comp = xmlXPathNewCompExpr();
1451956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	    if (comp == NULL) {
1452056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard		xmlXPathErrMemory(ctxt, "allocating streamable expression\n");
1452156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard		return(NULL);
1452256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	    }
1452356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	    comp->stream = stream;
1452456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	    comp->dict = dict;
1452556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	    if (comp->dict)
1452656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard		xmlDictReference(comp->dict);
1452756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	    return(comp);
1452856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	}
1452956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	xmlFreePattern(stream);
1453056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard    }
1453156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard    return(NULL);
1453256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard}
1453356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard#endif /* XPATH_STREAMING */
1453456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard
14535df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcikstatic int
14536df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. BuchcikxmlXPathCanRewriteDosExpression(xmlChar *expr)
14537df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik{
14538df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik    if (expr == NULL)
14539df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik	return(0);
14540df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik    do {
14541df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik        if ((*expr == '/') && (*(++expr) == '/'))
14542df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik	    return(1);
14543df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik    } while (*expr++);
14544df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik    return(0);
14545df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik}
14546df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcikstatic void
14547df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. BuchcikxmlXPathRewriteDOSExpression(xmlXPathCompExprPtr comp, xmlXPathStepOpPtr op)
14548df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik{
14549df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik    /*
14550df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik    * Try to rewrite "descendant-or-self::node()/foo" to an optimized
14551df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik    * internal representation.
14552df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik    */
14553df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik    if (op->ch1 != -1) {
14554df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik	if ((op->op == XPATH_OP_COLLECT /* 11 */) &&
1455545490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	    ((xmlXPathAxisVal) op->value == AXIS_CHILD /* 4 */) &&
14556df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik	    ((xmlXPathTestVal) op->value2 == NODE_TEST_NAME /* 5 */) &&
14557df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik	    ((xmlXPathTypeVal) op->value3 == NODE_TYPE_NODE /* 0 */))
14558df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik	{
14559df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik	    /*
145609bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    * This is a "child::foo"
14561df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik	    */
1456245490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	    xmlXPathStepOpPtr prevop = &comp->steps[op->ch1];
14563df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik
14564df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik	    if ((prevop->op == XPATH_OP_COLLECT /* 11 */) &&
1456545490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard		(prevop->ch1 != -1) &&
14566df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		((xmlXPathAxisVal) prevop->value ==
14567df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		    AXIS_DESCENDANT_OR_SELF) &&
14568df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		(prevop->ch2 == -1) &&
14569df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		((xmlXPathTestVal) prevop->value2 == NODE_TEST_TYPE) &&
14570080152c9017a0ee4b97149d54f85fea3ab348b6dKasimier T. Buchcik		((xmlXPathTypeVal) prevop->value3 == NODE_TYPE_NODE) &&
14571080152c9017a0ee4b97149d54f85fea3ab348b6dKasimier T. Buchcik		(comp->steps[prevop->ch1].op == XPATH_OP_ROOT))
1457245490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	    {
14573df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		/*
145749bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		* This is a "/descendant-or-self::node()" without predicates.
14575df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		* Eliminate it.
14576df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		*/
14577df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		op->ch1 = prevop->ch1;
1457845490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard		op->rewriteType = XP_REWRITE_DOS_CHILD_ELEM;
14579df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik	    }
14580df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik	}
14581df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik	if (op->ch1 != -1)
14582df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik	    xmlXPathRewriteDOSExpression(comp, &comp->steps[op->ch1]);
14583df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik    }
14584df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik    if (op->ch2 != -1)
14585df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik	xmlXPathRewriteDOSExpression(comp, &comp->steps[op->ch2]);
14586df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik}
14587df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik
14588afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard/**
145894773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard * xmlXPathCtxtCompile:
145904773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard * @ctxt: an XPath context
14591afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * @str:  the XPath expression
14592afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard *
14593afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile an XPath expression
14594afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard *
14595591b4be0fe1986b5e71d54c5c063493987ef4285Daniel Veillard * Returns the xmlXPathCompExprPtr resulting from the compilation or NULL.
14596afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard *         the caller has to free the object.
14597afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard */
14598afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompExprPtr
145994773df2a58be83e1b9b1b55840371acf37386820Daniel VeillardxmlXPathCtxtCompile(xmlXPathContextPtr ctxt, const xmlChar *str) {
146004773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard    xmlXPathParserContextPtr pctxt;
14601afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard    xmlXPathCompExprPtr comp;
14602afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard
1460356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard#ifdef XPATH_STREAMING
1460456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard    comp = xmlXPathTryStreamCompile(ctxt, str);
1460556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard    if (comp != NULL)
1460656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard        return(comp);
1460756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard#endif
1460856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard
14609afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard    xmlXPathInit();
14610afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard
146114773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard    pctxt = xmlXPathNewParserContext(str, ctxt);
1461211be2d02b0261c9b5fd5d2f511b7a5ca8a81342dWilliam M. Brack    if (pctxt == NULL)
1461311be2d02b0261c9b5fd5d2f511b7a5ca8a81342dWilliam M. Brack        return NULL;
146145691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik    xmlXPathCompileExpr(pctxt, 1);
14615ae9733aeaf99e5d967b6b2cd961c98bf58cfbb4cDaniel Veillard
146164773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard    if( pctxt->error != XPATH_EXPRESSION_OK )
14617ae9733aeaf99e5d967b6b2cd961c98bf58cfbb4cDaniel Veillard    {
146184773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard        xmlXPathFreeParserContext(pctxt);
1461924505b0f5c872c5afb6da5093565e5a6e09ca541Daniel Veillard        return(NULL);
14620ae9733aeaf99e5d967b6b2cd961c98bf58cfbb4cDaniel Veillard    }
14621ae9733aeaf99e5d967b6b2cd961c98bf58cfbb4cDaniel Veillard
146224773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard    if (*pctxt->cur != 0) {
1462345490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	/*
1462450fe8b1732048003f47b32b009507fe6cdecd39fAleksey Sanin	 * aleksey: in some cases this line prints *second* error message
1462550fe8b1732048003f47b32b009507fe6cdecd39fAleksey Sanin	 * (see bug #78858) and probably this should be fixed.
1462650fe8b1732048003f47b32b009507fe6cdecd39fAleksey Sanin	 * However, we are not sure that all error messages are printed
1462750fe8b1732048003f47b32b009507fe6cdecd39fAleksey Sanin	 * out in other places. It's not critical so we leave it as-is for now
1462850fe8b1732048003f47b32b009507fe6cdecd39fAleksey Sanin	 */
146294773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard	xmlXPatherror(pctxt, __FILE__, __LINE__, XPATH_EXPR_ERROR);
1463040af649f9b5b32f97879f10432c56bb5ef60c958Daniel Veillard	comp = NULL;
1463140af649f9b5b32f97879f10432c56bb5ef60c958Daniel Veillard    } else {
146324773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard	comp = pctxt->comp;
146334773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard	pctxt->comp = NULL;
1463440af649f9b5b32f97879f10432c56bb5ef60c958Daniel Veillard    }
146354773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard    xmlXPathFreeParserContext(pctxt);
14636631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik
14637f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    if (comp != NULL) {
14638ceb09b956efa2cf1ec41c1887394396e5a6030f2Daniel Veillard	comp->expr = xmlStrdup(str);
14639ceb09b956efa2cf1ec41c1887394396e5a6030f2Daniel Veillard#ifdef DEBUG_EVAL_COUNTS
14640f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	comp->string = xmlStrdup(str);
14641f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	comp->nb = 0;
1464245490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard#endif
14643766ed7e1e5a4361f3b107ba8dc7af3a8960801c9Kasimier T. Buchcik	if ((comp->expr != NULL) &&
14644766ed7e1e5a4361f3b107ba8dc7af3a8960801c9Kasimier T. Buchcik	    (comp->nbStep > 2) &&
14645766ed7e1e5a4361f3b107ba8dc7af3a8960801c9Kasimier T. Buchcik	    (comp->last >= 0) &&
146467cb3fa9d51a0a57d1e538854e4be84db82b75098Kasimier T. Buchcik	    (xmlXPathCanRewriteDosExpression(comp->expr) == 1))
146477cb3fa9d51a0a57d1e538854e4be84db82b75098Kasimier T. Buchcik	{
146487cb3fa9d51a0a57d1e538854e4be84db82b75098Kasimier T. Buchcik	    xmlXPathRewriteDOSExpression(comp, &comp->steps[comp->last]);
146499bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	}
14650df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik    }
14651afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard    return(comp);
14652afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard}
14653afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard
146549e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard/**
146554773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard * xmlXPathCompile:
146564773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard * @str:  the XPath expression
146574773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard *
146584773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard * Compile an XPath expression
146594773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard *
146604773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard * Returns the xmlXPathCompExprPtr resulting from the compilation or NULL.
146614773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard *         the caller has to free the object.
146624773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard */
146634773df2a58be83e1b9b1b55840371acf37386820Daniel VeillardxmlXPathCompExprPtr
146644773df2a58be83e1b9b1b55840371acf37386820Daniel VeillardxmlXPathCompile(const xmlChar *str) {
146654773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard    return(xmlXPathCtxtCompile(NULL, str));
146664773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard}
146674773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard
146684773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard/**
14669631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik * xmlXPathCompiledEvalInternal:
146709e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * @comp:  the compiled XPath expression
14671631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik * @ctxt:  the XPath context
14672631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik * @resObj: the resulting XPath object or NULL
14673631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik * @toBool: 1 if only a boolean result is requested
146749e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard *
146759e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * Evaluate the Precompiled XPath expression in the given context.
14676631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik * The caller has to free @resObj.
146779e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard *
14678cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * Returns the xmlXPathObjectPtr resulting from the evaluation or NULL.
146799e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard *         the caller has to free the object.
146809e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard */
14681631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcikstatic int
14682631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. BuchcikxmlXPathCompiledEvalInternal(xmlXPathCompExprPtr comp,
14683631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik			     xmlXPathContextPtr ctxt,
14684631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik			     xmlXPathObjectPtr *resObj,
14685631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik			     int toBool)
14686631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik{
1468745490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard    xmlXPathParserContextPtr pctxt;
146888146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard#ifndef LIBXML_THREAD_ENABLED
146898146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard    static int reentance = 0;
146908146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard#endif
14691631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik    int res;
146929e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
14693631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik    CHECK_CTXT_NEG(ctxt)
14694f13f77f0e6a7876063d5fba15c096befb0827cedWilliam M. Brack
14695f13f77f0e6a7876063d5fba15c096befb0827cedWilliam M. Brack    if (comp == NULL)
14696631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	return(-1);
146979e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    xmlXPathInit();
146989e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
146998146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard#ifndef LIBXML_THREAD_ENABLED
147008146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard    reentance++;
147018146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard    if (reentance > 1)
147028146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard	xmlXPathDisableOptimizer = 1;
147038146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard#endif
147048146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard
14705f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#ifdef DEBUG_EVAL_COUNTS
14706f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    comp->nb++;
14707f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    if ((comp->string != NULL) && (comp->nb > 100)) {
14708f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	fprintf(stderr, "100 x %s\n", comp->string);
14709f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	comp->nb = 0;
14710f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    }
14711f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#endif
14712631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik    pctxt = xmlXPathCompParserContext(comp, ctxt);
14713631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik    res = xmlXPathRunEval(pctxt, toBool);
147149e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
14715631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik    if (resObj) {
1471645490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	if (pctxt->value == NULL) {
14717631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    xmlGenericError(xmlGenericErrorContext,
14718cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard		"xmlXPathCompiledEval: evaluation failed\n");
1471945490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	    *resObj = NULL;
14720631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	} else {
14721631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    *resObj = valuePop(pctxt);
14722631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	}
147239e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    }
1472445490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
14725631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik    /*
14726631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik    * Pop all remaining objects from the stack.
14727631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik    */
14728631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik    if (pctxt->valueNr > 0) {
14729631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	xmlXPathObjectPtr tmp;
14730631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	int stack = 0;
14731631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik
14732631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	do {
14733631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    tmp = valuePop(pctxt);
14734631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    if (tmp != NULL) {
1473545490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard		stack++;
14736631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik		xmlXPathReleaseObject(ctxt, tmp);
14737631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    }
14738631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	} while (tmp != NULL);
14739631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	if ((stack != 0) &&
14740631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    ((toBool) || ((resObj) && (*resObj))))
14741631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	{
14742631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    xmlGenericError(xmlGenericErrorContext,
14743631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik		"xmlXPathCompiledEval: %d objects left on the stack.\n",
14744631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik		stack);
14745631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	}
147469e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    }
1474745490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
14748631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik    if ((pctxt->error != XPATH_EXPRESSION_OK) && (resObj) && (*resObj)) {
14749631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	xmlXPathFreeObject(*resObj);
14750631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	*resObj = NULL;
1475145490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard    }
14752631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik    pctxt->comp = NULL;
14753631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik    xmlXPathFreeParserContext(pctxt);
147548146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard#ifndef LIBXML_THREAD_ENABLED
147558146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard    reentance--;
147568146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard#endif
14757631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik
147589e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    return(res);
147599e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard}
147609e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
14761afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard/**
14762631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik * xmlXPathCompiledEval:
14763631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik * @comp:  the compiled XPath expression
14764631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik * @ctx:  the XPath context
14765631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik *
14766631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik * Evaluate the Precompiled XPath expression in the given context.
14767631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik *
14768631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik * Returns the xmlXPathObjectPtr resulting from the evaluation or NULL.
14769631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik *         the caller has to free the object.
14770631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik */
14771631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. BuchcikxmlXPathObjectPtr
14772631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. BuchcikxmlXPathCompiledEval(xmlXPathCompExprPtr comp, xmlXPathContextPtr ctx)
14773631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik{
14774631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik    xmlXPathObjectPtr res = NULL;
14775631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik
14776631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik    xmlXPathCompiledEvalInternal(comp, ctx, &res, 0);
14777631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik    return(res);
14778631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik}
14779631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik
14780631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik/**
14781631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik * xmlXPathCompiledEvalToBoolean:
14782631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik * @comp:  the compiled XPath expression
14783631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik * @ctxt:  the XPath context
14784631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik *
14785631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik * Applies the XPath boolean() function on the result of the given
14786631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik * compiled expression.
14787631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik *
14788631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik * Returns 1 if the expression evaluated to true, 0 if to false and
14789631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik *         -1 in API and internal errors.
14790631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik */
14791631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcikint
14792631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. BuchcikxmlXPathCompiledEvalToBoolean(xmlXPathCompExprPtr comp,
14793631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik			      xmlXPathContextPtr ctxt)
14794631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik{
14795631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik    return(xmlXPathCompiledEvalInternal(comp, ctxt, NULL, 1));
14796631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik}
14797631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik
14798631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik/**
14799afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathEvalExpr:
14800afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * @ctxt:  the XPath Parser context
14801afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard *
14802afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Parse and evaluate an XPath expression in the given context,
14803afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * then push the result on the context stack
14804afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard */
14805afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardvoid
14806afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathEvalExpr(xmlXPathParserContextPtr ctxt) {
1480756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard#ifdef XPATH_STREAMING
1480856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard    xmlXPathCompExprPtr comp;
1480956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard#endif
1481056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard
14811a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard    if (ctxt == NULL) return;
1481245490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
1481356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard#ifdef XPATH_STREAMING
1481456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard    comp = xmlXPathTryStreamCompile(ctxt->context, ctxt->base);
1481556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard    if (comp != NULL) {
1481656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard        if (ctxt->comp != NULL)
1481756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	    xmlXPathFreeCompExpr(ctxt->comp);
1481856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard        ctxt->comp = comp;
1481956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	if (ctxt->cur != NULL)
1482056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	    while (*ctxt->cur != 0) ctxt->cur++;
1482156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard    } else
1482256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard#endif
1482356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard    {
148245691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	xmlXPathCompileExpr(ctxt, 1);
14825766ed7e1e5a4361f3b107ba8dc7af3a8960801c9Kasimier T. Buchcik	/*
14826766ed7e1e5a4361f3b107ba8dc7af3a8960801c9Kasimier T. Buchcik	* In this scenario the expression string will sit in ctxt->base.
14827766ed7e1e5a4361f3b107ba8dc7af3a8960801c9Kasimier T. Buchcik	*/
14828766ed7e1e5a4361f3b107ba8dc7af3a8960801c9Kasimier T. Buchcik	if ((ctxt->error == XPATH_EXPRESSION_OK) &&
14829766ed7e1e5a4361f3b107ba8dc7af3a8960801c9Kasimier T. Buchcik	    (ctxt->comp != NULL) &&
14830766ed7e1e5a4361f3b107ba8dc7af3a8960801c9Kasimier T. Buchcik	    (ctxt->base != NULL) &&
148317cb3fa9d51a0a57d1e538854e4be84db82b75098Kasimier T. Buchcik	    (ctxt->comp->nbStep > 2) &&
14832766ed7e1e5a4361f3b107ba8dc7af3a8960801c9Kasimier T. Buchcik	    (ctxt->comp->last >= 0) &&
14833766ed7e1e5a4361f3b107ba8dc7af3a8960801c9Kasimier T. Buchcik	    (xmlXPathCanRewriteDosExpression((xmlChar *) ctxt->base) == 1))
14834080152c9017a0ee4b97149d54f85fea3ab348b6dKasimier T. Buchcik	{
14835080152c9017a0ee4b97149d54f85fea3ab348b6dKasimier T. Buchcik	    xmlXPathRewriteDOSExpression(ctxt->comp,
14836766ed7e1e5a4361f3b107ba8dc7af3a8960801c9Kasimier T. Buchcik		&ctxt->comp->steps[ctxt->comp->last]);
14837080152c9017a0ee4b97149d54f85fea3ab348b6dKasimier T. Buchcik	}
1483856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard    }
1483950fe8b1732048003f47b32b009507fe6cdecd39fAleksey Sanin    CHECK_ERROR;
1484045490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard    xmlXPathRunEval(ctxt, 0);
14841afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard}
148429e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
148433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
148443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathEval:
148453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @str:  the XPath expression
148463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctx:  the XPath context
148473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
148483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Evaluate the XPath Location Path in the given context.
148493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
14850cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * Returns the xmlXPathObjectPtr resulting from the evaluation or NULL.
148513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *         the caller has to free the object.
148523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
148533473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathObjectPtr
148543473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathEval(const xmlChar *str, xmlXPathContextPtr ctx) {
148553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathParserContextPtr ctxt;
148563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathObjectPtr res, tmp, init = NULL;
148573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    int stack = 0;
148583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
14859f13f77f0e6a7876063d5fba15c096befb0827cedWilliam M. Brack    CHECK_CTXT(ctx)
148603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
14861f13f77f0e6a7876063d5fba15c096befb0827cedWilliam M. Brack    xmlXPathInit();
148623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
148633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ctxt = xmlXPathNewParserContext(str, ctx);
1486411be2d02b0261c9b5fd5d2f511b7a5ca8a81342dWilliam M. Brack    if (ctxt == NULL)
1486511be2d02b0261c9b5fd5d2f511b7a5ca8a81342dWilliam M. Brack        return NULL;
148663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathEvalExpr(ctxt);
148673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
148683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ctxt->value == NULL) {
148693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	xmlGenericError(xmlGenericErrorContext,
148703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		"xmlXPathEval: evaluation failed\n");
148713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	res = NULL;
1487245490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard    } else if ((*ctxt->cur != 0) && (ctxt->comp != NULL)
1487356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard#ifdef XPATH_STREAMING
1487456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard            && (ctxt->comp->stream == NULL)
1487556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard#endif
1487656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	      ) {
148773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	xmlXPatherror(ctxt, __FILE__, __LINE__, XPATH_EXPR_ERROR);
148783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	res = NULL;
148793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    } else {
148803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	res = valuePop(ctxt);
148813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
148823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
148833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    do {
148843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        tmp = valuePop(ctxt);
148853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (tmp != NULL) {
148863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    if (tmp != init)
14887a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		stack++;
14888a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathReleaseObject(ctx, tmp);
148893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        }
148903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    } while (tmp != NULL);
148913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if ((stack != 0) && (res != NULL)) {
148923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	xmlGenericError(xmlGenericErrorContext,
148933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		"xmlXPathEval: %d object left on the stack\n",
148943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	        stack);
148953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
148963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ctxt->error != XPATH_EXPRESSION_OK) {
148973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	xmlXPathFreeObject(res);
148983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	res = NULL;
148993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
149009e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
149013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathFreeParserContext(ctxt);
149023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(res);
149033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
149043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
149053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
149063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathEvalExpression:
149073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @str:  the XPath expression
149083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath context
149093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
149103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Evaluate the XPath expression in the given context.
149113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
149123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the xmlXPathObjectPtr resulting from the evaluation or NULL.
149133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *         the caller has to free the object.
149143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
149153473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathObjectPtr
149163473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathEvalExpression(const xmlChar *str, xmlXPathContextPtr ctxt) {
149173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathParserContextPtr pctxt;
149183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathObjectPtr res, tmp;
149193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    int stack = 0;
149203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
14921f13f77f0e6a7876063d5fba15c096befb0827cedWilliam M. Brack    CHECK_CTXT(ctxt)
149223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
14923f13f77f0e6a7876063d5fba15c096befb0827cedWilliam M. Brack    xmlXPathInit();
149243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
149253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    pctxt = xmlXPathNewParserContext(str, ctxt);
1492611be2d02b0261c9b5fd5d2f511b7a5ca8a81342dWilliam M. Brack    if (pctxt == NULL)
1492711be2d02b0261c9b5fd5d2f511b7a5ca8a81342dWilliam M. Brack        return NULL;
149283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathEvalExpr(pctxt);
149293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
14930c465ffc20c75f6ee4656aec9649d5bc6a3bbbf26Daniel Veillard    if ((*pctxt->cur != 0) || (pctxt->error != XPATH_EXPRESSION_OK)) {
149313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	xmlXPatherror(pctxt, __FILE__, __LINE__, XPATH_EXPR_ERROR);
149323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	res = NULL;
149333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    } else {
149343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	res = valuePop(pctxt);
149353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
149363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    do {
149373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        tmp = valuePop(pctxt);
149383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (tmp != NULL) {
14939a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathReleaseObject(ctxt, tmp);
149403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    stack++;
149413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
149423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    } while (tmp != NULL);
149433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if ((stack != 0) && (res != NULL)) {
149443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	xmlGenericError(xmlGenericErrorContext,
149453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		"xmlXPathEvalExpression: %d object left on the stack\n",
149463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	        stack);
149473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
149483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathFreeParserContext(pctxt);
149493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(res);
149503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
149513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
1495242766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard/************************************************************************
1495342766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard *									*
1495442766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard *	Extra functions not pertaining to the XPath spec		*
1495542766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard *									*
1495642766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard ************************************************************************/
1495742766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard/**
1495842766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * xmlXPathEscapeUriFunction:
1495942766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * @ctxt:  the XPath Parser context
1496042766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * @nargs:  the number of arguments
1496142766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard *
1496242766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * Implement the escape-uri() XPath function
1496342766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard *    string escape-uri(string $str, bool $escape-reserved)
1496442766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard *
1496542766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * This function applies the URI escaping rules defined in section 2 of [RFC
1496642766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * 2396] to the string supplied as $uri-part, which typically represents all
1496742766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * or part of a URI. The effect of the function is to replace any special
1496842766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * character in the string by an escape sequence of the form %xx%yy...,
1496942766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * where xxyy... is the hexadecimal representation of the octets used to
1497042766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * represent the character in UTF-8.
1497142766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard *
1497242766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * The set of characters that are escaped depends on the setting of the
1497342766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * boolean argument $escape-reserved.
1497442766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard *
1497542766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * If $escape-reserved is true, all characters are escaped other than lower
1497642766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * case letters a-z, upper case letters A-Z, digits 0-9, and the characters
1497742766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * referred to in [RFC 2396] as "marks": specifically, "-" | "_" | "." | "!"
1497842766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * | "~" | "*" | "'" | "(" | ")". The "%" character itself is escaped only
1497942766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * if it is not followed by two hexadecimal digits (that is, 0-9, a-f, and
1498042766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * A-F).
1498142766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard *
1498242766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * If $escape-reserved is false, the behavior differs in that characters
1498342766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * referred to in [RFC 2396] as reserved characters are not escaped. These
1498442766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * characters are ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" | "$" | ",".
1498545490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *
1498642766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * [RFC 2396] does not define whether escaped URIs should use lower case or
1498742766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * upper case for hexadecimal digits. To ensure that escaped URIs can be
1498842766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * compared using string comparison functions, this function must always use
1498942766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * the upper-case letters A-F.
1499045490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *
1499142766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * Generally, $escape-reserved should be set to true when escaping a string
1499242766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * that is to form a single part of a URI, and to false when escaping an
1499342766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * entire URI or URI reference.
1499445490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *
1499545490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard * In the case of non-ascii characters, the string is encoded according to
1499642766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * utf-8 and then converted according to RFC 2396.
1499742766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard *
1499842766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * Examples
1499945490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *  xf:escape-uri ("gopher://spinaltap.micro.umn.edu/00/Weather/California/Los%20Angeles#ocean"), true())
1500042766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard *  returns "gopher%3A%2F%2Fspinaltap.micro.umn.edu%2F00%2FWeather%2FCalifornia%2FLos%20Angeles%23ocean"
1500142766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard *  xf:escape-uri ("gopher://spinaltap.micro.umn.edu/00/Weather/California/Los%20Angeles#ocean"), false())
1500242766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard *  returns "gopher://spinaltap.micro.umn.edu/00/Weather/California/Los%20Angeles%23ocean"
1500342766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard *
1500442766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard */
15005118aed78f360f51d182770e62b251ef324707aa2Daniel Veillardstatic void
1500642766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel VeillardxmlXPathEscapeUriFunction(xmlXPathParserContextPtr ctxt, int nargs) {
1500742766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard    xmlXPathObjectPtr str;
1500842766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard    int escape_reserved;
1500942766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard    xmlBufferPtr target;
1501042766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard    xmlChar *cptr;
1501142766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard    xmlChar escape[4];
1501245490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
1501342766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard    CHECK_ARITY(2);
1501445490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
1501542766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard    escape_reserved = xmlXPathPopBoolean(ctxt);
1501645490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
1501742766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard    CAST_TO_STRING;
1501842766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard    str = valuePop(ctxt);
1501945490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
1502042766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard    target = xmlBufferCreate();
1502145490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
1502242766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard    escape[0] = '%';
1502342766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard    escape[3] = 0;
1502445490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
1502542766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard    if (target) {
1502642766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard	for (cptr = str->stringval; *cptr; cptr++) {
1502742766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard	    if ((*cptr >= 'A' && *cptr <= 'Z') ||
1502842766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard		(*cptr >= 'a' && *cptr <= 'z') ||
1502942766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard		(*cptr >= '0' && *cptr <= '9') ||
1503045490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard		*cptr == '-' || *cptr == '_' || *cptr == '.' ||
1503142766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard		*cptr == '!' || *cptr == '~' || *cptr == '*' ||
1503242766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard		*cptr == '\''|| *cptr == '(' || *cptr == ')' ||
1503345490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard		(*cptr == '%' &&
1503442766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard		 ((cptr[1] >= 'A' && cptr[1] <= 'F') ||
1503542766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard		  (cptr[1] >= 'a' && cptr[1] <= 'f') ||
1503642766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard		  (cptr[1] >= '0' && cptr[1] <= '9')) &&
1503742766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard		 ((cptr[2] >= 'A' && cptr[2] <= 'F') ||
1503842766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard		  (cptr[2] >= 'a' && cptr[2] <= 'f') ||
1503942766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard		  (cptr[2] >= '0' && cptr[2] <= '9'))) ||
1504042766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard		(!escape_reserved &&
1504142766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard		 (*cptr == ';' || *cptr == '/' || *cptr == '?' ||
1504242766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard		  *cptr == ':' || *cptr == '@' || *cptr == '&' ||
1504342766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard		  *cptr == '=' || *cptr == '+' || *cptr == '$' ||
1504442766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard		  *cptr == ','))) {
1504542766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard		xmlBufferAdd(target, cptr, 1);
1504642766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard	    } else {
1504742766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard		if ((*cptr >> 4) < 10)
1504842766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard		    escape[1] = '0' + (*cptr >> 4);
1504942766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard		else
1505042766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard		    escape[1] = 'A' - 10 + (*cptr >> 4);
1505142766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard		if ((*cptr & 0xF) < 10)
1505242766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard		    escape[2] = '0' + (*cptr & 0xF);
1505342766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard		else
1505442766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard		    escape[2] = 'A' - 10 + (*cptr & 0xF);
1505545490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
1505642766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard		xmlBufferAdd(target, &escape[0], 3);
1505742766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard	    }
1505842766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard	}
1505942766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard    }
15060a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    valuePush(ctxt, xmlXPathCacheNewString(ctxt->context,
15061a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	xmlBufferContent(target)));
1506242766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard    xmlBufferFree(target);
15063a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathReleaseObject(ctxt->context, str);
1506442766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard}
1506542766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard
150663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
150673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathRegisterAllFunctions:
150683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath context
150693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
150703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Registers all default XPath functions in this context
150713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
150723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
150733473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathRegisterAllFunctions(xmlXPathContextPtr ctxt)
150743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor{
150753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathRegisterFunc(ctxt, (const xmlChar *)"boolean",
150763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor                         xmlXPathBooleanFunction);
150773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathRegisterFunc(ctxt, (const xmlChar *)"ceiling",
150783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor                         xmlXPathCeilingFunction);
150793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathRegisterFunc(ctxt, (const xmlChar *)"count",
150803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor                         xmlXPathCountFunction);
150813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathRegisterFunc(ctxt, (const xmlChar *)"concat",
150823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor                         xmlXPathConcatFunction);
150833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathRegisterFunc(ctxt, (const xmlChar *)"contains",
150843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor                         xmlXPathContainsFunction);
150853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathRegisterFunc(ctxt, (const xmlChar *)"id",
150863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor                         xmlXPathIdFunction);
150873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathRegisterFunc(ctxt, (const xmlChar *)"false",
150883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor                         xmlXPathFalseFunction);
150893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathRegisterFunc(ctxt, (const xmlChar *)"floor",
150903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor                         xmlXPathFloorFunction);
150913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathRegisterFunc(ctxt, (const xmlChar *)"last",
150923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor                         xmlXPathLastFunction);
150933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathRegisterFunc(ctxt, (const xmlChar *)"lang",
150943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor                         xmlXPathLangFunction);
150953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathRegisterFunc(ctxt, (const xmlChar *)"local-name",
150963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor                         xmlXPathLocalNameFunction);
150973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathRegisterFunc(ctxt, (const xmlChar *)"not",
150983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor                         xmlXPathNotFunction);
150993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathRegisterFunc(ctxt, (const xmlChar *)"name",
151003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor                         xmlXPathNameFunction);
151013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathRegisterFunc(ctxt, (const xmlChar *)"namespace-uri",
151023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor                         xmlXPathNamespaceURIFunction);
151033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathRegisterFunc(ctxt, (const xmlChar *)"normalize-space",
151043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor                         xmlXPathNormalizeFunction);
151053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathRegisterFunc(ctxt, (const xmlChar *)"number",
151063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor                         xmlXPathNumberFunction);
151073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathRegisterFunc(ctxt, (const xmlChar *)"position",
151083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor                         xmlXPathPositionFunction);
151093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathRegisterFunc(ctxt, (const xmlChar *)"round",
151103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor                         xmlXPathRoundFunction);
151113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathRegisterFunc(ctxt, (const xmlChar *)"string",
151123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor                         xmlXPathStringFunction);
151133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathRegisterFunc(ctxt, (const xmlChar *)"string-length",
151143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor                         xmlXPathStringLengthFunction);
151153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathRegisterFunc(ctxt, (const xmlChar *)"starts-with",
151163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor                         xmlXPathStartsWithFunction);
151173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathRegisterFunc(ctxt, (const xmlChar *)"substring",
151183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor                         xmlXPathSubstringFunction);
151193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathRegisterFunc(ctxt, (const xmlChar *)"substring-before",
151203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor                         xmlXPathSubstringBeforeFunction);
151213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathRegisterFunc(ctxt, (const xmlChar *)"substring-after",
151223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor                         xmlXPathSubstringAfterFunction);
151233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathRegisterFunc(ctxt, (const xmlChar *)"sum",
151243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor                         xmlXPathSumFunction);
151253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathRegisterFunc(ctxt, (const xmlChar *)"true",
151263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor                         xmlXPathTrueFunction);
151273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathRegisterFunc(ctxt, (const xmlChar *)"translate",
151283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor                         xmlXPathTranslateFunction);
1512942766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard
1513042766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard    xmlXPathRegisterFuncNS(ctxt, (const xmlChar *)"escape-uri",
1513142766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard	 (const xmlChar *)"http://www.w3.org/2002/08/xquery-functions",
1513242766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard                         xmlXPathEscapeUriFunction);
151333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
151343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
151353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif /* LIBXML_XPATH_ENABLED */
151365d4644ef6e38479a648615eca758c5e962a141d5Daniel Veillard#define bottom_xpath
151375d4644ef6e38479a648615eca758c5e962a141d5Daniel Veillard#include "elfgcchack.h"
15138