xpath.c revision 75801652a2342d22fa1f62047f86e5d23b4d1782
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
58ade10f2c57b4bd5c3812b96bce1144d8fa1d189eDaniel Veillard#include "buf.h"
59ade10f2c57b4bd5c3812b96bce1144d8fa1d189eDaniel Veillard
6056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard#ifdef LIBXML_PATTERN_ENABLED
61fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard#define XPATH_STREAMING
6256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard#endif
633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
6445490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard#define TODO								\
65d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard    xmlGenericError(xmlGenericErrorContext,				\
66d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard	    "Unimplemented block at %s:%d\n",				\
67d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard            __FILE__, __LINE__);
68d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard
693e031b7dae590bdd03084a5971d9f9e66fe5d50bVojtech Fried/**
703e031b7dae590bdd03084a5971d9f9e66fe5d50bVojtech Fried * WITH_TIM_SORT:
713e031b7dae590bdd03084a5971d9f9e66fe5d50bVojtech Fried *
723e031b7dae590bdd03084a5971d9f9e66fe5d50bVojtech Fried * Use the Timsort algorithm provided in timsort.h to sort
733e031b7dae590bdd03084a5971d9f9e66fe5d50bVojtech Fried * nodeset as this is a great improvement over the old Shell sort
743e031b7dae590bdd03084a5971d9f9e66fe5d50bVojtech Fried * used in xmlXPathNodeSetSort()
753e031b7dae590bdd03084a5971d9f9e66fe5d50bVojtech Fried */
763e031b7dae590bdd03084a5971d9f9e66fe5d50bVojtech Fried#define WITH_TIM_SORT
773e031b7dae590bdd03084a5971d9f9e66fe5d50bVojtech Fried
78d1757abcb891e01a9017f4aad041cc306d0d467bWilliam M. Brack/*
795691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik* XP_OPTIMIZED_NON_ELEM_COMPARISON:
802bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik* If defined, this will use xmlXPathCmpNodesExt() instead of
812bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik* xmlXPathCmpNodes(). The new function is optimized comparison of
822bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik* non-element nodes; actually it will speed up comparison only if
832bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik* xmlXPathOrderDocElems() was called in order to index the elements of
842bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik* a tree in document order; Libxslt does such an indexing, thus it will
852bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik* benefit from this optimization.
862bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik*/
875691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik#define XP_OPTIMIZED_NON_ELEM_COMPARISON
885691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik
895691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik/*
905691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik* XP_OPTIMIZED_FILTER_FIRST:
915691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik* If defined, this will optimize expressions like "key('foo', 'val')[b][1]"
925691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik* in a way, that it stop evaluation at the first node.
9345490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard*/
945691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik#define XP_OPTIMIZED_FILTER_FIRST
955691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik
9697258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik/*
97a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik* XP_DEBUG_OBJ_USAGE:
98a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik* Internal flag to enable tracking of how much XPath objects have been
99a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik* created.
100a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik*/
101a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik/* #define XP_DEBUG_OBJ_USAGE */
102a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
103a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik/*
104cd852ad154fd919d9a4bd955566b43bac848878aDaniel Veillard * XPATH_MAX_STEPS:
105cd852ad154fd919d9a4bd955566b43bac848878aDaniel Veillard * when compiling an XPath expression we arbitrary limit the maximum
106cd852ad154fd919d9a4bd955566b43bac848878aDaniel Veillard * number of step operation in the compiled expression. 1000000 is
107cd852ad154fd919d9a4bd955566b43bac848878aDaniel Veillard * an insanely large value which should never be reached under normal
108cd852ad154fd919d9a4bd955566b43bac848878aDaniel Veillard * circumstances
109cd852ad154fd919d9a4bd955566b43bac848878aDaniel Veillard */
110cd852ad154fd919d9a4bd955566b43bac848878aDaniel Veillard#define XPATH_MAX_STEPS 1000000
111cd852ad154fd919d9a4bd955566b43bac848878aDaniel Veillard
112cd852ad154fd919d9a4bd955566b43bac848878aDaniel Veillard/*
113cd852ad154fd919d9a4bd955566b43bac848878aDaniel Veillard * XPATH_MAX_STACK_DEPTH:
114cd852ad154fd919d9a4bd955566b43bac848878aDaniel Veillard * when evaluating an XPath expression we arbitrary limit the maximum
115cd852ad154fd919d9a4bd955566b43bac848878aDaniel Veillard * number of object allowed to be pushed on the stack. 1000000 is
116cd852ad154fd919d9a4bd955566b43bac848878aDaniel Veillard * an insanely large value which should never be reached under normal
117cd852ad154fd919d9a4bd955566b43bac848878aDaniel Veillard * circumstances
118cd852ad154fd919d9a4bd955566b43bac848878aDaniel Veillard */
119cd852ad154fd919d9a4bd955566b43bac848878aDaniel Veillard#define XPATH_MAX_STACK_DEPTH 1000000
120cd852ad154fd919d9a4bd955566b43bac848878aDaniel Veillard
121cd852ad154fd919d9a4bd955566b43bac848878aDaniel Veillard/*
122cd852ad154fd919d9a4bd955566b43bac848878aDaniel Veillard * XPATH_MAX_NODESET_LENGTH:
123cd852ad154fd919d9a4bd955566b43bac848878aDaniel Veillard * when evaluating an XPath expression nodesets are created and we
124cd852ad154fd919d9a4bd955566b43bac848878aDaniel Veillard * arbitrary limit the maximum length of those node set. 10000000 is
125cd852ad154fd919d9a4bd955566b43bac848878aDaniel Veillard * an insanely large value which should never be reached under normal
126cd852ad154fd919d9a4bd955566b43bac848878aDaniel Veillard * circumstances, one would first need to construct an in memory tree
127cd852ad154fd919d9a4bd955566b43bac848878aDaniel Veillard * with more than 10 millions nodes.
128cd852ad154fd919d9a4bd955566b43bac848878aDaniel Veillard */
129cd852ad154fd919d9a4bd955566b43bac848878aDaniel Veillard#define XPATH_MAX_NODESET_LENGTH 10000000
130cd852ad154fd919d9a4bd955566b43bac848878aDaniel Veillard
131cd852ad154fd919d9a4bd955566b43bac848878aDaniel Veillard/*
132d1757abcb891e01a9017f4aad041cc306d0d467bWilliam M. Brack * TODO:
133d1757abcb891e01a9017f4aad041cc306d0d467bWilliam M. Brack * There are a few spots where some tests are done which depend upon ascii
134d1757abcb891e01a9017f4aad041cc306d0d467bWilliam M. Brack * data.  These should be enhanced for full UTF8 support (see particularly
135d1757abcb891e01a9017f4aad041cc306d0d467bWilliam M. Brack * any use of the macros IS_ASCII_CHARACTER and IS_ASCII_DIGIT)
136d1757abcb891e01a9017f4aad041cc306d0d467bWilliam M. Brack */
13797258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik
138e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk#ifdef XP_OPTIMIZED_NON_ELEM_COMPARISON
139e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk/**
140e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk * xmlXPathCmpNodesExt:
141e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk * @node1:  the first node
142e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk * @node2:  the second node
143e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk *
144e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk * Compare two nodes w.r.t document order.
145e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk * This one is optimized for handling of non-element nodes.
146e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk *
147e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk * Returns -2 in case of error 1 if first point < second point, 0 if
148e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk *         it's the same node, -1 otherwise
149e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk */
150e28c8a1acef3047cceae1035924edae5e903a778Denis Paukstatic int
151e28c8a1acef3047cceae1035924edae5e903a778Denis PaukxmlXPathCmpNodesExt(xmlNodePtr node1, xmlNodePtr node2) {
152e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk    int depth1, depth2;
153e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk    int misc = 0, precedence1 = 0, precedence2 = 0;
154e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk    xmlNodePtr miscNode1 = NULL, miscNode2 = NULL;
155e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk    xmlNodePtr cur, root;
156e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk    long l1, l2;
157e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk
158e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk    if ((node1 == NULL) || (node2 == NULL))
159e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	return(-2);
160e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk
161e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk    if (node1 == node2)
162e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	return(0);
163e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk
164e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk    /*
165e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk     * a couple of optimizations which will avoid computations in most cases
166e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk     */
167e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk    switch (node1->type) {
168e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	case XML_ELEMENT_NODE:
169e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	    if (node2->type == XML_ELEMENT_NODE) {
170e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk		if ((0 > (long) node1->content) && /* TODO: Would a != 0 suffice here? */
171e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk		    (0 > (long) node2->content) &&
172e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk		    (node1->doc == node2->doc))
173e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk		{
174e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk		    l1 = -((long) node1->content);
175e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk		    l2 = -((long) node2->content);
176e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk		    if (l1 < l2)
177e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk			return(1);
178e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk		    if (l1 > l2)
179e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk			return(-1);
180e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk		} else
181e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk		    goto turtle_comparison;
182e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	    }
183e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	    break;
184e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	case XML_ATTRIBUTE_NODE:
185e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	    precedence1 = 1; /* element is owner */
186e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	    miscNode1 = node1;
187e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	    node1 = node1->parent;
188e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	    misc = 1;
189e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	    break;
190e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	case XML_TEXT_NODE:
191e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	case XML_CDATA_SECTION_NODE:
192e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	case XML_COMMENT_NODE:
193e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	case XML_PI_NODE: {
194e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	    miscNode1 = node1;
195e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	    /*
196e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	    * Find nearest element node.
197e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	    */
198e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	    if (node1->prev != NULL) {
199e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk		do {
200e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk		    node1 = node1->prev;
201e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk		    if (node1->type == XML_ELEMENT_NODE) {
202e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk			precedence1 = 3; /* element in prev-sibl axis */
203e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk			break;
204e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk		    }
205e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk		    if (node1->prev == NULL) {
206e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk			precedence1 = 2; /* element is parent */
207e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk			/*
208e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk			* URGENT TODO: Are there any cases, where the
209e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk			* parent of such a node is not an element node?
210e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk			*/
211e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk			node1 = node1->parent;
212e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk			break;
213e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk		    }
214e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk		} while (1);
215e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	    } else {
216e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk		precedence1 = 2; /* element is parent */
217e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk		node1 = node1->parent;
218e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	    }
219e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	    if ((node1 == NULL) || (node1->type != XML_ELEMENT_NODE) ||
220e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk		(0 <= (long) node1->content)) {
221e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk		/*
222e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk		* Fallback for whatever case.
223e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk		*/
224e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk		node1 = miscNode1;
225e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk		precedence1 = 0;
226e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	    } else
227e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk		misc = 1;
228e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	}
229e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	    break;
230e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	case XML_NAMESPACE_DECL:
231e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	    /*
232e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	    * TODO: why do we return 1 for namespace nodes?
233e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	    */
234e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	    return(1);
235e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	default:
236e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	    break;
237e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk    }
238e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk    switch (node2->type) {
239e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	case XML_ELEMENT_NODE:
240e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	    break;
241e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	case XML_ATTRIBUTE_NODE:
242e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	    precedence2 = 1; /* element is owner */
243e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	    miscNode2 = node2;
244e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	    node2 = node2->parent;
245e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	    misc = 1;
246e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	    break;
247e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	case XML_TEXT_NODE:
248e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	case XML_CDATA_SECTION_NODE:
249e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	case XML_COMMENT_NODE:
250e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	case XML_PI_NODE: {
251e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	    miscNode2 = node2;
252e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	    if (node2->prev != NULL) {
253e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk		do {
254e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk		    node2 = node2->prev;
255e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk		    if (node2->type == XML_ELEMENT_NODE) {
256e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk			precedence2 = 3; /* element in prev-sibl axis */
257e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk			break;
258e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk		    }
259e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk		    if (node2->prev == NULL) {
260e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk			precedence2 = 2; /* element is parent */
261e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk			node2 = node2->parent;
262e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk			break;
263e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk		    }
264e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk		} while (1);
265e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	    } else {
266e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk		precedence2 = 2; /* element is parent */
267e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk		node2 = node2->parent;
268e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	    }
269e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	    if ((node2 == NULL) || (node2->type != XML_ELEMENT_NODE) ||
270fcd458318916809edc4fc4cd1ce2d5ba9aed4665Gaurav		(0 <= (long) node2->content))
271e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	    {
272e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk		node2 = miscNode2;
273e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk		precedence2 = 0;
274e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	    } else
275e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk		misc = 1;
276e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	}
277e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	    break;
278e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	case XML_NAMESPACE_DECL:
279e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	    return(1);
280e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	default:
281e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	    break;
282e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk    }
283e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk    if (misc) {
284e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	if (node1 == node2) {
285e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	    if (precedence1 == precedence2) {
286e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk		/*
287e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk		* The ugly case; but normally there aren't many
288e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk		* adjacent non-element nodes around.
289e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk		*/
290e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk		cur = miscNode2->prev;
291e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk		while (cur != NULL) {
292e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk		    if (cur == miscNode1)
293e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk			return(1);
294e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk		    if (cur->type == XML_ELEMENT_NODE)
295e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk			return(-1);
296e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk		    cur = cur->prev;
297e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk		}
298e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk		return (-1);
299e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	    } else {
300e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk		/*
301e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk		* Evaluate based on higher precedence wrt to the element.
302e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk		* TODO: This assumes attributes are sorted before content.
303e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk		*   Is this 100% correct?
304e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk		*/
305e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk		if (precedence1 < precedence2)
306e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk		    return(1);
307e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk		else
308e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk		    return(-1);
309e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	    }
310e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	}
311e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	/*
312e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	* Special case: One of the helper-elements is contained by the other.
313e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	* <foo>
314e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	*   <node2>
315e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	*     <node1>Text-1(precedence1 == 2)</node1>
316e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	*   </node2>
317e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	*   Text-6(precedence2 == 3)
318e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	* </foo>
319e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	*/
320e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	if ((precedence2 == 3) && (precedence1 > 1)) {
321e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	    cur = node1->parent;
322e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	    while (cur) {
323e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk		if (cur == node2)
324e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk		    return(1);
325e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk		cur = cur->parent;
326e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	    }
327e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	}
328e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	if ((precedence1 == 3) && (precedence2 > 1)) {
329e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	    cur = node2->parent;
330e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	    while (cur) {
331e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk		if (cur == node1)
332e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk		    return(-1);
333e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk		cur = cur->parent;
334e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	    }
335e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	}
336e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk    }
337e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk
338e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk    /*
339e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk     * Speedup using document order if availble.
340e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk     */
341e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk    if ((node1->type == XML_ELEMENT_NODE) &&
342e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	(node2->type == XML_ELEMENT_NODE) &&
343e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	(0 > (long) node1->content) &&
344e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	(0 > (long) node2->content) &&
345e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	(node1->doc == node2->doc)) {
346e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk
347e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	l1 = -((long) node1->content);
348e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	l2 = -((long) node2->content);
349e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	if (l1 < l2)
350e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	    return(1);
351e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	if (l1 > l2)
352e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	    return(-1);
353e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk    }
354e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk
355e28c8a1acef3047cceae1035924edae5e903a778Denis Paukturtle_comparison:
356e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk
357e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk    if (node1 == node2->prev)
358e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	return(1);
359e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk    if (node1 == node2->next)
360e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	return(-1);
361e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk    /*
362e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk     * compute depth to root
363e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk     */
364e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk    for (depth2 = 0, cur = node2;cur->parent != NULL;cur = cur->parent) {
365e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	if (cur == node1)
366e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	    return(1);
367e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	depth2++;
368e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk    }
369e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk    root = cur;
370e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk    for (depth1 = 0, cur = node1;cur->parent != NULL;cur = cur->parent) {
371e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	if (cur == node2)
372e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	    return(-1);
373e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	depth1++;
374e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk    }
375e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk    /*
376e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk     * Distinct document (or distinct entities :-( ) case.
377e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk     */
378e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk    if (root != cur) {
379e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	return(-2);
380e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk    }
381e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk    /*
382e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk     * get the nearest common ancestor.
383e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk     */
384e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk    while (depth1 > depth2) {
385e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	depth1--;
386e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	node1 = node1->parent;
387e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk    }
388e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk    while (depth2 > depth1) {
389e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	depth2--;
390e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	node2 = node2->parent;
391e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk    }
392e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk    while (node1->parent != node2->parent) {
393e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	node1 = node1->parent;
394e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	node2 = node2->parent;
395e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	/* should not happen but just in case ... */
396e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	if ((node1 == NULL) || (node2 == NULL))
397e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	    return(-2);
398e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk    }
399e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk    /*
400e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk     * Find who's first.
401e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk     */
402e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk    if (node1 == node2->prev)
403e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	return(1);
404e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk    if (node1 == node2->next)
405e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	return(-1);
406e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk    /*
407e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk     * Speedup using document order if availble.
408e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk     */
409e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk    if ((node1->type == XML_ELEMENT_NODE) &&
410e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	(node2->type == XML_ELEMENT_NODE) &&
411e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	(0 > (long) node1->content) &&
412e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	(0 > (long) node2->content) &&
413e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	(node1->doc == node2->doc)) {
414e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk
415e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	l1 = -((long) node1->content);
416e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	l2 = -((long) node2->content);
417e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	if (l1 < l2)
418e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	    return(1);
419e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	if (l1 > l2)
420e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	    return(-1);
421e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk    }
422e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk
423e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk    for (cur = node1->next;cur != NULL;cur = cur->next)
424e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	if (cur == node2)
425e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	    return(1);
426e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk    return(-1); /* assume there is no sibling list corruption */
427e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk}
428e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk#endif /* XP_OPTIMIZED_NON_ELEM_COMPARISON */
429e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk
4303e031b7dae590bdd03084a5971d9f9e66fe5d50bVojtech Fried/*
4313e031b7dae590bdd03084a5971d9f9e66fe5d50bVojtech Fried * Wrapper for the Timsort argorithm from timsort.h
4323e031b7dae590bdd03084a5971d9f9e66fe5d50bVojtech Fried */
4333e031b7dae590bdd03084a5971d9f9e66fe5d50bVojtech Fried#ifdef WITH_TIM_SORT
4343e031b7dae590bdd03084a5971d9f9e66fe5d50bVojtech Fried#define SORT_NAME libxml_domnode
4353e031b7dae590bdd03084a5971d9f9e66fe5d50bVojtech Fried#define SORT_TYPE xmlNodePtr
4363e031b7dae590bdd03084a5971d9f9e66fe5d50bVojtech Fried/**
4373e031b7dae590bdd03084a5971d9f9e66fe5d50bVojtech Fried * wrap_cmp:
4383e031b7dae590bdd03084a5971d9f9e66fe5d50bVojtech Fried * @x: a node
4393e031b7dae590bdd03084a5971d9f9e66fe5d50bVojtech Fried * @y: another node
4403e031b7dae590bdd03084a5971d9f9e66fe5d50bVojtech Fried *
4413e031b7dae590bdd03084a5971d9f9e66fe5d50bVojtech Fried * Comparison function for the Timsort implementation
4423e031b7dae590bdd03084a5971d9f9e66fe5d50bVojtech Fried *
443510e7583f4c098858f5a1e7137c51c314d7c66caDaniel Veillard * Returns -2 in case of error -1 if first point < second point, 0 if
444510e7583f4c098858f5a1e7137c51c314d7c66caDaniel Veillard *         it's the same node, +1 otherwise
4453e031b7dae590bdd03084a5971d9f9e66fe5d50bVojtech Fried */
4463e031b7dae590bdd03084a5971d9f9e66fe5d50bVojtech Friedstatic
4473e031b7dae590bdd03084a5971d9f9e66fe5d50bVojtech Friedint wrap_cmp( xmlNodePtr x, xmlNodePtr y );
4483e031b7dae590bdd03084a5971d9f9e66fe5d50bVojtech Fried#ifdef XP_OPTIMIZED_NON_ELEM_COMPARISON
4493e031b7dae590bdd03084a5971d9f9e66fe5d50bVojtech Fried    static int wrap_cmp( xmlNodePtr x, xmlNodePtr y )
4503e031b7dae590bdd03084a5971d9f9e66fe5d50bVojtech Fried    {
4513e031b7dae590bdd03084a5971d9f9e66fe5d50bVojtech Fried        int res = xmlXPathCmpNodesExt(x, y);
4523e031b7dae590bdd03084a5971d9f9e66fe5d50bVojtech Fried        return res == -2 ? res : -res;
4533e031b7dae590bdd03084a5971d9f9e66fe5d50bVojtech Fried    }
4543e031b7dae590bdd03084a5971d9f9e66fe5d50bVojtech Fried#else
4553e031b7dae590bdd03084a5971d9f9e66fe5d50bVojtech Fried    static int wrap_cmp( xmlNodePtr x, xmlNodePtr y )
4563e031b7dae590bdd03084a5971d9f9e66fe5d50bVojtech Fried    {
4573e031b7dae590bdd03084a5971d9f9e66fe5d50bVojtech Fried        int res = xmlXPathCmpNodes(x, y);
4583e031b7dae590bdd03084a5971d9f9e66fe5d50bVojtech Fried        return res == -2 ? res : -res;
4593e031b7dae590bdd03084a5971d9f9e66fe5d50bVojtech Fried    }
4603e031b7dae590bdd03084a5971d9f9e66fe5d50bVojtech Fried#endif
4613e031b7dae590bdd03084a5971d9f9e66fe5d50bVojtech Fried#define SORT_CMP(x, y)  (wrap_cmp(x, y))
4623e031b7dae590bdd03084a5971d9f9e66fe5d50bVojtech Fried#include "timsort.h"
4633e031b7dae590bdd03084a5971d9f9e66fe5d50bVojtech Fried#endif /* WITH_TIM_SORT */
4643e031b7dae590bdd03084a5971d9f9e66fe5d50bVojtech Fried
46521e4ef20f64ebd740ebac0ead5d85a5631d2db5eWilliam M. Brack#if defined(LIBXML_XPATH_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED)
466a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
467a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik/************************************************************************
46845490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *									*
46945490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *			Floating point stuff				*
47045490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *									*
4719e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard ************************************************************************/
4729e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
473c0631a608f62902eca453096f0b2fc5b449b0b0aDaniel Veillard#ifndef TRIO_REPLACE_STDIO
474cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard#define TRIO_PUBLIC static
475c0631a608f62902eca453096f0b2fc5b449b0b0aDaniel Veillard#endif
476cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard#include "trionan.c"
477cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard
4783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/*
4793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The lack of portability of this section of the libc is annoying !
4803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
4813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylordouble xmlXPathNAN = 0;
4823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylordouble xmlXPathPINF = 1;
4833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylordouble xmlXPathNINF = -1;
48424505b0f5c872c5afb6da5093565e5a6e09ca541Daniel Veillardstatic double xmlXPathNZERO = 0; /* not exported from headers */
48520ee8c03107e5d5724765da513d595fdaf290dceDaniel Veillardstatic int xmlXPathInitialized = 0;
4863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
4873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
4883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathInit:
4893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
4903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Initialize the XPath environment
4913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
4923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
4933473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathInit(void) {
49420ee8c03107e5d5724765da513d595fdaf290dceDaniel Veillard    if (xmlXPathInitialized) return;
4953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
496450296070e14629141738fbb34b9a0ad13af1f02Bjorn Reese    xmlXPathPINF = trio_pinf();
497450296070e14629141738fbb34b9a0ad13af1f02Bjorn Reese    xmlXPathNINF = trio_ninf();
498450296070e14629141738fbb34b9a0ad13af1f02Bjorn Reese    xmlXPathNAN = trio_nan();
4995fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard    xmlXPathNZERO = trio_nzero();
5003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
50120ee8c03107e5d5724765da513d595fdaf290dceDaniel Veillard    xmlXPathInitialized = 1;
5023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
5033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
504cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard/**
505cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * xmlXPathIsNaN:
506cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * @val:  a double value
507cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard *
508cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * Provides a portable isnan() function to detect whether a double
509cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * is a NotaNumber. Based on trio code
510cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * http://sourceforge.net/projects/ctrio/
51145490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *
512cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * Returns 1 if the value is a NaN, 0 otherwise
513cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard */
514cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillardint
515cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel VeillardxmlXPathIsNaN(double val) {
516cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard    return(trio_isnan(val));
517cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard}
518cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard
519cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard/**
520cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * xmlXPathIsInf:
521cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * @val:  a double value
522cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard *
523cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * Provides a portable isinf() function to detect whether a double
524cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * is a +Infinite or -Infinite. Based on trio code
525cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * http://sourceforge.net/projects/ctrio/
52645490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *
527cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard * Returns 1 vi the value is +Infinite, -1 if -Infinite, 0 otherwise
528cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard */
529cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillardint
530cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel VeillardxmlXPathIsInf(double val) {
531cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard    return(trio_isinf(val));
532cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard}
533cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard
5344432df239b7aba6bff86c838e0be11d08f283b76Daniel Veillard#endif /* SCHEMAS or XPATH */
5354432df239b7aba6bff86c838e0be11d08f283b76Daniel Veillard#ifdef LIBXML_XPATH_ENABLED
5365fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard/**
5375fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard * xmlXPathGetSign:
5385fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard * @val:  a double value
5395fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard *
5405fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard * Provides a portable function to detect the sign of a double
5415fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard * Modified from trio code
5425fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard * http://sourceforge.net/projects/ctrio/
54345490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *
5445fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard * Returns 1 if the value is Negative, 0 if positive
5455fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard */
54621458c85e209cd2621ac3eadfee075ae2dc0121dDaniel Veillardstatic int
5475fc1f0893af6ffe76453ac16817204a866bdeab2Daniel VeillardxmlXPathGetSign(double val) {
54821458c85e209cd2621ac3eadfee075ae2dc0121dDaniel Veillard    return(trio_signbit(val));
5495fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard}
5505fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard
5515fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard
552d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillard/*
553d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillard * TODO: when compatibility allows remove all "fake node libxslt" strings
554d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillard *       the test should just be name[0] = ' '
555d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillard */
556074f37e7ebd5e76ceb584a89745a9e84df5b3be2Daniel Veillard#ifdef DEBUG_XPATH_EXPRESSION
557074f37e7ebd5e76ceb584a89745a9e84df5b3be2Daniel Veillard#define DEBUG_STEP
558074f37e7ebd5e76ceb584a89745a9e84df5b3be2Daniel Veillard#define DEBUG_EXPR
559074f37e7ebd5e76ceb584a89745a9e84df5b3be2Daniel Veillard#define DEBUG_EVAL_COUNTS
560074f37e7ebd5e76ceb584a89745a9e84df5b3be2Daniel Veillard#endif
561d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillard
562d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillardstatic xmlNs xmlXPathXMLNamespaceStruct = {
563d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillard    NULL,
564d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillard    XML_NAMESPACE_DECL,
565d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillard    XML_XML_NAMESPACE,
566d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillard    BAD_CAST "xml",
567ee0b982fe81018f8a190f62335c0e7957f4c5bcdWilliam M. Brack    NULL,
568d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillard    NULL
569d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillard};
570d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillardstatic xmlNsPtr xmlXPathXMLNamespace = &xmlXPathXMLNamespaceStruct;
571d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillard#ifndef LIBXML_THREAD_ENABLED
57245490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard/*
573d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillard * Optimizer is disabled only when threaded apps are detected while
574d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillard * the library ain't compiled for thread safety.
575d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillard */
576d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillardstatic int xmlXPathDisableOptimizer = 0;
577d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillard#endif
578d9d32aebd3d09df9431859c3d9e7f7de781c73d4Daniel Veillard
5793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/************************************************************************
580d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard *									*
581d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard *			Error handling routines				*
582d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard *									*
583d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard ************************************************************************/
584d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard
58524505b0f5c872c5afb6da5093565e5a6e09ca541Daniel Veillard/**
58624505b0f5c872c5afb6da5093565e5a6e09ca541Daniel Veillard * XP_ERRORNULL:
58724505b0f5c872c5afb6da5093565e5a6e09ca541Daniel Veillard * @X:  the error code
58824505b0f5c872c5afb6da5093565e5a6e09ca541Daniel Veillard *
58924505b0f5c872c5afb6da5093565e5a6e09ca541Daniel Veillard * Macro to raise an XPath error and return NULL.
59024505b0f5c872c5afb6da5093565e5a6e09ca541Daniel Veillard */
59124505b0f5c872c5afb6da5093565e5a6e09ca541Daniel Veillard#define XP_ERRORNULL(X)							\
59224505b0f5c872c5afb6da5093565e5a6e09ca541Daniel Veillard    { xmlXPathErr(ctxt, X); return(NULL); }
59324505b0f5c872c5afb6da5093565e5a6e09ca541Daniel Veillard
594081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack/*
595081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack * The array xmlXPathErrorMessages corresponds to the enum xmlXPathError
596081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack */
597d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillardstatic const char *xmlXPathErrorMessages[] = {
598d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard    "Ok\n",
599d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard    "Number encoding\n",
600d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard    "Unfinished literal\n",
601d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard    "Start of literal\n",
602d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard    "Expected $ for variable reference\n",
603d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard    "Undefined variable\n",
604d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard    "Invalid predicate\n",
605d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard    "Invalid expression\n",
606d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard    "Missing closing curly brace\n",
607d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard    "Unregistered function\n",
608d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard    "Invalid operand\n",
609d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard    "Invalid type\n",
610d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard    "Invalid number of arguments\n",
611d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard    "Invalid context size\n",
612d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard    "Invalid context position\n",
613d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard    "Memory allocation error\n",
614d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard    "Syntax error\n",
615d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard    "Resource error\n",
616d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard    "Sub resource error\n",
617d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard    "Undefined namespace prefix\n",
618d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard    "Encoding error\n",
61957b2516af5e2e06c54750b6549723cf5b8edf8a4Daniel Veillard    "Char out of XML range\n",
620cd65bc9a49b406899c78e9e8f6757acca54fc04eWilliam M. Brack    "Invalid or incomplete context\n",
62175801652a2342d22fa1f62047f86e5d23b4d1782Jan Pokorný    "Stack usage error\n",
62247881284aeaeeb93b3444419adeffc9e11ed1093Daniel Veillard    "Forbidden variable\n",
623cd65bc9a49b406899c78e9e8f6757acca54fc04eWilliam M. Brack    "?? Unknown error ??\n"	/* Must be last in the list! */
624d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard};
625cd65bc9a49b406899c78e9e8f6757acca54fc04eWilliam M. Brack#define MAXERRNO ((int)(sizeof(xmlXPathErrorMessages) /	\
626cd65bc9a49b406899c78e9e8f6757acca54fc04eWilliam M. Brack		   sizeof(xmlXPathErrorMessages[0])) - 1)
627d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard/**
628d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard * xmlXPathErrMemory:
629d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard * @ctxt:  an XPath context
630d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard * @extra:  extra informations
631d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard *
632d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard * Handle a redefinition of attribute error
633d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard */
634d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillardstatic void
635d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel VeillardxmlXPathErrMemory(xmlXPathContextPtr ctxt, const char *extra)
636d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard{
637d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard    if (ctxt != NULL) {
638d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard        if (extra) {
639d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard            xmlChar buf[200];
640d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard
641d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard            xmlStrPrintf(buf, 200,
642d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard                         BAD_CAST "Memory allocation failed : %s\n",
643d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard                         extra);
644d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard            ctxt->lastError.message = (char *) xmlStrdup(buf);
645d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard        } else {
646d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard            ctxt->lastError.message = (char *)
647d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard	       xmlStrdup(BAD_CAST "Memory allocation failed\n");
648d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard        }
649d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard        ctxt->lastError.domain = XML_FROM_XPATH;
650d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard        ctxt->lastError.code = XML_ERR_NO_MEMORY;
651d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard	if (ctxt->error != NULL)
652d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard	    ctxt->error(ctxt->userData, &ctxt->lastError);
653d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard    } else {
654d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard        if (extra)
655659e71ec2476d24bfca0d6432a69ef9a49a62be4Daniel Veillard            __xmlRaiseError(NULL, NULL, NULL,
656d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard                            NULL, NULL, XML_FROM_XPATH,
657d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard                            XML_ERR_NO_MEMORY, XML_ERR_FATAL, NULL, 0,
658d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard                            extra, NULL, NULL, 0, 0,
659d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard                            "Memory allocation failed : %s\n", extra);
660d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard        else
661659e71ec2476d24bfca0d6432a69ef9a49a62be4Daniel Veillard            __xmlRaiseError(NULL, NULL, NULL,
662d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard                            NULL, NULL, XML_FROM_XPATH,
663d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard                            XML_ERR_NO_MEMORY, XML_ERR_FATAL, NULL, 0,
664d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard                            NULL, NULL, NULL, 0, 0,
665d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard                            "Memory allocation failed\n");
666d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard    }
667d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard}
668d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard
669d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard/**
6708de5c0bd79cceeca3d55d6dbf8f0248b7239e050Daniel Veillard * xmlXPathPErrMemory:
671d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard * @ctxt:  an XPath parser context
672d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard * @extra:  extra informations
673d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard *
674d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard * Handle a redefinition of attribute error
675d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard */
676d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillardstatic void
677d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel VeillardxmlXPathPErrMemory(xmlXPathParserContextPtr ctxt, const char *extra)
678d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard{
679d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard    if (ctxt == NULL)
680d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard	xmlXPathErrMemory(NULL, extra);
68111ce4004d86bb4b317c48b7d5124ba33e40e10f5Daniel Veillard    else {
68211ce4004d86bb4b317c48b7d5124ba33e40e10f5Daniel Veillard	ctxt->error = XPATH_MEMORY_ERROR;
683d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard	xmlXPathErrMemory(ctxt->context, extra);
68411ce4004d86bb4b317c48b7d5124ba33e40e10f5Daniel Veillard    }
685d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard}
686d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard
687d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard/**
688d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard * xmlXPathErr:
689d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard * @ctxt:  a XPath parser context
690d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard * @error:  the error code
691d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard *
692cd65bc9a49b406899c78e9e8f6757acca54fc04eWilliam M. Brack * Handle an XPath error
693d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard */
694d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillardvoid
695d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel VeillardxmlXPathErr(xmlXPathParserContextPtr ctxt, int error)
696d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard{
697cd65bc9a49b406899c78e9e8f6757acca54fc04eWilliam M. Brack    if ((error < 0) || (error > MAXERRNO))
698cd65bc9a49b406899c78e9e8f6757acca54fc04eWilliam M. Brack	error = MAXERRNO;
699f88d8cf9f1c9538dba187290ad5add003dc22bc7Daniel Veillard    if (ctxt == NULL) {
700659e71ec2476d24bfca0d6432a69ef9a49a62be4Daniel Veillard	__xmlRaiseError(NULL, NULL, NULL,
701d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard			NULL, NULL, XML_FROM_XPATH,
702d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard			error + XML_XPATH_EXPRESSION_OK - XPATH_EXPRESSION_OK,
703d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard			XML_ERR_ERROR, NULL, 0,
704d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard			NULL, NULL, NULL, 0, 0,
705bccae2d21038967f5d83109f27b925bcd4795602Daniel Veillard			"%s", xmlXPathErrorMessages[error]);
706d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard	return;
707d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard    }
708f88d8cf9f1c9538dba187290ad5add003dc22bc7Daniel Veillard    ctxt->error = error;
709f88d8cf9f1c9538dba187290ad5add003dc22bc7Daniel Veillard    if (ctxt->context == NULL) {
710f88d8cf9f1c9538dba187290ad5add003dc22bc7Daniel Veillard	__xmlRaiseError(NULL, NULL, NULL,
711f88d8cf9f1c9538dba187290ad5add003dc22bc7Daniel Veillard			NULL, NULL, XML_FROM_XPATH,
712f88d8cf9f1c9538dba187290ad5add003dc22bc7Daniel Veillard			error + XML_XPATH_EXPRESSION_OK - XPATH_EXPRESSION_OK,
713f88d8cf9f1c9538dba187290ad5add003dc22bc7Daniel Veillard			XML_ERR_ERROR, NULL, 0,
714f88d8cf9f1c9538dba187290ad5add003dc22bc7Daniel Veillard			(const char *) ctxt->base, NULL, NULL,
715f88d8cf9f1c9538dba187290ad5add003dc22bc7Daniel Veillard			ctxt->cur - ctxt->base, 0,
716bccae2d21038967f5d83109f27b925bcd4795602Daniel Veillard			"%s", xmlXPathErrorMessages[error]);
717f88d8cf9f1c9538dba187290ad5add003dc22bc7Daniel Veillard	return;
718f88d8cf9f1c9538dba187290ad5add003dc22bc7Daniel Veillard    }
7191b2be101e8c7c6c0b65d9961a302885aead9bc22Aleksey Sanin
7201b2be101e8c7c6c0b65d9961a302885aead9bc22Aleksey Sanin    /* cleanup current last error */
72145490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard    xmlResetError(&ctxt->context->lastError);
7221b2be101e8c7c6c0b65d9961a302885aead9bc22Aleksey Sanin
723d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard    ctxt->context->lastError.domain = XML_FROM_XPATH;
724d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard    ctxt->context->lastError.code = error + XML_XPATH_EXPRESSION_OK -
725d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard                           XPATH_EXPRESSION_OK;
726fcf719ce0a94f0d438f69b73cd1ca31a7000da81Daniel Veillard    ctxt->context->lastError.level = XML_ERR_ERROR;
727d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard    ctxt->context->lastError.str1 = (char *) xmlStrdup(ctxt->base);
728d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard    ctxt->context->lastError.int1 = ctxt->cur - ctxt->base;
729d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard    ctxt->context->lastError.node = ctxt->context->debugNode;
730d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard    if (ctxt->context->error != NULL) {
731d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard	ctxt->context->error(ctxt->context->userData,
732d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard	                     &ctxt->context->lastError);
733d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard    } else {
734659e71ec2476d24bfca0d6432a69ef9a49a62be4Daniel Veillard	__xmlRaiseError(NULL, NULL, NULL,
735d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard			NULL, ctxt->context->debugNode, XML_FROM_XPATH,
736d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard			error + XML_XPATH_EXPRESSION_OK - XPATH_EXPRESSION_OK,
737d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard			XML_ERR_ERROR, NULL, 0,
738d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard			(const char *) ctxt->base, NULL, NULL,
739d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard			ctxt->cur - ctxt->base, 0,
740bccae2d21038967f5d83109f27b925bcd4795602Daniel Veillard			"%s", xmlXPathErrorMessages[error]);
741d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard    }
742d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard
743d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard}
744d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard
745d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard/**
746d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard * xmlXPatherror:
747d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard * @ctxt:  the XPath Parser context
748d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard * @file:  the file name
749d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard * @line:  the line number
750d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard * @no:  the error number
751d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard *
752d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard * Formats an error message.
753d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard */
754d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillardvoid
755d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel VeillardxmlXPatherror(xmlXPathParserContextPtr ctxt, const char *file ATTRIBUTE_UNUSED,
756d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard              int line ATTRIBUTE_UNUSED, int no) {
757d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard    xmlXPathErr(ctxt, no);
758d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard}
759d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard
760a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik/************************************************************************
76145490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *									*
76245490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *			Utilities					*
76345490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *									*
764a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik ************************************************************************/
765a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
766a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik/**
767a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * xsltPointerList:
768a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik *
769a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * Pointer-list for various purposes.
770a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik */
771a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchciktypedef struct _xmlPointerList xmlPointerList;
772a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchciktypedef xmlPointerList *xmlPointerListPtr;
773a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikstruct _xmlPointerList {
774a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    void **items;
775a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    int number;
776a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    int size;
777a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik};
778a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik/*
779a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik* TODO: Since such a list-handling is used in xmlschemas.c and libxslt
780a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik* and here, we should make the functions public.
781a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik*/
782a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikstatic int
78345490aebe7a60704e8ed850c498969858ab900eeDaniel VeillardxmlPointerListAddSize(xmlPointerListPtr list,
784a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		       void *item,
785a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		       int initialSize)
786a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik{
787a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    if (list->items == NULL) {
788a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	if (initialSize <= 0)
789a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    initialSize = 1;
790cd852ad154fd919d9a4bd955566b43bac848878aDaniel Veillard	list->items = (void **) xmlMalloc(initialSize * sizeof(void *));
791a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	if (list->items == NULL) {
792a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathErrMemory(NULL,
793a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		"xmlPointerListCreate: allocating item\n");
794a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    return(-1);
795a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	}
796a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	list->number = 0;
797a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	list->size = initialSize;
798a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    } else if (list->size <= list->number) {
799cd852ad154fd919d9a4bd955566b43bac848878aDaniel Veillard        if (list->size > 50000000) {
800cd852ad154fd919d9a4bd955566b43bac848878aDaniel Veillard	    xmlXPathErrMemory(NULL,
801cd852ad154fd919d9a4bd955566b43bac848878aDaniel Veillard		"xmlPointerListAddSize: re-allocating item\n");
802cd852ad154fd919d9a4bd955566b43bac848878aDaniel Veillard            return(-1);
803cd852ad154fd919d9a4bd955566b43bac848878aDaniel Veillard        }
804a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	list->size *= 2;
805a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	list->items = (void **) xmlRealloc(list->items,
806a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    list->size * sizeof(void *));
807a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	if (list->items == NULL) {
808a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathErrMemory(NULL,
809cd852ad154fd919d9a4bd955566b43bac848878aDaniel Veillard		"xmlPointerListAddSize: re-allocating item\n");
810a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    list->size = 0;
811a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    return(-1);
812a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	}
813a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    }
814a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    list->items[list->number++] = item;
815a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    return(0);
816a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik}
817a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
818a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik/**
819a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * xsltPointerListCreate:
820a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik *
821a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * Creates an xsltPointerList structure.
822a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik *
823a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * Returns a xsltPointerList structure or NULL in case of an error.
824a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik */
825a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikstatic xmlPointerListPtr
826a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. BuchcikxmlPointerListCreate(int initialSize)
827a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik{
828a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlPointerListPtr ret;
829a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
830a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    ret = xmlMalloc(sizeof(xmlPointerList));
831a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    if (ret == NULL) {
832a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	xmlXPathErrMemory(NULL,
833a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    "xmlPointerListCreate: allocating item\n");
834a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	return (NULL);
835a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    }
836a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    memset(ret, 0, sizeof(xmlPointerList));
837a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    if (initialSize > 0) {
838a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	xmlPointerListAddSize(ret, NULL, initialSize);
839a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	ret->number = 0;
840a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    }
841a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    return (ret);
842a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik}
843a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
844a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik/**
845a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * xsltPointerListFree:
846a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik *
847a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * Frees the xsltPointerList structure. This does not free
848a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * the content of the list.
849a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik */
850a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikstatic void
851a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. BuchcikxmlPointerListFree(xmlPointerListPtr list)
852a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik{
853a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    if (list == NULL)
854a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	return;
855a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    if (list->items != NULL)
856a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	xmlFree(list->items);
857a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlFree(list);
858a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik}
859d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard
860d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard/************************************************************************
86145490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *									*
86245490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *			Parser Types					*
86345490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *									*
8649e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard ************************************************************************/
8659e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
8669e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard/*
8679e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * Types are private:
8689e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard */
8699e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
8709e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillardtypedef enum {
8719e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    XPATH_OP_END=0,
8729e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    XPATH_OP_AND,
8739e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    XPATH_OP_OR,
8749e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    XPATH_OP_EQUAL,
8759e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    XPATH_OP_CMP,
8769e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    XPATH_OP_PLUS,
8779e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    XPATH_OP_MULT,
8789e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    XPATH_OP_UNION,
8799e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    XPATH_OP_ROOT,
8809e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    XPATH_OP_NODE,
8815691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik    XPATH_OP_RESET, /* 10 */
8829e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    XPATH_OP_COLLECT,
8835691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik    XPATH_OP_VALUE, /* 12 */
8849e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    XPATH_OP_VARIABLE,
8859e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    XPATH_OP_FUNCTION,
8869e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    XPATH_OP_ARG,
8879e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    XPATH_OP_PREDICATE,
8885691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik    XPATH_OP_FILTER, /* 17 */
8895691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik    XPATH_OP_SORT /* 18 */
8909e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard#ifdef LIBXML_XPTR_ENABLED
8919e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    ,XPATH_OP_RANGETO
8929e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard#endif
8939e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard} xmlXPathOp;
8949e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
8959e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillardtypedef enum {
8969e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    AXIS_ANCESTOR = 1,
8979e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    AXIS_ANCESTOR_OR_SELF,
8989e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    AXIS_ATTRIBUTE,
8999e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    AXIS_CHILD,
9009e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    AXIS_DESCENDANT,
9019e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    AXIS_DESCENDANT_OR_SELF,
9029e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    AXIS_FOLLOWING,
9039e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    AXIS_FOLLOWING_SIBLING,
9049e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    AXIS_NAMESPACE,
9059e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    AXIS_PARENT,
9069e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    AXIS_PRECEDING,
9079e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    AXIS_PRECEDING_SIBLING,
90845490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard    AXIS_SELF
9099e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard} xmlXPathAxisVal;
9109e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
9119e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillardtypedef enum {
9129e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    NODE_TEST_NONE = 0,
9139e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    NODE_TEST_TYPE = 1,
9149e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    NODE_TEST_PI = 2,
9159e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    NODE_TEST_ALL = 3,
9169e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    NODE_TEST_NS = 4,
9179e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    NODE_TEST_NAME = 5
9189e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard} xmlXPathTestVal;
9199e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
9209e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillardtypedef enum {
9219e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    NODE_TYPE_NODE = 0,
9229e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    NODE_TYPE_COMMENT = XML_COMMENT_NODE,
9239e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    NODE_TYPE_TEXT = XML_TEXT_NODE,
92445490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard    NODE_TYPE_PI = XML_PI_NODE
9259e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard} xmlXPathTypeVal;
9269e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
9279e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillardtypedef struct _xmlXPathStepOp xmlXPathStepOp;
9289e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillardtypedef xmlXPathStepOp *xmlXPathStepOpPtr;
9299e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillardstruct _xmlXPathStepOp {
930081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack    xmlXPathOp op;		/* The identifier of the operation */
931081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack    int ch1;			/* First child */
932081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack    int ch2;			/* Second child */
9339e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    int value;
9349e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    int value2;
9359e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    int value3;
9369e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    void *value4;
9379e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    void *value5;
938e39a93d0d3df9907cf3538cd3f1fbbe4106e893dDaniel Veillard    void *cache;
93942596ad20cdf1925dd79ea801cbe598b6e7b7aecDaniel Veillard    void *cacheURI;
9409e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard};
9419e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
9429e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillardstruct _xmlXPathCompExpr {
943081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack    int nbStep;			/* Number of steps in this expression */
944081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack    int maxStep;		/* Maximum number of steps allocated */
945081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack    xmlXPathStepOp *steps;	/* ops for computation of this expression */
946081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack    int last;			/* index of last step in expression */
947081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack    xmlChar *expr;		/* the expression being computed */
9484773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard    xmlDictPtr dict;		/* the dictionnary to use if any */
949f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#ifdef DEBUG_EVAL_COUNTS
950f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    int nb;
951f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    xmlChar *string;
952f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#endif
95356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard#ifdef XPATH_STREAMING
95456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard    xmlPatternPtr stream;
95556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard#endif
9569e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard};
9579e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
9589e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard/************************************************************************
95945490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *									*
96045490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *			Forward declarations				*
96145490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *									*
962631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik ************************************************************************/
963631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcikstatic void
964631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. BuchcikxmlXPathFreeValueTree(xmlNodeSetPtr obj);
965631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcikstatic void
966631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. BuchcikxmlXPathReleaseObject(xmlXPathContextPtr ctxt, xmlXPathObjectPtr obj);
967631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcikstatic int
968631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. BuchcikxmlXPathCompOpEvalFirst(xmlXPathParserContextPtr ctxt,
969631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik                        xmlXPathStepOpPtr op, xmlNodePtr *first);
970631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcikstatic int
971631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. BuchcikxmlXPathCompOpEvalToBoolean(xmlXPathParserContextPtr ctxt,
972324c75b3c3edffcd30e7afa2a32f0d83d928b10dKasimier T. Buchcik			    xmlXPathStepOpPtr op,
973324c75b3c3edffcd30e7afa2a32f0d83d928b10dKasimier T. Buchcik			    int isPredicate);
974631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik
975631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik/************************************************************************
97645490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *									*
97745490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *			Parser Type functions				*
97845490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *									*
9799e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard ************************************************************************/
9809e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
9819e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard/**
9829e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * xmlXPathNewCompExpr:
9839e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard *
9849e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * Create a new Xpath component
9859e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard *
9869e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * Returns the newly allocated xmlXPathCompExprPtr or NULL in case of error
9879e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard */
98856a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic xmlXPathCompExprPtr
9899e7160d45a18bfa26d708e22ba991f7670d0128bDaniel VeillardxmlXPathNewCompExpr(void) {
9909e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    xmlXPathCompExprPtr cur;
9919e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
9929e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    cur = (xmlXPathCompExprPtr) xmlMalloc(sizeof(xmlXPathCompExpr));
9939e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    if (cur == NULL) {
994d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard        xmlXPathErrMemory(NULL, "allocating component\n");
9959e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	return(NULL);
9969e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    }
9979e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    memset(cur, 0, sizeof(xmlXPathCompExpr));
9989e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    cur->maxStep = 10;
9999e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    cur->nbStep = 0;
10009e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    cur->steps = (xmlXPathStepOp *) xmlMalloc(cur->maxStep *
10019e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	                                   sizeof(xmlXPathStepOp));
10029e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    if (cur->steps == NULL) {
1003d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard        xmlXPathErrMemory(NULL, "allocating steps\n");
10049e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	xmlFree(cur);
10059e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	return(NULL);
10069e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    }
10079e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    memset(cur->steps, 0, cur->maxStep * sizeof(xmlXPathStepOp));
10089e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    cur->last = -1;
1009f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#ifdef DEBUG_EVAL_COUNTS
1010f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    cur->nb = 0;
1011f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#endif
10129e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    return(cur);
10139e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard}
10149e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
10159e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard/**
10169e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * xmlXPathFreeCompExpr:
10179e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * @comp:  an XPATH comp
10189e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard *
10199e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * Free up the memory allocated by @comp
10209e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard */
10219e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillardvoid
1022f06307e2c172284bb41376c396f757bdac9bdd19Daniel VeillardxmlXPathFreeCompExpr(xmlXPathCompExprPtr comp)
1023f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard{
10249e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    xmlXPathStepOpPtr op;
10259e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    int i;
10269e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
10279e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    if (comp == NULL)
1028f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        return;
10294773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard    if (comp->dict == NULL) {
10304773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard	for (i = 0; i < comp->nbStep; i++) {
10314773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard	    op = &comp->steps[i];
10324773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard	    if (op->value4 != NULL) {
10334773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard		if (op->op == XPATH_OP_VALUE)
10344773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard		    xmlXPathFreeObject(op->value4);
10354773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard		else
10364773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard		    xmlFree(op->value4);
10374773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard	    }
10384773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard	    if (op->value5 != NULL)
10394773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard		xmlFree(op->value5);
10404773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard	}
10414773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard    } else {
10424773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard	for (i = 0; i < comp->nbStep; i++) {
10434773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard	    op = &comp->steps[i];
10444773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard	    if (op->value4 != NULL) {
10454773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard		if (op->op == XPATH_OP_VALUE)
10464773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard		    xmlXPathFreeObject(op->value4);
10474773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard	    }
10484773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard	}
10494773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard        xmlDictFree(comp->dict);
10509e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    }
10519e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    if (comp->steps != NULL) {
1052f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        xmlFree(comp->steps);
10539e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    }
1054f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#ifdef DEBUG_EVAL_COUNTS
1055f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    if (comp->string != NULL) {
1056f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        xmlFree(comp->string);
1057f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    }
1058f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#endif
105956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard#ifdef XPATH_STREAMING
106056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard    if (comp->stream != NULL) {
106156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard        xmlFreePatternList(comp->stream);
106256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard    }
106356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard#endif
1064118aed78f360f51d182770e62b251ef324707aa2Daniel Veillard    if (comp->expr != NULL) {
1065118aed78f360f51d182770e62b251ef324707aa2Daniel Veillard        xmlFree(comp->expr);
1066118aed78f360f51d182770e62b251ef324707aa2Daniel Veillard    }
1067f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
10689e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    xmlFree(comp);
10699e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard}
10709e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
10719e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard/**
10729e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * xmlXPathCompExprAdd:
10739e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * @comp:  the compiled expression
10749e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * @ch1: first child index
10759e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * @ch2: second child index
10769e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * @op:  an op
10779e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * @value:  the first int value
10789e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * @value2:  the second int value
10799e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * @value3:  the third int value
10809e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * @value4:  the first string value
10819e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * @value5:  the second string value
10829e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard *
1083081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack * Add a step to an XPath Compiled Expression
10849e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard *
10859e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * Returns -1 in case of failure, the index otherwise
10869e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard */
108756a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic int
10889e7160d45a18bfa26d708e22ba991f7670d0128bDaniel VeillardxmlXPathCompExprAdd(xmlXPathCompExprPtr comp, int ch1, int ch2,
10899e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard   xmlXPathOp op, int value,
10909e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard   int value2, int value3, void *value4, void *value5) {
10919e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    if (comp->nbStep >= comp->maxStep) {
10929e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	xmlXPathStepOp *real;
10939e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
1094cd852ad154fd919d9a4bd955566b43bac848878aDaniel Veillard        if (comp->maxStep >= XPATH_MAX_STEPS) {
1095cd852ad154fd919d9a4bd955566b43bac848878aDaniel Veillard	    xmlXPathErrMemory(NULL, "adding step\n");
1096cd852ad154fd919d9a4bd955566b43bac848878aDaniel Veillard	    return(-1);
1097cd852ad154fd919d9a4bd955566b43bac848878aDaniel Veillard        }
10989e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	comp->maxStep *= 2;
10999e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	real = (xmlXPathStepOp *) xmlRealloc(comp->steps,
11009e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		                      comp->maxStep * sizeof(xmlXPathStepOp));
11019e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	if (real == NULL) {
11029e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    comp->maxStep /= 2;
1103d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard	    xmlXPathErrMemory(NULL, "adding step\n");
11049e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    return(-1);
11059e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	}
11069e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	comp->steps = real;
11079e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    }
11089e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    comp->last = comp->nbStep;
11099e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    comp->steps[comp->nbStep].ch1 = ch1;
11109e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    comp->steps[comp->nbStep].ch2 = ch2;
11119e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    comp->steps[comp->nbStep].op = op;
11129e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    comp->steps[comp->nbStep].value = value;
11139e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    comp->steps[comp->nbStep].value2 = value2;
11149e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    comp->steps[comp->nbStep].value3 = value3;
11154773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard    if ((comp->dict != NULL) &&
11164773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard        ((op == XPATH_OP_FUNCTION) || (op == XPATH_OP_VARIABLE) ||
11174773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard	 (op == XPATH_OP_COLLECT))) {
11184773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard        if (value4 != NULL) {
1119b337795500cbe3fc47ac2b81f3d955126c6fbfdeDaniel Veillard	    comp->steps[comp->nbStep].value4 = (xmlChar *)
1120c07ed5e6a14fb801cfd6bbb2a582caf726e5324eWilliam M. Brack	        (void *)xmlDictLookup(comp->dict, value4, -1);
11214773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard	    xmlFree(value4);
11224773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard	} else
11234773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard	    comp->steps[comp->nbStep].value4 = NULL;
11244773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard        if (value5 != NULL) {
1125b337795500cbe3fc47ac2b81f3d955126c6fbfdeDaniel Veillard	    comp->steps[comp->nbStep].value5 = (xmlChar *)
1126c07ed5e6a14fb801cfd6bbb2a582caf726e5324eWilliam M. Brack	        (void *)xmlDictLookup(comp->dict, value5, -1);
11274773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard	    xmlFree(value5);
11284773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard	} else
11294773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard	    comp->steps[comp->nbStep].value5 = NULL;
11304773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard    } else {
11314773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard	comp->steps[comp->nbStep].value4 = value4;
11324773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard	comp->steps[comp->nbStep].value5 = value5;
11334773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard    }
1134e39a93d0d3df9907cf3538cd3f1fbbe4106e893dDaniel Veillard    comp->steps[comp->nbStep].cache = NULL;
11359e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    return(comp->nbStep++);
11369e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard}
11379e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
1138f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard/**
1139f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * xmlXPathCompSwap:
1140f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * @comp:  the compiled expression
1141f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * @op: operation index
1142f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard *
1143f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Swaps 2 operations in the compiled expression
1144f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */
1145f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillardstatic void
1146f06307e2c172284bb41376c396f757bdac9bdd19Daniel VeillardxmlXPathCompSwap(xmlXPathStepOpPtr op) {
1147f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    int tmp;
1148f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
1149bc6f759ac9b41773e3643ad288b5214732051c98Daniel Veillard#ifndef LIBXML_THREAD_ENABLED
11508146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard    /*
11518146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard     * Since this manipulates possibly shared variables, this is
1152081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack     * disabled if one detects that the library is used in a multithreaded
11538146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard     * application
11548146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard     */
11558146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard    if (xmlXPathDisableOptimizer)
11568146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard	return;
11578146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard#endif
11588146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard
1159f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    tmp = op->ch1;
1160f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    op->ch1 = op->ch2;
1161f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    op->ch2 = tmp;
1162f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard}
1163f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
1164d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#define PUSH_FULL_EXPR(op, op1, op2, val, val2, val3, val4, val5)	\
1165d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard    xmlXPathCompExprAdd(ctxt->comp, (op1), (op2),			\
1166d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	                (op), (val), (val2), (val3), (val4), (val5))
11679e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard#define PUSH_LONG_EXPR(op, val, val2, val3, val4, val5)			\
11689e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    xmlXPathCompExprAdd(ctxt->comp, ctxt->comp->last, -1,		\
11699e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	                (op), (val), (val2), (val3), (val4), (val5))
11709e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
117145490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard#define PUSH_LEAVE_EXPR(op, val, val2)					\
11729e7160d45a18bfa26d708e22ba991f7670d0128bDaniel VeillardxmlXPathCompExprAdd(ctxt->comp, -1, -1, (op), (val), (val2), 0 ,NULL ,NULL)
11739e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
117445490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard#define PUSH_UNARY_EXPR(op, ch, val, val2)				\
11759e7160d45a18bfa26d708e22ba991f7670d0128bDaniel VeillardxmlXPathCompExprAdd(ctxt->comp, (ch), -1, (op), (val), (val2), 0 ,NULL ,NULL)
11769e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
117745490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard#define PUSH_BINARY_EXPR(op, ch1, ch2, val, val2)			\
1178081719182de3d15e6a438f32fdc3d1ca240a08e8William M. BrackxmlXPathCompExprAdd(ctxt->comp, (ch1), (ch2), (op),			\
1179081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack			(val), (val2), 0 ,NULL ,NULL)
11809e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
11819e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard/************************************************************************
11823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *									*
118345490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *		XPath object cache structures				*
1184a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik *									*
1185a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik ************************************************************************/
1186a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
1187a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik/* #define XP_DEFAULT_CACHE_ON */
1188a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
11895869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik#define XP_HAS_CACHE(c) ((c != NULL) && ((c)->cache != NULL))
1190a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
11915869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchciktypedef struct _xmlXPathContextCache xmlXPathContextCache;
11925869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchciktypedef xmlXPathContextCache *xmlXPathContextCachePtr;
11935869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcikstruct _xmlXPathContextCache {
119475af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik    xmlPointerListPtr nodesetObjs;  /* contains xmlXPathObjectPtr */
119575af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik    xmlPointerListPtr stringObjs;   /* contains xmlXPathObjectPtr */
119675af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik    xmlPointerListPtr booleanObjs;  /* contains xmlXPathObjectPtr */
119775af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik    xmlPointerListPtr numberObjs;   /* contains xmlXPathObjectPtr */
119875af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik    xmlPointerListPtr miscObjs;     /* contains xmlXPathObjectPtr */
1199a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    int maxNodeset;
1200a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    int maxString;
1201a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    int maxBoolean;
1202a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    int maxNumber;
1203a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    int maxMisc;
1204a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#ifdef XP_DEBUG_OBJ_USAGE
1205a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    int dbgCachedAll;
1206a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    int dbgCachedNodeset;
1207a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    int dbgCachedString;
1208a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    int dbgCachedBool;
1209a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    int dbgCachedNumber;
1210a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    int dbgCachedPoint;
1211a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    int dbgCachedRange;
1212a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    int dbgCachedLocset;
1213a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    int dbgCachedUsers;
1214a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    int dbgCachedXSLTTree;
121545490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard    int dbgCachedUndefined;
121645490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
1217a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
1218a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    int dbgReusedAll;
1219a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    int dbgReusedNodeset;
1220a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    int dbgReusedString;
1221a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    int dbgReusedBool;
1222a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    int dbgReusedNumber;
1223a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    int dbgReusedPoint;
1224a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    int dbgReusedRange;
1225a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    int dbgReusedLocset;
1226a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    int dbgReusedUsers;
1227a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    int dbgReusedXSLTTree;
1228a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    int dbgReusedUndefined;
1229a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
1230a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#endif
1231a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik};
1232a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
1233a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik/************************************************************************
1234a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik *									*
123545490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *		Debugging related functions				*
12363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *									*
12373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ************************************************************************/
12383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
123945490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard#define STRANGE							\
12403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlGenericError(xmlGenericErrorContext,				\
12413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    "Internal error at %s:%d\n",				\
12423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            __FILE__, __LINE__);
12433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
12443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef LIBXML_DEBUG_ENABLED
124556a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic void
124656a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel VeillardxmlXPathDebugDumpNode(FILE *output, xmlNodePtr cur, int depth) {
12473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    int i;
12483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    char shift[100];
12493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
12503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    for (i = 0;((i < depth) && (i < 25));i++)
12513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        shift[2 * i] = shift[2 * i + 1] = ' ';
12523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    shift[2 * i] = shift[2 * i + 1] = 0;
12533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (cur == NULL) {
1254bccae2d21038967f5d83109f27b925bcd4795602Daniel Veillard	fprintf(output, "%s", shift);
12553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	fprintf(output, "Node is NULL !\n");
12563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return;
125745490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
12583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
12593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
12603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if ((cur->type == XML_DOCUMENT_NODE) ||
12613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	     (cur->type == XML_HTML_DOCUMENT_NODE)) {
1262bccae2d21038967f5d83109f27b925bcd4795602Daniel Veillard	fprintf(output, "%s", shift);
12633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	fprintf(output, " /\n");
12643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    } else if (cur->type == XML_ATTRIBUTE_NODE)
12653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	xmlDebugDumpAttr(output, (xmlAttrPtr)cur, depth);
12663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    else
12673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	xmlDebugDumpOneNode(output, cur, depth);
12683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
126956a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic void
127056a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel VeillardxmlXPathDebugDumpNodeList(FILE *output, xmlNodePtr cur, int depth) {
1271f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard    xmlNodePtr tmp;
1272f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard    int i;
1273f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard    char shift[100];
1274f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard
1275f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard    for (i = 0;((i < depth) && (i < 25));i++)
1276f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard        shift[2 * i] = shift[2 * i + 1] = ' ';
1277f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard    shift[2 * i] = shift[2 * i + 1] = 0;
1278f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard    if (cur == NULL) {
1279bccae2d21038967f5d83109f27b925bcd4795602Daniel Veillard	fprintf(output, "%s", shift);
1280f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard	fprintf(output, "Node is NULL !\n");
1281f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard	return;
128245490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
1283f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard    }
1284f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard
1285f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard    while (cur != NULL) {
1286f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard	tmp = cur;
1287f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard	cur = cur->next;
1288f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard	xmlDebugDumpOneNode(output, tmp, depth);
1289f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard    }
1290f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard}
12913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
129256a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic void
129356a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel VeillardxmlXPathDebugDumpNodeSet(FILE *output, xmlNodeSetPtr cur, int depth) {
12943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    int i;
12953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    char shift[100];
12963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
12973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    for (i = 0;((i < depth) && (i < 25));i++)
12983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        shift[2 * i] = shift[2 * i + 1] = ' ';
12993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    shift[2 * i] = shift[2 * i + 1] = 0;
13003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
13013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (cur == NULL) {
1302bccae2d21038967f5d83109f27b925bcd4795602Daniel Veillard	fprintf(output, "%s", shift);
13033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	fprintf(output, "NodeSet is NULL !\n");
13043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return;
130545490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
13063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
13073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
1308911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard    if (cur != NULL) {
1309911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard	fprintf(output, "Set contains %d nodes:\n", cur->nodeNr);
1310911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard	for (i = 0;i < cur->nodeNr;i++) {
1311bccae2d21038967f5d83109f27b925bcd4795602Daniel Veillard	    fprintf(output, "%s", shift);
1312911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard	    fprintf(output, "%d", i + 1);
1313911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard	    xmlXPathDebugDumpNode(output, cur->nodeTab[i], depth + 1);
1314911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard	}
13153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
13163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
13173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
131856a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic void
131956a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel VeillardxmlXPathDebugDumpValueTree(FILE *output, xmlNodeSetPtr cur, int depth) {
1320f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard    int i;
1321f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard    char shift[100];
1322f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard
1323f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard    for (i = 0;((i < depth) && (i < 25));i++)
1324f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard        shift[2 * i] = shift[2 * i + 1] = ' ';
1325f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard    shift[2 * i] = shift[2 * i + 1] = 0;
1326f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard
1327f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard    if ((cur == NULL) || (cur->nodeNr == 0) || (cur->nodeTab[0] == NULL)) {
1328bccae2d21038967f5d83109f27b925bcd4795602Daniel Veillard	fprintf(output, "%s", shift);
1329f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard	fprintf(output, "Value Tree is NULL !\n");
1330f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard	return;
133145490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
1332f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard    }
1333f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard
1334bccae2d21038967f5d83109f27b925bcd4795602Daniel Veillard    fprintf(output, "%s", shift);
1335f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard    fprintf(output, "%d", i + 1);
1336f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard    xmlXPathDebugDumpNodeList(output, cur->nodeTab[0]->children, depth + 1);
1337f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard}
13383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#if defined(LIBXML_XPTR_ENABLED)
133956a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic void
134056a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel VeillardxmlXPathDebugDumpLocationSet(FILE *output, xmlLocationSetPtr cur, int depth) {
13413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    int i;
13423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    char shift[100];
13433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
13443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    for (i = 0;((i < depth) && (i < 25));i++)
13453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        shift[2 * i] = shift[2 * i + 1] = ' ';
13463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    shift[2 * i] = shift[2 * i + 1] = 0;
13473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
13483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (cur == NULL) {
1349bccae2d21038967f5d83109f27b925bcd4795602Daniel Veillard	fprintf(output, "%s", shift);
13503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	fprintf(output, "LocationSet is NULL !\n");
13513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return;
135245490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
13533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
13543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
13553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    for (i = 0;i < cur->locNr;i++) {
1356bccae2d21038967f5d83109f27b925bcd4795602Daniel Veillard	fprintf(output, "%s", shift);
13573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        fprintf(output, "%d : ", i + 1);
13583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	xmlXPathDebugDumpObject(output, cur->locTab[i], depth + 1);
13593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
13603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
1361017b108fcf16dbce05ca7ebd75763f3d888abb5fDaniel Veillard#endif /* LIBXML_XPTR_ENABLED */
13623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
1363afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard/**
1364afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathDebugDumpObject:
1365afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * @output:  the FILE * to dump the output
1366afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * @cur:  the object to inspect
1367afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * @depth:  indentation level
1368afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard *
1369afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Dump the content of the object for debugging purposes
1370afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard */
1371afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardvoid
1372afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathDebugDumpObject(FILE *output, xmlXPathObjectPtr cur, int depth) {
13733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    int i;
13743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    char shift[100];
13753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
1376a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard    if (output == NULL) return;
1377a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard
13783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    for (i = 0;((i < depth) && (i < 25));i++)
13793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        shift[2 * i] = shift[2 * i + 1] = ' ';
13803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    shift[2 * i] = shift[2 * i + 1] = 0;
13813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
138297258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik
1383bccae2d21038967f5d83109f27b925bcd4795602Daniel Veillard    fprintf(output, "%s", shift);
13843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
13853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (cur == NULL) {
13863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        fprintf(output, "Object is empty (NULL)\n");
13873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return;
13883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
13893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    switch(cur->type) {
13903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        case XPATH_UNDEFINED:
13913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    fprintf(output, "Object is uninitialized\n");
13923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    break;
13933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        case XPATH_NODESET:
13943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    fprintf(output, "Object is a Node Set :\n");
13953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    xmlXPathDebugDumpNodeSet(output, cur->nodesetval, depth);
13963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    break;
13973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XPATH_XSLT_TREE:
13983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    fprintf(output, "Object is an XSLT value tree :\n");
1399f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard	    xmlXPathDebugDumpValueTree(output, cur->nodesetval, depth);
14003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    break;
14013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        case XPATH_BOOLEAN:
14023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    fprintf(output, "Object is a Boolean : ");
14033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    if (cur->boolval) fprintf(output, "true\n");
14043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    else fprintf(output, "false\n");
14053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    break;
14063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        case XPATH_NUMBER:
1407cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard	    switch (xmlXPathIsInf(cur->floatval)) {
1408357c960e4035ee2fb40d0072bb7bde4533be76f8Daniel Veillard	    case 1:
14095fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard		fprintf(output, "Object is a number : Infinity\n");
1410357c960e4035ee2fb40d0072bb7bde4533be76f8Daniel Veillard		break;
1411357c960e4035ee2fb40d0072bb7bde4533be76f8Daniel Veillard	    case -1:
1412357c960e4035ee2fb40d0072bb7bde4533be76f8Daniel Veillard		fprintf(output, "Object is a number : -Infinity\n");
1413357c960e4035ee2fb40d0072bb7bde4533be76f8Daniel Veillard		break;
1414357c960e4035ee2fb40d0072bb7bde4533be76f8Daniel Veillard	    default:
1415cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard		if (xmlXPathIsNaN(cur->floatval)) {
1416357c960e4035ee2fb40d0072bb7bde4533be76f8Daniel Veillard		    fprintf(output, "Object is a number : NaN\n");
1417d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard		} else if (cur->floatval == 0 && xmlXPathGetSign(cur->floatval) != 0) {
1418d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard		    fprintf(output, "Object is a number : 0\n");
1419357c960e4035ee2fb40d0072bb7bde4533be76f8Daniel Veillard		} else {
1420357c960e4035ee2fb40d0072bb7bde4533be76f8Daniel Veillard		    fprintf(output, "Object is a number : %0g\n", cur->floatval);
1421357c960e4035ee2fb40d0072bb7bde4533be76f8Daniel Veillard		}
1422357c960e4035ee2fb40d0072bb7bde4533be76f8Daniel Veillard	    }
14233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    break;
14243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        case XPATH_STRING:
14253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    fprintf(output, "Object is a string : ");
14263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    xmlDebugDumpString(output, cur->stringval);
14273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    fprintf(output, "\n");
14283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    break;
14293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XPATH_POINT:
14303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    fprintf(output, "Object is a point : index %d in node", cur->index);
14313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    xmlXPathDebugDumpNode(output, (xmlNodePtr) cur->user, depth + 1);
14323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    fprintf(output, "\n");
14333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    break;
14343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XPATH_RANGE:
14353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    if ((cur->user2 == NULL) ||
14363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		((cur->user2 == cur->user) && (cur->index == cur->index2))) {
14373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		fprintf(output, "Object is a collapsed range :\n");
1438bccae2d21038967f5d83109f27b925bcd4795602Daniel Veillard		fprintf(output, "%s", shift);
14393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		if (cur->index >= 0)
14403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    fprintf(output, "index %d in ", cur->index);
14413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		fprintf(output, "node\n");
14423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		xmlXPathDebugDumpNode(output, (xmlNodePtr) cur->user,
14433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor			              depth + 1);
14443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    } else  {
14453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		fprintf(output, "Object is a range :\n");
1446bccae2d21038967f5d83109f27b925bcd4795602Daniel Veillard		fprintf(output, "%s", shift);
14473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		fprintf(output, "From ");
14483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		if (cur->index >= 0)
14493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    fprintf(output, "index %d in ", cur->index);
14503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		fprintf(output, "node\n");
14513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		xmlXPathDebugDumpNode(output, (xmlNodePtr) cur->user,
14523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor			              depth + 1);
1453bccae2d21038967f5d83109f27b925bcd4795602Daniel Veillard		fprintf(output, "%s", shift);
14543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		fprintf(output, "To ");
14553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		if (cur->index2 >= 0)
14563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    fprintf(output, "index %d in ", cur->index2);
14573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		fprintf(output, "node\n");
14583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		xmlXPathDebugDumpNode(output, (xmlNodePtr) cur->user2,
14593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor			              depth + 1);
14603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		fprintf(output, "\n");
14613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    }
14623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    break;
14633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XPATH_LOCATIONSET:
14643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#if defined(LIBXML_XPTR_ENABLED)
14653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    fprintf(output, "Object is a Location Set:\n");
14663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    xmlXPathDebugDumpLocationSet(output,
14673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    (xmlLocationSetPtr) cur->user, depth);
14683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif
14693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    break;
14703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XPATH_USERS:
14713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    fprintf(output, "Object is user defined\n");
14723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    break;
14733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
14743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
14759e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
147656a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic void
147756a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel VeillardxmlXPathDebugDumpStepOp(FILE *output, xmlXPathCompExprPtr comp,
14789e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	                     xmlXPathStepOpPtr op, int depth) {
14799e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    int i;
14809e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    char shift[100];
14819e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
14829e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    for (i = 0;((i < depth) && (i < 25));i++)
14839e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard        shift[2 * i] = shift[2 * i + 1] = ' ';
14849e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    shift[2 * i] = shift[2 * i + 1] = 0;
14859e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
1486bccae2d21038967f5d83109f27b925bcd4795602Daniel Veillard    fprintf(output, "%s", shift);
14879e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    if (op == NULL) {
14889e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	fprintf(output, "Step is NULL\n");
14899e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	return;
14909e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    }
14919e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    switch (op->op) {
14929e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard        case XPATH_OP_END:
14939e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    fprintf(output, "END"); break;
14949e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard        case XPATH_OP_AND:
14959e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    fprintf(output, "AND"); break;
14969e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard        case XPATH_OP_OR:
14979e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    fprintf(output, "OR"); break;
14989e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard        case XPATH_OP_EQUAL:
14999e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	     if (op->value)
15009e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		 fprintf(output, "EQUAL =");
15019e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	     else
15029e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		 fprintf(output, "EQUAL !=");
15039e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	     break;
15049e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard        case XPATH_OP_CMP:
15059e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	     if (op->value)
15069e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		 fprintf(output, "CMP <");
15079e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	     else
15089e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		 fprintf(output, "CMP >");
15099e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	     if (!op->value2)
15109e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		 fprintf(output, "=");
15119e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	     break;
15129e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard        case XPATH_OP_PLUS:
15139e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	     if (op->value == 0)
15149e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		 fprintf(output, "PLUS -");
15159e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	     else if (op->value == 1)
15169e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		 fprintf(output, "PLUS +");
15179e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	     else if (op->value == 2)
15189e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		 fprintf(output, "PLUS unary -");
15199e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	     else if (op->value == 3)
15209e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		 fprintf(output, "PLUS unary - -");
15219e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	     break;
15229e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard        case XPATH_OP_MULT:
15239e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	     if (op->value == 0)
15249e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		 fprintf(output, "MULT *");
15259e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	     else if (op->value == 1)
15269e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		 fprintf(output, "MULT div");
15279e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	     else
15289e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		 fprintf(output, "MULT mod");
15299e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	     break;
15309e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard        case XPATH_OP_UNION:
15319e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	     fprintf(output, "UNION"); break;
15329e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard        case XPATH_OP_ROOT:
15339e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	     fprintf(output, "ROOT"); break;
15349e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard        case XPATH_OP_NODE:
15359e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	     fprintf(output, "NODE"); break;
15369e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard        case XPATH_OP_RESET:
15379e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	     fprintf(output, "RESET"); break;
15389e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard        case XPATH_OP_SORT:
15399e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	     fprintf(output, "SORT"); break;
15409e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard        case XPATH_OP_COLLECT: {
154178637da0ea1c833dfdfad87a9aa5bea14510d08aWilliam M. Brack	    xmlXPathAxisVal axis = (xmlXPathAxisVal)op->value;
154278637da0ea1c833dfdfad87a9aa5bea14510d08aWilliam M. Brack	    xmlXPathTestVal test = (xmlXPathTestVal)op->value2;
154378637da0ea1c833dfdfad87a9aa5bea14510d08aWilliam M. Brack	    xmlXPathTypeVal type = (xmlXPathTypeVal)op->value3;
15449e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    const xmlChar *prefix = op->value4;
15459e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    const xmlChar *name = op->value5;
15469e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
15479e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    fprintf(output, "COLLECT ");
15489e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    switch (axis) {
15499e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		case AXIS_ANCESTOR:
15509e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    fprintf(output, " 'ancestors' "); break;
15519e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		case AXIS_ANCESTOR_OR_SELF:
15529e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    fprintf(output, " 'ancestors-or-self' "); break;
15539e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		case AXIS_ATTRIBUTE:
15549e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    fprintf(output, " 'attributes' "); break;
15559e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		case AXIS_CHILD:
15569e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    fprintf(output, " 'child' "); break;
15579e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		case AXIS_DESCENDANT:
15589e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    fprintf(output, " 'descendant' "); break;
15599e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		case AXIS_DESCENDANT_OR_SELF:
15609e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    fprintf(output, " 'descendant-or-self' "); break;
15619e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		case AXIS_FOLLOWING:
15629e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    fprintf(output, " 'following' "); break;
15639e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		case AXIS_FOLLOWING_SIBLING:
15649e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    fprintf(output, " 'following-siblings' "); break;
15659e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		case AXIS_NAMESPACE:
15669e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    fprintf(output, " 'namespace' "); break;
15679e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		case AXIS_PARENT:
15689e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    fprintf(output, " 'parent' "); break;
15699e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		case AXIS_PRECEDING:
15709e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    fprintf(output, " 'preceding' "); break;
15719e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		case AXIS_PRECEDING_SIBLING:
15729e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    fprintf(output, " 'preceding-sibling' "); break;
15739e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		case AXIS_SELF:
15749e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    fprintf(output, " 'self' "); break;
15759e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    }
15769e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    switch (test) {
15779e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard                case NODE_TEST_NONE:
15789e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    fprintf(output, "'none' "); break;
15799e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard                case NODE_TEST_TYPE:
15809e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    fprintf(output, "'type' "); break;
15819e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard                case NODE_TEST_PI:
15829e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    fprintf(output, "'PI' "); break;
15839e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard                case NODE_TEST_ALL:
15849e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    fprintf(output, "'all' "); break;
15859e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard                case NODE_TEST_NS:
15869e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    fprintf(output, "'namespace' "); break;
15879e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard                case NODE_TEST_NAME:
15889e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    fprintf(output, "'name' "); break;
15899e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    }
15909e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    switch (type) {
15919e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard                case NODE_TYPE_NODE:
15929e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    fprintf(output, "'node' "); break;
15939e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard                case NODE_TYPE_COMMENT:
15949e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    fprintf(output, "'comment' "); break;
15959e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard                case NODE_TYPE_TEXT:
15969e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    fprintf(output, "'text' "); break;
15979e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard                case NODE_TYPE_PI:
15989e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    fprintf(output, "'PI' "); break;
15999e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    }
16009e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    if (prefix != NULL)
16019e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		fprintf(output, "%s:", prefix);
16029e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    if (name != NULL)
1603580ced8ee28ecd99374da9383897678e4ba6c358Daniel Veillard		fprintf(output, "%s", (const char *) name);
16049e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    break;
16059e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
16069e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard        }
16079e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	case XPATH_OP_VALUE: {
16089e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    xmlXPathObjectPtr object = (xmlXPathObjectPtr) op->value4;
16099e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
16109e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    fprintf(output, "ELEM ");
16119e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    xmlXPathDebugDumpObject(output, object, 0);
16129e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    goto finish;
16139e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	}
16149e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	case XPATH_OP_VARIABLE: {
16159e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    const xmlChar *prefix = op->value5;
16169e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    const xmlChar *name = op->value4;
16179e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
16189e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    if (prefix != NULL)
16199e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		fprintf(output, "VARIABLE %s:%s", prefix, name);
16209e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    else
16219e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		fprintf(output, "VARIABLE %s", name);
16229e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    break;
16239e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	}
16249e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	case XPATH_OP_FUNCTION: {
16259e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    int nbargs = op->value;
16269e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    const xmlChar *prefix = op->value5;
16279e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    const xmlChar *name = op->value4;
16289e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
16299e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    if (prefix != NULL)
16309e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		fprintf(output, "FUNCTION %s:%s(%d args)",
16319e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard			prefix, name, nbargs);
16329e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    else
16339e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		fprintf(output, "FUNCTION %s(%d args)", name, nbargs);
16349e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    break;
16359e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	}
16369e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard        case XPATH_OP_ARG: fprintf(output, "ARG"); break;
16379e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard        case XPATH_OP_PREDICATE: fprintf(output, "PREDICATE"); break;
1638d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard        case XPATH_OP_FILTER: fprintf(output, "FILTER"); break;
1639fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard#ifdef LIBXML_XPTR_ENABLED
1640fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard        case XPATH_OP_RANGETO: fprintf(output, "RANGETO"); break;
1641fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard#endif
16429e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	default:
16439e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard        fprintf(output, "UNKNOWN %d\n", op->op); return;
16449e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    }
1645a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    fprintf(output, "\n");
1646a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikfinish:
1647a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    if (op->ch1 >= 0)
1648a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	xmlXPathDebugDumpStepOp(output, comp, &comp->steps[op->ch1], depth + 1);
1649a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    if (op->ch2 >= 0)
1650a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	xmlXPathDebugDumpStepOp(output, comp, &comp->steps[op->ch2], depth + 1);
1651a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik}
1652a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
1653a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik/**
1654a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * xmlXPathDebugDumpCompExpr:
1655a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * @output:  the FILE * for the output
1656a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * @comp:  the precompiled XPath expression
1657a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * @depth:  the indentation level.
1658a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik *
1659a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * Dumps the tree of the compiled XPath expression.
1660a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik */
1661a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikvoid
1662a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. BuchcikxmlXPathDebugDumpCompExpr(FILE *output, xmlXPathCompExprPtr comp,
1663a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	                  int depth) {
1664a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    int i;
1665a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    char shift[100];
1666a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
1667a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    if ((output == NULL) || (comp == NULL)) return;
1668a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
1669a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    for (i = 0;((i < depth) && (i < 25));i++)
1670a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik        shift[2 * i] = shift[2 * i + 1] = ' ';
1671a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    shift[2 * i] = shift[2 * i + 1] = 0;
1672a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
1673bccae2d21038967f5d83109f27b925bcd4795602Daniel Veillard    fprintf(output, "%s", shift);
1674a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
1675a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    fprintf(output, "Compiled Expression : %d elements\n",
1676a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    comp->nbStep);
1677a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    i = comp->last;
1678a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathDebugDumpStepOp(output, comp, &comp->steps[i], depth + 1);
1679a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik}
1680a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
1681a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#ifdef XP_DEBUG_OBJ_USAGE
1682a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
1683a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik/*
1684a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik* XPath object usage related debugging variables.
1685a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik*/
1686a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikstatic int xmlXPathDebugObjCounterUndefined = 0;
1687a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikstatic int xmlXPathDebugObjCounterNodeset = 0;
1688a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikstatic int xmlXPathDebugObjCounterBool = 0;
1689a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikstatic int xmlXPathDebugObjCounterNumber = 0;
1690a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikstatic int xmlXPathDebugObjCounterString = 0;
1691a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikstatic int xmlXPathDebugObjCounterPoint = 0;
1692a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikstatic int xmlXPathDebugObjCounterRange = 0;
1693a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikstatic int xmlXPathDebugObjCounterLocset = 0;
1694a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikstatic int xmlXPathDebugObjCounterUsers = 0;
1695a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikstatic int xmlXPathDebugObjCounterXSLTTree = 0;
1696a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikstatic int xmlXPathDebugObjCounterAll = 0;
1697a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
1698a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikstatic int xmlXPathDebugObjTotalUndefined = 0;
1699a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikstatic int xmlXPathDebugObjTotalNodeset = 0;
1700a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikstatic int xmlXPathDebugObjTotalBool = 0;
1701a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikstatic int xmlXPathDebugObjTotalNumber = 0;
1702a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikstatic int xmlXPathDebugObjTotalString = 0;
1703a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikstatic int xmlXPathDebugObjTotalPoint = 0;
1704a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikstatic int xmlXPathDebugObjTotalRange = 0;
1705a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikstatic int xmlXPathDebugObjTotalLocset = 0;
1706a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikstatic int xmlXPathDebugObjTotalUsers = 0;
1707a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikstatic int xmlXPathDebugObjTotalXSLTTree = 0;
170845490aebe7a60704e8ed850c498969858ab900eeDaniel Veillardstatic int xmlXPathDebugObjTotalAll = 0;
1709a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
1710a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikstatic int xmlXPathDebugObjMaxUndefined = 0;
1711a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikstatic int xmlXPathDebugObjMaxNodeset = 0;
1712a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikstatic int xmlXPathDebugObjMaxBool = 0;
1713a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikstatic int xmlXPathDebugObjMaxNumber = 0;
1714a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikstatic int xmlXPathDebugObjMaxString = 0;
1715a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikstatic int xmlXPathDebugObjMaxPoint = 0;
1716a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikstatic int xmlXPathDebugObjMaxRange = 0;
1717a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikstatic int xmlXPathDebugObjMaxLocset = 0;
1718a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikstatic int xmlXPathDebugObjMaxUsers = 0;
1719a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikstatic int xmlXPathDebugObjMaxXSLTTree = 0;
1720a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikstatic int xmlXPathDebugObjMaxAll = 0;
1721a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
1722a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik/* REVISIT TODO: Make this static when committing */
1723a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikstatic void
1724a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. BuchcikxmlXPathDebugObjUsageReset(xmlXPathContextPtr ctxt)
1725a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik{
1726a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    if (ctxt != NULL) {
17275869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik	if (ctxt->cache != NULL) {
17285869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik	    xmlXPathContextCachePtr cache =
17295869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik		(xmlXPathContextCachePtr) ctxt->cache;
1730a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
1731a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    cache->dbgCachedAll = 0;
1732a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    cache->dbgCachedNodeset = 0;
1733a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    cache->dbgCachedString = 0;
1734a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    cache->dbgCachedBool = 0;
1735a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    cache->dbgCachedNumber = 0;
1736a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    cache->dbgCachedPoint = 0;
1737a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    cache->dbgCachedRange = 0;
1738a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    cache->dbgCachedLocset = 0;
1739a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    cache->dbgCachedUsers = 0;
1740a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    cache->dbgCachedXSLTTree = 0;
174145490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	    cache->dbgCachedUndefined = 0;
1742a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
1743a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    cache->dbgReusedAll = 0;
1744a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    cache->dbgReusedNodeset = 0;
1745a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    cache->dbgReusedString = 0;
1746a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    cache->dbgReusedBool = 0;
1747a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    cache->dbgReusedNumber = 0;
1748a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    cache->dbgReusedPoint = 0;
1749a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    cache->dbgReusedRange = 0;
1750a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    cache->dbgReusedLocset = 0;
1751a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    cache->dbgReusedUsers = 0;
1752a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    cache->dbgReusedXSLTTree = 0;
1753a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    cache->dbgReusedUndefined = 0;
1754a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	}
175545490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard    }
1756a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
1757a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathDebugObjCounterUndefined = 0;
1758a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathDebugObjCounterNodeset = 0;
1759a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathDebugObjCounterBool = 0;
1760a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathDebugObjCounterNumber = 0;
1761a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathDebugObjCounterString = 0;
1762a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathDebugObjCounterPoint = 0;
1763a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathDebugObjCounterRange = 0;
1764a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathDebugObjCounterLocset = 0;
1765a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathDebugObjCounterUsers = 0;
1766a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathDebugObjCounterXSLTTree = 0;
1767a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathDebugObjCounterAll = 0;
176845490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
1769a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathDebugObjTotalUndefined = 0;
1770a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathDebugObjTotalNodeset = 0;
1771a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathDebugObjTotalBool = 0;
1772a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathDebugObjTotalNumber = 0;
1773a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathDebugObjTotalString = 0;
1774a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathDebugObjTotalPoint = 0;
1775a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathDebugObjTotalRange = 0;
1776a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathDebugObjTotalLocset = 0;
1777a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathDebugObjTotalUsers = 0;
1778a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathDebugObjTotalXSLTTree = 0;
177945490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard    xmlXPathDebugObjTotalAll = 0;
1780a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
1781a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathDebugObjMaxUndefined = 0;
1782a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathDebugObjMaxNodeset = 0;
1783a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathDebugObjMaxBool = 0;
1784a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathDebugObjMaxNumber = 0;
1785a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathDebugObjMaxString = 0;
1786a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathDebugObjMaxPoint = 0;
1787a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathDebugObjMaxRange = 0;
1788a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathDebugObjMaxLocset = 0;
1789a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathDebugObjMaxUsers = 0;
1790a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathDebugObjMaxXSLTTree = 0;
1791a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathDebugObjMaxAll = 0;
1792a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
1793a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik}
1794a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
1795a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikstatic void
1796a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. BuchcikxmlXPathDebugObjUsageRequested(xmlXPathContextPtr ctxt,
1797a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik			      xmlXPathObjectType objType)
1798a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik{
1799a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    int isCached = 0;
1800a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
1801a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    if (ctxt != NULL) {
18025869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik	if (ctxt->cache != NULL) {
18035869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik	    xmlXPathContextCachePtr cache =
18045869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik		(xmlXPathContextCachePtr) ctxt->cache;
180545490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
1806a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    isCached = 1;
180745490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
180845490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	    cache->dbgReusedAll++;
1809a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    switch (objType) {
1810a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		case XPATH_UNDEFINED:
1811a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    cache->dbgReusedUndefined++;
1812a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    break;
1813a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		case XPATH_NODESET:
1814a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    cache->dbgReusedNodeset++;
1815a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    break;
1816a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		case XPATH_BOOLEAN:
1817a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    cache->dbgReusedBool++;
1818a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    break;
1819a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		case XPATH_NUMBER:
1820a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    cache->dbgReusedNumber++;
1821a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    break;
1822a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		case XPATH_STRING:
1823a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    cache->dbgReusedString++;
1824a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    break;
1825a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		case XPATH_POINT:
1826a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    cache->dbgReusedPoint++;
1827a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    break;
1828a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		case XPATH_RANGE:
1829a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    cache->dbgReusedRange++;
1830a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    break;
1831a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		case XPATH_LOCATIONSET:
1832a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    cache->dbgReusedLocset++;
1833a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    break;
1834a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		case XPATH_USERS:
1835a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    cache->dbgReusedUsers++;
1836a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    break;
1837a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		case XPATH_XSLT_TREE:
1838a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    cache->dbgReusedXSLTTree++;
1839a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    break;
1840a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		default:
1841a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    break;
184245490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	    }
1843a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	}
1844a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    }
1845a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
1846a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    switch (objType) {
1847a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	case XPATH_UNDEFINED:
1848a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    if (! isCached)
1849a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		xmlXPathDebugObjTotalUndefined++;
185045490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	    xmlXPathDebugObjCounterUndefined++;
1851a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    if (xmlXPathDebugObjCounterUndefined >
1852a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		xmlXPathDebugObjMaxUndefined)
1853a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		xmlXPathDebugObjMaxUndefined =
1854a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    xmlXPathDebugObjCounterUndefined;
1855a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    break;
1856a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	case XPATH_NODESET:
1857a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    if (! isCached)
1858a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		xmlXPathDebugObjTotalNodeset++;
185945490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	    xmlXPathDebugObjCounterNodeset++;
1860a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    if (xmlXPathDebugObjCounterNodeset >
1861a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		xmlXPathDebugObjMaxNodeset)
1862a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		xmlXPathDebugObjMaxNodeset =
1863a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    xmlXPathDebugObjCounterNodeset;
1864a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    break;
1865a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	case XPATH_BOOLEAN:
1866a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    if (! isCached)
1867a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		xmlXPathDebugObjTotalBool++;
186845490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	    xmlXPathDebugObjCounterBool++;
1869a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    if (xmlXPathDebugObjCounterBool >
1870a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		xmlXPathDebugObjMaxBool)
1871a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		xmlXPathDebugObjMaxBool =
1872a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    xmlXPathDebugObjCounterBool;
1873a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    break;
1874a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	case XPATH_NUMBER:
1875a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    if (! isCached)
1876a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		xmlXPathDebugObjTotalNumber++;
187745490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	    xmlXPathDebugObjCounterNumber++;
1878a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    if (xmlXPathDebugObjCounterNumber >
1879a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		xmlXPathDebugObjMaxNumber)
1880a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		xmlXPathDebugObjMaxNumber =
1881a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    xmlXPathDebugObjCounterNumber;
1882a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    break;
1883a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	case XPATH_STRING:
1884a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    if (! isCached)
1885a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		xmlXPathDebugObjTotalString++;
188645490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	    xmlXPathDebugObjCounterString++;
1887a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    if (xmlXPathDebugObjCounterString >
1888a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		xmlXPathDebugObjMaxString)
1889a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		xmlXPathDebugObjMaxString =
1890a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    xmlXPathDebugObjCounterString;
1891a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    break;
1892a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	case XPATH_POINT:
1893a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    if (! isCached)
1894a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		xmlXPathDebugObjTotalPoint++;
189545490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	    xmlXPathDebugObjCounterPoint++;
1896a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    if (xmlXPathDebugObjCounterPoint >
1897a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		xmlXPathDebugObjMaxPoint)
1898a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		xmlXPathDebugObjMaxPoint =
1899a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    xmlXPathDebugObjCounterPoint;
1900a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    break;
1901a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	case XPATH_RANGE:
1902a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    if (! isCached)
1903a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		xmlXPathDebugObjTotalRange++;
1904a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathDebugObjCounterRange++;
1905a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    if (xmlXPathDebugObjCounterRange >
1906a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		xmlXPathDebugObjMaxRange)
1907a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		xmlXPathDebugObjMaxRange =
1908a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    xmlXPathDebugObjCounterRange;
1909a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    break;
1910a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	case XPATH_LOCATIONSET:
1911a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    if (! isCached)
1912a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		xmlXPathDebugObjTotalLocset++;
1913a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathDebugObjCounterLocset++;
1914a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    if (xmlXPathDebugObjCounterLocset >
1915a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		xmlXPathDebugObjMaxLocset)
1916a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		xmlXPathDebugObjMaxLocset =
1917a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    xmlXPathDebugObjCounterLocset;
1918a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    break;
1919a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	case XPATH_USERS:
1920a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    if (! isCached)
1921a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		xmlXPathDebugObjTotalUsers++;
192245490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	    xmlXPathDebugObjCounterUsers++;
1923a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    if (xmlXPathDebugObjCounterUsers >
1924a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		xmlXPathDebugObjMaxUsers)
1925a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		xmlXPathDebugObjMaxUsers =
1926a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    xmlXPathDebugObjCounterUsers;
1927a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    break;
1928a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	case XPATH_XSLT_TREE:
1929a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    if (! isCached)
1930a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		xmlXPathDebugObjTotalXSLTTree++;
193145490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	    xmlXPathDebugObjCounterXSLTTree++;
1932a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    if (xmlXPathDebugObjCounterXSLTTree >
1933a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		xmlXPathDebugObjMaxXSLTTree)
1934a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		xmlXPathDebugObjMaxXSLTTree =
1935a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    xmlXPathDebugObjCounterXSLTTree;
1936a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    break;
1937a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	default:
1938a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    break;
1939a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    }
1940a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    if (! isCached)
1941a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	xmlXPathDebugObjTotalAll++;
1942a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathDebugObjCounterAll++;
1943a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    if (xmlXPathDebugObjCounterAll >
1944a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	xmlXPathDebugObjMaxAll)
1945a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	xmlXPathDebugObjMaxAll =
1946a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathDebugObjCounterAll;
1947a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik}
1948a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
1949a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikstatic void
1950a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. BuchcikxmlXPathDebugObjUsageReleased(xmlXPathContextPtr ctxt,
1951a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik			      xmlXPathObjectType objType)
1952a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik{
1953a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    int isCached = 0;
1954a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
1955a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    if (ctxt != NULL) {
19565869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik	if (ctxt->cache != NULL) {
19575869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik	    xmlXPathContextCachePtr cache =
19585869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik		(xmlXPathContextCachePtr) ctxt->cache;
1959a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
196045490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	    isCached = 1;
196145490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
1962a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    cache->dbgCachedAll++;
1963a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    switch (objType) {
1964a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		case XPATH_UNDEFINED:
1965a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    cache->dbgCachedUndefined++;
1966a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    break;
1967a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		case XPATH_NODESET:
1968a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    cache->dbgCachedNodeset++;
1969a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    break;
1970a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		case XPATH_BOOLEAN:
1971a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    cache->dbgCachedBool++;
1972a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    break;
1973a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		case XPATH_NUMBER:
1974a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    cache->dbgCachedNumber++;
1975a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    break;
1976a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		case XPATH_STRING:
1977a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    cache->dbgCachedString++;
1978a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    break;
1979a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		case XPATH_POINT:
1980a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    cache->dbgCachedPoint++;
1981a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    break;
1982a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		case XPATH_RANGE:
1983a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    cache->dbgCachedRange++;
1984a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    break;
1985a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		case XPATH_LOCATIONSET:
1986a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    cache->dbgCachedLocset++;
1987a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    break;
1988a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		case XPATH_USERS:
1989a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    cache->dbgCachedUsers++;
1990a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    break;
1991a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		case XPATH_XSLT_TREE:
1992a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    cache->dbgCachedXSLTTree++;
1993a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    break;
1994a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		default:
1995a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    break;
1996a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    }
199745490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
1998a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	}
1999a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    }
2000a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    switch (objType) {
2001a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	case XPATH_UNDEFINED:
2002a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathDebugObjCounterUndefined--;
2003a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    break;
2004a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	case XPATH_NODESET:
2005a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathDebugObjCounterNodeset--;
2006a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    break;
2007a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	case XPATH_BOOLEAN:
2008a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathDebugObjCounterBool--;
2009a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    break;
2010a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	case XPATH_NUMBER:
2011a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathDebugObjCounterNumber--;
2012a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    break;
2013a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	case XPATH_STRING:
2014a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathDebugObjCounterString--;
2015a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    break;
2016a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	case XPATH_POINT:
2017a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathDebugObjCounterPoint--;
2018a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    break;
2019a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	case XPATH_RANGE:
2020a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathDebugObjCounterRange--;
2021a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    break;
2022a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	case XPATH_LOCATIONSET:
2023a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathDebugObjCounterLocset--;
2024a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    break;
2025a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	case XPATH_USERS:
2026a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathDebugObjCounterUsers--;
2027a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    break;
2028a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	case XPATH_XSLT_TREE:
2029a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathDebugObjCounterXSLTTree--;
2030a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    break;
2031a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	default:
2032a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    break;
203345490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard    }
2034a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathDebugObjCounterAll--;
2035a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik}
2036a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
2037a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik/* REVISIT TODO: Make this static when committing */
2038a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikstatic void
2039a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. BuchcikxmlXPathDebugObjUsageDisplay(xmlXPathContextPtr ctxt)
2040a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik{
2041a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    int reqAll, reqNodeset, reqString, reqBool, reqNumber,
2042a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	reqXSLTTree, reqUndefined;
2043a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    int caAll = 0, caNodeset = 0, caString = 0, caBool = 0,
2044a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	caNumber = 0, caXSLTTree = 0, caUndefined = 0;
2045a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    int reAll = 0, reNodeset = 0, reString = 0, reBool = 0,
2046a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	reNumber = 0, reXSLTTree = 0, reUndefined = 0;
2047a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    int leftObjs = xmlXPathDebugObjCounterAll;
2048a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
2049a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    reqAll = xmlXPathDebugObjTotalAll;
2050a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    reqNodeset = xmlXPathDebugObjTotalNodeset;
2051a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    reqString = xmlXPathDebugObjTotalString;
2052a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    reqBool = xmlXPathDebugObjTotalBool;
2053a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    reqNumber = xmlXPathDebugObjTotalNumber;
2054a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    reqXSLTTree = xmlXPathDebugObjTotalXSLTTree;
2055a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    reqUndefined = xmlXPathDebugObjTotalUndefined;
205645490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
2057a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    printf("# XPath object usage:\n");
2058a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
2059a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    if (ctxt != NULL) {
20605869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik	if (ctxt->cache != NULL) {
20615869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik	    xmlXPathContextCachePtr cache =
20625869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik		(xmlXPathContextCachePtr) ctxt->cache;
2063a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
2064a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    reAll = cache->dbgReusedAll;
2065a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    reqAll += reAll;
2066a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    reNodeset = cache->dbgReusedNodeset;
2067a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    reqNodeset += reNodeset;
2068a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    reString = cache->dbgReusedString;
2069a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    reqString += reString;
2070a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    reBool = cache->dbgReusedBool;
2071a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    reqBool += reBool;
2072a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    reNumber = cache->dbgReusedNumber;
2073a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    reqNumber += reNumber;
2074a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    reXSLTTree = cache->dbgReusedXSLTTree;
2075a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    reqXSLTTree += reXSLTTree;
2076a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    reUndefined = cache->dbgReusedUndefined;
2077a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    reqUndefined += reUndefined;
207845490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
2079a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    caAll = cache->dbgCachedAll;
2080a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    caBool = cache->dbgCachedBool;
2081a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    caNodeset = cache->dbgCachedNodeset;
2082a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    caString = cache->dbgCachedString;
2083a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    caNumber = cache->dbgCachedNumber;
2084a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    caXSLTTree = cache->dbgCachedXSLTTree;
2085a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    caUndefined = cache->dbgCachedUndefined;
208645490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
2087a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    if (cache->nodesetObjs)
2088a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		leftObjs -= cache->nodesetObjs->number;
2089a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    if (cache->stringObjs)
2090a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		leftObjs -= cache->stringObjs->number;
2091a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    if (cache->booleanObjs)
2092a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		leftObjs -= cache->booleanObjs->number;
2093a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    if (cache->numberObjs)
2094a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		leftObjs -= cache->numberObjs->number;
2095a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    if (cache->miscObjs)
2096a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		leftObjs -= cache->miscObjs->number;
2097a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	}
2098a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    }
209945490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
210045490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard    printf("# all\n");
2101a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    printf("#   total  : %d\n", reqAll);
2102a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    printf("#   left  : %d\n", leftObjs);
2103a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    printf("#   created: %d\n", xmlXPathDebugObjTotalAll);
2104a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    printf("#   reused : %d\n", reAll);
2105a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    printf("#   max    : %d\n", xmlXPathDebugObjMaxAll);
2106a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
2107a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    printf("# node-sets\n");
2108a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    printf("#   total  : %d\n", reqNodeset);
2109a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    printf("#   created: %d\n", xmlXPathDebugObjTotalNodeset);
2110a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    printf("#   reused : %d\n", reNodeset);
2111a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    printf("#   max    : %d\n", xmlXPathDebugObjMaxNodeset);
2112a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
2113a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    printf("# strings\n");
2114a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    printf("#   total  : %d\n", reqString);
2115a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    printf("#   created: %d\n", xmlXPathDebugObjTotalString);
2116a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    printf("#   reused : %d\n", reString);
2117a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    printf("#   max    : %d\n", xmlXPathDebugObjMaxString);
2118a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
2119a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    printf("# booleans\n");
2120a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    printf("#   total  : %d\n", reqBool);
2121a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    printf("#   created: %d\n", xmlXPathDebugObjTotalBool);
2122a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    printf("#   reused : %d\n", reBool);
2123a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    printf("#   max    : %d\n", xmlXPathDebugObjMaxBool);
2124a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
2125a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    printf("# numbers\n");
2126a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    printf("#   total  : %d\n", reqNumber);
2127a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    printf("#   created: %d\n", xmlXPathDebugObjTotalNumber);
2128a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    printf("#   reused : %d\n", reNumber);
2129a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    printf("#   max    : %d\n", xmlXPathDebugObjMaxNumber);
2130a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
2131a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    printf("# XSLT result tree fragments\n");
2132a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    printf("#   total  : %d\n", reqXSLTTree);
2133a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    printf("#   created: %d\n", xmlXPathDebugObjTotalXSLTTree);
2134a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    printf("#   reused : %d\n", reXSLTTree);
2135a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    printf("#   max    : %d\n", xmlXPathDebugObjMaxXSLTTree);
2136a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
2137a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    printf("# undefined\n");
2138a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    printf("#   total  : %d\n", reqUndefined);
2139a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    printf("#   created: %d\n", xmlXPathDebugObjTotalUndefined);
2140a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    printf("#   reused : %d\n", reUndefined);
2141a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    printf("#   max    : %d\n", xmlXPathDebugObjMaxUndefined);
2142a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
2143a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik}
2144a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
2145a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#endif /* XP_DEBUG_OBJ_USAGE */
2146a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
2147a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#endif /* LIBXML_DEBUG_ENABLED */
2148a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
2149a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik/************************************************************************
2150a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik *									*
2151a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik *			XPath object caching				*
2152a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik *									*
2153a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik ************************************************************************/
2154a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
2155a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik/**
21565869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik * xmlXPathNewCache:
2157a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik *
2158a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * Create a new object cache
2159a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik *
21605869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik * Returns the xmlXPathCache just allocated.
2161a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik */
21625869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcikstatic xmlXPathContextCachePtr
21635869469f42db259a21fb0721d66513de0b619097Kasimier T. BuchcikxmlXPathNewCache(void)
2164a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik{
21655869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik    xmlXPathContextCachePtr ret;
2166a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
21675869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik    ret = (xmlXPathContextCachePtr) xmlMalloc(sizeof(xmlXPathContextCache));
2168a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    if (ret == NULL) {
2169a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik        xmlXPathErrMemory(NULL, "creating object cache\n");
2170a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	return(NULL);
2171a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    }
21725869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik    memset(ret, 0 , (size_t) sizeof(xmlXPathContextCache));
2173a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    ret->maxNodeset = 100;
2174a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    ret->maxString = 100;
2175a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    ret->maxBoolean = 100;
2176a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    ret->maxNumber = 100;
2177a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    ret->maxMisc = 100;
2178a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    return(ret);
2179a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik}
2180a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
2181a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikstatic void
21825869469f42db259a21fb0721d66513de0b619097Kasimier T. BuchcikxmlXPathCacheFreeObjectList(xmlPointerListPtr list)
2183a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik{
2184a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    int i;
2185a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathObjectPtr obj;
2186a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
2187a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    if (list == NULL)
2188a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	return;
2189a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
2190a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    for (i = 0; i < list->number; i++) {
2191a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	obj = list->items[i];
2192a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	/*
2193a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	* Note that it is already assured that we don't need to
2194a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	* look out for namespace nodes in the node-set.
2195a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	*/
2196a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	if (obj->nodesetval != NULL) {
2197a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    if (obj->nodesetval->nodeTab != NULL)
2198a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		xmlFree(obj->nodesetval->nodeTab);
2199a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlFree(obj->nodesetval);
2200a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	}
2201a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	xmlFree(obj);
2202a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#ifdef XP_DEBUG_OBJ_USAGE
2203a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	xmlXPathDebugObjCounterAll--;
2204a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#endif
2205a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    }
2206a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlPointerListFree(list);
2207a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik}
2208a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
2209a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikstatic void
22105869469f42db259a21fb0721d66513de0b619097Kasimier T. BuchcikxmlXPathFreeCache(xmlXPathContextCachePtr cache)
2211a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik{
2212a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    if (cache == NULL)
2213a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	return;
2214a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    if (cache->nodesetObjs)
22155869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik	xmlXPathCacheFreeObjectList(cache->nodesetObjs);
2216a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    if (cache->stringObjs)
22175869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik	xmlXPathCacheFreeObjectList(cache->stringObjs);
2218a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    if (cache->booleanObjs)
22195869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik	xmlXPathCacheFreeObjectList(cache->booleanObjs);
2220a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    if (cache->numberObjs)
22215869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik	xmlXPathCacheFreeObjectList(cache->numberObjs);
2222a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    if (cache->miscObjs)
222345490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	xmlXPathCacheFreeObjectList(cache->miscObjs);
2224a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlFree(cache);
2225a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik}
2226a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
2227a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik/**
22285869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik * xmlXPathContextSetCache:
2229a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik *
2230a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * @ctxt:  the XPath context
2231a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * @active: enables/disables (creates/frees) the cache
223245490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard * @value: a value with semantics dependant on @options
22335869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik * @options: options (currently only the value 0 is used)
2234a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik *
2235a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * Creates/frees an object cache on the XPath context.
2236a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * If activates XPath objects (xmlXPathObject) will be cached internally
22371b2be101e8c7c6c0b65d9961a302885aead9bc22Aleksey Sanin * to be reused.
22381b2be101e8c7c6c0b65d9961a302885aead9bc22Aleksey Sanin * @options:
22391b2be101e8c7c6c0b65d9961a302885aead9bc22Aleksey Sanin *   0: This will set the XPath object caching:
22401b2be101e8c7c6c0b65d9961a302885aead9bc22Aleksey Sanin *      @value:
22411b2be101e8c7c6c0b65d9961a302885aead9bc22Aleksey Sanin *        This will set the maximum number of XPath objects
22425869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik *        to be cached per slot
22435869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik *        There are 5 slots for: node-set, string, number, boolean, and
22441b2be101e8c7c6c0b65d9961a302885aead9bc22Aleksey Sanin *        misc objects. Use <0 for the default number (100).
22455869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik *   Other values for @options have currently no effect.
2246a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik *
2247a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * Returns 0 if the setting succeeded, and -1 on API or internal errors.
2248a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik */
2249a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikint
22505869469f42db259a21fb0721d66513de0b619097Kasimier T. BuchcikxmlXPathContextSetCache(xmlXPathContextPtr ctxt,
22515869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik			int active,
22525869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik			int value,
22535869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik			int options)
2254a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik{
2255a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    if (ctxt == NULL)
2256a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	return(-1);
2257a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    if (active) {
22585869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik	xmlXPathContextCachePtr cache;
225945490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
22605869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik	if (ctxt->cache == NULL) {
22615869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik	    ctxt->cache = xmlXPathNewCache();
22625869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik	    if (ctxt->cache == NULL)
2263a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		return(-1);
2264a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	}
22651b2be101e8c7c6c0b65d9961a302885aead9bc22Aleksey Sanin	cache = (xmlXPathContextCachePtr) ctxt->cache;
22665869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik	if (options == 0) {
22675869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik	    if (value < 0)
22685869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik		value = 100;
22695869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik	    cache->maxNodeset = value;
22705869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik	    cache->maxString = value;
22715869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik	    cache->maxNumber = value;
22725869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik	    cache->maxBoolean = value;
22731b2be101e8c7c6c0b65d9961a302885aead9bc22Aleksey Sanin	    cache->maxMisc = value;
22745869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik	}
22755869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik    } else if (ctxt->cache != NULL) {
22765869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik	xmlXPathFreeCache((xmlXPathContextCachePtr) ctxt->cache);
22775869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik	ctxt->cache = NULL;
2278a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    }
2279a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    return(0);
2280a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik}
2281a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
2282a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik/**
2283a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * xmlXPathCacheWrapNodeSet:
2284a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * @ctxt: the XPath context
2285a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * @val:  the NodePtr value
2286a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik *
2287a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * This is the cached version of xmlXPathWrapNodeSet().
2288a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * Wrap the Nodeset @val in a new xmlXPathObjectPtr
2289a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik *
2290a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * Returns the created or reused object.
2291a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik */
2292a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikstatic xmlXPathObjectPtr
2293a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. BuchcikxmlXPathCacheWrapNodeSet(xmlXPathContextPtr ctxt, xmlNodeSetPtr val)
229445490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard{
22955869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik    if ((ctxt != NULL) && (ctxt->cache != NULL)) {
22965869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik	xmlXPathContextCachePtr cache =
22975869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik	    (xmlXPathContextCachePtr) ctxt->cache;
2298a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
2299a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	if ((cache->miscObjs != NULL) &&
2300a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    (cache->miscObjs->number != 0))
2301a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	{
2302a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathObjectPtr ret;
230345490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
2304a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    ret = (xmlXPathObjectPtr)
2305a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		cache->miscObjs->items[--cache->miscObjs->number];
2306a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    ret->type = XPATH_NODESET;
2307a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    ret->nodesetval = val;
2308a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#ifdef XP_DEBUG_OBJ_USAGE
2309a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathDebugObjUsageRequested(ctxt, XPATH_NODESET);
2310a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#endif
231145490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	    return(ret);
2312a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	}
2313a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    }
231445490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
2315a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    return(xmlXPathWrapNodeSet(val));
231645490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
2317a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik}
2318a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
2319a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik/**
2320a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * xmlXPathCacheWrapString:
2321a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * @ctxt: the XPath context
2322a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * @val:  the xmlChar * value
2323a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik *
2324a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * This is the cached version of xmlXPathWrapString().
2325a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * Wraps the @val string into an XPath object.
2326a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik *
2327a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * Returns the created or reused object.
2328a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik */
2329a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikstatic xmlXPathObjectPtr
2330a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. BuchcikxmlXPathCacheWrapString(xmlXPathContextPtr ctxt, xmlChar *val)
233145490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard{
23325869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik    if ((ctxt != NULL) && (ctxt->cache != NULL)) {
23335869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik	xmlXPathContextCachePtr cache = (xmlXPathContextCachePtr) ctxt->cache;
2334a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
2335a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	if ((cache->stringObjs != NULL) &&
2336a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    (cache->stringObjs->number != 0))
2337a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	{
233845490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
2339a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathObjectPtr ret;
234045490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
2341a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    ret = (xmlXPathObjectPtr)
2342a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		cache->stringObjs->items[--cache->stringObjs->number];
2343a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    ret->type = XPATH_STRING;
2344a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    ret->stringval = val;
2345a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#ifdef XP_DEBUG_OBJ_USAGE
2346a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathDebugObjUsageRequested(ctxt, XPATH_STRING);
2347a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#endif
2348a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    return(ret);
2349a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	} else if ((cache->miscObjs != NULL) &&
2350a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    (cache->miscObjs->number != 0))
2351a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	{
2352a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathObjectPtr ret;
2353a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    /*
2354a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    * Fallback to misc-cache.
2355a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    */
2356a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    ret = (xmlXPathObjectPtr)
2357a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		cache->miscObjs->items[--cache->miscObjs->number];
2358a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
2359a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    ret->type = XPATH_STRING;
2360a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    ret->stringval = val;
2361a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#ifdef XP_DEBUG_OBJ_USAGE
2362a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathDebugObjUsageRequested(ctxt, XPATH_STRING);
2363a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#endif
2364a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    return(ret);
2365a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	}
2366a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    }
2367a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    return(xmlXPathWrapString(val));
2368a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik}
2369a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
2370a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik/**
2371a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * xmlXPathCacheNewNodeSet:
2372a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * @ctxt: the XPath context
2373a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * @val:  the NodePtr value
2374a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik *
2375a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * This is the cached version of xmlXPathNewNodeSet().
2376a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * Acquire an xmlXPathObjectPtr of type NodeSet and initialize
2377a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * it with the single Node @val
2378a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik *
2379a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * Returns the created or reused object.
2380a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik */
2381a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikstatic xmlXPathObjectPtr
2382a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. BuchcikxmlXPathCacheNewNodeSet(xmlXPathContextPtr ctxt, xmlNodePtr val)
2383a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik{
23845869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik    if ((ctxt != NULL) && (ctxt->cache)) {
23855869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik	xmlXPathContextCachePtr cache = (xmlXPathContextCachePtr) ctxt->cache;
2386a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
2387a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	if ((cache->nodesetObjs != NULL) &&
2388a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    (cache->nodesetObjs->number != 0))
238945490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	{
2390a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathObjectPtr ret;
2391a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    /*
2392a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    * Use the nodset-cache.
239345490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	    */
2394a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    ret = (xmlXPathObjectPtr)
2395a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		cache->nodesetObjs->items[--cache->nodesetObjs->number];
2396a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    ret->type = XPATH_NODESET;
2397a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    ret->boolval = 0;
239845490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	    if (val) {
2399a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		if ((ret->nodesetval->nodeMax == 0) ||
2400a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    (val->type == XML_NAMESPACE_DECL))
2401a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		{
240245490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard		    xmlXPathNodeSetAddUnique(ret->nodesetval, val);
2403a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		} else {
2404a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    ret->nodesetval->nodeTab[0] = val;
2405a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    ret->nodesetval->nodeNr = 1;
2406a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		}
2407a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    }
2408a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#ifdef XP_DEBUG_OBJ_USAGE
2409a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathDebugObjUsageRequested(ctxt, XPATH_NODESET);
2410a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#endif
2411a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    return(ret);
2412a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	} else if ((cache->miscObjs != NULL) &&
2413a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    (cache->miscObjs->number != 0))
2414a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	{
2415a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathObjectPtr ret;
2416a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    /*
2417a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    * Fallback to misc-cache.
2418a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    */
2419a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
2420a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    ret = (xmlXPathObjectPtr)
2421a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		cache->miscObjs->items[--cache->miscObjs->number];
2422a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
2423a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    ret->type = XPATH_NODESET;
2424a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    ret->boolval = 0;
2425a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    ret->nodesetval = xmlXPathNodeSetCreate(val);
24261bd45d13091e5af9e1fe0582b5e335c60d45535fDaniel Veillard	    if (ret->nodesetval == NULL) {
24271bd45d13091e5af9e1fe0582b5e335c60d45535fDaniel Veillard		ctxt->lastError.domain = XML_FROM_XPATH;
24281bd45d13091e5af9e1fe0582b5e335c60d45535fDaniel Veillard		ctxt->lastError.code = XML_ERR_NO_MEMORY;
24291bd45d13091e5af9e1fe0582b5e335c60d45535fDaniel Veillard		return(NULL);
24301bd45d13091e5af9e1fe0582b5e335c60d45535fDaniel Veillard	    }
2431a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#ifdef XP_DEBUG_OBJ_USAGE
2432a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathDebugObjUsageRequested(ctxt, XPATH_NODESET);
2433a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#endif
2434a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    return(ret);
2435a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	}
2436a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    }
2437a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    return(xmlXPathNewNodeSet(val));
2438a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik}
2439a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
2440a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik/**
2441a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * xmlXPathCacheNewCString:
2442a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * @ctxt: the XPath context
2443a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * @val:  the char * value
2444a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik *
2445a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * This is the cached version of xmlXPathNewCString().
2446a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * Acquire an xmlXPathObjectPtr of type string and of value @val
2447a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik *
2448a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * Returns the created or reused object.
2449a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik */
2450a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikstatic xmlXPathObjectPtr
2451a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. BuchcikxmlXPathCacheNewCString(xmlXPathContextPtr ctxt, const char *val)
245245490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard{
24535869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik    if ((ctxt != NULL) && (ctxt->cache)) {
24545869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik	xmlXPathContextCachePtr cache = (xmlXPathContextCachePtr) ctxt->cache;
2455a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
2456a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	if ((cache->stringObjs != NULL) &&
2457a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    (cache->stringObjs->number != 0))
245845490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	{
2459a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathObjectPtr ret;
246045490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
2461a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    ret = (xmlXPathObjectPtr)
2462a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		cache->stringObjs->items[--cache->stringObjs->number];
2463a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
2464a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    ret->type = XPATH_STRING;
2465a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    ret->stringval = xmlStrdup(BAD_CAST val);
2466a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#ifdef XP_DEBUG_OBJ_USAGE
2467a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathDebugObjUsageRequested(ctxt, XPATH_STRING);
2468a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#endif
2469a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    return(ret);
2470a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	} else if ((cache->miscObjs != NULL) &&
2471a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    (cache->miscObjs->number != 0))
2472a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	{
2473a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathObjectPtr ret;
2474a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
2475a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    ret = (xmlXPathObjectPtr)
2476a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		cache->miscObjs->items[--cache->miscObjs->number];
2477a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
2478a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    ret->type = XPATH_STRING;
2479a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    ret->stringval = xmlStrdup(BAD_CAST val);
2480a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#ifdef XP_DEBUG_OBJ_USAGE
2481a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathDebugObjUsageRequested(ctxt, XPATH_STRING);
2482a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#endif
2483a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    return(ret);
2484a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	}
2485a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    }
2486a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    return(xmlXPathNewCString(val));
2487a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik}
2488a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
2489a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik/**
2490a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * xmlXPathCacheNewString:
2491a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * @ctxt: the XPath context
2492a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * @val:  the xmlChar * value
2493a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik *
2494a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * This is the cached version of xmlXPathNewString().
2495a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * Acquire an xmlXPathObjectPtr of type string and of value @val
2496a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik *
2497a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * Returns the created or reused object.
2498a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik */
2499a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikstatic xmlXPathObjectPtr
2500a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. BuchcikxmlXPathCacheNewString(xmlXPathContextPtr ctxt, const xmlChar *val)
250145490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard{
25025869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik    if ((ctxt != NULL) && (ctxt->cache)) {
25035869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik	xmlXPathContextCachePtr cache = (xmlXPathContextCachePtr) ctxt->cache;
2504a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
2505a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	if ((cache->stringObjs != NULL) &&
2506a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    (cache->stringObjs->number != 0))
250745490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	{
2508a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathObjectPtr ret;
250945490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
2510a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    ret = (xmlXPathObjectPtr)
2511a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		cache->stringObjs->items[--cache->stringObjs->number];
2512a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    ret->type = XPATH_STRING;
2513a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    if (val != NULL)
2514a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		ret->stringval = xmlStrdup(val);
2515a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    else
2516a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		ret->stringval = xmlStrdup((const xmlChar *)"");
2517a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#ifdef XP_DEBUG_OBJ_USAGE
2518a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathDebugObjUsageRequested(ctxt, XPATH_STRING);
2519a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#endif
2520a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    return(ret);
2521a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	} else if ((cache->miscObjs != NULL) &&
2522a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    (cache->miscObjs->number != 0))
2523a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	{
2524a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathObjectPtr ret;
2525a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
2526a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    ret = (xmlXPathObjectPtr)
2527a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		cache->miscObjs->items[--cache->miscObjs->number];
2528a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
2529a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    ret->type = XPATH_STRING;
2530a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    if (val != NULL)
2531a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		ret->stringval = xmlStrdup(val);
2532a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    else
2533a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		ret->stringval = xmlStrdup((const xmlChar *)"");
2534a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#ifdef XP_DEBUG_OBJ_USAGE
2535a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathDebugObjUsageRequested(ctxt, XPATH_STRING);
2536a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#endif
2537a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    return(ret);
2538a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	}
2539a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    }
2540a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    return(xmlXPathNewString(val));
2541a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik}
2542a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
2543a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik/**
2544a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * xmlXPathCacheNewBoolean:
2545a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * @ctxt: the XPath context
2546a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * @val:  the boolean value
2547a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik *
2548a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * This is the cached version of xmlXPathNewBoolean().
2549a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * Acquires an xmlXPathObjectPtr of type boolean and of value @val
2550a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik *
2551a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * Returns the created or reused object.
2552a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik */
2553a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikstatic xmlXPathObjectPtr
2554a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. BuchcikxmlXPathCacheNewBoolean(xmlXPathContextPtr ctxt, int val)
255545490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard{
25565869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik    if ((ctxt != NULL) && (ctxt->cache)) {
25575869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik	xmlXPathContextCachePtr cache = (xmlXPathContextCachePtr) ctxt->cache;
2558a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
2559a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	if ((cache->booleanObjs != NULL) &&
2560a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    (cache->booleanObjs->number != 0))
256145490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	{
2562a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathObjectPtr ret;
256345490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
2564a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    ret = (xmlXPathObjectPtr)
2565a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		cache->booleanObjs->items[--cache->booleanObjs->number];
2566a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    ret->type = XPATH_BOOLEAN;
2567a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    ret->boolval = (val != 0);
2568a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#ifdef XP_DEBUG_OBJ_USAGE
2569a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathDebugObjUsageRequested(ctxt, XPATH_BOOLEAN);
2570a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#endif
2571a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    return(ret);
2572a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	} else if ((cache->miscObjs != NULL) &&
2573a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    (cache->miscObjs->number != 0))
2574a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	{
2575a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathObjectPtr ret;
2576a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
2577a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    ret = (xmlXPathObjectPtr)
2578a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		cache->miscObjs->items[--cache->miscObjs->number];
2579a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
2580a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    ret->type = XPATH_BOOLEAN;
2581a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    ret->boolval = (val != 0);
2582a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#ifdef XP_DEBUG_OBJ_USAGE
2583a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathDebugObjUsageRequested(ctxt, XPATH_BOOLEAN);
2584a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#endif
2585a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    return(ret);
2586a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	}
2587a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    }
2588a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    return(xmlXPathNewBoolean(val));
2589a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik}
2590a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
2591a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik/**
2592a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * xmlXPathCacheNewFloat:
2593a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * @ctxt: the XPath context
2594a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * @val:  the double value
2595a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik *
2596a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * This is the cached version of xmlXPathNewFloat().
2597a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * Acquires an xmlXPathObjectPtr of type double and of value @val
2598a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik *
2599a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * Returns the created or reused object.
2600a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik */
2601a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikstatic xmlXPathObjectPtr
2602a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. BuchcikxmlXPathCacheNewFloat(xmlXPathContextPtr ctxt, double val)
2603a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik{
26045869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik     if ((ctxt != NULL) && (ctxt->cache)) {
26055869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik	xmlXPathContextCachePtr cache = (xmlXPathContextCachePtr) ctxt->cache;
2606a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
2607a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	if ((cache->numberObjs != NULL) &&
2608a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    (cache->numberObjs->number != 0))
260945490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	{
2610a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathObjectPtr ret;
261145490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
2612a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    ret = (xmlXPathObjectPtr)
2613a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		cache->numberObjs->items[--cache->numberObjs->number];
2614a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    ret->type = XPATH_NUMBER;
2615a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    ret->floatval = val;
2616a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#ifdef XP_DEBUG_OBJ_USAGE
2617a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathDebugObjUsageRequested(ctxt, XPATH_NUMBER);
2618a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#endif
2619a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    return(ret);
2620a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	} else if ((cache->miscObjs != NULL) &&
2621a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    (cache->miscObjs->number != 0))
2622a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	{
2623a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathObjectPtr ret;
2624a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
2625a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    ret = (xmlXPathObjectPtr)
2626a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		cache->miscObjs->items[--cache->miscObjs->number];
2627a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
2628a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    ret->type = XPATH_NUMBER;
2629a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    ret->floatval = val;
2630a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#ifdef XP_DEBUG_OBJ_USAGE
2631a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathDebugObjUsageRequested(ctxt, XPATH_NUMBER);
2632a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#endif
2633a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    return(ret);
2634a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	}
2635a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    }
2636a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    return(xmlXPathNewFloat(val));
2637a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik}
2638a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
2639a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik/**
2640a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * xmlXPathCacheConvertString:
2641a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * @ctxt: the XPath context
2642a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * @val:  an XPath object
2643a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik *
2644a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * This is the cached version of xmlXPathConvertString().
2645a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * Converts an existing object to its string() equivalent
2646a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik *
2647a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * Returns a created or reused object, the old one is freed (cached)
2648a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik *         (or the operation is done directly on @val)
2649a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik */
2650a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
2651a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikstatic xmlXPathObjectPtr
2652a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. BuchcikxmlXPathCacheConvertString(xmlXPathContextPtr ctxt, xmlXPathObjectPtr val) {
265345490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard    xmlChar *res = NULL;
2654a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
2655a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    if (val == NULL)
2656a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	return(xmlXPathCacheNewCString(ctxt, ""));
2657a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
2658a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    switch (val->type) {
2659a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    case XPATH_UNDEFINED:
2660a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#ifdef DEBUG_EXPR
2661a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	xmlGenericError(xmlGenericErrorContext, "STRING: undefined\n");
2662a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#endif
2663a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	break;
2664a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    case XPATH_NODESET:
2665a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    case XPATH_XSLT_TREE:
2666a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	res = xmlXPathCastNodeSetToString(val->nodesetval);
2667a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	break;
2668a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    case XPATH_STRING:
2669a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	return(val);
2670a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    case XPATH_BOOLEAN:
2671a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	res = xmlXPathCastBooleanToString(val->boolval);
2672a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	break;
2673a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    case XPATH_NUMBER:
2674a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	res = xmlXPathCastNumberToString(val->floatval);
2675a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	break;
2676a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    case XPATH_USERS:
2677a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    case XPATH_POINT:
2678a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    case XPATH_RANGE:
2679a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    case XPATH_LOCATIONSET:
2680a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	TODO;
2681a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	break;
2682a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    }
2683a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathReleaseObject(ctxt, val);
2684a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    if (res == NULL)
2685a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	return(xmlXPathCacheNewCString(ctxt, ""));
2686a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    return(xmlXPathCacheWrapString(ctxt, res));
26879e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard}
268856a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillard
26895e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard/**
2690a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * xmlXPathCacheObjectCopy:
2691a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * @ctxt: the XPath context
2692a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * @val:  the original object
26935e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard *
2694a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * This is the cached version of xmlXPathObjectCopy().
2695a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * Acquire a copy of a given object
2696a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik *
2697a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * Returns a created or reused created object.
26985e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard */
2699a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikstatic xmlXPathObjectPtr
2700a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. BuchcikxmlXPathCacheObjectCopy(xmlXPathContextPtr ctxt, xmlXPathObjectPtr val)
2701a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik{
2702a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    if (val == NULL)
2703a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	return(NULL);
2704a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard
2705631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik    if (XP_HAS_CACHE(ctxt)) {
2706631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	switch (val->type) {
2707631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    case XPATH_NODESET:
2708a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		return(xmlXPathCacheWrapNodeSet(ctxt,
2709a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    xmlXPathNodeSetMerge(NULL, val->nodesetval)));
2710631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    case XPATH_STRING:
2711a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		return(xmlXPathCacheNewString(ctxt, val->stringval));
2712631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    case XPATH_BOOLEAN:
2713a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		return(xmlXPathCacheNewBoolean(ctxt, val->boolval));
2714631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    case XPATH_NUMBER:
2715631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik		return(xmlXPathCacheNewFloat(ctxt, val->floatval));
2716631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    default:
2717631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik		break;
2718631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	}
2719a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    }
2720a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    return(xmlXPathObjectCopy(val));
2721a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik}
27229e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
2723a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik/**
2724a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * xmlXPathCacheConvertBoolean:
2725a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * @ctxt: the XPath context
2726a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * @val:  an XPath object
2727a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik *
2728a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * This is the cached version of xmlXPathConvertBoolean().
2729a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * Converts an existing object to its boolean() equivalent
2730a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik *
2731a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * Returns a created or reused object, the old one is freed (or the operation
2732a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik *         is done directly on @val)
2733a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik */
2734a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikstatic xmlXPathObjectPtr
2735a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. BuchcikxmlXPathCacheConvertBoolean(xmlXPathContextPtr ctxt, xmlXPathObjectPtr val) {
2736a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathObjectPtr ret;
273745490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
2738a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    if (val == NULL)
2739a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	return(xmlXPathCacheNewBoolean(ctxt, 0));
2740a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    if (val->type == XPATH_BOOLEAN)
2741a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	return(val);
2742a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    ret = xmlXPathCacheNewBoolean(ctxt, xmlXPathCastToBoolean(val));
2743a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathReleaseObject(ctxt, val);
2744a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    return(ret);
2745a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik}
27469e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
2747a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik/**
2748a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * xmlXPathCacheConvertNumber:
2749a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * @ctxt: the XPath context
2750a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * @val:  an XPath object
2751a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik *
2752a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * This is the cached version of xmlXPathConvertNumber().
2753a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * Converts an existing object to its number() equivalent
2754a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik *
2755a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * Returns a created or reused object, the old one is freed (or the operation
2756a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik *         is done directly on @val)
2757a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik */
2758a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikstatic xmlXPathObjectPtr
2759a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. BuchcikxmlXPathCacheConvertNumber(xmlXPathContextPtr ctxt, xmlXPathObjectPtr val) {
2760a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathObjectPtr ret;
276145490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
2762a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    if (val == NULL)
2763a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	return(xmlXPathCacheNewFloat(ctxt, 0.0));
2764a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    if (val->type == XPATH_NUMBER)
2765a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	return(val);
2766a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    ret = xmlXPathCacheNewFloat(ctxt, xmlXPathCastToNumber(val));
2767a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathReleaseObject(ctxt, val);
2768a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    return(ret);
27699e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard}
27703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
27713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/************************************************************************
27723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *									*
277345490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *		Parser stacks related functions and macros		*
27743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *									*
27753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ************************************************************************/
27763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
27775e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard/**
2778f5048b3e71fc30ad096970b8df6e7af073bae4cbDaniel Veillard * xmlXPathSetFrame:
2779f5048b3e71fc30ad096970b8df6e7af073bae4cbDaniel Veillard * @ctxt: an XPath parser context
2780f5048b3e71fc30ad096970b8df6e7af073bae4cbDaniel Veillard *
2781f5048b3e71fc30ad096970b8df6e7af073bae4cbDaniel Veillard * Set the callee evaluation frame
2782f5048b3e71fc30ad096970b8df6e7af073bae4cbDaniel Veillard *
2783f5048b3e71fc30ad096970b8df6e7af073bae4cbDaniel Veillard * Returns the previous frame value to be restored once done
2784f5048b3e71fc30ad096970b8df6e7af073bae4cbDaniel Veillard */
2785f5048b3e71fc30ad096970b8df6e7af073bae4cbDaniel Veillardstatic int
2786f5048b3e71fc30ad096970b8df6e7af073bae4cbDaniel VeillardxmlXPathSetFrame(xmlXPathParserContextPtr ctxt) {
2787f5048b3e71fc30ad096970b8df6e7af073bae4cbDaniel Veillard    int ret;
2788f5048b3e71fc30ad096970b8df6e7af073bae4cbDaniel Veillard
2789f5048b3e71fc30ad096970b8df6e7af073bae4cbDaniel Veillard    if (ctxt == NULL)
2790f5048b3e71fc30ad096970b8df6e7af073bae4cbDaniel Veillard        return(0);
2791f5048b3e71fc30ad096970b8df6e7af073bae4cbDaniel Veillard    ret = ctxt->valueFrame;
2792f5048b3e71fc30ad096970b8df6e7af073bae4cbDaniel Veillard    ctxt->valueFrame = ctxt->valueNr;
2793f5048b3e71fc30ad096970b8df6e7af073bae4cbDaniel Veillard    return(ret);
2794f5048b3e71fc30ad096970b8df6e7af073bae4cbDaniel Veillard}
2795f5048b3e71fc30ad096970b8df6e7af073bae4cbDaniel Veillard
2796f5048b3e71fc30ad096970b8df6e7af073bae4cbDaniel Veillard/**
2797f5048b3e71fc30ad096970b8df6e7af073bae4cbDaniel Veillard * xmlXPathPopFrame:
2798f5048b3e71fc30ad096970b8df6e7af073bae4cbDaniel Veillard * @ctxt: an XPath parser context
2799f5048b3e71fc30ad096970b8df6e7af073bae4cbDaniel Veillard * @frame: the previous frame value
2800f5048b3e71fc30ad096970b8df6e7af073bae4cbDaniel Veillard *
2801f5048b3e71fc30ad096970b8df6e7af073bae4cbDaniel Veillard * Remove the callee evaluation frame
2802f5048b3e71fc30ad096970b8df6e7af073bae4cbDaniel Veillard */
2803f5048b3e71fc30ad096970b8df6e7af073bae4cbDaniel Veillardstatic void
2804f5048b3e71fc30ad096970b8df6e7af073bae4cbDaniel VeillardxmlXPathPopFrame(xmlXPathParserContextPtr ctxt, int frame) {
2805f5048b3e71fc30ad096970b8df6e7af073bae4cbDaniel Veillard    if (ctxt == NULL)
2806f5048b3e71fc30ad096970b8df6e7af073bae4cbDaniel Veillard        return;
2807f5048b3e71fc30ad096970b8df6e7af073bae4cbDaniel Veillard    if (ctxt->valueNr < ctxt->valueFrame) {
2808f5048b3e71fc30ad096970b8df6e7af073bae4cbDaniel Veillard        xmlXPatherror(ctxt, __FILE__, __LINE__, XPATH_STACK_ERROR);
2809f5048b3e71fc30ad096970b8df6e7af073bae4cbDaniel Veillard    }
2810f5048b3e71fc30ad096970b8df6e7af073bae4cbDaniel Veillard    ctxt->valueFrame = frame;
2811f5048b3e71fc30ad096970b8df6e7af073bae4cbDaniel Veillard}
2812f5048b3e71fc30ad096970b8df6e7af073bae4cbDaniel Veillard
2813f5048b3e71fc30ad096970b8df6e7af073bae4cbDaniel Veillard/**
28145e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard * valuePop:
28155e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard * @ctxt: an XPath evaluation context
28165e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard *
28175e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard * Pops the top XPath object from the value stack
28185e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard *
28195e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard * Returns the XPath object just removed
28205e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard */
282124505b0f5c872c5afb6da5093565e5a6e09ca541Daniel VeillardxmlXPathObjectPtr
28221c732d2e10935529b717864b6fa4296f80edace1Daniel VeillardvaluePop(xmlXPathParserContextPtr ctxt)
28231c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard{
28241c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard    xmlXPathObjectPtr ret;
28251c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard
2826a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard    if ((ctxt == NULL) || (ctxt->valueNr <= 0))
282724505b0f5c872c5afb6da5093565e5a6e09ca541Daniel Veillard        return (NULL);
2828f5048b3e71fc30ad096970b8df6e7af073bae4cbDaniel Veillard
2829f5048b3e71fc30ad096970b8df6e7af073bae4cbDaniel Veillard    if (ctxt->valueNr <= ctxt->valueFrame) {
2830f5048b3e71fc30ad096970b8df6e7af073bae4cbDaniel Veillard        xmlXPatherror(ctxt, __FILE__, __LINE__, XPATH_STACK_ERROR);
2831f5048b3e71fc30ad096970b8df6e7af073bae4cbDaniel Veillard        return (NULL);
2832f5048b3e71fc30ad096970b8df6e7af073bae4cbDaniel Veillard    }
2833f5048b3e71fc30ad096970b8df6e7af073bae4cbDaniel Veillard
28341c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard    ctxt->valueNr--;
28351c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard    if (ctxt->valueNr > 0)
28361c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard        ctxt->value = ctxt->valueTab[ctxt->valueNr - 1];
28371c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard    else
28381c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard        ctxt->value = NULL;
28391c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard    ret = ctxt->valueTab[ctxt->valueNr];
284024505b0f5c872c5afb6da5093565e5a6e09ca541Daniel Veillard    ctxt->valueTab[ctxt->valueNr] = NULL;
28411c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard    return (ret);
28421c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard}
28435e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard/**
28445e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard * valuePush:
28455e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard * @ctxt:  an XPath evaluation context
28465e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard * @value:  the XPath object
28475e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard *
28485e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard * Pushes a new XPath object on top of the value stack
2849cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard *
2850cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * returns the number of items on the value stack
28515e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard */
285224505b0f5c872c5afb6da5093565e5a6e09ca541Daniel Veillardint
28531c732d2e10935529b717864b6fa4296f80edace1Daniel VeillardvaluePush(xmlXPathParserContextPtr ctxt, xmlXPathObjectPtr value)
28541c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard{
2855a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard    if ((ctxt == NULL) || (value == NULL)) return(-1);
28561c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard    if (ctxt->valueNr >= ctxt->valueMax) {
2857a918b5b08ac20d4e7c765bdce653969ebad6c315Daniel Veillard        xmlXPathObjectPtr *tmp;
2858a918b5b08ac20d4e7c765bdce653969ebad6c315Daniel Veillard
2859cd852ad154fd919d9a4bd955566b43bac848878aDaniel Veillard        if (ctxt->valueMax >= XPATH_MAX_STACK_DEPTH) {
2860cd852ad154fd919d9a4bd955566b43bac848878aDaniel Veillard            xmlXPathErrMemory(NULL, "XPath stack depth limit reached\n");
2861cd852ad154fd919d9a4bd955566b43bac848878aDaniel Veillard            ctxt->error = XPATH_MEMORY_ERROR;
2862cd852ad154fd919d9a4bd955566b43bac848878aDaniel Veillard            return (0);
2863cd852ad154fd919d9a4bd955566b43bac848878aDaniel Veillard        }
2864a918b5b08ac20d4e7c765bdce653969ebad6c315Daniel Veillard        tmp = (xmlXPathObjectPtr *) xmlRealloc(ctxt->valueTab,
2865a918b5b08ac20d4e7c765bdce653969ebad6c315Daniel Veillard                                             2 * ctxt->valueMax *
28661c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard                                             sizeof(ctxt->valueTab[0]));
2867a918b5b08ac20d4e7c765bdce653969ebad6c315Daniel Veillard        if (tmp == NULL) {
2868cd852ad154fd919d9a4bd955566b43bac848878aDaniel Veillard            xmlXPathErrMemory(NULL, "pushing value\n");
28691d4526f6f4ec8d18c40e2a09b387652a6c1aa2cdDaniel Veillard            ctxt->error = XPATH_MEMORY_ERROR;
28701c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard            return (0);
28711c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard        }
2872a918b5b08ac20d4e7c765bdce653969ebad6c315Daniel Veillard        ctxt->valueMax *= 2;
2873a918b5b08ac20d4e7c765bdce653969ebad6c315Daniel Veillard	ctxt->valueTab = tmp;
28741c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard    }
28751c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard    ctxt->valueTab[ctxt->valueNr] = value;
28761c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard    ctxt->value = value;
28771c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard    return (ctxt->valueNr++);
28781c732d2e10935529b717864b6fa4296f80edace1Daniel Veillard}
28793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
2880f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/**
2881f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathPopBoolean:
2882f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @ctxt:  an XPath parser context
2883f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *
2884f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Pops a boolean from the stack, handling conversion if needed.
2885f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Check error with #xmlXPathCheckError.
2886f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *
2887f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns the boolean
2888f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */
2889f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyerint
2890f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathPopBoolean (xmlXPathParserContextPtr ctxt) {
2891f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    xmlXPathObjectPtr obj;
2892f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    int ret;
2893f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer
2894f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    obj = valuePop(ctxt);
2895f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    if (obj == NULL) {
2896f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer	xmlXPathSetError(ctxt, XPATH_INVALID_OPERAND);
2897f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer	return(0);
2898f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    }
2899081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack    if (obj->type != XPATH_BOOLEAN)
2900081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack	ret = xmlXPathCastToBoolean(obj);
2901081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack    else
2902081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack        ret = obj->boolval;
2903a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathReleaseObject(ctxt->context, obj);
2904f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    return(ret);
2905f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer}
2906f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer
2907f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/**
2908f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathPopNumber:
2909f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @ctxt:  an XPath parser context
2910f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *
2911f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Pops a number from the stack, handling conversion if needed.
2912f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Check error with #xmlXPathCheckError.
2913f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *
2914f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns the number
2915f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */
2916f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyerdouble
2917f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathPopNumber (xmlXPathParserContextPtr ctxt) {
2918f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    xmlXPathObjectPtr obj;
2919f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    double ret;
2920f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer
2921f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    obj = valuePop(ctxt);
2922f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    if (obj == NULL) {
2923f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer	xmlXPathSetError(ctxt, XPATH_INVALID_OPERAND);
2924f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer	return(0);
2925f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    }
2926081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack    if (obj->type != XPATH_NUMBER)
2927081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack	ret = xmlXPathCastToNumber(obj);
2928081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack    else
2929081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack        ret = obj->floatval;
2930a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathReleaseObject(ctxt->context, obj);
2931f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    return(ret);
2932f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer}
2933f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer
2934f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/**
2935f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathPopString:
2936f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @ctxt:  an XPath parser context
2937f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *
2938f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Pops a string from the stack, handling conversion if needed.
2939f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Check error with #xmlXPathCheckError.
2940f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *
2941f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns the string
2942f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */
2943f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlChar *
2944f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathPopString (xmlXPathParserContextPtr ctxt) {
2945f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    xmlXPathObjectPtr obj;
2946f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    xmlChar * ret;
2947f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer
2948f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    obj = valuePop(ctxt);
2949f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    if (obj == NULL) {
2950f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer	xmlXPathSetError(ctxt, XPATH_INVALID_OPERAND);
2951f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer	return(NULL);
2952f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    }
2953081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack    ret = xmlXPathCastToString(obj);	/* this does required strdup */
2954f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    /* TODO: needs refactoring somewhere else */
2955f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    if (obj->stringval == ret)
2956f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer	obj->stringval = NULL;
2957a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathReleaseObject(ctxt->context, obj);
2958f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    return(ret);
2959f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer}
2960f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer
2961f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/**
2962f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathPopNodeSet:
2963f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @ctxt:  an XPath parser context
2964f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *
2965f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Pops a node-set from the stack, handling conversion if needed.
2966f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Check error with #xmlXPathCheckError.
2967f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *
2968f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns the node-set
2969f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */
2970f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlNodeSetPtr
2971f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathPopNodeSet (xmlXPathParserContextPtr ctxt) {
2972f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    xmlXPathObjectPtr obj;
2973f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    xmlNodeSetPtr ret;
2974f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer
2975f2a36f98e16efa8a89d9bed359d59be10e5d33cdDaniel Veillard    if (ctxt == NULL) return(NULL);
2976f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    if (ctxt->value == NULL) {
2977f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer	xmlXPathSetError(ctxt, XPATH_INVALID_OPERAND);
2978f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer	return(NULL);
2979f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    }
2980f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    if (!xmlXPathStackIsNodeSet(ctxt)) {
2981f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer	xmlXPathSetTypeError(ctxt);
2982f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer	return(NULL);
2983f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    }
2984f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    obj = valuePop(ctxt);
2985f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    ret = obj->nodesetval;
2986e9449c5d29d87b1dc51de7784ed947ae1e3da831William M. Brack#if 0
29879deb242b558cbcff45165866e0634a1962404885Daniel Veillard    /* to fix memory leak of not clearing obj->user */
29889deb242b558cbcff45165866e0634a1962404885Daniel Veillard    if (obj->boolval && obj->user != NULL)
29899deb242b558cbcff45165866e0634a1962404885Daniel Veillard        xmlFreeNodeList((xmlNodePtr) obj->user);
2990e9449c5d29d87b1dc51de7784ed947ae1e3da831William M. Brack#endif
2991a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    obj->nodesetval = NULL;
2992a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathReleaseObject(ctxt->context, obj);
2993f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    return(ret);
2994f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer}
2995f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer
2996f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/**
2997f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathPopExternal:
2998f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @ctxt:  an XPath parser context
2999f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *
3000cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * Pops an external object from the stack, handling conversion if needed.
3001f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Check error with #xmlXPathCheckError.
3002f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *
3003f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns the object
3004f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */
3005f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyervoid *
3006f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathPopExternal (xmlXPathParserContextPtr ctxt) {
3007f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    xmlXPathObjectPtr obj;
3008f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    void * ret;
3009f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer
3010a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard    if ((ctxt == NULL) || (ctxt->value == NULL)) {
3011f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer	xmlXPathSetError(ctxt, XPATH_INVALID_OPERAND);
3012f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer	return(NULL);
3013f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    }
3014f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    if (ctxt->value->type != XPATH_USERS) {
3015f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer	xmlXPathSetTypeError(ctxt);
3016f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer	return(NULL);
3017f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    }
3018f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    obj = valuePop(ctxt);
3019f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    ret = obj->user;
3020a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    obj->user = NULL;
3021a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathReleaseObject(ctxt->context, obj);
3022f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    return(ret);
3023f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer}
3024f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer
30253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/*
30263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Macros for accessing the content. Those should be used only by the parser,
30273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * and not exported.
30283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
30293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Dirty macros, i.e. one need to make assumption on the context to use them
30303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
30313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *   CUR_PTR return the current pointer to the xmlChar to be parsed.
30323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *   CUR     returns the current xmlChar value, i.e. a 8 bit value
30333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *           in ISO-Latin or UTF-8.
30343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *           This should be used internally by the parser
30353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *           only to compare to ASCII values otherwise it would break when
30363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *           running with UTF-8 encoding.
30373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *   NXT(n)  returns the n'th next xmlChar. Same as CUR is should be used only
30383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *           to compare on ASCII based substring.
30393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *   SKIP(n) Skip n xmlChar, and must also be used only to skip ASCII defined
30403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *           strings within the parser.
30413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *   CURRENT Returns the current char value, with the full decoding of
30423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *           UTF-8 if we are using this mode. It returns an int.
30433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *   NEXT    Skip to the next character, this does the proper decoding
30443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *           in UTF-8 mode. It also pop-up unfinished entities on the fly.
30453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *           It returns the pointer to the current xmlChar.
30463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
30473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
30483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define CUR (*ctxt->cur)
30493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define SKIP(val) ctxt->cur += (val)
30503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define NXT(val) ctxt->cur[(val)]
30513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define CUR_PTR ctxt->cur
305261d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard#define CUR_CHAR(l) xmlXPathCurrentChar(ctxt, &l)
305361d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard
305461d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard#define COPY_BUF(l,b,i,v)                                              \
305561d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard    if (l == 1) b[i++] = (xmlChar) v;                                  \
305661d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard    else i += xmlCopyChar(l,&b[i],v)
305761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard
305861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard#define NEXTL(l)  ctxt->cur += l
30593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
306045490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard#define SKIP_BLANKS							\
306176e95df05556c9610b564b14cf578c8f9e34c9c1William M. Brack    while (IS_BLANK_CH(*(ctxt->cur))) NEXT
30623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
30633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define CURRENT (*ctxt->cur)
30643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define NEXT ((*ctxt->cur) ?  ctxt->cur++: ctxt->cur)
30653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
3066e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese
3067e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese#ifndef DBL_DIG
3068e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese#define DBL_DIG 16
3069e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese#endif
3070e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese#ifndef DBL_EPSILON
3071e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese#define DBL_EPSILON 1E-9
3072e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese#endif
3073e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese
3074e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese#define UPPER_DOUBLE 1E9
3075e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese#define LOWER_DOUBLE 1E-5
3076ca79788eaa34765e184801c4db50560e5a0dda91William M. Brack#define	LOWER_DOUBLE_EXP 5
3077e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese
3078e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese#define INTEGER_DIGITS DBL_DIG
3079ca79788eaa34765e184801c4db50560e5a0dda91William M. Brack#define FRACTION_DIGITS (DBL_DIG + 1 + (LOWER_DOUBLE_EXP))
3080e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese#define EXPONENT_DIGITS (3 + 2)
3081e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese
3082e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese/**
3083e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese * xmlXPathFormatNumber:
3084e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese * @number:     number to format
3085e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese * @buffer:     output buffer
3086e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese * @buffersize: size of output buffer
3087e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese *
3088e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese * Convert the number into a string representation.
3089e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese */
3090e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reesestatic void
3091e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn ReesexmlXPathFormatNumber(double number, char buffer[], int buffersize)
3092e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese{
3093cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard    switch (xmlXPathIsInf(number)) {
3094e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese    case 1:
30955fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard	if (buffersize > (int)sizeof("Infinity"))
309649cc97565fbe2928388a1e437c44429097a504aeAleksey Sanin	    snprintf(buffer, buffersize, "Infinity");
3097e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese	break;
3098e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese    case -1:
3099e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese	if (buffersize > (int)sizeof("-Infinity"))
310049cc97565fbe2928388a1e437c44429097a504aeAleksey Sanin	    snprintf(buffer, buffersize, "-Infinity");
3101e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese	break;
3102e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese    default:
3103cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard	if (xmlXPathIsNaN(number)) {
3104e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese	    if (buffersize > (int)sizeof("NaN"))
310549cc97565fbe2928388a1e437c44429097a504aeAleksey Sanin		snprintf(buffer, buffersize, "NaN");
3106d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard	} else if (number == 0 && xmlXPathGetSign(number) != 0) {
310749cc97565fbe2928388a1e437c44429097a504aeAleksey Sanin	    snprintf(buffer, buffersize, "0");
310828cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard	} else if (number == ((int) number)) {
310928cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard	    char work[30];
311028cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard	    char *ptr, *cur;
3111b3d1491b69060f8a67516b9a3ef12617adf88954Daniel Veillard	    int value = (int) number;
311228cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard
311328cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard            ptr = &buffer[0];
311428cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard	    if (value == 0) {
311528cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard		*ptr++ = '0';
311628cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard	    } else {
3117b3d1491b69060f8a67516b9a3ef12617adf88954Daniel Veillard		snprintf(work, 29, "%d", value);
311828cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard		cur = &work[0];
3119b3d1491b69060f8a67516b9a3ef12617adf88954Daniel Veillard		while ((*cur) && (ptr - buffer < buffersize)) {
3120b3d1491b69060f8a67516b9a3ef12617adf88954Daniel Veillard		    *ptr++ = *cur++;
312128cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard		}
312228cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard	    }
312328cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard	    if (ptr - buffer < buffersize) {
312428cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard		*ptr = 0;
312528cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard	    } else if (buffersize > 0) {
312628cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard		ptr--;
312728cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard		*ptr = 0;
312828cac6b5a9558001844e02f00bfddda211b466d2Daniel Veillard	    }
3129e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese	} else {
3130ca79788eaa34765e184801c4db50560e5a0dda91William M. Brack	    /*
3131ca79788eaa34765e184801c4db50560e5a0dda91William M. Brack	      For the dimension of work,
3132ca79788eaa34765e184801c4db50560e5a0dda91William M. Brack	          DBL_DIG is number of significant digits
3133ca79788eaa34765e184801c4db50560e5a0dda91William M. Brack		  EXPONENT is only needed for "scientific notation"
3134ca79788eaa34765e184801c4db50560e5a0dda91William M. Brack	          3 is sign, decimal point, and terminating zero
3135ca79788eaa34765e184801c4db50560e5a0dda91William M. Brack		  LOWER_DOUBLE_EXP is max number of leading zeroes in fraction
3136ca79788eaa34765e184801c4db50560e5a0dda91William M. Brack	      Note that this dimension is slightly (a few characters)
3137ca79788eaa34765e184801c4db50560e5a0dda91William M. Brack	      larger than actually necessary.
3138ca79788eaa34765e184801c4db50560e5a0dda91William M. Brack	    */
3139ca79788eaa34765e184801c4db50560e5a0dda91William M. Brack	    char work[DBL_DIG + EXPONENT_DIGITS + 3 + LOWER_DOUBLE_EXP];
314070a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese	    int integer_place, fraction_place;
314170a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese	    char *ptr;
314270a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese	    char *after_fraction;
314370a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese	    double absolute_value;
314470a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese	    int size;
314570a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese
314670a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese	    absolute_value = fabs(number);
314770a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese
314870a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese	    /*
314970a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese	     * First choose format - scientific or regular floating point.
315070a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese	     * In either case, result is in work, and after_fraction points
315170a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese	     * just past the fractional part.
315270a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese	    */
315370a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese	    if ( ((absolute_value > UPPER_DOUBLE) ||
315470a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese		  (absolute_value < LOWER_DOUBLE)) &&
315570a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese		 (absolute_value != 0.0) ) {
315670a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese		/* Use scientific notation */
315770a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese		integer_place = DBL_DIG + EXPONENT_DIGITS + 1;
315870a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese		fraction_place = DBL_DIG - 1;
315911ce4004d86bb4b317c48b7d5124ba33e40e10f5Daniel Veillard		size = snprintf(work, sizeof(work),"%*.*e",
316070a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese			 integer_place, fraction_place, number);
316111ce4004d86bb4b317c48b7d5124ba33e40e10f5Daniel Veillard		while ((size > 0) && (work[size] != 'e')) size--;
316211ce4004d86bb4b317c48b7d5124ba33e40e10f5Daniel Veillard
3163e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese	    }
316470a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese	    else {
316570a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese		/* Use regular notation */
3166ca79788eaa34765e184801c4db50560e5a0dda91William M. Brack		if (absolute_value > 0.0) {
3167ca79788eaa34765e184801c4db50560e5a0dda91William M. Brack		    integer_place = (int)log10(absolute_value);
3168ca79788eaa34765e184801c4db50560e5a0dda91William M. Brack		    if (integer_place > 0)
3169ca79788eaa34765e184801c4db50560e5a0dda91William M. Brack		        fraction_place = DBL_DIG - integer_place - 1;
3170ca79788eaa34765e184801c4db50560e5a0dda91William M. Brack		    else
3171ca79788eaa34765e184801c4db50560e5a0dda91William M. Brack		        fraction_place = DBL_DIG - integer_place;
3172ca79788eaa34765e184801c4db50560e5a0dda91William M. Brack		} else {
3173ca79788eaa34765e184801c4db50560e5a0dda91William M. Brack		    fraction_place = 1;
3174ca79788eaa34765e184801c4db50560e5a0dda91William M. Brack		}
317570a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese		size = snprintf(work, sizeof(work), "%0.*f",
317670a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese				fraction_place, number);
3177e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese	    }
3178e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese
3179b9e4d5b6395f9aa0a34cb74e9a3672a20d37b943Daniel Veillard	    /* Remove leading spaces sometimes inserted by snprintf */
3180b9e4d5b6395f9aa0a34cb74e9a3672a20d37b943Daniel Veillard	    while (work[0] == ' ') {
3181b9e4d5b6395f9aa0a34cb74e9a3672a20d37b943Daniel Veillard	        for (ptr = &work[0];(ptr[0] = ptr[1]);ptr++);
3182b9e4d5b6395f9aa0a34cb74e9a3672a20d37b943Daniel Veillard		size--;
3183b9e4d5b6395f9aa0a34cb74e9a3672a20d37b943Daniel Veillard	    }
3184b9e4d5b6395f9aa0a34cb74e9a3672a20d37b943Daniel Veillard
318570a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese	    /* Remove fractional trailing zeroes */
3186ca79788eaa34765e184801c4db50560e5a0dda91William M. Brack	    after_fraction = work + size;
318770a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese	    ptr = after_fraction;
318870a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese	    while (*(--ptr) == '0')
318970a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese		;
319070a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese	    if (*ptr != '.')
319170a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese	        ptr++;
31925dd3c9622ab6a8e75870bc5351499155e7963abcDaniel Veillard	    while ((*ptr++ = *after_fraction++) != 0);
319370a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese
319470a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese	    /* Finally copy result back to caller */
319570a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese	    size = strlen(work) + 1;
319670a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese	    if (size > buffersize) {
319770a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese		work[buffersize - 1] = 0;
319870a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese		size = buffersize;
319970a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese	    }
32005dd3c9622ab6a8e75870bc5351499155e7963abcDaniel Veillard	    memmove(buffer, work, size);
3201e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese	}
3202e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese	break;
3203e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese    }
3204e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese}
3205e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese
32063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
32073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/************************************************************************
32083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *									*
32093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *			Routines to handle NodeSets			*
32103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *									*
32113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ************************************************************************/
32123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
32133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
3214e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard * xmlXPathOrderDocElems:
3215e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard * @doc:  an input document
3216e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard *
3217e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard * Call this routine to speed up XPath computation on static documents.
3218e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard * This stamps all the element nodes with the document order
3219e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard * Like for line information, the order is kept in the element->content
3220081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack * field, the value stored is actually - the node number (starting at -1)
3221081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack * to be able to differentiate from line numbers.
3222e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard *
3223081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack * Returns the number of elements found in the document or -1 in case
3224e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard *    of error.
3225e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk */
3226e28c8a1acef3047cceae1035924edae5e903a778Denis Pauklong
3227e28c8a1acef3047cceae1035924edae5e903a778Denis PaukxmlXPathOrderDocElems(xmlDocPtr doc) {
3228e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk    long count = 0;
3229e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk    xmlNodePtr cur;
3230f49be4778db34e8bbcfabc5d5f1ad33c594b7387Daniel Veillard
3231e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk    if (doc == NULL)
3232e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	return(-1);
3233e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk    cur = doc->children;
3234e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk    while (cur != NULL) {
3235e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	if (cur->type == XML_ELEMENT_NODE) {
3236e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	    cur->content = (void *) (-(++count));
3237e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	    if (cur->children != NULL) {
3238e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk		cur = cur->children;
3239e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk		continue;
3240e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	    }
3241e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	}
3242e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	if (cur->next != NULL) {
3243e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	    cur = cur->next;
3244e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	    continue;
3245e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	}
3246e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	do {
3247e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	    cur = cur->parent;
3248e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	    if (cur == NULL)
3249e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk		break;
3250e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	    if (cur == (xmlNodePtr) doc) {
3251e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk		cur = NULL;
3252e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk		break;
3253e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	    }
3254e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	    if (cur->next != NULL) {
3255e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk		cur = cur->next;
3256e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk		break;
3257e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	    }
3258e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	} while (cur != NULL);
3259e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk    }
3260e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk    return(count);
32613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
32623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
32632bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik/**
3264e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk * xmlXPathCmpNodes:
32652bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik * @node1:  the first node
32662bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik * @node2:  the second node
32672bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik *
3268e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk * Compare two nodes w.r.t document order
32692bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik *
32702bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik * Returns -2 in case of error 1 if first point < second point, 0 if
32712bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik *         it's the same node, -1 otherwise
32722bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik */
3273e28c8a1acef3047cceae1035924edae5e903a778Denis Paukint
3274e28c8a1acef3047cceae1035924edae5e903a778Denis PaukxmlXPathCmpNodes(xmlNodePtr node1, xmlNodePtr node2) {
32752bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik    int depth1, depth2;
3276e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk    int attr1 = 0, attr2 = 0;
3277e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk    xmlNodePtr attrNode1 = NULL, attrNode2 = NULL;
32782bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik    xmlNodePtr cur, root;
32792bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik
32802bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik    if ((node1 == NULL) || (node2 == NULL))
32812bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	return(-2);
32822bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik    /*
32832bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik     * a couple of optimizations which will avoid computations in most cases
328445490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard     */
3285e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk    if (node1 == node2)		/* trivial case */
3286e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	return(0);
3287e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk    if (node1->type == XML_ATTRIBUTE_NODE) {
3288e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	attr1 = 1;
3289e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	attrNode1 = node1;
3290e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	node1 = node1->parent;
329145490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard    }
3292e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk    if (node2->type == XML_ATTRIBUTE_NODE) {
3293e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	attr2 = 1;
3294e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	attrNode2 = node2;
3295e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	node2 = node2->parent;
32962bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik    }
3297e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk    if (node1 == node2) {
3298e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	if (attr1 == attr2) {
3299e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	    /* not required, but we keep attributes in order */
3300e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	    if (attr1 != 0) {
3301e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	        cur = attrNode2->prev;
33022bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik		while (cur != NULL) {
3303e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk		    if (cur == attrNode1)
3304e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk		        return (1);
33052bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik		    cur = cur->prev;
33062bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik		}
33072bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik		return (-1);
33082bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	    }
3309e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	    return(0);
33102bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	}
3311e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	if (attr2 == 1)
3312e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	    return(1);
3313e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	return(-1);
331445490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard    }
3315e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk    if ((node1->type == XML_NAMESPACE_DECL) ||
3316e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk        (node2->type == XML_NAMESPACE_DECL))
3317e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	return(1);
3318e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk    if (node1 == node2->prev)
3319e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	return(1);
3320e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk    if (node1 == node2->next)
3321e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	return(-1);
33222bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik
33232bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik    /*
33242bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik     * Speedup using document order if availble.
33252bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik     */
332645490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard    if ((node1->type == XML_ELEMENT_NODE) &&
33272bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	(node2->type == XML_ELEMENT_NODE) &&
33282bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	(0 > (long) node1->content) &&
33292bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	(0 > (long) node2->content) &&
333045490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	(node1->doc == node2->doc)) {
3331e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	long l1, l2;
33322bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik
33332bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	l1 = -((long) node1->content);
33342bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	l2 = -((long) node2->content);
33352bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	if (l1 < l2)
33362bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	    return(1);
33372bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	if (l1 > l2)
33382bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	    return(-1);
33392bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik    }
33402bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik
33412bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik    /*
33422bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik     * compute depth to root
33432bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik     */
33442bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik    for (depth2 = 0, cur = node2;cur->parent != NULL;cur = cur->parent) {
33452bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	if (cur == node1)
33462bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	    return(1);
33472bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	depth2++;
33482bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik    }
33492bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik    root = cur;
33502bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik    for (depth1 = 0, cur = node1;cur->parent != NULL;cur = cur->parent) {
33512bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	if (cur == node2)
33522bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	    return(-1);
33532bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	depth1++;
33542bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik    }
33552bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik    /*
33562bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik     * Distinct document (or distinct entities :-( ) case.
33572bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik     */
33582bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik    if (root != cur) {
33592bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	return(-2);
33602bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik    }
33612bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik    /*
33622bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik     * get the nearest common ancestor.
33632bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik     */
33642bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik    while (depth1 > depth2) {
33652bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	depth1--;
33662bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	node1 = node1->parent;
33672bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik    }
33682bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik    while (depth2 > depth1) {
33692bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	depth2--;
33702bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	node2 = node2->parent;
33712bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik    }
33722bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik    while (node1->parent != node2->parent) {
33732bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	node1 = node1->parent;
33742bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	node2 = node2->parent;
33752bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	/* should not happen but just in case ... */
33762bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	if ((node1 == NULL) || (node2 == NULL))
33772bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	    return(-2);
33782bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik    }
33792bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik    /*
33802bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik     * Find who's first.
33812bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik     */
33822bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik    if (node1 == node2->prev)
33832bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	return(1);
33842bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik    if (node1 == node2->next)
33852bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	return(-1);
33862bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik    /*
33872bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik     * Speedup using document order if availble.
33882bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik     */
33892bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik    if ((node1->type == XML_ELEMENT_NODE) &&
33902bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	(node2->type == XML_ELEMENT_NODE) &&
33912bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	(0 > (long) node1->content) &&
33922bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	(0 > (long) node2->content) &&
339345490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	(node1->doc == node2->doc)) {
3394e28c8a1acef3047cceae1035924edae5e903a778Denis Pauk	long l1, l2;
33952bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik
33962bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	l1 = -((long) node1->content);
33972bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	l2 = -((long) node2->content);
33982bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	if (l1 < l2)
33992bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	    return(1);
34002bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	if (l1 > l2)
34012bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	    return(-1);
34022bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik    }
34032bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik
34042bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik    for (cur = node1->next;cur != NULL;cur = cur->next)
34052bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	if (cur == node2)
34062bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik	    return(1);
34072bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik    return(-1); /* assume there is no sibling list corruption */
34082bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik}
34092bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik
34103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
34113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNodeSetSort:
34123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @set:  the node set
34133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
34143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Sort the node set in document order
34153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
34163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
34173473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNodeSetSort(xmlNodeSetPtr set) {
34183e031b7dae590bdd03084a5971d9f9e66fe5d50bVojtech Fried#ifndef WITH_TIM_SORT
3419e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese    int i, j, incr, len;
34203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlNodePtr tmp;
34213e031b7dae590bdd03084a5971d9f9e66fe5d50bVojtech Fried#endif
34223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
34233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (set == NULL)
34243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return;
34253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
34263e031b7dae590bdd03084a5971d9f9e66fe5d50bVojtech Fried#ifndef WITH_TIM_SORT
34273e031b7dae590bdd03084a5971d9f9e66fe5d50bVojtech Fried    /*
34283e031b7dae590bdd03084a5971d9f9e66fe5d50bVojtech Fried     * Use the old Shell's sort implementation to sort the node-set
34293e031b7dae590bdd03084a5971d9f9e66fe5d50bVojtech Fried     * Timsort ought to be quite faster
34303e031b7dae590bdd03084a5971d9f9e66fe5d50bVojtech Fried     */
34313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    len = set->nodeNr;
34323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    for (incr = len / 2; incr > 0; incr /= 2) {
34333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	for (i = incr; i < len; i++) {
34343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    j = i - incr;
34353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    while (j >= 0) {
34365691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik#ifdef XP_OPTIMIZED_NON_ELEM_COMPARISON
34372bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik		if (xmlXPathCmpNodesExt(set->nodeTab[j],
34382bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik			set->nodeTab[j + incr]) == -1)
34392bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik#else
3440e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese		if (xmlXPathCmpNodes(set->nodeTab[j],
34412bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik			set->nodeTab[j + incr]) == -1)
34422bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik#endif
34432bdabbd711356e534940431053523f1538d1a93eKasimier T. Buchcik		{
34443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    tmp = set->nodeTab[j];
34453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    set->nodeTab[j] = set->nodeTab[j + incr];
34463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    set->nodeTab[j + incr] = tmp;
34473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    j -= incr;
34483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		} else
34493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    break;
34503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    }
34513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
34523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
34533e031b7dae590bdd03084a5971d9f9e66fe5d50bVojtech Fried#else /* WITH_TIM_SORT */
34543e031b7dae590bdd03084a5971d9f9e66fe5d50bVojtech Fried    libxml_domnode_tim_sort(set->nodeTab, set->nodeNr);
34553e031b7dae590bdd03084a5971d9f9e66fe5d50bVojtech Fried#endif /* WITH_TIM_SORT */
34563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
34573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
34583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define XML_NODESET_DEFAULT	10
34593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
3460044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * xmlXPathNodeSetDupNs:
3461044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * @node:  the parent node of the namespace XPath node
3462044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * @ns:  the libxml namespace declaration node.
3463044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard *
3464044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * Namespace node in libxml don't match the XPath semantic. In a node set
3465044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * the namespace nodes are duplicated and the next pointer is set to the
3466044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * parent node in the XPath semantic.
3467044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard *
3468044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * Returns the newly created object.
3469044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard */
3470044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillardstatic xmlNodePtr
3471044fc6b7476798cbb95277b4905e5111d7c2775dDaniel VeillardxmlXPathNodeSetDupNs(xmlNodePtr node, xmlNsPtr ns) {
3472044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    xmlNsPtr cur;
3473044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard
3474044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    if ((ns == NULL) || (ns->type != XML_NAMESPACE_DECL))
3475044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard	return(NULL);
3476044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    if ((node == NULL) || (node->type == XML_NAMESPACE_DECL))
3477044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard	return((xmlNodePtr) ns);
3478044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard
3479044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    /*
3480044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard     * Allocate a new Namespace and fill the fields.
3481044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard     */
3482044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    cur = (xmlNsPtr) xmlMalloc(sizeof(xmlNs));
3483044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    if (cur == NULL) {
3484d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard        xmlXPathErrMemory(NULL, "duplicating namespace\n");
3485044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard	return(NULL);
3486044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    }
3487044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    memset(cur, 0, sizeof(xmlNs));
3488044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    cur->type = XML_NAMESPACE_DECL;
3489044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    if (ns->href != NULL)
349045490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	cur->href = xmlStrdup(ns->href);
3491044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    if (ns->prefix != NULL)
349245490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	cur->prefix = xmlStrdup(ns->prefix);
3493044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    cur->next = (xmlNsPtr) node;
3494044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    return((xmlNodePtr) cur);
3495044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard}
3496044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard
3497044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard/**
3498044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * xmlXPathNodeSetFreeNs:
3499044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * @ns:  the XPath namespace node found in a nodeset.
3500044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard *
3501081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack * Namespace nodes in libxml don't match the XPath semantic. In a node set
3502044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * the namespace nodes are duplicated and the next pointer is set to the
3503081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack * parent node in the XPath semantic. Check if such a node needs to be freed
3504044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard */
3505f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Saninvoid
3506044fc6b7476798cbb95277b4905e5111d7c2775dDaniel VeillardxmlXPathNodeSetFreeNs(xmlNsPtr ns) {
3507044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    if ((ns == NULL) || (ns->type != XML_NAMESPACE_DECL))
3508044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard	return;
3509044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard
3510044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    if ((ns->next != NULL) && (ns->next->type != XML_NAMESPACE_DECL)) {
3511044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard	if (ns->href != NULL)
3512044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard	    xmlFree((xmlChar *)ns->href);
3513044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard	if (ns->prefix != NULL)
3514044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard	    xmlFree((xmlChar *)ns->prefix);
3515044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard	xmlFree(ns);
3516044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    }
3517044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard}
3518044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard
3519044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard/**
35203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNodeSetCreate:
35213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val:  an initial xmlNodePtr, or NULL
35223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
35233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Create a new xmlNodeSetPtr of type double and of value @val
35243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
35253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the newly created object.
35263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
35273473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNodeSetPtr
35283473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNodeSetCreate(xmlNodePtr val) {
35293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlNodeSetPtr ret;
35303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
35313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret = (xmlNodeSetPtr) xmlMalloc(sizeof(xmlNodeSet));
35323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ret == NULL) {
3533d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard        xmlXPathErrMemory(NULL, "creating nodeset\n");
35343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(NULL);
35353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
35363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    memset(ret, 0 , (size_t) sizeof(xmlNodeSet));
35373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (val != NULL) {
35383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        ret->nodeTab = (xmlNodePtr *) xmlMalloc(XML_NODESET_DEFAULT *
35393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor					     sizeof(xmlNodePtr));
35403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (ret->nodeTab == NULL) {
3541d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard	    xmlXPathErrMemory(NULL, "creating nodeset\n");
3542d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard	    xmlFree(ret);
35433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    return(NULL);
35443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
35453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	memset(ret->nodeTab, 0 ,
35463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	       XML_NODESET_DEFAULT * (size_t) sizeof(xmlNodePtr));
35473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        ret->nodeMax = XML_NODESET_DEFAULT;
3548044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard	if (val->type == XML_NAMESPACE_DECL) {
3549044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard	    xmlNsPtr ns = (xmlNsPtr) val;
3550044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard
3551044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard	    ret->nodeTab[ret->nodeNr++] =
3552044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard		xmlXPathNodeSetDupNs((xmlNodePtr) ns->next, ns);
3553044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard	} else
3554044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard	    ret->nodeTab[ret->nodeNr++] = val;
35553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
35563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(ret);
35573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
35583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
35595691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik/**
35609bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik * xmlXPathNodeSetCreateSize:
35619bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik * @size:  the initial size of the set
35629bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik *
35639bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik * Create a new xmlNodeSetPtr of type double and of value @val
35649bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik *
35659bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik * Returns the newly created object.
35669bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik */
35679bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcikstatic xmlNodeSetPtr
35689bca933a6e39bae6dd8952825528270f006c97dfKasimier T. BuchcikxmlXPathNodeSetCreateSize(int size) {
35699bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    xmlNodeSetPtr ret;
35709bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik
35719bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    ret = (xmlNodeSetPtr) xmlMalloc(sizeof(xmlNodeSet));
35729bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    if (ret == NULL) {
35739bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik        xmlXPathErrMemory(NULL, "creating nodeset\n");
35749bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	return(NULL);
35759bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    }
35769bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    memset(ret, 0 , (size_t) sizeof(xmlNodeSet));
35779bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    if (size < XML_NODESET_DEFAULT)
35789bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	size = XML_NODESET_DEFAULT;
35799bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    ret->nodeTab = (xmlNodePtr *) xmlMalloc(size * sizeof(xmlNodePtr));
35809bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    if (ret->nodeTab == NULL) {
35819bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	xmlXPathErrMemory(NULL, "creating nodeset\n");
35829bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	xmlFree(ret);
35839bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	return(NULL);
35849bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    }
35859bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    memset(ret->nodeTab, 0 , size * (size_t) sizeof(xmlNodePtr));
358645490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard    ret->nodeMax = size;
35879bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    return(ret);
35889bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik}
35899bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik
35909bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik/**
3591f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathNodeSetContains:
3592f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @cur:  the node-set
3593f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @val:  the node
3594f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *
3595f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * checks whether @cur contains @val
3596f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *
3597f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns true (1) if @cur contains @val, false (0) otherwise
3598f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */
3599f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyerint
3600f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathNodeSetContains (xmlNodeSetPtr cur, xmlNodePtr val) {
3601f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    int i;
3602f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer
3603a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard    if ((cur == NULL) || (val == NULL)) return(0);
3604044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    if (val->type == XML_NAMESPACE_DECL) {
3605044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard	for (i = 0; i < cur->nodeNr; i++) {
3606044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard	    if (cur->nodeTab[i]->type == XML_NAMESPACE_DECL) {
3607044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard		xmlNsPtr ns1, ns2;
3608044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard
3609044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard		ns1 = (xmlNsPtr) val;
3610044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard		ns2 = (xmlNsPtr) cur->nodeTab[i];
3611044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard		if (ns1 == ns2)
3612044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard		    return(1);
3613044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard		if ((ns1->next != NULL) && (ns2->next == ns1->next) &&
3614044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard	            (xmlStrEqual(ns1->prefix, ns2->prefix)))
3615044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard		    return(1);
3616044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard	    }
3617044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard	}
3618044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    } else {
3619044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard	for (i = 0; i < cur->nodeNr; i++) {
3620044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard	    if (cur->nodeTab[i] == val)
3621044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard		return(1);
3622044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard	}
3623f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    }
3624f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    return(0);
3625f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer}
3626f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer
3627f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/**
3628044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * xmlXPathNodeSetAddNs:
3629044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * @cur:  the initial node set
3630044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * @node:  the hosting node
3631044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * @ns:  a the namespace node
3632044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard *
3633044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * add a new namespace node to an existing NodeSet
36341bd45d13091e5af9e1fe0582b5e335c60d45535fDaniel Veillard *
36351bd45d13091e5af9e1fe0582b5e335c60d45535fDaniel Veillard * Returns 0 in case of success and -1 in case of error
3636044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard */
36371bd45d13091e5af9e1fe0582b5e335c60d45535fDaniel Veillardint
3638044fc6b7476798cbb95277b4905e5111d7c2775dDaniel VeillardxmlXPathNodeSetAddNs(xmlNodeSetPtr cur, xmlNodePtr node, xmlNsPtr ns) {
3639044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    int i;
3640044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard
364145490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
3642a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard    if ((cur == NULL) || (ns == NULL) || (node == NULL) ||
3643a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard        (ns->type != XML_NAMESPACE_DECL) ||
3644044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard	(node->type != XML_ELEMENT_NODE))
36451bd45d13091e5af9e1fe0582b5e335c60d45535fDaniel Veillard	return(-1);
3646044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard
3647081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack    /* @@ with_ns to check whether namespace nodes should be looked at @@ */
3648044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    /*
3649081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack     * prevent duplicates
3650044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard     */
3651044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    for (i = 0;i < cur->nodeNr;i++) {
3652044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard        if ((cur->nodeTab[i] != NULL) &&
3653044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard	    (cur->nodeTab[i]->type == XML_NAMESPACE_DECL) &&
3654c62a147963b5839fc815267706eaec381f90ca16Daniel Veillard	    (((xmlNsPtr)cur->nodeTab[i])->next == (xmlNsPtr) node) &&
3655044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard	    (xmlStrEqual(ns->prefix, ((xmlNsPtr)cur->nodeTab[i])->prefix)))
36561bd45d13091e5af9e1fe0582b5e335c60d45535fDaniel Veillard	    return(0);
3657044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    }
3658044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard
3659044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    /*
3660044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard     * grow the nodeTab if needed
3661044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard     */
3662044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    if (cur->nodeMax == 0) {
3663044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard        cur->nodeTab = (xmlNodePtr *) xmlMalloc(XML_NODESET_DEFAULT *
3664044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard					     sizeof(xmlNodePtr));
3665044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard	if (cur->nodeTab == NULL) {
3666d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard	    xmlXPathErrMemory(NULL, "growing nodeset\n");
36671bd45d13091e5af9e1fe0582b5e335c60d45535fDaniel Veillard	    return(-1);
3668044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard	}
3669044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard	memset(cur->nodeTab, 0 ,
3670044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard	       XML_NODESET_DEFAULT * (size_t) sizeof(xmlNodePtr));
3671044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard        cur->nodeMax = XML_NODESET_DEFAULT;
3672044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    } else if (cur->nodeNr == cur->nodeMax) {
3673044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard        xmlNodePtr *temp;
3674044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard
3675cd852ad154fd919d9a4bd955566b43bac848878aDaniel Veillard        if (cur->nodeMax >= XPATH_MAX_NODESET_LENGTH) {
3676cd852ad154fd919d9a4bd955566b43bac848878aDaniel Veillard            xmlXPathErrMemory(NULL, "growing nodeset hit limit\n");
36771bd45d13091e5af9e1fe0582b5e335c60d45535fDaniel Veillard            return(-1);
3678cd852ad154fd919d9a4bd955566b43bac848878aDaniel Veillard        }
3679d7958b21e7f8c447a26bb2436f08402b2c308be4Chris Evans	temp = (xmlNodePtr *) xmlRealloc(cur->nodeTab, cur->nodeMax * 2 *
3680044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard				      sizeof(xmlNodePtr));
3681044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard	if (temp == NULL) {
3682d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard	    xmlXPathErrMemory(NULL, "growing nodeset\n");
36831bd45d13091e5af9e1fe0582b5e335c60d45535fDaniel Veillard	    return(-1);
3684044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard	}
3685d7958b21e7f8c447a26bb2436f08402b2c308be4Chris Evans        cur->nodeMax *= 2;
3686044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard	cur->nodeTab = temp;
3687044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    }
3688044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    cur->nodeTab[cur->nodeNr++] = xmlXPathNodeSetDupNs(node, ns);
36891bd45d13091e5af9e1fe0582b5e335c60d45535fDaniel Veillard    return(0);
3690044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard}
3691044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard
3692044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard/**
36933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNodeSetAdd:
36943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur:  the initial node set
36953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val:  a new xmlNodePtr
36963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
3697cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * add a new xmlNodePtr to an existing NodeSet
36981bd45d13091e5af9e1fe0582b5e335c60d45535fDaniel Veillard *
36991bd45d13091e5af9e1fe0582b5e335c60d45535fDaniel Veillard * Returns 0 in case of success, and -1 in case of error
37003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
37011bd45d13091e5af9e1fe0582b5e335c60d45535fDaniel Veillardint
37023473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNodeSetAdd(xmlNodeSetPtr cur, xmlNodePtr val) {
37033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    int i;
37043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
37051bd45d13091e5af9e1fe0582b5e335c60d45535fDaniel Veillard    if ((cur == NULL) || (val == NULL)) return(-1);
37063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
3707081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack    /* @@ with_ns to check whether namespace nodes should be looked at @@ */
37083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    /*
3709081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack     * prevent duplcates
37103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor     */
37113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    for (i = 0;i < cur->nodeNr;i++)
37121bd45d13091e5af9e1fe0582b5e335c60d45535fDaniel Veillard        if (cur->nodeTab[i] == val) return(0);
37133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
37143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    /*
37153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor     * grow the nodeTab if needed
37163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor     */
37173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (cur->nodeMax == 0) {
37183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        cur->nodeTab = (xmlNodePtr *) xmlMalloc(XML_NODESET_DEFAULT *
37193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor					     sizeof(xmlNodePtr));
37203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (cur->nodeTab == NULL) {
3721d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard	    xmlXPathErrMemory(NULL, "growing nodeset\n");
37221bd45d13091e5af9e1fe0582b5e335c60d45535fDaniel Veillard	    return(-1);
37233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
37243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	memset(cur->nodeTab, 0 ,
37253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	       XML_NODESET_DEFAULT * (size_t) sizeof(xmlNodePtr));
37263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        cur->nodeMax = XML_NODESET_DEFAULT;
37273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    } else if (cur->nodeNr == cur->nodeMax) {
37283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        xmlNodePtr *temp;
37293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
3730cd852ad154fd919d9a4bd955566b43bac848878aDaniel Veillard        if (cur->nodeMax >= XPATH_MAX_NODESET_LENGTH) {
3731cd852ad154fd919d9a4bd955566b43bac848878aDaniel Veillard            xmlXPathErrMemory(NULL, "growing nodeset hit limit\n");
37321bd45d13091e5af9e1fe0582b5e335c60d45535fDaniel Veillard            return(-1);
3733cd852ad154fd919d9a4bd955566b43bac848878aDaniel Veillard        }
37340cbeb50ee03ce582a0c979c70d8fbf030e270c37Daniel Veillard	temp = (xmlNodePtr *) xmlRealloc(cur->nodeTab, cur->nodeMax * 2 *
37353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor				      sizeof(xmlNodePtr));
37363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (temp == NULL) {
3737d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard	    xmlXPathErrMemory(NULL, "growing nodeset\n");
37381bd45d13091e5af9e1fe0582b5e335c60d45535fDaniel Veillard	    return(-1);
37393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
37400cbeb50ee03ce582a0c979c70d8fbf030e270c37Daniel Veillard        cur->nodeMax *= 2;
37413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	cur->nodeTab = temp;
37423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
3743044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    if (val->type == XML_NAMESPACE_DECL) {
3744044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard	xmlNsPtr ns = (xmlNsPtr) val;
3745044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard
374645490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	cur->nodeTab[cur->nodeNr++] =
3747044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard	    xmlXPathNodeSetDupNs((xmlNodePtr) ns->next, ns);
3748044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    } else
3749044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard	cur->nodeTab[cur->nodeNr++] = val;
37501bd45d13091e5af9e1fe0582b5e335c60d45535fDaniel Veillard    return(0);
37513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
37523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
37533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
37543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNodeSetAddUnique:
37553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur:  the initial node set
37563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val:  a new xmlNodePtr
37573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
3758cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * add a new xmlNodePtr to an existing NodeSet, optimized version
37593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * when we are sure the node is not already in the set.
37601bd45d13091e5af9e1fe0582b5e335c60d45535fDaniel Veillard *
37611bd45d13091e5af9e1fe0582b5e335c60d45535fDaniel Veillard * Returns 0 in case of success and -1 in case of failure
37623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
37631bd45d13091e5af9e1fe0582b5e335c60d45535fDaniel Veillardint
37643473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNodeSetAddUnique(xmlNodeSetPtr cur, xmlNodePtr val) {
37651bd45d13091e5af9e1fe0582b5e335c60d45535fDaniel Veillard    if ((cur == NULL) || (val == NULL)) return(-1);
37663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
3767081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack    /* @@ with_ns to check whether namespace nodes should be looked at @@ */
37683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    /*
37693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor     * grow the nodeTab if needed
37703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor     */
37713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (cur->nodeMax == 0) {
37723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        cur->nodeTab = (xmlNodePtr *) xmlMalloc(XML_NODESET_DEFAULT *
37733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor					     sizeof(xmlNodePtr));
37743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (cur->nodeTab == NULL) {
3775d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard	    xmlXPathErrMemory(NULL, "growing nodeset\n");
37761bd45d13091e5af9e1fe0582b5e335c60d45535fDaniel Veillard	    return(-1);
37773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
37783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	memset(cur->nodeTab, 0 ,
37793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	       XML_NODESET_DEFAULT * (size_t) sizeof(xmlNodePtr));
37803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        cur->nodeMax = XML_NODESET_DEFAULT;
37813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    } else if (cur->nodeNr == cur->nodeMax) {
37823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        xmlNodePtr *temp;
37833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
3784cd852ad154fd919d9a4bd955566b43bac848878aDaniel Veillard        if (cur->nodeMax >= XPATH_MAX_NODESET_LENGTH) {
3785cd852ad154fd919d9a4bd955566b43bac848878aDaniel Veillard            xmlXPathErrMemory(NULL, "growing nodeset hit limit\n");
37861bd45d13091e5af9e1fe0582b5e335c60d45535fDaniel Veillard            return(-1);
3787cd852ad154fd919d9a4bd955566b43bac848878aDaniel Veillard        }
3788d7958b21e7f8c447a26bb2436f08402b2c308be4Chris Evans	temp = (xmlNodePtr *) xmlRealloc(cur->nodeTab, cur->nodeMax * 2 *
37893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor				      sizeof(xmlNodePtr));
37903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (temp == NULL) {
3791d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard	    xmlXPathErrMemory(NULL, "growing nodeset\n");
37921bd45d13091e5af9e1fe0582b5e335c60d45535fDaniel Veillard	    return(-1);
37933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
37943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	cur->nodeTab = temp;
3795d7958b21e7f8c447a26bb2436f08402b2c308be4Chris Evans        cur->nodeMax *= 2;
37963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
3797044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    if (val->type == XML_NAMESPACE_DECL) {
3798044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard	xmlNsPtr ns = (xmlNsPtr) val;
3799044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard
380045490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	cur->nodeTab[cur->nodeNr++] =
3801044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard	    xmlXPathNodeSetDupNs((xmlNodePtr) ns->next, ns);
3802044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    } else
3803044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard	cur->nodeTab[cur->nodeNr++] = val;
38041bd45d13091e5af9e1fe0582b5e335c60d45535fDaniel Veillard    return(0);
38053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
38063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
38073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
38083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNodeSetMerge:
38093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val1:  the first NodeSet or NULL
38103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val2:  the second NodeSet
38113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
38123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Merges two nodesets, all nodes from @val2 are added to @val1
38133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * if @val1 is NULL, a new set is created and copied from @val2
38143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
3815cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * Returns @val1 once extended or NULL in case of error.
38163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
38173473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNodeSetPtr
38183473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNodeSetMerge(xmlNodeSetPtr val1, xmlNodeSetPtr val2) {
3819d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard    int i, j, initNr, skip;
38205691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik    xmlNodePtr n1, n2;
38213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
38223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (val2 == NULL) return(val1);
38233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (val1 == NULL) {
3824984a9aeddf69378a05f79ee750e7996bfa791c24Kasimier T. Buchcik	val1 = xmlXPathNodeSetCreate(NULL);
3825f88d849a4e994c94c0d0814a4befb43c990ceebdDaniel Veillard    if (val1 == NULL)
3826f88d849a4e994c94c0d0814a4befb43c990ceebdDaniel Veillard        return (NULL);
3827984a9aeddf69378a05f79ee750e7996bfa791c24Kasimier T. Buchcik#if 0
3828a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	/*
3829a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	* TODO: The optimization won't work in every case, since
3830a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	*  those nasty namespace nodes need to be added with
3831a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	*  xmlXPathNodeSetDupNs() to the set; thus a pure
3832a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	*  memcpy is not possible.
3833df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik	*  If there was a flag on the nodesetval, indicating that
3834df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik	*  some temporary nodes are in, that would be helpfull.
3835a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	*/
383645490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	/*
3837a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	* Optimization: Create an equally sized node-set
3838a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	* and memcpy the content.
3839a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	*/
3840a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	val1 = xmlXPathNodeSetCreateSize(val2->nodeNr);
3841a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	if (val1 == NULL)
3842a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    return(NULL);
3843a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	if (val2->nodeNr != 0) {
38445691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    if (val2->nodeNr == 1)
38455691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		*(val1->nodeTab) = *(val2->nodeTab);
38465691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    else {
38475691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		memcpy(val1->nodeTab, val2->nodeTab,
38485691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		    val2->nodeNr * sizeof(xmlNodePtr));
38495691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    }
38505691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    val1->nodeNr = val2->nodeNr;
3851a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	}
38525691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	return(val1);
3853a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#endif
38543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
38553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
3856081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack    /* @@ with_ns to check whether namespace nodes should be looked at @@ */
38573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    initNr = val1->nodeNr;
38583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
38593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    for (i = 0;i < val2->nodeNr;i++) {
386045490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	n2 = val2->nodeTab[i];
38613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	/*
3862081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack	 * check against duplicates
38633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	 */
3864d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	skip = 0;
3865d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	for (j = 0; j < initNr; j++) {
38665691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    n1 = val1->nodeTab[j];
38675691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    if (n1 == n2) {
3868d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard		skip = 1;
3869d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard		break;
38705691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    } else if ((n1->type == XML_NAMESPACE_DECL) &&
387145490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard		       (n2->type == XML_NAMESPACE_DECL)) {
38725691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		if ((((xmlNsPtr) n1)->next == ((xmlNsPtr) n2)->next) &&
38735691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		    (xmlStrEqual(((xmlNsPtr) n1)->prefix,
38745691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik			((xmlNsPtr) n2)->prefix)))
38755691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		{
3876044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard		    skip = 1;
3877044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard		    break;
3878044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard		}
3879d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	    }
3880d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	}
3881d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	if (skip)
3882d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	    continue;
38833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
38843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	/*
38853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	 * grow the nodeTab if needed
38863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	 */
38873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (val1->nodeMax == 0) {
38883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    val1->nodeTab = (xmlNodePtr *) xmlMalloc(XML_NODESET_DEFAULT *
38893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor						    sizeof(xmlNodePtr));
38903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    if (val1->nodeTab == NULL) {
3891d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard	        xmlXPathErrMemory(NULL, "merging nodeset\n");
38923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		return(NULL);
38933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    }
38943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    memset(val1->nodeTab, 0 ,
38953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		   XML_NODESET_DEFAULT * (size_t) sizeof(xmlNodePtr));
38963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    val1->nodeMax = XML_NODESET_DEFAULT;
38973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	} else if (val1->nodeNr == val1->nodeMax) {
38983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    xmlNodePtr *temp;
38993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
3900cd852ad154fd919d9a4bd955566b43bac848878aDaniel Veillard            if (val1->nodeMax >= XPATH_MAX_NODESET_LENGTH) {
3901cd852ad154fd919d9a4bd955566b43bac848878aDaniel Veillard                xmlXPathErrMemory(NULL, "merging nodeset hit limit\n");
3902cd852ad154fd919d9a4bd955566b43bac848878aDaniel Veillard                return(NULL);
3903cd852ad154fd919d9a4bd955566b43bac848878aDaniel Veillard            }
3904d7958b21e7f8c447a26bb2436f08402b2c308be4Chris Evans	    temp = (xmlNodePtr *) xmlRealloc(val1->nodeTab, val1->nodeMax * 2 *
39053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor					     sizeof(xmlNodePtr));
39063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    if (temp == NULL) {
3907d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard	        xmlXPathErrMemory(NULL, "merging nodeset\n");
39083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		return(NULL);
39093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    }
39103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    val1->nodeTab = temp;
3911d7958b21e7f8c447a26bb2436f08402b2c308be4Chris Evans	    val1->nodeMax *= 2;
39123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
39135691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	if (n2->type == XML_NAMESPACE_DECL) {
39145691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    xmlNsPtr ns = (xmlNsPtr) n2;
3915044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard
3916044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard	    val1->nodeTab[val1->nodeNr++] =
3917044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard		xmlXPathNodeSetDupNs((xmlNodePtr) ns->next, ns);
3918044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard	} else
39195691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    val1->nodeTab[val1->nodeNr++] = n2;
39203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
39213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
39223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(val1);
39233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
39243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
39259bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik
39269bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik/**
39279bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik * xmlXPathNodeSetMergeAndClear:
39289bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik * @set1:  the first NodeSet or NULL
39299bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik * @set2:  the second NodeSet
39309bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik * @hasSet2NsNodes: 1 if set2 contains namespaces nodes
39319bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik *
39329bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik * Merges two nodesets, all nodes from @set2 are added to @set1
39339bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik * if @set1 is NULL, a new set is created and copied from @set2.
39349bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik * Checks for duplicate nodes. Clears set2.
39359bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik *
39369bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik * Returns @set1 once extended or NULL in case of error.
39379bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik */
39389bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcikstatic xmlNodeSetPtr
39399bca933a6e39bae6dd8952825528270f006c97dfKasimier T. BuchcikxmlXPathNodeSetMergeAndClear(xmlNodeSetPtr set1, xmlNodeSetPtr set2,
39409bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik			     int hasNullEntries)
39419bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik{
39429bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    if ((set1 == NULL) && (hasNullEntries == 0)) {
39439bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	/*
39449bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	* Note that doing a memcpy of the list, namespace nodes are
39459bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	* just assigned to set1, since set2 is cleared anyway.
39469bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	*/
39479bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	set1 = xmlXPathNodeSetCreateSize(set2->nodeNr);
39489bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	if (set1 == NULL)
39499bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    return(NULL);
39509bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	if (set2->nodeNr != 0) {
39519bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    memcpy(set1->nodeTab, set2->nodeTab,
39529bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		set2->nodeNr * sizeof(xmlNodePtr));
39539bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    set1->nodeNr = set2->nodeNr;
39549bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	}
39559bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    } else {
39569bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	int i, j, initNbSet1;
39579bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	xmlNodePtr n1, n2;
39589bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik
39599bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	if (set1 == NULL)
3960f88d849a4e994c94c0d0814a4befb43c990ceebdDaniel Veillard            set1 = xmlXPathNodeSetCreate(NULL);
3961f88d849a4e994c94c0d0814a4befb43c990ceebdDaniel Veillard        if (set1 == NULL)
3962f88d849a4e994c94c0d0814a4befb43c990ceebdDaniel Veillard            return (NULL);
39639bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik
396445490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	initNbSet1 = set1->nodeNr;
39659bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	for (i = 0;i < set2->nodeNr;i++) {
39669bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    n2 = set2->nodeTab[i];
39679bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    /*
39689bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    * Skip NULLed entries.
39699bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    */
39709bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    if (n2 == NULL)
39719bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		continue;
39729bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    /*
39739bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    * Skip duplicates.
39749bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    */
39759bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    for (j = 0; j < initNbSet1; j++) {
39769bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		n1 = set1->nodeTab[j];
397745490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard		if (n1 == n2) {
39789bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		    goto skip_node;
39799bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		} else if ((n1->type == XML_NAMESPACE_DECL) &&
39809bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		    (n2->type == XML_NAMESPACE_DECL))
398145490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard		{
39829bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		    if ((((xmlNsPtr) n1)->next == ((xmlNsPtr) n2)->next) &&
39839bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik			(xmlStrEqual(((xmlNsPtr) n1)->prefix,
39849bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik			((xmlNsPtr) n2)->prefix)))
39859bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		    {
39869bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik			/*
39879bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik			* Free the namespace node.
39889bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik			*/
39899bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik			set2->nodeTab[i] = NULL;
39909bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik			xmlXPathNodeSetFreeNs((xmlNsPtr) n2);
39919bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik			goto skip_node;
39929bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		    }
39939bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		}
39949bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    }
39959bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    /*
39969bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    * grow the nodeTab if needed
39979bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    */
39989bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    if (set1->nodeMax == 0) {
39999bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		set1->nodeTab = (xmlNodePtr *) xmlMalloc(
40009bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		    XML_NODESET_DEFAULT * sizeof(xmlNodePtr));
40019bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		if (set1->nodeTab == NULL) {
40029bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		    xmlXPathErrMemory(NULL, "merging nodeset\n");
40039bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		    return(NULL);
40049bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		}
40059bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		memset(set1->nodeTab, 0,
40069bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		    XML_NODESET_DEFAULT * (size_t) sizeof(xmlNodePtr));
40079bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		set1->nodeMax = XML_NODESET_DEFAULT;
40089bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    } else if (set1->nodeNr >= set1->nodeMax) {
40099bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		xmlNodePtr *temp;
401045490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
4011cd852ad154fd919d9a4bd955566b43bac848878aDaniel Veillard                if (set1->nodeMax >= XPATH_MAX_NODESET_LENGTH) {
4012cd852ad154fd919d9a4bd955566b43bac848878aDaniel Veillard                    xmlXPathErrMemory(NULL, "merging nodeset hit limit\n");
4013cd852ad154fd919d9a4bd955566b43bac848878aDaniel Veillard                    return(NULL);
4014cd852ad154fd919d9a4bd955566b43bac848878aDaniel Veillard                }
40159bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		temp = (xmlNodePtr *) xmlRealloc(
4016d7958b21e7f8c447a26bb2436f08402b2c308be4Chris Evans		    set1->nodeTab, set1->nodeMax * 2 * sizeof(xmlNodePtr));
40179bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		if (temp == NULL) {
40189bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		    xmlXPathErrMemory(NULL, "merging nodeset\n");
40199bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		    return(NULL);
40209bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		}
40219bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		set1->nodeTab = temp;
4022d7958b21e7f8c447a26bb2436f08402b2c308be4Chris Evans		set1->nodeMax *= 2;
40239bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    }
40249bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    if (n2->type == XML_NAMESPACE_DECL) {
40259bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		xmlNsPtr ns = (xmlNsPtr) n2;
402645490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
40279bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		set1->nodeTab[set1->nodeNr++] =
40289bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		    xmlXPathNodeSetDupNs((xmlNodePtr) ns->next, ns);
40299bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    } else
40309bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		set1->nodeTab[set1->nodeNr++] = n2;
40319bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcikskip_node:
40329bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    {}
40339bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	}
40349bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    }
40359bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    set2->nodeNr = 0;
40369bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    return(set1);
40379bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik}
40389bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik
40399bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik/**
40409bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik * xmlXPathNodeSetMergeAndClearNoDupls:
40419bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik * @set1:  the first NodeSet or NULL
40429bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik * @set2:  the second NodeSet
40439bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik * @hasSet2NsNodes: 1 if set2 contains namespaces nodes
40449bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik *
40459bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik * Merges two nodesets, all nodes from @set2 are added to @set1
40469bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik * if @set1 is NULL, a new set is created and copied from @set2.
40479bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik * Doesn't chack for duplicate nodes. Clears set2.
40489bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik *
40499bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik * Returns @set1 once extended or NULL in case of error.
40509bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik */
40519bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcikstatic xmlNodeSetPtr
40529bca933a6e39bae6dd8952825528270f006c97dfKasimier T. BuchcikxmlXPathNodeSetMergeAndClearNoDupls(xmlNodeSetPtr set1, xmlNodeSetPtr set2,
40539bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik				    int hasNullEntries)
405445490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard{
40559bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    if (set2 == NULL)
40569bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	return(set1);
40579bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    if ((set1 == NULL) && (hasNullEntries == 0)) {
40589bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	/*
40599bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	* Note that doing a memcpy of the list, namespace nodes are
40609bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	* just assigned to set1, since set2 is cleared anyway.
40619bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	*/
40629bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	set1 = xmlXPathNodeSetCreateSize(set2->nodeNr);
40639bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	if (set1 == NULL)
40649bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    return(NULL);
40659bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	if (set2->nodeNr != 0) {
40669bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    memcpy(set1->nodeTab, set2->nodeTab,
40679bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		set2->nodeNr * sizeof(xmlNodePtr));
40689bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    set1->nodeNr = set2->nodeNr;
40699bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	}
40709bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    } else {
40719bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	int i;
40729bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	xmlNodePtr n2;
40739bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik
40749bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	if (set1 == NULL)
40759bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    set1 = xmlXPathNodeSetCreate(NULL);
4076f88d849a4e994c94c0d0814a4befb43c990ceebdDaniel Veillard        if (set1 == NULL)
4077f88d849a4e994c94c0d0814a4befb43c990ceebdDaniel Veillard            return (NULL);
407845490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
40799bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	for (i = 0;i < set2->nodeNr;i++) {
40809bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    n2 = set2->nodeTab[i];
40819bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    /*
40829bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    * Skip NULLed entries.
40839bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    */
40849bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    if (n2 == NULL)
408545490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard		continue;
40869bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    if (set1->nodeMax == 0) {
40879bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		set1->nodeTab = (xmlNodePtr *) xmlMalloc(
40889bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		    XML_NODESET_DEFAULT * sizeof(xmlNodePtr));
40899bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		if (set1->nodeTab == NULL) {
40909bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		    xmlXPathErrMemory(NULL, "merging nodeset\n");
40919bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		    return(NULL);
40929bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		}
40939bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		memset(set1->nodeTab, 0,
40949bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		    XML_NODESET_DEFAULT * (size_t) sizeof(xmlNodePtr));
40959bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		set1->nodeMax = XML_NODESET_DEFAULT;
40969bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    } else if (set1->nodeNr >= set1->nodeMax) {
40979bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		xmlNodePtr *temp;
409845490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
4099cd852ad154fd919d9a4bd955566b43bac848878aDaniel Veillard                if (set1->nodeMax >= XPATH_MAX_NODESET_LENGTH) {
4100cd852ad154fd919d9a4bd955566b43bac848878aDaniel Veillard                    xmlXPathErrMemory(NULL, "merging nodeset hit limit\n");
4101cd852ad154fd919d9a4bd955566b43bac848878aDaniel Veillard                    return(NULL);
4102cd852ad154fd919d9a4bd955566b43bac848878aDaniel Veillard                }
41039bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		temp = (xmlNodePtr *) xmlRealloc(
4104d7958b21e7f8c447a26bb2436f08402b2c308be4Chris Evans		    set1->nodeTab, set1->nodeMax * 2 * sizeof(xmlNodePtr));
41059bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		if (temp == NULL) {
41069bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		    xmlXPathErrMemory(NULL, "merging nodeset\n");
41079bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		    return(NULL);
41089bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		}
41099bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		set1->nodeTab = temp;
4110d7958b21e7f8c447a26bb2436f08402b2c308be4Chris Evans		set1->nodeMax *= 2;
41119bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    }
41129bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    set1->nodeTab[set1->nodeNr++] = n2;
41139bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	}
41149bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    }
41159bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    set2->nodeNr = 0;
41169bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    return(set1);
41179bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik}
411875be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard
411975be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard/**
41203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNodeSetDel:
41213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur:  the initial node set
41223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val:  an xmlNodePtr
41233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
41243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Removes an xmlNodePtr from an existing NodeSet
41253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
41263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
41273473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNodeSetDel(xmlNodeSetPtr cur, xmlNodePtr val) {
41283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    int i;
41293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
41303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (cur == NULL) return;
41313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (val == NULL) return;
41323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
41333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    /*
4134081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack     * find node in nodeTab
41353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor     */
41363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    for (i = 0;i < cur->nodeNr;i++)
41373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        if (cur->nodeTab[i] == val) break;
41383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
4139081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack    if (i >= cur->nodeNr) {	/* not found */
41403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG
414145490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard        xmlGenericError(xmlGenericErrorContext,
41423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	        "xmlXPathNodeSetDel: Node %s wasn't found in NodeList\n",
41433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		val->name);
41443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif
41453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        return;
41463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
4147044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    if ((cur->nodeTab[i] != NULL) &&
4148044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard	(cur->nodeTab[i]->type == XML_NAMESPACE_DECL))
4149044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard	xmlXPathNodeSetFreeNs((xmlNsPtr) cur->nodeTab[i]);
41503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    cur->nodeNr--;
41513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    for (;i < cur->nodeNr;i++)
41523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        cur->nodeTab[i] = cur->nodeTab[i + 1];
41533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    cur->nodeTab[cur->nodeNr] = NULL;
41543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
41553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
41563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
41573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNodeSetRemove:
41583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur:  the initial node set
41593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val:  the index to remove
41603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
41613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Removes an entry from an existing NodeSet list.
41623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
41633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
41643473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNodeSetRemove(xmlNodeSetPtr cur, int val) {
41653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (cur == NULL) return;
41663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (val >= cur->nodeNr) return;
4167044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    if ((cur->nodeTab[val] != NULL) &&
4168044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard	(cur->nodeTab[val]->type == XML_NAMESPACE_DECL))
4169044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard	xmlXPathNodeSetFreeNs((xmlNsPtr) cur->nodeTab[val]);
41703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    cur->nodeNr--;
41713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    for (;val < cur->nodeNr;val++)
41723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        cur->nodeTab[val] = cur->nodeTab[val + 1];
41733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    cur->nodeTab[cur->nodeNr] = NULL;
41743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
41753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
41763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
41773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathFreeNodeSet:
41783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @obj:  the xmlNodeSetPtr to free
41793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
41803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Free the NodeSet compound (not the actual nodes !).
41813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
41823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
41833473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathFreeNodeSet(xmlNodeSetPtr obj) {
41843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (obj == NULL) return;
41853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (obj->nodeTab != NULL) {
4186044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard	int i;
4187044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard
4188081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack	/* @@ with_ns to check whether namespace nodes should be looked at @@ */
4189044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard	for (i = 0;i < obj->nodeNr;i++)
4190044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard	    if ((obj->nodeTab[i] != NULL) &&
4191044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard		(obj->nodeTab[i]->type == XML_NAMESPACE_DECL))
4192044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard		xmlXPathNodeSetFreeNs((xmlNsPtr) obj->nodeTab[i]);
41933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	xmlFree(obj->nodeTab);
41943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
41953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlFree(obj);
41963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
41973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
41983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
4199a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * xmlXPathNodeSetClear:
42009bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik * @set:  the node set to clear
420145490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *
4202a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * Clears the list from all temporary XPath objects (e.g. namespace nodes
4203a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * are feed), but does *not* free the list itself. Sets the length of the
4204a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * list to 0.
4205a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik */
4206a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikstatic void
42079bca933a6e39bae6dd8952825528270f006c97dfKasimier T. BuchcikxmlXPathNodeSetClear(xmlNodeSetPtr set, int hasNsNodes)
42089bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik{
4209a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    if ((set == NULL) || (set->nodeNr <= 0))
4210a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	return;
42119bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    else if (hasNsNodes) {
42129bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	int i;
42139bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	xmlNodePtr node;
421445490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
42159bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	for (i = 0; i < set->nodeNr; i++) {
42169bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    node = set->nodeTab[i];
42179bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    if ((node != NULL) &&
42189bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		(node->type == XML_NAMESPACE_DECL))
42199bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		xmlXPathNodeSetFreeNs((xmlNsPtr) node);
422045490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	}
4221a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    }
4222a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    set->nodeNr = 0;
4223a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik}
4224a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
4225a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik/**
42269bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik * xmlXPathNodeSetClearFromPos:
42279bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik * @set: the node set to be cleared
42289bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik * @pos: the start position to clear from
422945490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *
42309bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik * Clears the list from temporary XPath objects (e.g. namespace nodes
42319bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik * are feed) starting with the entry at @pos, but does *not* free the list
42329bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik * itself. Sets the length of the list to @pos.
42339bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik */
42349bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcikstatic void
42359bca933a6e39bae6dd8952825528270f006c97dfKasimier T. BuchcikxmlXPathNodeSetClearFromPos(xmlNodeSetPtr set, int pos, int hasNsNodes)
42369bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik{
42379bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    if ((set == NULL) || (set->nodeNr <= 0) || (pos >= set->nodeNr))
42389bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	return;
42399bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    else if ((hasNsNodes)) {
42409bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	int i;
42419bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	xmlNodePtr node;
424245490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
42439bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	for (i = pos; i < set->nodeNr; i++) {
42449bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    node = set->nodeTab[i];
42459bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    if ((node != NULL) &&
42469bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		(node->type == XML_NAMESPACE_DECL))
42479bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		xmlXPathNodeSetFreeNs((xmlNsPtr) node);
424845490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	}
42499bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    }
42509bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    set->nodeNr = pos;
42519bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik}
42529bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik
42539bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik/**
42543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathFreeValueTree:
42553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @obj:  the xmlNodeSetPtr to free
42563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
42573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Free the NodeSet compound and the actual tree, this is different
42583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * from xmlXPathFreeNodeSet()
42593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
426056a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic void
42613473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathFreeValueTree(xmlNodeSetPtr obj) {
42623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    int i;
42633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
42643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (obj == NULL) return;
42653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
42663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (obj->nodeTab != NULL) {
4267044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard	for (i = 0;i < obj->nodeNr;i++) {
4268044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard	    if (obj->nodeTab[i] != NULL) {
4269044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard		if (obj->nodeTab[i]->type == XML_NAMESPACE_DECL) {
4270044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard		    xmlXPathNodeSetFreeNs((xmlNsPtr) obj->nodeTab[i]);
4271044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard		} else {
4272044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard		    xmlFreeNodeList(obj->nodeTab[i]);
4273044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard		}
4274044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard	    }
4275044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard	}
42763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	xmlFree(obj->nodeTab);
42773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
42783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlFree(obj);
42793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
42803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
42813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#if defined(DEBUG) || defined(DEBUG_STEP)
42823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
42833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlGenericErrorContextNodeSet:
42843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @output:  a FILE * for the output
4285081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack * @obj:  the xmlNodeSetPtr to display
42863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
42873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Quick display of a NodeSet
42883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
42893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
42903473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlGenericErrorContextNodeSet(FILE *output, xmlNodeSetPtr obj) {
42913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    int i;
42923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
42933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (output == NULL) output = xmlGenericErrorContext;
42943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (obj == NULL)  {
42953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        fprintf(output, "NodeSet == NULL !\n");
42963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return;
42973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
42983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (obj->nodeNr == 0) {
42993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        fprintf(output, "NodeSet is empty\n");
43003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return;
43013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
43023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (obj->nodeTab == NULL) {
43033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	fprintf(output, " nodeTab == NULL !\n");
43043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return;
43053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
43063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    for (i = 0; i < obj->nodeNr; i++) {
43073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        if (obj->nodeTab[i] == NULL) {
43083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    fprintf(output, " NULL !\n");
43093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    return;
43103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        }
43113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if ((obj->nodeTab[i]->type == XML_DOCUMENT_NODE) ||
43123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    (obj->nodeTab[i]->type == XML_HTML_DOCUMENT_NODE))
43133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    fprintf(output, " /");
43143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	else if (obj->nodeTab[i]->name == NULL)
43153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    fprintf(output, " noname!");
43163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	else fprintf(output, " %s", obj->nodeTab[i]->name);
43173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
43183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    fprintf(output, "\n");
43193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
43203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif
43213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
43223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
43233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNewNodeSet:
43243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val:  the NodePtr value
43253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
43263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Create a new xmlXPathObjectPtr of type NodeSet and initialize
43273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * it with the single Node @val
43283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
43293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the newly created object.
43303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
43313473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathObjectPtr
43323473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNewNodeSet(xmlNodePtr val) {
43333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathObjectPtr ret;
43343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
43353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
43363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ret == NULL) {
4337d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard        xmlXPathErrMemory(NULL, "creating nodeset\n");
43383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(NULL);
43393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
43403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
43413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret->type = XPATH_NODESET;
434277851710aba3a0effdc6af67ea4caf212307420cDaniel Veillard    ret->boolval = 0;
43433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret->nodesetval = xmlXPathNodeSetCreate(val);
4344081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack    /* @@ with_ns to check whether namespace nodes should be looked at @@ */
4345a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#ifdef XP_DEBUG_OBJ_USAGE
4346a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathDebugObjUsageRequested(NULL, XPATH_NODESET);
4347a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#endif
43483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(ret);
43493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
43503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
43513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
43523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNewValueTree:
43533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val:  the NodePtr value
43543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
43553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Create a new xmlXPathObjectPtr of type Value Tree (XSLT) and initialize
43563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * it with the tree root @val
43573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
43583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the newly created object.
43593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
43603473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathObjectPtr
43613473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNewValueTree(xmlNodePtr val) {
43623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathObjectPtr ret;
43633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
43643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
43653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ret == NULL) {
4366d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard        xmlXPathErrMemory(NULL, "creating result value tree\n");
43673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(NULL);
43683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
43693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
43703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret->type = XPATH_XSLT_TREE;
43710ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard    ret->boolval = 1;
43720ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard    ret->user = (void *) val;
43733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret->nodesetval = xmlXPathNodeSetCreate(val);
4374a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#ifdef XP_DEBUG_OBJ_USAGE
4375a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathDebugObjUsageRequested(NULL, XPATH_XSLT_TREE);
4376a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#endif
43773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(ret);
43783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
43793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
43803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
43813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNewNodeSetList:
43823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val:  an existing NodeSet
43833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
43843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Create a new xmlXPathObjectPtr of type NodeSet and initialize
43853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * it with the Nodeset @val
43863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
43873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the newly created object.
43883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
43893473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathObjectPtr
4390044fc6b7476798cbb95277b4905e5111d7c2775dDaniel VeillardxmlXPathNewNodeSetList(xmlNodeSetPtr val)
4391044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard{
43923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathObjectPtr ret;
43933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    int i;
43943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
43953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (val == NULL)
4396044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard        ret = NULL;
43973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    else if (val->nodeTab == NULL)
4398044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard        ret = xmlXPathNewNodeSet(NULL);
4399044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    else {
4400044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard        ret = xmlXPathNewNodeSet(val->nodeTab[0]);
44011bd45d13091e5af9e1fe0582b5e335c60d45535fDaniel Veillard        if (ret) {
44021bd45d13091e5af9e1fe0582b5e335c60d45535fDaniel Veillard            for (i = 1; i < val->nodeNr; ++i) {
44031bd45d13091e5af9e1fe0582b5e335c60d45535fDaniel Veillard                if (xmlXPathNodeSetAddUnique(ret->nodesetval, val->nodeTab[i])
44041bd45d13091e5af9e1fe0582b5e335c60d45535fDaniel Veillard		    < 0) break;
44051bd45d13091e5af9e1fe0582b5e335c60d45535fDaniel Veillard	    }
44061bd45d13091e5af9e1fe0582b5e335c60d45535fDaniel Veillard	}
4407044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    }
44083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
4409044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard    return (ret);
44103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
44113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
44123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
44133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathWrapNodeSet:
44143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val:  the NodePtr value
44153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
44163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Wrap the Nodeset @val in a new xmlXPathObjectPtr
44173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
44183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the newly created object.
44193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
44203473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathObjectPtr
44213473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathWrapNodeSet(xmlNodeSetPtr val) {
44223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathObjectPtr ret;
44233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
44243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
44253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ret == NULL) {
4426d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard        xmlXPathErrMemory(NULL, "creating node set object\n");
44273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(NULL);
44283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
44293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
44303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret->type = XPATH_NODESET;
44313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret->nodesetval = val;
4432a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#ifdef XP_DEBUG_OBJ_USAGE
4433a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathDebugObjUsageRequested(NULL, XPATH_NODESET);
4434a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#endif
44353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(ret);
44363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
44373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
44383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
44393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathFreeNodeSetList:
44403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @obj:  an existing NodeSetList object
44413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
44423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Free up the xmlXPathObjectPtr @obj but don't deallocate the objects in
44433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the list contrary to xmlXPathFreeObject().
44443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
44453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
44463473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathFreeNodeSetList(xmlXPathObjectPtr obj) {
44473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (obj == NULL) return;
4448a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#ifdef XP_DEBUG_OBJ_USAGE
4449a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathDebugObjUsageReleased(NULL, obj->type);
4450a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#endif
44513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlFree(obj);
44523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
44533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
4454f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/**
4455f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathDifference:
4456f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes1:  a node-set
4457f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes2:  a node-set
4458f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *
4459f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Implements the EXSLT - Sets difference() function:
4460f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *    node-set set:difference (node-set, node-set)
4461f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *
4462f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns the difference between the two node sets, or nodes1 if
4463f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *         nodes2 is empty
4464f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */
4465f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlNodeSetPtr
4466f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathDifference (xmlNodeSetPtr nodes1, xmlNodeSetPtr nodes2) {
4467f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    xmlNodeSetPtr ret;
4468f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    int i, l1;
4469f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    xmlNodePtr cur;
4470f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer
4471f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    if (xmlXPathNodeSetIsEmpty(nodes2))
4472f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer	return(nodes1);
4473f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer
4474f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    ret = xmlXPathNodeSetCreate(NULL);
4475f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    if (xmlXPathNodeSetIsEmpty(nodes1))
4476f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer	return(ret);
4477f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer
4478f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    l1 = xmlXPathNodeSetGetLength(nodes1);
4479f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer
4480f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    for (i = 0; i < l1; i++) {
4481f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer	cur = xmlXPathNodeSetItem(nodes1, i);
44821bd45d13091e5af9e1fe0582b5e335c60d45535fDaniel Veillard	if (!xmlXPathNodeSetContains(nodes2, cur)) {
44831bd45d13091e5af9e1fe0582b5e335c60d45535fDaniel Veillard	    if (xmlXPathNodeSetAddUnique(ret, cur) < 0)
44841bd45d13091e5af9e1fe0582b5e335c60d45535fDaniel Veillard	        break;
44851bd45d13091e5af9e1fe0582b5e335c60d45535fDaniel Veillard	}
4486f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    }
4487f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    return(ret);
4488f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer}
4489f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer
4490f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/**
4491f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathIntersection:
4492f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes1:  a node-set
4493f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes2:  a node-set
4494f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *
4495f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Implements the EXSLT - Sets intersection() function:
4496f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *    node-set set:intersection (node-set, node-set)
4497f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *
4498f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns a node set comprising the nodes that are within both the
4499f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *         node sets passed as arguments
4500f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */
4501f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlNodeSetPtr
4502f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathIntersection (xmlNodeSetPtr nodes1, xmlNodeSetPtr nodes2) {
4503f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    xmlNodeSetPtr ret = xmlXPathNodeSetCreate(NULL);
4504f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    int i, l1;
4505f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    xmlNodePtr cur;
4506f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer
4507f88d849a4e994c94c0d0814a4befb43c990ceebdDaniel Veillard    if (ret == NULL)
4508f88d849a4e994c94c0d0814a4befb43c990ceebdDaniel Veillard        return(ret);
4509f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    if (xmlXPathNodeSetIsEmpty(nodes1))
4510f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer	return(ret);
4511f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    if (xmlXPathNodeSetIsEmpty(nodes2))
4512f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer	return(ret);
4513f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer
4514f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    l1 = xmlXPathNodeSetGetLength(nodes1);
4515f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer
4516f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    for (i = 0; i < l1; i++) {
4517f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer	cur = xmlXPathNodeSetItem(nodes1, i);
45181bd45d13091e5af9e1fe0582b5e335c60d45535fDaniel Veillard	if (xmlXPathNodeSetContains(nodes2, cur)) {
45191bd45d13091e5af9e1fe0582b5e335c60d45535fDaniel Veillard	    if (xmlXPathNodeSetAddUnique(ret, cur) < 0)
45201bd45d13091e5af9e1fe0582b5e335c60d45535fDaniel Veillard	        break;
45211bd45d13091e5af9e1fe0582b5e335c60d45535fDaniel Veillard	}
4522f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    }
4523f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    return(ret);
4524f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer}
4525f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer
4526f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/**
4527f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathDistinctSorted:
4528f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes:  a node-set, sorted by document order
4529f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *
4530f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Implements the EXSLT - Sets distinct() function:
4531f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *    node-set set:distinct (node-set)
453245490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *
4533f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns a subset of the nodes contained in @nodes, or @nodes if
4534f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *         it is empty
4535f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */
4536f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlNodeSetPtr
4537f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathDistinctSorted (xmlNodeSetPtr nodes) {
4538f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    xmlNodeSetPtr ret;
4539f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    xmlHashTablePtr hash;
4540f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    int i, l;
4541f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    xmlChar * strval;
4542f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    xmlNodePtr cur;
4543f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer
4544f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    if (xmlXPathNodeSetIsEmpty(nodes))
4545f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer	return(nodes);
4546f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer
4547f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    ret = xmlXPathNodeSetCreate(NULL);
4548f88d849a4e994c94c0d0814a4befb43c990ceebdDaniel Veillard    if (ret == NULL)
4549f88d849a4e994c94c0d0814a4befb43c990ceebdDaniel Veillard        return(ret);
4550f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    l = xmlXPathNodeSetGetLength(nodes);
4551f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    hash = xmlHashCreate (l);
4552f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    for (i = 0; i < l; i++) {
4553f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer	cur = xmlXPathNodeSetItem(nodes, i);
4554f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer	strval = xmlXPathCastNodeToString(cur);
4555f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer	if (xmlHashLookup(hash, strval) == NULL) {
4556f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer	    xmlHashAddEntry(hash, strval, strval);
45571bd45d13091e5af9e1fe0582b5e335c60d45535fDaniel Veillard	    if (xmlXPathNodeSetAddUnique(ret, cur) < 0)
45581bd45d13091e5af9e1fe0582b5e335c60d45535fDaniel Veillard	        break;
4559f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer	} else {
4560f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer	    xmlFree(strval);
4561f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer	}
4562f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    }
4563f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    xmlHashFree(hash, (xmlHashDeallocator) xmlFree);
4564f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    return(ret);
4565f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer}
4566f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer
4567f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/**
4568f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathDistinct:
4569f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes:  a node-set
4570f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *
4571f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Implements the EXSLT - Sets distinct() function:
4572f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *    node-set set:distinct (node-set)
4573f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes is sorted by document order, then #exslSetsDistinctSorted
4574f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * is called with the sorted node-set
4575f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *
4576f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns a subset of the nodes contained in @nodes, or @nodes if
4577f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *         it is empty
4578f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */
4579f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlNodeSetPtr
4580f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathDistinct (xmlNodeSetPtr nodes) {
4581f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    if (xmlXPathNodeSetIsEmpty(nodes))
4582f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer	return(nodes);
4583f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer
4584f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    xmlXPathNodeSetSort(nodes);
4585f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    return(xmlXPathDistinctSorted(nodes));
4586f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer}
4587f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer
4588f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/**
4589f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathHasSameNodes:
4590f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes1:  a node-set
4591f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes2:  a node-set
4592f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *
4593f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Implements the EXSLT - Sets has-same-nodes function:
4594f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *    boolean set:has-same-node(node-set, node-set)
4595f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *
4596f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns true (1) if @nodes1 shares any node with @nodes2, false (0)
4597f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *         otherwise
4598f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */
4599f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyerint
4600f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathHasSameNodes (xmlNodeSetPtr nodes1, xmlNodeSetPtr nodes2) {
4601f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    int i, l;
4602f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    xmlNodePtr cur;
4603f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer
4604f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    if (xmlXPathNodeSetIsEmpty(nodes1) ||
4605f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer	xmlXPathNodeSetIsEmpty(nodes2))
4606f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer	return(0);
4607f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer
4608f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    l = xmlXPathNodeSetGetLength(nodes1);
4609f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    for (i = 0; i < l; i++) {
4610f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer	cur = xmlXPathNodeSetItem(nodes1, i);
4611f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer	if (xmlXPathNodeSetContains(nodes2, cur))
4612f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer	    return(1);
4613f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    }
4614f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    return(0);
4615f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer}
4616f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer
4617f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/**
4618f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathNodeLeadingSorted:
4619f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes: a node-set, sorted by document order
4620f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @node: a node
4621f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *
4622f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Implements the EXSLT - Sets leading() function:
4623f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *    node-set set:leading (node-set, node-set)
4624f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *
4625f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns the nodes in @nodes that precede @node in document order,
4626f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *         @nodes if @node is NULL or an empty node-set if @nodes
4627f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *         doesn't contain @node
4628f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */
4629f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlNodeSetPtr
4630f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathNodeLeadingSorted (xmlNodeSetPtr nodes, xmlNodePtr node) {
4631f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    int i, l;
4632f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    xmlNodePtr cur;
4633f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    xmlNodeSetPtr ret;
4634f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer
4635f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    if (node == NULL)
4636f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer	return(nodes);
4637f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer
4638f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    ret = xmlXPathNodeSetCreate(NULL);
4639f88d849a4e994c94c0d0814a4befb43c990ceebdDaniel Veillard    if (ret == NULL)
4640f88d849a4e994c94c0d0814a4befb43c990ceebdDaniel Veillard        return(ret);
4641f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    if (xmlXPathNodeSetIsEmpty(nodes) ||
4642f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer	(!xmlXPathNodeSetContains(nodes, node)))
4643f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer	return(ret);
4644f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer
4645f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    l = xmlXPathNodeSetGetLength(nodes);
4646f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    for (i = 0; i < l; i++) {
4647f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer	cur = xmlXPathNodeSetItem(nodes, i);
4648f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer	if (cur == node)
4649f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer	    break;
46501bd45d13091e5af9e1fe0582b5e335c60d45535fDaniel Veillard	if (xmlXPathNodeSetAddUnique(ret, cur) < 0)
46511bd45d13091e5af9e1fe0582b5e335c60d45535fDaniel Veillard	    break;
4652f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    }
4653f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    return(ret);
4654f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer}
4655f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer
4656f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/**
4657f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathNodeLeading:
4658f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes:  a node-set
4659f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @node:  a node
4660f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *
4661f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Implements the EXSLT - Sets leading() function:
4662f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *    node-set set:leading (node-set, node-set)
4663f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes is sorted by document order, then #exslSetsNodeLeadingSorted
4664f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * is called.
4665f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *
4666f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns the nodes in @nodes that precede @node in document order,
4667f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *         @nodes if @node is NULL or an empty node-set if @nodes
4668f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *         doesn't contain @node
4669f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */
4670f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlNodeSetPtr
4671f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathNodeLeading (xmlNodeSetPtr nodes, xmlNodePtr node) {
4672f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    xmlXPathNodeSetSort(nodes);
4673f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    return(xmlXPathNodeLeadingSorted(nodes, node));
4674f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer}
4675f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer
4676f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/**
4677f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathLeadingSorted:
4678f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes1:  a node-set, sorted by document order
4679f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes2:  a node-set, sorted by document order
4680f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *
4681f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Implements the EXSLT - Sets leading() function:
4682f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *    node-set set:leading (node-set, node-set)
4683f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *
4684f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns the nodes in @nodes1 that precede the first node in @nodes2
4685f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *         in document order, @nodes1 if @nodes2 is NULL or empty or
4686f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *         an empty node-set if @nodes1 doesn't contain @nodes2
4687f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */
4688f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlNodeSetPtr
4689f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathLeadingSorted (xmlNodeSetPtr nodes1, xmlNodeSetPtr nodes2) {
4690f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    if (xmlXPathNodeSetIsEmpty(nodes2))
4691f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer	return(nodes1);
4692f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    return(xmlXPathNodeLeadingSorted(nodes1,
4693f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer				     xmlXPathNodeSetItem(nodes2, 1)));
4694f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer}
4695f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer
4696f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/**
4697f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathLeading:
4698f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes1:  a node-set
4699f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes2:  a node-set
4700f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *
4701f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Implements the EXSLT - Sets leading() function:
4702f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *    node-set set:leading (node-set, node-set)
4703f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes1 and @nodes2 are sorted by document order, then
4704f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * #exslSetsLeadingSorted is called.
4705f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *
4706f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns the nodes in @nodes1 that precede the first node in @nodes2
4707f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *         in document order, @nodes1 if @nodes2 is NULL or empty or
4708f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *         an empty node-set if @nodes1 doesn't contain @nodes2
4709f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */
4710f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlNodeSetPtr
4711f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathLeading (xmlNodeSetPtr nodes1, xmlNodeSetPtr nodes2) {
4712f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    if (xmlXPathNodeSetIsEmpty(nodes2))
4713f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer	return(nodes1);
4714f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    if (xmlXPathNodeSetIsEmpty(nodes1))
4715f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer	return(xmlXPathNodeSetCreate(NULL));
4716f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    xmlXPathNodeSetSort(nodes1);
4717f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    xmlXPathNodeSetSort(nodes2);
4718f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    return(xmlXPathNodeLeadingSorted(nodes1,
4719f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer				     xmlXPathNodeSetItem(nodes2, 1)));
4720f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer}
4721f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer
4722f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/**
4723f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathNodeTrailingSorted:
4724f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes: a node-set, sorted by document order
4725f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @node: a node
4726f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *
4727f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Implements the EXSLT - Sets trailing() function:
4728f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *    node-set set:trailing (node-set, node-set)
4729f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *
4730f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns the nodes in @nodes that follow @node in document order,
4731f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *         @nodes if @node is NULL or an empty node-set if @nodes
4732f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *         doesn't contain @node
4733f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */
4734f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlNodeSetPtr
4735f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathNodeTrailingSorted (xmlNodeSetPtr nodes, xmlNodePtr node) {
4736f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    int i, l;
4737f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    xmlNodePtr cur;
4738f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    xmlNodeSetPtr ret;
4739f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer
4740f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    if (node == NULL)
4741f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer	return(nodes);
4742f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer
4743f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    ret = xmlXPathNodeSetCreate(NULL);
4744f88d849a4e994c94c0d0814a4befb43c990ceebdDaniel Veillard    if (ret == NULL)
4745f88d849a4e994c94c0d0814a4befb43c990ceebdDaniel Veillard        return(ret);
4746f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    if (xmlXPathNodeSetIsEmpty(nodes) ||
4747f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer	(!xmlXPathNodeSetContains(nodes, node)))
4748f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer	return(ret);
4749f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer
4750f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    l = xmlXPathNodeSetGetLength(nodes);
475197ac819cc650e5241303baa65b0fd04d112fd9e1William M. Brack    for (i = l - 1; i >= 0; i--) {
4752f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer	cur = xmlXPathNodeSetItem(nodes, i);
4753f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer	if (cur == node)
4754f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer	    break;
47551bd45d13091e5af9e1fe0582b5e335c60d45535fDaniel Veillard	if (xmlXPathNodeSetAddUnique(ret, cur) < 0)
47561bd45d13091e5af9e1fe0582b5e335c60d45535fDaniel Veillard	    break;
4757f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    }
475897ac819cc650e5241303baa65b0fd04d112fd9e1William M. Brack    xmlXPathNodeSetSort(ret);	/* bug 413451 */
4759f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    return(ret);
4760f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer}
4761f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer
4762f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/**
4763f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathNodeTrailing:
4764f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes:  a node-set
4765f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @node:  a node
4766f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *
4767f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Implements the EXSLT - Sets trailing() function:
4768f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *    node-set set:trailing (node-set, node-set)
4769f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes is sorted by document order, then #xmlXPathNodeTrailingSorted
4770f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * is called.
4771f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *
4772f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns the nodes in @nodes that follow @node in document order,
4773f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *         @nodes if @node is NULL or an empty node-set if @nodes
4774f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *         doesn't contain @node
4775f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */
4776f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlNodeSetPtr
4777f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathNodeTrailing (xmlNodeSetPtr nodes, xmlNodePtr node) {
4778f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    xmlXPathNodeSetSort(nodes);
4779f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    return(xmlXPathNodeTrailingSorted(nodes, node));
4780f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer}
4781f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer
4782f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/**
4783f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathTrailingSorted:
4784f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes1:  a node-set, sorted by document order
4785f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes2:  a node-set, sorted by document order
4786f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *
4787f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Implements the EXSLT - Sets trailing() function:
4788f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *    node-set set:trailing (node-set, node-set)
4789f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *
4790f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns the nodes in @nodes1 that follow the first node in @nodes2
4791f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *         in document order, @nodes1 if @nodes2 is NULL or empty or
4792f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *         an empty node-set if @nodes1 doesn't contain @nodes2
4793f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */
4794f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlNodeSetPtr
4795f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathTrailingSorted (xmlNodeSetPtr nodes1, xmlNodeSetPtr nodes2) {
4796f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    if (xmlXPathNodeSetIsEmpty(nodes2))
4797f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer	return(nodes1);
4798f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    return(xmlXPathNodeTrailingSorted(nodes1,
4799f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer				      xmlXPathNodeSetItem(nodes2, 0)));
4800f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer}
4801f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer
4802f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/**
4803f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathTrailing:
4804f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes1:  a node-set
4805f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes2:  a node-set
4806f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *
4807f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Implements the EXSLT - Sets trailing() function:
4808f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *    node-set set:trailing (node-set, node-set)
4809f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @nodes1 and @nodes2 are sorted by document order, then
4810f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * #xmlXPathTrailingSorted is called.
4811f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *
4812f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns the nodes in @nodes1 that follow the first node in @nodes2
4813f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *         in document order, @nodes1 if @nodes2 is NULL or empty or
4814f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *         an empty node-set if @nodes1 doesn't contain @nodes2
4815f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */
4816f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlNodeSetPtr
4817f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathTrailing (xmlNodeSetPtr nodes1, xmlNodeSetPtr nodes2) {
4818f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    if (xmlXPathNodeSetIsEmpty(nodes2))
4819f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer	return(nodes1);
4820f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    if (xmlXPathNodeSetIsEmpty(nodes1))
4821f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer	return(xmlXPathNodeSetCreate(NULL));
4822f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    xmlXPathNodeSetSort(nodes1);
4823f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    xmlXPathNodeSetSort(nodes2);
4824f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    return(xmlXPathNodeTrailingSorted(nodes1,
4825f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer				      xmlXPathNodeSetItem(nodes2, 0)));
4826f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer}
4827f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer
48283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/************************************************************************
48293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *									*
48303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *		Routines to handle extra functions			*
48313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *									*
48323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ************************************************************************/
48333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
48343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
48353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathRegisterFunc:
48363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath context
48373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @name:  the function name
48383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @f:  the function implementation or NULL
48393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
48403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Register a new function. If @f is NULL it unregisters the function
48413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
48423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns 0 in case of success, -1 in case of error
48433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
484445490aebe7a60704e8ed850c498969858ab900eeDaniel Veillardint
48453473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathRegisterFunc(xmlXPathContextPtr ctxt, const xmlChar *name,
48463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		     xmlXPathFunction f) {
48473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(xmlXPathRegisterFuncNS(ctxt, name, NULL, f));
48483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
48493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
48503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
48513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathRegisterFuncNS:
48523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath context
48533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @name:  the function name
48543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ns_uri:  the function namespace URI
48553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @f:  the function implementation or NULL
48563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
48573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Register a new function. If @f is NULL it unregisters the function
48583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
48593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns 0 in case of success, -1 in case of error
48603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
48613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorint
48623473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathRegisterFuncNS(xmlXPathContextPtr ctxt, const xmlChar *name,
48633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		       const xmlChar *ns_uri, xmlXPathFunction f) {
48643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ctxt == NULL)
48653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(-1);
48663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (name == NULL)
48673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(-1);
48683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
48693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ctxt->funcHash == NULL)
48703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	ctxt->funcHash = xmlHashCreate(0);
48713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ctxt->funcHash == NULL)
48723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(-1);
487394394cd1e494f8d669b310748f54192268185c8dDaniel Veillard    if (f == NULL)
487494394cd1e494f8d669b310748f54192268185c8dDaniel Veillard        return(xmlHashRemoveEntry2(ctxt->funcHash, name, ns_uri, NULL));
4875ad0e67c57f26f691fc120d5c5336cee9885cf324William M. Brack    return(xmlHashAddEntry2(ctxt->funcHash, name, ns_uri, XML_CAST_FPTR(f)));
48763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
48773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
48783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
4879ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer * xmlXPathRegisterFuncLookup:
4880ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer * @ctxt:  the XPath context
4881ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer * @f:  the lookup function
4882cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * @funcCtxt:  the lookup data
4883ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer *
4884cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * Registers an external mechanism to do function lookup.
4885ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer */
4886ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyervoid
4887ba4ad3263bf7f5625329f115367e0c7018521a16Thomas BroyerxmlXPathRegisterFuncLookup (xmlXPathContextPtr ctxt,
4888ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer			    xmlXPathFuncLookupFunc f,
4889ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer			    void *funcCtxt) {
4890ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer    if (ctxt == NULL)
4891ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer	return;
48926ebf3c4c1a78406d15e8629b4a7b3d52549f0c8bDaniel Veillard    ctxt->funcLookupFunc = f;
4893ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer    ctxt->funcLookupData = funcCtxt;
4894ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer}
4895ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer
4896ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer/**
48973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathFunctionLookup:
48983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath context
48993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @name:  the function name
49003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
49013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Search in the Function array of the context for the given
49023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * function.
49033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
49043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the xmlXPathFunction or NULL if not found
49053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
49063473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathFunction
49073473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathFunctionLookup(xmlXPathContextPtr ctxt, const xmlChar *name) {
4908ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer    if (ctxt == NULL)
4909ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer	return (NULL);
4910ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer
4911ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer    if (ctxt->funcLookupFunc != NULL) {
4912ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer	xmlXPathFunction ret;
491399e55ebe945f6f4de33e8454f2770e02295a3a00Daniel Veillard	xmlXPathFuncLookupFunc f;
4914ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer
49156ebf3c4c1a78406d15e8629b4a7b3d52549f0c8bDaniel Veillard	f = ctxt->funcLookupFunc;
4916963d2ae41574066f9b44bcae610dd280c1e57dd8Daniel Veillard	ret = f(ctxt->funcLookupData, name, NULL);
4917ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer	if (ret != NULL)
4918ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer	    return(ret);
4919ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer    }
49203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(xmlXPathFunctionLookupNS(ctxt, name, NULL));
49213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
49223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
49233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
49243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathFunctionLookupNS:
49253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath context
49263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @name:  the function name
49273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ns_uri:  the function namespace URI
49283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
49293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Search in the Function array of the context for the given
49303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * function.
49313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
49323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the xmlXPathFunction or NULL if not found
49333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
49343473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathFunction
49353473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathFunctionLookupNS(xmlXPathContextPtr ctxt, const xmlChar *name,
49363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor			 const xmlChar *ns_uri) {
4937ad0e67c57f26f691fc120d5c5336cee9885cf324William M. Brack    xmlXPathFunction ret;
493845490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
49393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ctxt == NULL)
49403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(NULL);
49413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (name == NULL)
49423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(NULL);
49433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
4944ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer    if (ctxt->funcLookupFunc != NULL) {
494599e55ebe945f6f4de33e8454f2770e02295a3a00Daniel Veillard	xmlXPathFuncLookupFunc f;
4946ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer
49476ebf3c4c1a78406d15e8629b4a7b3d52549f0c8bDaniel Veillard	f = ctxt->funcLookupFunc;
4948963d2ae41574066f9b44bcae610dd280c1e57dd8Daniel Veillard	ret = f(ctxt->funcLookupData, name, ns_uri);
4949ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer	if (ret != NULL)
4950ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer	    return(ret);
4951ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer    }
4952ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer
4953ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer    if (ctxt->funcHash == NULL)
4954ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer	return(NULL);
4955ba4ad3263bf7f5625329f115367e0c7018521a16Thomas Broyer
4956ad0e67c57f26f691fc120d5c5336cee9885cf324William M. Brack    XML_CAST_FPTR(ret) = xmlHashLookup2(ctxt->funcHash, name, ns_uri);
4957ad0e67c57f26f691fc120d5c5336cee9885cf324William M. Brack    return(ret);
49583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
49593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
49603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
49613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathRegisteredFuncsCleanup:
49623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath context
49633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
49643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Cleanup the XPath context data associated to registered functions
49653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
49663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
49673473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathRegisteredFuncsCleanup(xmlXPathContextPtr ctxt) {
49683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ctxt == NULL)
49693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return;
49703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
49713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlHashFree(ctxt->funcHash, NULL);
49723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ctxt->funcHash = NULL;
49733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
49743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
49753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/************************************************************************
49763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *									*
4977081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack *			Routines to handle Variables			*
49783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *									*
49793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ************************************************************************/
49803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
49813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
49823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathRegisterVariable:
49833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath context
49843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @name:  the variable name
49853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @value:  the variable value or NULL
49863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
49873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Register a new variable value. If @value is NULL it unregisters
49883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the variable
49893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
49903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns 0 in case of success, -1 in case of error
49913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
499245490aebe7a60704e8ed850c498969858ab900eeDaniel Veillardint
49933473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathRegisterVariable(xmlXPathContextPtr ctxt, const xmlChar *name,
49943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor			 xmlXPathObjectPtr value) {
49953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(xmlXPathRegisterVariableNS(ctxt, name, NULL, value));
49963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
49973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
49983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
49993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathRegisterVariableNS:
50003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath context
50013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @name:  the variable name
50023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ns_uri:  the variable namespace URI
50033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @value:  the variable value or NULL
50043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
50053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Register a new variable value. If @value is NULL it unregisters
50063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the variable
50073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
50083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns 0 in case of success, -1 in case of error
50093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
50103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorint
50113473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathRegisterVariableNS(xmlXPathContextPtr ctxt, const xmlChar *name,
50123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor			   const xmlChar *ns_uri,
50133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor			   xmlXPathObjectPtr value) {
50143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ctxt == NULL)
50153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(-1);
50163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (name == NULL)
50173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(-1);
50183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
50193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ctxt->varHash == NULL)
50203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	ctxt->varHash = xmlHashCreate(0);
50213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ctxt->varHash == NULL)
50223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(-1);
502394394cd1e494f8d669b310748f54192268185c8dDaniel Veillard    if (value == NULL)
502445490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard        return(xmlHashRemoveEntry2(ctxt->varHash, name, ns_uri,
502594394cd1e494f8d669b310748f54192268185c8dDaniel Veillard	                           (xmlHashDeallocator)xmlXPathFreeObject));
50263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(xmlHashUpdateEntry2(ctxt->varHash, name, ns_uri,
50273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor			       (void *) value,
50283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor			       (xmlHashDeallocator)xmlXPathFreeObject));
50293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
50303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
50313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
50323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathRegisterVariableLookup:
50333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath context
50343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @f:  the lookup function
50353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @data:  the lookup data
50363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
50373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * register an external mechanism to do variable lookup
50383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
50393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
50403473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathRegisterVariableLookup(xmlXPathContextPtr ctxt,
50413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	 xmlXPathVariableLookupFunc f, void *data) {
50423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ctxt == NULL)
50433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return;
50446ebf3c4c1a78406d15e8629b4a7b3d52549f0c8bDaniel Veillard    ctxt->varLookupFunc = f;
50453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ctxt->varLookupData = data;
50463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
50473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
50483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
50493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathVariableLookup:
50503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath context
50513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @name:  the variable name
50523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
50533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Search in the Variable array of the context for the given
50543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * variable value.
50553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
505673c9c049195bf897dbcb6308a1ab9d16b3fe6b2cDaniel Veillard * Returns a copy of the value or NULL if not found
50573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
50583473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathObjectPtr
50593473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathVariableLookup(xmlXPathContextPtr ctxt, const xmlChar *name) {
50603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ctxt == NULL)
50613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(NULL);
50623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
50633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ctxt->varLookupFunc != NULL) {
50643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	xmlXPathObjectPtr ret;
50653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
50663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	ret = ((xmlXPathVariableLookupFunc)ctxt->varLookupFunc)
50673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	        (ctxt->varLookupData, name, NULL);
5068556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard	return(ret);
50693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
50703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(xmlXPathVariableLookupNS(ctxt, name, NULL));
50713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
50723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
50733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
50743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathVariableLookupNS:
50753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath context
50763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @name:  the variable name
50773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ns_uri:  the variable namespace URI
50783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
50793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Search in the Variable array of the context for the given
508045490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard * variable value.
50813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
508273c9c049195bf897dbcb6308a1ab9d16b3fe6b2cDaniel Veillard * Returns the a copy of the value or NULL if not found
50833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
50843473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathObjectPtr
50853473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathVariableLookupNS(xmlXPathContextPtr ctxt, const xmlChar *name,
50863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor			 const xmlChar *ns_uri) {
50873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ctxt == NULL)
50883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(NULL);
50893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
50903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ctxt->varLookupFunc != NULL) {
50913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	xmlXPathObjectPtr ret;
50923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
50933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	ret = ((xmlXPathVariableLookupFunc)ctxt->varLookupFunc)
50943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	        (ctxt->varLookupData, name, ns_uri);
50953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (ret != NULL) return(ret);
50963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
50973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
50983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ctxt->varHash == NULL)
50993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(NULL);
51003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (name == NULL)
51013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(NULL);
51023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
5103a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    return(xmlXPathCacheObjectCopy(ctxt, (xmlXPathObjectPtr)
51048c357d58c2d1dde022b67393a47dcb52100ce129Daniel Veillard		xmlHashLookup2(ctxt->varHash, name, ns_uri)));
51053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
51063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
51073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
51083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathRegisteredVariablesCleanup:
51093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath context
51103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
51113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Cleanup the XPath context data associated to registered variables
51123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
51133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
51143473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathRegisteredVariablesCleanup(xmlXPathContextPtr ctxt) {
51153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ctxt == NULL)
51163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return;
51173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
511876d66f416d2d0d5db4a09d212b4e43087e9cdae7Daniel Veillard    xmlHashFree(ctxt->varHash, (xmlHashDeallocator)xmlXPathFreeObject);
51193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ctxt->varHash = NULL;
51203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
51213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
51223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
51233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathRegisterNs:
51243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath context
5125db3ce96906c09559d944c72b69eb984105f34776Daniel Veillard * @prefix:  the namespace prefix cannot be NULL or empty string
51263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ns_uri:  the namespace name
51273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
51283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Register a new namespace. If @ns_uri is NULL it unregisters
51293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the namespace
51303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
51313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns 0 in case of success, -1 in case of error
51323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
51333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorint
51343473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathRegisterNs(xmlXPathContextPtr ctxt, const xmlChar *prefix,
51353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor			   const xmlChar *ns_uri) {
51363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ctxt == NULL)
51373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(-1);
51383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (prefix == NULL)
51393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(-1);
5140db3ce96906c09559d944c72b69eb984105f34776Daniel Veillard    if (prefix[0] == 0)
5141db3ce96906c09559d944c72b69eb984105f34776Daniel Veillard	return(-1);
51423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
51433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ctxt->nsHash == NULL)
51443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	ctxt->nsHash = xmlHashCreate(10);
51453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ctxt->nsHash == NULL)
51463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(-1);
5147e991fe958f5269a459262bcff802a3d26167edb8Daniel Veillard    if (ns_uri == NULL)
514894394cd1e494f8d669b310748f54192268185c8dDaniel Veillard        return(xmlHashRemoveEntry(ctxt->nsHash, prefix,
5149e991fe958f5269a459262bcff802a3d26167edb8Daniel Veillard	                          (xmlHashDeallocator)xmlFree));
515042766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard    return(xmlHashUpdateEntry(ctxt->nsHash, prefix, (void *) xmlStrdup(ns_uri),
51513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor			      (xmlHashDeallocator)xmlFree));
51523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
51533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
51543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
51553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNsLookup:
51563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath context
51573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @prefix:  the namespace prefix value
51583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
51593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Search in the namespace declaration array of the context for the given
51603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * namespace name associated to the given prefix
51613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
51623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the value or NULL if not found
51633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
51643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorconst xmlChar *
51653473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNsLookup(xmlXPathContextPtr ctxt, const xmlChar *prefix) {
51663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ctxt == NULL)
51673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(NULL);
51683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (prefix == NULL)
51693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(NULL);
51703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
51713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef XML_XML_NAMESPACE
51723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (xmlStrEqual(prefix, (const xmlChar *) "xml"))
51733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(XML_XML_NAMESPACE);
51743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif
51753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
5176c8f620ba7f95b3ceb687699e140eeaa33343e41aDaniel Veillard    if (ctxt->namespaces != NULL) {
5177c8f620ba7f95b3ceb687699e140eeaa33343e41aDaniel Veillard	int i;
5178c8f620ba7f95b3ceb687699e140eeaa33343e41aDaniel Veillard
5179c8f620ba7f95b3ceb687699e140eeaa33343e41aDaniel Veillard	for (i = 0;i < ctxt->nsNr;i++) {
5180c8f620ba7f95b3ceb687699e140eeaa33343e41aDaniel Veillard	    if ((ctxt->namespaces[i] != NULL) &&
5181c8f620ba7f95b3ceb687699e140eeaa33343e41aDaniel Veillard		(xmlStrEqual(ctxt->namespaces[i]->prefix, prefix)))
5182c8f620ba7f95b3ceb687699e140eeaa33343e41aDaniel Veillard		return(ctxt->namespaces[i]->href);
5183c8f620ba7f95b3ceb687699e140eeaa33343e41aDaniel Veillard	}
5184c8f620ba7f95b3ceb687699e140eeaa33343e41aDaniel Veillard    }
51853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
51863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return((const xmlChar *) xmlHashLookup(ctxt->nsHash, prefix));
51873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
51883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
51893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
51905e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard * xmlXPathRegisteredNsCleanup:
51913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath context
51923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
51933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Cleanup the XPath context data associated to registered variables
51943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
51953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
51963473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathRegisteredNsCleanup(xmlXPathContextPtr ctxt) {
51973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ctxt == NULL)
51983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return;
51993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
520042766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard    xmlHashFree(ctxt->nsHash, (xmlHashDeallocator)xmlFree);
52013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ctxt->nsHash = NULL;
52023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
52033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
52043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/************************************************************************
52053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *									*
52063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *			Routines to handle Values			*
52073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *									*
52083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ************************************************************************/
52093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
5210081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack/* Allocations are terrible, one needs to optimize all this !!! */
52113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
52123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
52133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNewFloat:
52143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val:  the double value
52153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
52163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Create a new xmlXPathObjectPtr of type double and of value @val
52173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
52183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the newly created object.
52193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
52203473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathObjectPtr
52213473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNewFloat(double val) {
52223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathObjectPtr ret;
52233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
52243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
52253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ret == NULL) {
5226d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard        xmlXPathErrMemory(NULL, "creating float object\n");
52273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(NULL);
52283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
52293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
52303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret->type = XPATH_NUMBER;
52313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret->floatval = val;
5232a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#ifdef XP_DEBUG_OBJ_USAGE
5233a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathDebugObjUsageRequested(NULL, XPATH_NUMBER);
5234a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#endif
52353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(ret);
52363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
52373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
52383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
52393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNewBoolean:
52403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val:  the boolean value
52413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
52423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Create a new xmlXPathObjectPtr of type boolean and of value @val
52433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
52443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the newly created object.
52453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
52463473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathObjectPtr
52473473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNewBoolean(int val) {
52483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathObjectPtr ret;
52493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
52503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
52513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ret == NULL) {
5252d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard        xmlXPathErrMemory(NULL, "creating boolean object\n");
52533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(NULL);
52543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
52553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
52563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret->type = XPATH_BOOLEAN;
52573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret->boolval = (val != 0);
5258a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#ifdef XP_DEBUG_OBJ_USAGE
5259a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathDebugObjUsageRequested(NULL, XPATH_BOOLEAN);
5260a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#endif
52613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(ret);
52623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
52633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
52643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
52653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNewString:
52663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val:  the xmlChar * value
52673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
52683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Create a new xmlXPathObjectPtr of type string and of value @val
52693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
52703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the newly created object.
52713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
52723473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathObjectPtr
52733473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNewString(const xmlChar *val) {
52743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathObjectPtr ret;
52753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
52763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
52773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ret == NULL) {
5278d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard        xmlXPathErrMemory(NULL, "creating string object\n");
52793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(NULL);
52803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
52813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
52823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret->type = XPATH_STRING;
52833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (val != NULL)
52843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	ret->stringval = xmlStrdup(val);
52853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    else
52863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	ret->stringval = xmlStrdup((const xmlChar *)"");
5287a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#ifdef XP_DEBUG_OBJ_USAGE
5288a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathDebugObjUsageRequested(NULL, XPATH_STRING);
5289a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#endif
52903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(ret);
52913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
52923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
52933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
5294ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathWrapString:
5295ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @val:  the xmlChar * value
5296ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
5297ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Wraps the @val string into an XPath object.
5298ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
5299ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns the newly created object.
5300ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */
5301ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathObjectPtr
5302ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathWrapString (xmlChar *val) {
5303ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    xmlXPathObjectPtr ret;
5304ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
5305ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
5306ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    if (ret == NULL) {
5307d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard        xmlXPathErrMemory(NULL, "creating string object\n");
5308ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	return(NULL);
5309ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    }
5310ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
5311ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    ret->type = XPATH_STRING;
5312ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    ret->stringval = val;
5313a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#ifdef XP_DEBUG_OBJ_USAGE
5314a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathDebugObjUsageRequested(NULL, XPATH_STRING);
5315a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#endif
5316ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    return(ret);
5317ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard}
5318ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
5319ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/**
53203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNewCString:
53213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val:  the char * value
53223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
53233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Create a new xmlXPathObjectPtr of type string and of value @val
53243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
53253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the newly created object.
53263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
53273473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathObjectPtr
53283473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNewCString(const char *val) {
53293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathObjectPtr ret;
53303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
53313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
53323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ret == NULL) {
5333d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard        xmlXPathErrMemory(NULL, "creating string object\n");
53343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(NULL);
53353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
53363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
53373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret->type = XPATH_STRING;
53383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret->stringval = xmlStrdup(BAD_CAST val);
5339a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#ifdef XP_DEBUG_OBJ_USAGE
5340a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathDebugObjUsageRequested(NULL, XPATH_STRING);
5341a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#endif
53423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(ret);
53433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
53443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
53453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
5346ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathWrapCString:
5347ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @val:  the char * value
5348ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
5349ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Wraps a string into an XPath object.
5350ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
5351ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns the newly created object.
5352ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */
5353ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathObjectPtr
5354ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathWrapCString (char * val) {
5355ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    return(xmlXPathWrapString((xmlChar *)(val)));
5356ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard}
5357ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
5358ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/**
5359f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * xmlXPathWrapExternal:
5360f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * @val:  the user data
5361f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *
5362f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Wraps the @val data into an XPath object.
5363f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer *
5364f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer * Returns the newly created object.
5365f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer */
5366f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathObjectPtr
5367f06a3d8b53686e215eb3302eea32436e8c3f693fThomas BroyerxmlXPathWrapExternal (void *val) {
5368f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    xmlXPathObjectPtr ret;
5369f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer
5370f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
5371f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    if (ret == NULL) {
5372d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard        xmlXPathErrMemory(NULL, "creating user object\n");
5373f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer	return(NULL);
5374f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    }
5375f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
5376f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    ret->type = XPATH_USERS;
5377f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    ret->user = val;
5378a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#ifdef XP_DEBUG_OBJ_USAGE
5379a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathDebugObjUsageRequested(NULL, XPATH_USERS);
5380a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#endif
5381f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer    return(ret);
5382f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer}
5383f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer
5384f06a3d8b53686e215eb3302eea32436e8c3f693fThomas Broyer/**
53853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathObjectCopy:
53863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val:  the original object
53873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
53883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * allocate a new copy of a given object
53893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
53903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the newly created object.
53913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
53923473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathObjectPtr
53933473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathObjectCopy(xmlXPathObjectPtr val) {
53943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathObjectPtr ret;
53953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
53963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (val == NULL)
53973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(NULL);
53983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
53993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
54003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ret == NULL) {
5401d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard        xmlXPathErrMemory(NULL, "copying object\n");
54023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(NULL);
54033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
54043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    memcpy(ret, val , (size_t) sizeof(xmlXPathObject));
5405a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#ifdef XP_DEBUG_OBJ_USAGE
5406a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathDebugObjUsageRequested(NULL, val->type);
5407a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#endif
54083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    switch (val->type) {
54093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XPATH_BOOLEAN:
54103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XPATH_NUMBER:
54113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XPATH_POINT:
54123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XPATH_RANGE:
54133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    break;
54143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XPATH_STRING:
54153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    ret->stringval = xmlStrdup(val->stringval);
54163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    break;
54173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XPATH_XSLT_TREE:
5418e9449c5d29d87b1dc51de7784ed947ae1e3da831William M. Brack#if 0
5419e9449c5d29d87b1dc51de7784ed947ae1e3da831William M. Brack/*
5420e9449c5d29d87b1dc51de7784ed947ae1e3da831William M. Brack  Removed 11 July 2004 - the current handling of xslt tmpRVT nodes means that
5421e9449c5d29d87b1dc51de7784ed947ae1e3da831William M. Brack  this previous handling is no longer correct, and can cause some serious
5422e9449c5d29d87b1dc51de7784ed947ae1e3da831William M. Brack  problems (ref. bug 145547)
5423e9449c5d29d87b1dc51de7784ed947ae1e3da831William M. Brack*/
54243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    if ((val->nodesetval != NULL) &&
54250ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard		(val->nodesetval->nodeTab != NULL)) {
54269adc0469d4691e798ea4ad59b84c874cdea8b38dDaniel Veillard		xmlNodePtr cur, tmp;
54279adc0469d4691e798ea4ad59b84c874cdea8b38dDaniel Veillard		xmlDocPtr top;
5428ef0b45016373d65700ef6f7d494a200758b2e4c5Daniel Veillard
54290ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard		ret->boolval = 1;
54309adc0469d4691e798ea4ad59b84c874cdea8b38dDaniel Veillard		top =  xmlNewDoc(NULL);
54319adc0469d4691e798ea4ad59b84c874cdea8b38dDaniel Veillard		top->name = (char *)
54329adc0469d4691e798ea4ad59b84c874cdea8b38dDaniel Veillard		    xmlStrdup(val->nodesetval->nodeTab[0]->name);
5433ef0b45016373d65700ef6f7d494a200758b2e4c5Daniel Veillard		ret->user = top;
5434ef0b45016373d65700ef6f7d494a200758b2e4c5Daniel Veillard		if (top != NULL) {
54359adc0469d4691e798ea4ad59b84c874cdea8b38dDaniel Veillard		    top->doc = top;
5436ef0b45016373d65700ef6f7d494a200758b2e4c5Daniel Veillard		    cur = val->nodesetval->nodeTab[0]->children;
5437ef0b45016373d65700ef6f7d494a200758b2e4c5Daniel Veillard		    while (cur != NULL) {
54389adc0469d4691e798ea4ad59b84c874cdea8b38dDaniel Veillard			tmp = xmlDocCopyNode(cur, top, 1);
54399adc0469d4691e798ea4ad59b84c874cdea8b38dDaniel Veillard			xmlAddChild((xmlNodePtr) top, tmp);
5440ef0b45016373d65700ef6f7d494a200758b2e4c5Daniel Veillard			cur = cur->next;
5441ef0b45016373d65700ef6f7d494a200758b2e4c5Daniel Veillard		    }
5442ef0b45016373d65700ef6f7d494a200758b2e4c5Daniel Veillard		}
5443e9449c5d29d87b1dc51de7784ed947ae1e3da831William M. Brack
54449adc0469d4691e798ea4ad59b84c874cdea8b38dDaniel Veillard		ret->nodesetval = xmlXPathNodeSetCreate((xmlNodePtr) top);
54450ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard	    } else
54463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		ret->nodesetval = xmlXPathNodeSetCreate(NULL);
54470ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard	    /* Deallocate the copied tree value */
54483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    break;
5449e9449c5d29d87b1dc51de7784ed947ae1e3da831William M. Brack#endif
54503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XPATH_NODESET:
54513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    ret->nodesetval = xmlXPathNodeSetMerge(NULL, val->nodesetval);
54520ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard	    /* Do not deallocate the copied tree value */
54530ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard	    ret->boolval = 0;
54543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    break;
54553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XPATH_LOCATIONSET:
54563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef LIBXML_XPTR_ENABLED
54573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	{
54583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    xmlLocationSetPtr loc = val->user;
54593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    ret->user = (void *) xmlXPtrLocationSetMerge(NULL, loc);
54603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    break;
54613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
54623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif
546347334c09f4373e4cff71334e60a623fee73a525fThomas Broyer        case XPATH_USERS:
546447334c09f4373e4cff71334e60a623fee73a525fThomas Broyer	    ret->user = val->user;
546545490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	    break;
546647334c09f4373e4cff71334e60a623fee73a525fThomas Broyer        case XPATH_UNDEFINED:
54673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    xmlGenericError(xmlGenericErrorContext,
54683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    "xmlXPathObjectCopy: unsupported type %d\n",
54693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    val->type);
54703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    break;
54713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
54723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(ret);
54733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
54743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
54753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
54763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathFreeObject:
54773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @obj:  the object to free
54783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
54793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Free up an xmlXPathObjectPtr object.
54803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
54813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
54823473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathFreeObject(xmlXPathObjectPtr obj) {
54833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (obj == NULL) return;
54840ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard    if ((obj->type == XPATH_NODESET) || (obj->type == XPATH_XSLT_TREE)) {
548577851710aba3a0effdc6af67ea4caf212307420cDaniel Veillard	if (obj->boolval) {
5486e9449c5d29d87b1dc51de7784ed947ae1e3da831William M. Brack#if 0
54870ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard	    if (obj->user != NULL) {
54880ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard                xmlXPathFreeNodeSet(obj->nodesetval);
548938bf6f042507c6051bfa2db5cc9b6666cfc35c2aDaniel Veillard		xmlFreeNodeList((xmlNodePtr) obj->user);
5490e9449c5d29d87b1dc51de7784ed947ae1e3da831William M. Brack	    } else
5491e9449c5d29d87b1dc51de7784ed947ae1e3da831William M. Brack#endif
5492a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    obj->type = XPATH_XSLT_TREE; /* TODO: Just for debugging. */
5493e9449c5d29d87b1dc51de7784ed947ae1e3da831William M. Brack	    if (obj->nodesetval != NULL)
549445490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard		xmlXPathFreeValueTree(obj->nodesetval);
549577851710aba3a0effdc6af67ea4caf212307420cDaniel Veillard	} else {
549677851710aba3a0effdc6af67ea4caf212307420cDaniel Veillard	    if (obj->nodesetval != NULL)
549777851710aba3a0effdc6af67ea4caf212307420cDaniel Veillard		xmlXPathFreeNodeSet(obj->nodesetval);
549877851710aba3a0effdc6af67ea4caf212307420cDaniel Veillard	}
54993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef LIBXML_XPTR_ENABLED
55003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    } else if (obj->type == XPATH_LOCATIONSET) {
55013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (obj->user != NULL)
55023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    xmlXPtrFreeLocationSet(obj->user);
55033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif
55043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    } else if (obj->type == XPATH_STRING) {
55053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (obj->stringval != NULL)
55063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    xmlFree(obj->stringval);
55073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
5508a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#ifdef XP_DEBUG_OBJ_USAGE
5509a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathDebugObjUsageReleased(NULL, obj->type);
5510a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#endif
551145490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard    xmlFree(obj);
5512a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik}
55133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
5514a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik/**
5515a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * xmlXPathReleaseObject:
5516a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * @obj:  the xmlXPathObjectPtr to free or to cache
5517a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik *
5518a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * Depending on the state of the cache this frees the given
5519a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik * XPath object or stores it in the cache.
5520a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik */
5521a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikstatic void
5522a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. BuchcikxmlXPathReleaseObject(xmlXPathContextPtr ctxt, xmlXPathObjectPtr obj)
5523a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik{
5524a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#define XP_CACHE_ADD(sl, o) if (sl == NULL) { \
5525a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	sl = xmlPointerListCreate(10); if (sl == NULL) goto free_obj; } \
5526a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    if (xmlPointerListAddSize(sl, obj, 0) == -1) goto free_obj;
5527a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
5528a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#define XP_CACHE_WANTS(sl, n) ((sl == NULL) || ((sl)->number < n))
5529a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
5530a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    if (obj == NULL)
5531a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	return;
55325869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik    if ((ctxt == NULL) || (ctxt->cache == NULL)) {
5533a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	 xmlXPathFreeObject(obj);
553445490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard    } else {
55355869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik	xmlXPathContextCachePtr cache =
55365869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik	    (xmlXPathContextCachePtr) ctxt->cache;
5537a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
5538a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	switch (obj->type) {
5539a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    case XPATH_NODESET:
5540a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    case XPATH_XSLT_TREE:
5541a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		if (obj->nodesetval != NULL) {
5542a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    if (obj->boolval) {
554345490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard			/*
5544a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik			* It looks like the @boolval is used for
5545a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik			* evaluation if this an XSLT Result Tree Fragment.
5546a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik			* TODO: Check if this assumption is correct.
5547a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik			*/
5548a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik			obj->type = XPATH_XSLT_TREE; /* just for debugging */
5549a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik			xmlXPathFreeValueTree(obj->nodesetval);
5550a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik			obj->nodesetval = NULL;
5551a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    } else if ((obj->nodesetval->nodeMax <= 40) &&
5552a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik			(XP_CACHE_WANTS(cache->nodesetObjs,
5553a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik					cache->maxNodeset)))
5554a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    {
5555a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik			XP_CACHE_ADD(cache->nodesetObjs, obj);
5556a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik			goto obj_cached;
5557a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    } else {
5558a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik			xmlXPathFreeNodeSet(obj->nodesetval);
5559a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik			obj->nodesetval = NULL;
5560a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    }
5561a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		}
5562a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		break;
5563a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    case XPATH_STRING:
5564a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		if (obj->stringval != NULL)
5565a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    xmlFree(obj->stringval);
5566a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
5567a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		if (XP_CACHE_WANTS(cache->stringObjs, cache->maxString)) {
5568a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    XP_CACHE_ADD(cache->stringObjs, obj);
5569a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    goto obj_cached;
5570a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		}
5571a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		break;
5572a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    case XPATH_BOOLEAN:
5573a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		if (XP_CACHE_WANTS(cache->booleanObjs, cache->maxBoolean)) {
5574a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    XP_CACHE_ADD(cache->booleanObjs, obj);
5575a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    goto obj_cached;
5576a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		}
5577a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		break;
5578a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    case XPATH_NUMBER:
5579a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		if (XP_CACHE_WANTS(cache->numberObjs, cache->maxNumber)) {
5580a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    XP_CACHE_ADD(cache->numberObjs, obj);
5581a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    goto obj_cached;
5582a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		}
5583a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		break;
5584a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#ifdef LIBXML_XPTR_ENABLED
5585a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    case XPATH_LOCATIONSET:
5586a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		if (obj->user != NULL) {
5587a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    xmlXPtrFreeLocationSet(obj->user);
5588a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		}
5589a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		goto free_obj;
559045490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard#endif
5591a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    default:
5592a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		goto free_obj;
5593a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	}
5594a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
5595a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	/*
5596a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	* Fallback to adding to the misc-objects slot.
5597a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	*/
5598a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	if (XP_CACHE_WANTS(cache->miscObjs, cache->maxMisc)) {
5599a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    XP_CACHE_ADD(cache->miscObjs, obj);
5600a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	} else
5601a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    goto free_obj;
5602a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
5603a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikobj_cached:
5604a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
5605a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#ifdef XP_DEBUG_OBJ_USAGE
5606a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	xmlXPathDebugObjUsageReleased(ctxt, obj->type);
5607a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#endif
5608a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
5609a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	if (obj->nodesetval != NULL) {
5610a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlNodeSetPtr tmpset = obj->nodesetval;
561145490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
5612a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    /*
5613a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    * TODO: Due to those nasty ns-nodes, we need to traverse
5614a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    *  the list and free the ns-nodes.
5615a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    * URGENT TODO: Check if it's actually slowing things down.
5616a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    *  Maybe we shouldn't try to preserve the list.
5617a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    */
5618a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    if (tmpset->nodeNr > 1) {
5619a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		int i;
5620a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		xmlNodePtr node;
5621a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
5622a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		for (i = 0; i < tmpset->nodeNr; i++) {
5623a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    node = tmpset->nodeTab[i];
5624a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    if ((node != NULL) &&
5625a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik			(node->type == XML_NAMESPACE_DECL))
5626a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    {
5627a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik			xmlXPathNodeSetFreeNs((xmlNsPtr) node);
5628a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    }
5629a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		}
5630a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    } else if (tmpset->nodeNr == 1) {
5631a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		if ((tmpset->nodeTab[0] != NULL) &&
5632a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    (tmpset->nodeTab[0]->type == XML_NAMESPACE_DECL))
5633a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    xmlXPathNodeSetFreeNs((xmlNsPtr) tmpset->nodeTab[0]);
563445490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	    }
5635a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    tmpset->nodeNr = 0;
5636a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    memset(obj, 0, sizeof(xmlXPathObject));
5637a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    obj->nodesetval = tmpset;
5638a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	} else
5639a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    memset(obj, 0, sizeof(xmlXPathObject));
5640a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
5641a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	return;
5642a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
5643a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcikfree_obj:
5644a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	/*
5645a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	* Cache is full; free the object.
564645490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	*/
5647a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	if (obj->nodesetval != NULL)
5648a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathFreeNodeSet(obj->nodesetval);
5649a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#ifdef XP_DEBUG_OBJ_USAGE
5650a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	xmlXPathDebugObjUsageReleased(NULL, obj->type);
5651a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#endif
5652a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	xmlFree(obj);
5653a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    }
5654a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    return;
56553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
56563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
5657ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
5658ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/************************************************************************
5659ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *									*
5660ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *			Type Casting Routines				*
5661ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *									*
5662ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ************************************************************************/
5663ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
5664ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/**
5665ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathCastBooleanToString:
5666ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @val:  a boolean
5667ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
5668ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts a boolean to its string value.
5669ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
5670ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns a newly allocated string.
5671ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */
5672ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlChar *
5673ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathCastBooleanToString (int val) {
5674ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    xmlChar *ret;
5675ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    if (val)
5676ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	ret = xmlStrdup((const xmlChar *) "true");
5677ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    else
5678ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	ret = xmlStrdup((const xmlChar *) "false");
5679ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    return(ret);
5680ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard}
5681ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
5682ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/**
5683ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathCastNumberToString:
5684ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @val:  a number
5685ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
5686ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts a number to its string value.
5687ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
5688ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns a newly allocated string.
5689ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */
5690ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlChar *
5691ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathCastNumberToString (double val) {
5692ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    xmlChar *ret;
5693cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard    switch (xmlXPathIsInf(val)) {
5694ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    case 1:
56955fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard	ret = xmlStrdup((const xmlChar *) "Infinity");
5696ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	break;
5697ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    case -1:
5698ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	ret = xmlStrdup((const xmlChar *) "-Infinity");
5699ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	break;
5700ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    default:
5701cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard	if (xmlXPathIsNaN(val)) {
5702ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	    ret = xmlStrdup((const xmlChar *) "NaN");
5703d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard	} else if (val == 0 && xmlXPathGetSign(val) != 0) {
5704d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard	    ret = xmlStrdup((const xmlChar *) "0");
5705ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	} else {
5706ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	    /* could be improved */
5707ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	    char buf[100];
570811ce4004d86bb4b317c48b7d5124ba33e40e10f5Daniel Veillard	    xmlXPathFormatNumber(val, buf, 99);
570911ce4004d86bb4b317c48b7d5124ba33e40e10f5Daniel Veillard	    buf[99] = 0;
5710ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	    ret = xmlStrdup((const xmlChar *) buf);
5711ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	}
5712ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    }
5713ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    return(ret);
5714ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard}
5715ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
5716ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/**
5717ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathCastNodeToString:
5718ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @node:  a node
5719ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
5720ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts a node to its string value.
5721ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
5722ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns a newly allocated string.
5723ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */
5724ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlChar *
5725ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathCastNodeToString (xmlNodePtr node) {
5726d611c88a010fa7c64c407155e43b04bc4c7e9e38William M. BrackxmlChar *ret;
5727d611c88a010fa7c64c407155e43b04bc4c7e9e38William M. Brack    if ((ret = xmlNodeGetContent(node)) == NULL)
5728d611c88a010fa7c64c407155e43b04bc4c7e9e38William M. Brack	ret = xmlStrdup((const xmlChar *) "");
5729d611c88a010fa7c64c407155e43b04bc4c7e9e38William M. Brack    return(ret);
5730ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard}
5731ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
5732ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/**
5733ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathCastNodeSetToString:
5734ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @ns:  a node-set
5735ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
5736ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts a node-set to its string value.
5737ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
5738ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns a newly allocated string.
5739ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */
5740ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlChar *
5741ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathCastNodeSetToString (xmlNodeSetPtr ns) {
5742ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    if ((ns == NULL) || (ns->nodeNr == 0) || (ns->nodeTab == NULL))
5743ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	return(xmlStrdup((const xmlChar *) ""));
5744ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
574564f7e1a85fe9c973cf9b21cc0bd53efa6cc3dafcKasimier T. Buchcik    if (ns->nodeNr > 1)
574664f7e1a85fe9c973cf9b21cc0bd53efa6cc3dafcKasimier T. Buchcik	xmlXPathNodeSetSort(ns);
5747ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    return(xmlXPathCastNodeToString(ns->nodeTab[0]));
5748ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard}
5749ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
5750ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/**
5751ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathCastToString:
5752ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @val:  an XPath object
5753ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
5754ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts an existing object to its string() equivalent
5755ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
575650128ad7cc312ad559801bbc7121201c1018857aKasimier T. Buchcik * Returns the allocated string value of the object, NULL in case of error.
575745490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *         It's up to the caller to free the string memory with xmlFree().
5758ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */
5759ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlChar *
5760ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathCastToString(xmlXPathObjectPtr val) {
5761ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    xmlChar *ret = NULL;
5762ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
5763ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    if (val == NULL)
5764ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	return(xmlStrdup((const xmlChar *) ""));
5765ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    switch (val->type) {
5766ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	case XPATH_UNDEFINED:
5767ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard#ifdef DEBUG_EXPR
5768ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	    xmlGenericError(xmlGenericErrorContext, "String: undefined\n");
5769ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard#endif
5770ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	    ret = xmlStrdup((const xmlChar *) "");
5771ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	    break;
5772ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard        case XPATH_NODESET:
57730c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack        case XPATH_XSLT_TREE:
5774ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	    ret = xmlXPathCastNodeSetToString(val->nodesetval);
5775ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	    break;
5776ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	case XPATH_STRING:
57774e2df54bb17645ef0d3f28b9665b2d2dde4b47a3Daniel Veillard	    return(xmlStrdup(val->stringval));
5778ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard        case XPATH_BOOLEAN:
5779ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	    ret = xmlXPathCastBooleanToString(val->boolval);
5780ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	    break;
5781ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	case XPATH_NUMBER: {
5782ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	    ret = xmlXPathCastNumberToString(val->floatval);
5783ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	    break;
5784ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	}
5785ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	case XPATH_USERS:
5786ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	case XPATH_POINT:
5787ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	case XPATH_RANGE:
5788ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	case XPATH_LOCATIONSET:
5789ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	    TODO
5790ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	    ret = xmlStrdup((const xmlChar *) "");
5791ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	    break;
5792ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    }
5793ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    return(ret);
5794ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard}
5795ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
5796ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/**
5797ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathConvertString:
5798ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @val:  an XPath object
5799ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
5800ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts an existing object to its string() equivalent
5801ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
5802ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns the new object, the old one is freed (or the operation
5803ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *         is done directly on @val)
5804ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */
5805ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathObjectPtr
5806ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathConvertString(xmlXPathObjectPtr val) {
5807ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    xmlChar *res = NULL;
5808ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
5809ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    if (val == NULL)
5810ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	return(xmlXPathNewCString(""));
5811ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
5812ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    switch (val->type) {
5813ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    case XPATH_UNDEFINED:
5814ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard#ifdef DEBUG_EXPR
5815ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	xmlGenericError(xmlGenericErrorContext, "STRING: undefined\n");
5816ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard#endif
5817ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	break;
5818ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    case XPATH_NODESET:
58190c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack    case XPATH_XSLT_TREE:
5820ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	res = xmlXPathCastNodeSetToString(val->nodesetval);
5821ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	break;
5822ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    case XPATH_STRING:
5823ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	return(val);
5824ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    case XPATH_BOOLEAN:
5825ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	res = xmlXPathCastBooleanToString(val->boolval);
5826ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	break;
5827ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    case XPATH_NUMBER:
5828ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	res = xmlXPathCastNumberToString(val->floatval);
5829ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	break;
5830ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    case XPATH_USERS:
5831ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    case XPATH_POINT:
5832ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    case XPATH_RANGE:
5833ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    case XPATH_LOCATIONSET:
5834ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	TODO;
5835ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	break;
5836ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    }
5837ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    xmlXPathFreeObject(val);
5838ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    if (res == NULL)
5839ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	return(xmlXPathNewCString(""));
5840ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    return(xmlXPathWrapString(res));
5841ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard}
5842ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
5843ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/**
5844ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathCastBooleanToNumber:
5845ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @val:  a boolean
5846ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
5847ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts a boolean to its number value
5848ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
5849ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns the number value
5850ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */
5851ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillarddouble
5852ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathCastBooleanToNumber(int val) {
5853ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    if (val)
5854ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	return(1.0);
5855ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    return(0.0);
5856ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard}
5857ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
5858ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/**
5859ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathCastStringToNumber:
5860ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @val:  a string
5861ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
5862ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts a string to its number value
5863ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
5864ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns the number value
5865ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */
5866ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillarddouble
5867ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathCastStringToNumber(const xmlChar * val) {
5868ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    return(xmlXPathStringEvalNumber(val));
5869ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard}
5870ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
5871ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/**
5872ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathCastNodeToNumber:
5873ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @node:  a node
5874ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
5875ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts a node to its number value
5876ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
5877ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns the number value
5878ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */
5879ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillarddouble
5880ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathCastNodeToNumber (xmlNodePtr node) {
5881ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    xmlChar *strval;
5882ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    double ret;
5883ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
5884ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    if (node == NULL)
5885ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	return(xmlXPathNAN);
5886ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    strval = xmlXPathCastNodeToString(node);
5887ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    if (strval == NULL)
5888ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	return(xmlXPathNAN);
5889ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    ret = xmlXPathCastStringToNumber(strval);
5890ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    xmlFree(strval);
5891ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
5892ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    return(ret);
5893ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard}
5894ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
5895ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/**
5896ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathCastNodeSetToNumber:
5897ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @ns:  a node-set
5898ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
5899ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts a node-set to its number value
5900ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
5901ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns the number value
5902ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */
5903ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillarddouble
5904ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathCastNodeSetToNumber (xmlNodeSetPtr ns) {
5905ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    xmlChar *str;
5906ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    double ret;
5907ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
5908ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    if (ns == NULL)
5909ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	return(xmlXPathNAN);
5910ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    str = xmlXPathCastNodeSetToString(ns);
5911ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    ret = xmlXPathCastStringToNumber(str);
5912ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    xmlFree(str);
5913ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    return(ret);
5914ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard}
5915ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
5916ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/**
5917ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathCastToNumber:
5918ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @val:  an XPath object
5919ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
5920ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts an XPath object to its number value
5921ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
5922ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns the number value
5923ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */
5924ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillarddouble
5925ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathCastToNumber(xmlXPathObjectPtr val) {
5926ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    double ret = 0.0;
5927ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
5928ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    if (val == NULL)
5929ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	return(xmlXPathNAN);
5930ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    switch (val->type) {
5931ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    case XPATH_UNDEFINED:
5932ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard#ifdef DEGUB_EXPR
5933ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	xmlGenericError(xmlGenericErrorContext, "NUMBER: undefined\n");
5934ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard#endif
5935ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	ret = xmlXPathNAN;
5936ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	break;
5937ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    case XPATH_NODESET:
59380c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack    case XPATH_XSLT_TREE:
5939ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	ret = xmlXPathCastNodeSetToNumber(val->nodesetval);
5940ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	break;
5941ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    case XPATH_STRING:
5942ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	ret = xmlXPathCastStringToNumber(val->stringval);
5943ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	break;
5944ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    case XPATH_NUMBER:
5945ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	ret = val->floatval;
5946ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	break;
5947ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    case XPATH_BOOLEAN:
5948ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	ret = xmlXPathCastBooleanToNumber(val->boolval);
5949ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	break;
5950ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    case XPATH_USERS:
5951ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    case XPATH_POINT:
5952ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    case XPATH_RANGE:
5953ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    case XPATH_LOCATIONSET:
5954ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	TODO;
5955ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	ret = xmlXPathNAN;
5956ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	break;
5957ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    }
5958ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    return(ret);
5959ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard}
5960ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
5961ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/**
5962ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathConvertNumber:
5963ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @val:  an XPath object
5964ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
5965ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts an existing object to its number() equivalent
5966ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
5967ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns the new object, the old one is freed (or the operation
5968ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *         is done directly on @val)
5969ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */
5970ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathObjectPtr
5971ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathConvertNumber(xmlXPathObjectPtr val) {
5972ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    xmlXPathObjectPtr ret;
5973ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
5974ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    if (val == NULL)
5975ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	return(xmlXPathNewFloat(0.0));
5976ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    if (val->type == XPATH_NUMBER)
5977ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	return(val);
5978ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    ret = xmlXPathNewFloat(xmlXPathCastToNumber(val));
5979ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    xmlXPathFreeObject(val);
5980ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    return(ret);
5981ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard}
5982ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
5983ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/**
5984ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathCastNumberToBoolean:
5985ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @val:  a number
5986ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
5987ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts a number to its boolean value
5988ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
5989ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns the boolean value
5990ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */
5991ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillardint
5992ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathCastNumberToBoolean (double val) {
5993cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard     if (xmlXPathIsNaN(val) || (val == 0.0))
5994ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	 return(0);
5995ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard     return(1);
5996ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard}
5997ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
5998ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/**
5999ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathCastStringToBoolean:
6000ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @val:  a string
6001ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
6002ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts a string to its boolean value
6003ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
6004ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns the boolean value
6005ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */
6006ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillardint
6007ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathCastStringToBoolean (const xmlChar *val) {
6008ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    if ((val == NULL) || (xmlStrlen(val) == 0))
6009ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	return(0);
6010ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    return(1);
6011ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard}
6012ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
6013ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/**
6014ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathCastNodeSetToBoolean:
6015ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @ns:  a node-set
6016ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
6017ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts a node-set to its boolean value
6018ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
6019ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns the boolean value
6020ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */
6021ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillardint
6022ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathCastNodeSetToBoolean (xmlNodeSetPtr ns) {
6023ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    if ((ns == NULL) || (ns->nodeNr == 0))
6024ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	return(0);
6025ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    return(1);
6026ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard}
6027ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
6028ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/**
60295e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard * xmlXPathCastToBoolean:
6030ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @val:  an XPath object
6031ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
6032ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts an XPath object to its boolean value
6033ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
6034ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns the boolean value
6035ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */
6036ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillardint
6037ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathCastToBoolean (xmlXPathObjectPtr val) {
6038ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    int ret = 0;
6039ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
6040ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    if (val == NULL)
6041ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	return(0);
6042ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    switch (val->type) {
6043ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    case XPATH_UNDEFINED:
6044ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard#ifdef DEBUG_EXPR
6045ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	xmlGenericError(xmlGenericErrorContext, "BOOLEAN: undefined\n");
6046ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard#endif
6047ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	ret = 0;
6048ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	break;
6049ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    case XPATH_NODESET:
60500c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack    case XPATH_XSLT_TREE:
6051ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	ret = xmlXPathCastNodeSetToBoolean(val->nodesetval);
6052ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	break;
6053ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    case XPATH_STRING:
6054ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	ret = xmlXPathCastStringToBoolean(val->stringval);
6055ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	break;
6056ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    case XPATH_NUMBER:
6057ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	ret = xmlXPathCastNumberToBoolean(val->floatval);
6058ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	break;
6059ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    case XPATH_BOOLEAN:
6060ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	ret = val->boolval;
6061ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	break;
6062ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    case XPATH_USERS:
6063ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    case XPATH_POINT:
6064ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    case XPATH_RANGE:
6065ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    case XPATH_LOCATIONSET:
6066ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	TODO;
6067ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	ret = 0;
6068ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	break;
6069ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    }
6070ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    return(ret);
6071ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard}
6072ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
6073ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
6074ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/**
6075ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathConvertBoolean:
6076ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @val:  an XPath object
6077ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
6078ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts an existing object to its boolean() equivalent
6079ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
6080ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns the new object, the old one is freed (or the operation
6081ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *         is done directly on @val)
6082ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */
6083ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathObjectPtr
6084ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathConvertBoolean(xmlXPathObjectPtr val) {
6085ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    xmlXPathObjectPtr ret;
6086ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
6087ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    if (val == NULL)
6088ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	return(xmlXPathNewBoolean(0));
6089ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    if (val->type == XPATH_BOOLEAN)
6090ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	return(val);
6091ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    ret = xmlXPathNewBoolean(xmlXPathCastToBoolean(val));
6092ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    xmlXPathFreeObject(val);
6093ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    return(ret);
6094ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard}
6095ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
60963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/************************************************************************
60973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *									*
60983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *		Routines to handle XPath contexts			*
60993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *									*
61003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ************************************************************************/
61013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
61023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
61033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNewContext:
61043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @doc:  the XML document
61053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
61063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Create a new xmlXPathContext
61073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
6108af43f63aaabf0dc4b4a070773875d0927da3d8a2Daniel Veillard * Returns the xmlXPathContext just allocated. The caller will need to free it.
61093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
61103473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathContextPtr
61113473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNewContext(xmlDocPtr doc) {
61123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathContextPtr ret;
61133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
61143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret = (xmlXPathContextPtr) xmlMalloc(sizeof(xmlXPathContext));
61153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ret == NULL) {
6116d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard        xmlXPathErrMemory(NULL, "creating context\n");
61173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(NULL);
61183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
61193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    memset(ret, 0 , (size_t) sizeof(xmlXPathContext));
61203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret->doc = doc;
61213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret->node = NULL;
61223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
61233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret->varHash = NULL;
61243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
61253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret->nb_types = 0;
61263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret->max_types = 0;
61273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret->types = NULL;
61283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
61293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret->funcHash = xmlHashCreate(0);
61303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
61313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret->nb_axis = 0;
61323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret->max_axis = 0;
61333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret->axis = NULL;
61343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
61353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret->nsHash = NULL;
61363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret->user = NULL;
61373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
61383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret->contextSize = -1;
61393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret->proximityPosition = -1;
61403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
6141a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#ifdef XP_DEFAULT_CACHE_ON
61425869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik    if (xmlXPathContextSetCache(ret, 1, -1, 0) == -1) {
6143a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	xmlXPathFreeContext(ret);
6144a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	return(NULL);
6145a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    }
6146a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik#endif
6147a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
614845490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard    xmlXPathRegisterAllFunctions(ret);
6149a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
61503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(ret);
61513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
61523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
61533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
61543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathFreeContext:
61553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the context to free
61563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
61573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Free up an xmlXPathContext
61583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
61593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
61603473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathFreeContext(xmlXPathContextPtr ctxt) {
61617eca35fbaef6bd06074c4b978d381303609fcb0bDaniel Veillard    if (ctxt == NULL) return;
61627eca35fbaef6bd06074c4b978d381303609fcb0bDaniel Veillard
61635869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik    if (ctxt->cache != NULL)
61645869469f42db259a21fb0721d66513de0b619097Kasimier T. Buchcik	xmlXPathFreeCache((xmlXPathContextCachePtr) ctxt->cache);
61653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathRegisteredNsCleanup(ctxt);
61663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathRegisteredFuncsCleanup(ctxt);
61673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathRegisteredVariablesCleanup(ctxt);
61687eca35fbaef6bd06074c4b978d381303609fcb0bDaniel Veillard    xmlResetError(&ctxt->lastError);
61693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlFree(ctxt);
61703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
61713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
61723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/************************************************************************
61733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *									*
61743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *		Routines to handle XPath parser contexts		*
61753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *									*
61763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ************************************************************************/
61773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
61783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define CHECK_CTXT(ctxt)						\
617945490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard    if (ctxt == NULL) {						\
6180f13f77f0e6a7876063d5fba15c096befb0827cedWilliam M. Brack	__xmlRaiseError(NULL, NULL, NULL,				\
6181f13f77f0e6a7876063d5fba15c096befb0827cedWilliam M. Brack		NULL, NULL, XML_FROM_XPATH,				\
6182f13f77f0e6a7876063d5fba15c096befb0827cedWilliam M. Brack		XML_ERR_INTERNAL_ERROR, XML_ERR_FATAL,			\
6183f13f77f0e6a7876063d5fba15c096befb0827cedWilliam M. Brack		__FILE__, __LINE__,					\
6184f13f77f0e6a7876063d5fba15c096befb0827cedWilliam M. Brack		NULL, NULL, NULL, 0, 0,					\
6185f13f77f0e6a7876063d5fba15c096befb0827cedWilliam M. Brack		"NULL context pointer\n");				\
6186f13f77f0e6a7876063d5fba15c096befb0827cedWilliam M. Brack	return(NULL);							\
61873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }									\
61883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
6189631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik#define CHECK_CTXT_NEG(ctxt)						\
619045490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard    if (ctxt == NULL) {						\
6191631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	__xmlRaiseError(NULL, NULL, NULL,				\
6192631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik		NULL, NULL, XML_FROM_XPATH,				\
6193631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik		XML_ERR_INTERNAL_ERROR, XML_ERR_FATAL,			\
6194631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik		__FILE__, __LINE__,					\
6195631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik		NULL, NULL, NULL, 0, 0,					\
6196631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik		"NULL context pointer\n");				\
6197631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	return(-1);							\
6198631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik    }									\
6199631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik
62003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
62013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define CHECK_CONTEXT(ctxt)						\
620257b2516af5e2e06c54750b6549723cf5b8edf8a4Daniel Veillard    if ((ctxt == NULL) || (ctxt->doc == NULL) ||			\
620345490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard        (ctxt->doc->children == NULL)) {				\
620457b2516af5e2e06c54750b6549723cf5b8edf8a4Daniel Veillard	xmlXPatherror(ctxt, __FILE__, __LINE__, XPATH_INVALID_CTXT);	\
6205ce682bc24b79f1dd29b781d4c17f9bf169ce7e32Daniel Veillard	return(NULL);							\
620657b2516af5e2e06c54750b6549723cf5b8edf8a4Daniel Veillard    }
62073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
62083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
62093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
62103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNewParserContext:
62113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @str:  the XPath expression
62123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath context
62133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
62143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Create a new xmlXPathParserContext
62153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
62163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the xmlXPathParserContext just allocated.
62173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
62183473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathParserContextPtr
62193473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNewParserContext(const xmlChar *str, xmlXPathContextPtr ctxt) {
62203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathParserContextPtr ret;
62213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
62223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret = (xmlXPathParserContextPtr) xmlMalloc(sizeof(xmlXPathParserContext));
62233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ret == NULL) {
6224d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard        xmlXPathErrMemory(ctxt, "creating parser context\n");
62253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(NULL);
62263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
62273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    memset(ret, 0 , (size_t) sizeof(xmlXPathParserContext));
62283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret->cur = ret->base = str;
62293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret->context = ctxt;
62303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
62319e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    ret->comp = xmlXPathNewCompExpr();
62329e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    if (ret->comp == NULL) {
62339e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	xmlFree(ret->valueTab);
62349e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	xmlFree(ret);
62359e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	return(NULL);
62369e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    }
62374773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard    if ((ctxt != NULL) && (ctxt->dict != NULL)) {
62384773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard        ret->comp->dict = ctxt->dict;
62394773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard	xmlDictReference(ret->comp->dict);
62404773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard    }
62419e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
62429e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    return(ret);
62439e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard}
62449e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
62459e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard/**
62469e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * xmlXPathCompParserContext:
62479e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * @comp:  the XPath compiled expression
62489e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * @ctxt:  the XPath context
62499e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard *
62509e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * Create a new xmlXPathParserContext when processing a compiled expression
62519e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard *
62529e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * Returns the xmlXPathParserContext just allocated.
62539e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard */
625456a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic xmlXPathParserContextPtr
62559e7160d45a18bfa26d708e22ba991f7670d0128bDaniel VeillardxmlXPathCompParserContext(xmlXPathCompExprPtr comp, xmlXPathContextPtr ctxt) {
62569e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    xmlXPathParserContextPtr ret;
62579e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
62589e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    ret = (xmlXPathParserContextPtr) xmlMalloc(sizeof(xmlXPathParserContext));
62599e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    if (ret == NULL) {
6260d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard        xmlXPathErrMemory(ctxt, "creating evaluation context\n");
62619e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	return(NULL);
62629e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    }
62639e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    memset(ret, 0 , (size_t) sizeof(xmlXPathParserContext));
62649e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
62653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    /* Allocate the value stack */
626645490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard    ret->valueTab = (xmlXPathObjectPtr *)
62673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor                     xmlMalloc(10 * sizeof(xmlXPathObjectPtr));
62689e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    if (ret->valueTab == NULL) {
62699e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	xmlFree(ret);
6270d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard	xmlXPathErrMemory(ctxt, "creating evaluation context\n");
62719e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	return(NULL);
62729e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    }
62733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret->valueNr = 0;
62743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret->valueMax = 10;
62753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret->value = NULL;
6276f5048b3e71fc30ad096970b8df6e7af073bae4cbDaniel Veillard    ret->valueFrame = 0;
62779e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
6278fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard    ret->context = ctxt;
62799e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    ret->comp = comp;
62809e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
62813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(ret);
62823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
62833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
62843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
62853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathFreeParserContext:
62863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the context to free
62873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
62883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Free up an xmlXPathParserContext
62893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
62903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
62913473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathFreeParserContext(xmlXPathParserContextPtr ctxt) {
62923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ctxt->valueTab != NULL) {
62933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        xmlFree(ctxt->valueTab);
62943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
629556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard    if (ctxt->comp != NULL) {
629656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard#ifdef XPATH_STREAMING
629756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	if (ctxt->comp->stream != NULL) {
629856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	    xmlFreePatternList(ctxt->comp->stream);
629956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	    ctxt->comp->stream = NULL;
630056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	}
630156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard#endif
63029e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	xmlXPathFreeCompExpr(ctxt->comp);
630356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard    }
63043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlFree(ctxt);
63053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
63063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
63073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/************************************************************************
63083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *									*
63093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *		The implicit core function library			*
63103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *									*
63113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ************************************************************************/
63123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
63133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
631401c13b5be2d249ef66d86585adee87901bb8efa2Daniel Veillard * xmlXPathNodeValHash:
6315f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * @node:  a node pointer
6316f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard *
6317f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Function computing the beginning of the string value of the node,
6318f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * used to speed up comparisons
6319f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard *
6320f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Returns an int usable as a hash
6321f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */
6322f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillardstatic unsigned int
6323f06307e2c172284bb41376c396f757bdac9bdd19Daniel VeillardxmlXPathNodeValHash(xmlNodePtr node) {
6324f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    int len = 2;
6325f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    const xmlChar * string = NULL;
6326f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    xmlNodePtr tmp = NULL;
6327f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    unsigned int ret = 0;
6328f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
6329f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    if (node == NULL)
6330f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	return(0);
6331f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
63329adc0469d4691e798ea4ad59b84c874cdea8b38dDaniel Veillard    if (node->type == XML_DOCUMENT_NODE) {
63339adc0469d4691e798ea4ad59b84c874cdea8b38dDaniel Veillard	tmp = xmlDocGetRootElement((xmlDocPtr) node);
63349adc0469d4691e798ea4ad59b84c874cdea8b38dDaniel Veillard	if (tmp == NULL)
63359adc0469d4691e798ea4ad59b84c874cdea8b38dDaniel Veillard	    node = node->children;
63369adc0469d4691e798ea4ad59b84c874cdea8b38dDaniel Veillard	else
63379adc0469d4691e798ea4ad59b84c874cdea8b38dDaniel Veillard	    node = tmp;
63389adc0469d4691e798ea4ad59b84c874cdea8b38dDaniel Veillard
63399adc0469d4691e798ea4ad59b84c874cdea8b38dDaniel Veillard	if (node == NULL)
63409adc0469d4691e798ea4ad59b84c874cdea8b38dDaniel Veillard	    return(0);
63419adc0469d4691e798ea4ad59b84c874cdea8b38dDaniel Veillard    }
6342f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
6343f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    switch (node->type) {
6344f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	case XML_COMMENT_NODE:
6345f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	case XML_PI_NODE:
6346f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	case XML_CDATA_SECTION_NODE:
6347f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	case XML_TEXT_NODE:
6348f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	    string = node->content;
6349f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	    if (string == NULL)
6350f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard		return(0);
6351f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	    if (string[0] == 0)
6352f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard		return(0);
6353f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	    return(((unsigned int) string[0]) +
6354f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard		   (((unsigned int) string[1]) << 8));
6355f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	case XML_NAMESPACE_DECL:
6356f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	    string = ((xmlNsPtr)node)->href;
6357f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	    if (string == NULL)
6358f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard		return(0);
6359f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	    if (string[0] == 0)
6360f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard		return(0);
6361f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	    return(((unsigned int) string[0]) +
6362f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard		   (((unsigned int) string[1]) << 8));
6363f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	case XML_ATTRIBUTE_NODE:
6364f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	    tmp = ((xmlAttrPtr) node)->children;
6365f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	    break;
6366f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	case XML_ELEMENT_NODE:
6367f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	    tmp = node->children;
6368f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	    break;
6369f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	default:
6370f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	    return(0);
6371f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    }
6372f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    while (tmp != NULL) {
6373f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	switch (tmp->type) {
6374f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	    case XML_COMMENT_NODE:
6375f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	    case XML_PI_NODE:
6376f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	    case XML_CDATA_SECTION_NODE:
6377f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	    case XML_TEXT_NODE:
6378f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard		string = tmp->content;
6379f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard		break;
6380f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	    case XML_NAMESPACE_DECL:
6381f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard		string = ((xmlNsPtr)tmp)->href;
6382f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard		break;
6383f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	    default:
6384f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard		break;
6385f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	}
6386f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	if ((string != NULL) && (string[0] != 0)) {
6387f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	    if (len == 1) {
6388f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard		return(ret + (((unsigned int) string[0]) << 8));
6389f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	    }
6390f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	    if (string[1] == 0) {
6391f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard		len = 1;
6392f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard		ret = (unsigned int) string[0];
6393f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	    } else {
6394f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard		return(((unsigned int) string[0]) +
6395f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard		       (((unsigned int) string[1]) << 8));
6396f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	    }
6397f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	}
6398f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	/*
6399f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	 * Skip to next node
6400f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	 */
6401f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	if ((tmp->children != NULL) && (tmp->type != XML_DTD_NODE)) {
6402f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	    if (tmp->children->type != XML_ENTITY_DECL) {
6403f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard		tmp = tmp->children;
6404f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard		continue;
6405f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	    }
6406f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	}
6407f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	if (tmp == node)
6408f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	    break;
6409f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
6410f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	if (tmp->next != NULL) {
6411f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	    tmp = tmp->next;
6412f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	    continue;
6413f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	}
641445490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
6415f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	do {
6416f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	    tmp = tmp->parent;
6417f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	    if (tmp == NULL)
6418f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard		break;
6419f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	    if (tmp == node) {
6420f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard		tmp = NULL;
6421f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard		break;
6422f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	    }
6423f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	    if (tmp->next != NULL) {
6424f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard		tmp = tmp->next;
6425f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard		break;
6426f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	    }
6427f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	} while (tmp != NULL);
6428f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    }
6429f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    return(ret);
6430f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard}
6431f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
6432f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard/**
6433f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * xmlXPathStringHash:
6434f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * @string:  a string
6435f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard *
6436f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Function computing the beginning of the string value of the node,
6437f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * used to speed up comparisons
6438f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard *
6439f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Returns an int usable as a hash
6440f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */
6441f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillardstatic unsigned int
6442f06307e2c172284bb41376c396f757bdac9bdd19Daniel VeillardxmlXPathStringHash(const xmlChar * string) {
6443f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    if (string == NULL)
6444f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	return((unsigned int) 0);
6445f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    if (string[0] == 0)
6446f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	return(0);
6447f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    return(((unsigned int) string[0]) +
6448f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	   (((unsigned int) string[1]) << 8));
6449f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard}
6450f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
6451f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard/**
64523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathCompareNodeSetFloat:
64533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
64543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @inf:  less than (1) or greater than (0)
64553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @strict:  is the comparison strict
64563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @arg:  the node set
64573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @f:  the value
64583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
64593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the compare operation between a nodeset and a number
64603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *     @ns < @val    (1, 1, ...
64613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *     @ns <= @val   (1, 0, ...
64623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *     @ns > @val    (0, 1, ...
64633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *     @ns >= @val   (0, 0, ...
64643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
64653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * If one object to be compared is a node-set and the other is a number,
64663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * then the comparison will be true if and only if there is a node in the
64673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * node-set such that the result of performing the comparison on the number
64683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * to be compared and on the result of converting the string-value of that
64693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * node to a number using the number function is true.
64703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
64713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns 0 or 1 depending on the results of the test.
64723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
647356a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic int
64743473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathCompareNodeSetFloat(xmlXPathParserContextPtr ctxt, int inf, int strict,
64753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	                    xmlXPathObjectPtr arg, xmlXPathObjectPtr f) {
64763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    int i, ret = 0;
64773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlNodeSetPtr ns;
64783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlChar *str2;
64793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
64803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if ((f == NULL) || (arg == NULL) ||
64813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	((arg->type != XPATH_NODESET) && (arg->type != XPATH_XSLT_TREE))) {
6482a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	xmlXPathReleaseObject(ctxt->context, arg);
6483a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	xmlXPathReleaseObject(ctxt->context, f);
64843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        return(0);
64853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
64863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ns = arg->nodesetval;
6487911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard    if (ns != NULL) {
6488911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard	for (i = 0;i < ns->nodeNr;i++) {
6489ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	     str2 = xmlXPathCastNodeToString(ns->nodeTab[i]);
6490911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard	     if (str2 != NULL) {
6491911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard		 valuePush(ctxt,
6492a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik			   xmlXPathCacheNewString(ctxt->context, str2));
6493911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard		 xmlFree(str2);
6494911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard		 xmlXPathNumberFunction(ctxt, 1);
6495a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		 valuePush(ctxt, xmlXPathCacheObjectCopy(ctxt->context, f));
6496911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard		 ret = xmlXPathCompareValues(ctxt, inf, strict);
6497911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard		 if (ret)
6498911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard		     break;
6499911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard	     }
6500911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard	}
65013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
6502a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathReleaseObject(ctxt->context, arg);
6503a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathReleaseObject(ctxt->context, f);
65043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(ret);
65053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
65063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
65073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
65083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathCompareNodeSetString:
65093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
65103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @inf:  less than (1) or greater than (0)
65113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @strict:  is the comparison strict
65123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @arg:  the node set
65133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @s:  the value
65143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
65153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the compare operation between a nodeset and a string
65163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *     @ns < @val    (1, 1, ...
65173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *     @ns <= @val   (1, 0, ...
65183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *     @ns > @val    (0, 1, ...
65193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *     @ns >= @val   (0, 0, ...
65203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
65213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * If one object to be compared is a node-set and the other is a string,
65223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * then the comparison will be true if and only if there is a node in
65233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the node-set such that the result of performing the comparison on the
65243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * string-value of the node and the other string is true.
65253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
65263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns 0 or 1 depending on the results of the test.
65273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
652856a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic int
65293473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathCompareNodeSetString(xmlXPathParserContextPtr ctxt, int inf, int strict,
65303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	                    xmlXPathObjectPtr arg, xmlXPathObjectPtr s) {
65313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    int i, ret = 0;
65323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlNodeSetPtr ns;
65333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlChar *str2;
65343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
65353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if ((s == NULL) || (arg == NULL) ||
65363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	((arg->type != XPATH_NODESET) && (arg->type != XPATH_XSLT_TREE))) {
6537a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	xmlXPathReleaseObject(ctxt->context, arg);
6538a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	xmlXPathReleaseObject(ctxt->context, s);
65393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        return(0);
65403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
65413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ns = arg->nodesetval;
6542911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard    if (ns != NULL) {
6543911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard	for (i = 0;i < ns->nodeNr;i++) {
6544ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	     str2 = xmlXPathCastNodeToString(ns->nodeTab[i]);
6545911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard	     if (str2 != NULL) {
6546911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard		 valuePush(ctxt,
6547a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik			   xmlXPathCacheNewString(ctxt->context, str2));
6548911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard		 xmlFree(str2);
6549a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		 valuePush(ctxt, xmlXPathCacheObjectCopy(ctxt->context, s));
6550911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard		 ret = xmlXPathCompareValues(ctxt, inf, strict);
6551911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard		 if (ret)
6552911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard		     break;
6553911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard	     }
6554911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard	}
65553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
6556a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathReleaseObject(ctxt->context, arg);
6557a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathReleaseObject(ctxt->context, s);
65583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(ret);
65593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
65603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
65613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
65623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathCompareNodeSets:
6563ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @inf:  less than (1) or greater than (0)
65643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @strict:  is the comparison strict
6565cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * @arg1:  the first node set object
65663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @arg2:  the second node set object
65673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
65683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the compare operation on nodesets:
65693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
65703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * If both objects to be compared are node-sets, then the comparison
65713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * will be true if and only if there is a node in the first node-set
65723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * and a node in the second node-set such that the result of performing
657345490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard * the comparison on the string-values of the two nodes is true.
65743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * ....
65753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * When neither object to be compared is a node-set and the operator
65763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * is <=, <, >= or >, then the objects are compared by converting both
65773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * objects to numbers and comparing the numbers according to IEEE 754.
65783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * ....
65793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The number function converts its argument to a number as follows:
65803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *  - a string that consists of optional whitespace followed by an
65813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *    optional minus sign followed by a Number followed by whitespace
65823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *    is converted to the IEEE 754 number that is nearest (according
65833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *    to the IEEE 754 round-to-nearest rule) to the mathematical value
65843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *    represented by the string; any other string is converted to NaN
65853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
65863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Conclusion all nodes need to be converted first to their string value
658745490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard * and then the comparison must be done when possible
65883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
658956a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic int
659056a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel VeillardxmlXPathCompareNodeSets(int inf, int strict,
65913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	                xmlXPathObjectPtr arg1, xmlXPathObjectPtr arg2) {
65923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    int i, j, init = 0;
65933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    double val1;
65943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    double *values2;
65953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    int ret = 0;
65963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlNodeSetPtr ns1;
65973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlNodeSetPtr ns2;
65983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
65993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if ((arg1 == NULL) ||
66004dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard	((arg1->type != XPATH_NODESET) && (arg1->type != XPATH_XSLT_TREE))) {
66014dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard	xmlXPathFreeObject(arg2);
66023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        return(0);
66034dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard    }
66043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if ((arg2 == NULL) ||
66054dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard	((arg2->type != XPATH_NODESET) && (arg2->type != XPATH_XSLT_TREE))) {
66064dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard	xmlXPathFreeObject(arg1);
66074dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard	xmlXPathFreeObject(arg2);
66083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        return(0);
66094dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard    }
66103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
66113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ns1 = arg1->nodesetval;
66123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ns2 = arg2->nodesetval;
66133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
6614d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard    if ((ns1 == NULL) || (ns1->nodeNr <= 0)) {
66154dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard	xmlXPathFreeObject(arg1);
66164dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard	xmlXPathFreeObject(arg2);
66173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(0);
66184dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard    }
6619d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard    if ((ns2 == NULL) || (ns2->nodeNr <= 0)) {
66204dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard	xmlXPathFreeObject(arg1);
66214dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard	xmlXPathFreeObject(arg2);
66223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(0);
66234dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard    }
66243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
66253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    values2 = (double *) xmlMalloc(ns2->nodeNr * sizeof(double));
66263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (values2 == NULL) {
6627d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard        xmlXPathErrMemory(NULL, "comparing nodesets\n");
66284dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard	xmlXPathFreeObject(arg1);
66294dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard	xmlXPathFreeObject(arg2);
66303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(0);
66313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
66323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    for (i = 0;i < ns1->nodeNr;i++) {
6633ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	val1 = xmlXPathCastNodeToNumber(ns1->nodeTab[i]);
6634cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard	if (xmlXPathIsNaN(val1))
66353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    continue;
66363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	for (j = 0;j < ns2->nodeNr;j++) {
66373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    if (init == 0) {
6638ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard		values2[j] = xmlXPathCastNodeToNumber(ns2->nodeTab[j]);
66393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    }
6640cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard	    if (xmlXPathIsNaN(values2[j]))
66413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		continue;
664245490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	    if (inf && strict)
66433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		ret = (val1 < values2[j]);
66443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    else if (inf && !strict)
66453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		ret = (val1 <= values2[j]);
66463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    else if (!inf && strict)
66473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		ret = (val1 > values2[j]);
66483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    else if (!inf && !strict)
66493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		ret = (val1 >= values2[j]);
66503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    if (ret)
66513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		break;
66523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
66533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (ret)
66543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    break;
66553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	init = 1;
66563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
66573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlFree(values2);
66584dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard    xmlXPathFreeObject(arg1);
66594dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard    xmlXPathFreeObject(arg2);
66603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(ret);
66613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
66623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
66633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
66643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathCompareNodeSetValue:
66653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
66663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @inf:  less than (1) or greater than (0)
66673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @strict:  is the comparison strict
66683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @arg:  the node set
66693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val:  the value
66703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
66713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the compare operation between a nodeset and a value
66723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *     @ns < @val    (1, 1, ...
66733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *     @ns <= @val   (1, 0, ...
66743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *     @ns > @val    (0, 1, ...
66753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *     @ns >= @val   (0, 0, ...
66763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
66773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * If one object to be compared is a node-set and the other is a boolean,
66783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * then the comparison will be true if and only if the result of performing
66793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the comparison on the boolean and on the result of converting
66803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the node-set to a boolean using the boolean function is true.
66813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
66823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns 0 or 1 depending on the results of the test.
66833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
668456a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic int
66853473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathCompareNodeSetValue(xmlXPathParserContextPtr ctxt, int inf, int strict,
66863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	                    xmlXPathObjectPtr arg, xmlXPathObjectPtr val) {
66873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if ((val == NULL) || (arg == NULL) ||
66883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	((arg->type != XPATH_NODESET) && (arg->type != XPATH_XSLT_TREE)))
66893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        return(0);
66903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
66913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    switch(val->type) {
66923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        case XPATH_NUMBER:
66933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    return(xmlXPathCompareNodeSetFloat(ctxt, inf, strict, arg, val));
66943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        case XPATH_NODESET:
66953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        case XPATH_XSLT_TREE:
669656a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillard	    return(xmlXPathCompareNodeSets(inf, strict, arg, val));
66973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        case XPATH_STRING:
66983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    return(xmlXPathCompareNodeSetString(ctxt, inf, strict, arg, val));
66993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        case XPATH_BOOLEAN:
67003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    valuePush(ctxt, arg);
67013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    xmlXPathBooleanFunction(ctxt, 1);
67023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    valuePush(ctxt, val);
67033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    return(xmlXPathCompareValues(ctxt, inf, strict));
67043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	default:
67053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    TODO
67063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
67073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(0);
67083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
67093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
67103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
671101c13b5be2d249ef66d86585adee87901bb8efa2Daniel Veillard * xmlXPathEqualNodeSetString:
67123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @arg:  the nodeset object argument
67133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @str:  the string to compare to.
67140c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack * @neq:  flag to show whether for '=' (0) or '!=' (1)
67153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
67163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the equal operation on XPath objects content: @arg1 == @arg2
67173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * If one object to be compared is a node-set and the other is a string,
67183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * then the comparison will be true if and only if there is a node in
67193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the node-set such that the result of performing the comparison on the
67203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * string-value of the node and the other string is true.
67213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
67223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns 0 or 1 depending on the results of the test.
67233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
672456a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic int
67250c022ad8234a9228288c651f5e6a9bce7efcd789William M. BrackxmlXPathEqualNodeSetString(xmlXPathObjectPtr arg, const xmlChar * str, int neq)
6726f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard{
67273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    int i;
67283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlNodeSetPtr ns;
67293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlChar *str2;
6730f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    unsigned int hash;
67313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
67323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if ((str == NULL) || (arg == NULL) ||
6733f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        ((arg->type != XPATH_NODESET) && (arg->type != XPATH_XSLT_TREE)))
6734f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        return (0);
67353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ns = arg->nodesetval;
6736c125a721a4b7856f5356334137d467f95e6bf4b2William M. Brack    /*
6737c125a721a4b7856f5356334137d467f95e6bf4b2William M. Brack     * A NULL nodeset compared with a string is always false
6738c125a721a4b7856f5356334137d467f95e6bf4b2William M. Brack     * (since there is no node equal, and no node not equal)
6739c125a721a4b7856f5356334137d467f95e6bf4b2William M. Brack     */
6740c125a721a4b7856f5356334137d467f95e6bf4b2William M. Brack    if ((ns == NULL) || (ns->nodeNr <= 0) )
6741f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        return (0);
6742c125a721a4b7856f5356334137d467f95e6bf4b2William M. Brack    hash = xmlXPathStringHash(str);
6743f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    for (i = 0; i < ns->nodeNr; i++) {
6744f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        if (xmlXPathNodeValHash(ns->nodeTab[i]) == hash) {
6745f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            str2 = xmlNodeGetContent(ns->nodeTab[i]);
6746f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            if ((str2 != NULL) && (xmlStrEqual(str, str2))) {
6747f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                xmlFree(str2);
67480c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		if (neq)
67490c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		    continue;
6750f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                return (1);
67519adc0469d4691e798ea4ad59b84c874cdea8b38dDaniel Veillard	    } else if ((str2 == NULL) && (xmlStrEqual(str, BAD_CAST ""))) {
67529adc0469d4691e798ea4ad59b84c874cdea8b38dDaniel Veillard		if (neq)
67539adc0469d4691e798ea4ad59b84c874cdea8b38dDaniel Veillard		    continue;
67549adc0469d4691e798ea4ad59b84c874cdea8b38dDaniel Veillard                return (1);
67550c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack            } else if (neq) {
67560c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		if (str2 != NULL)
67570c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		    xmlFree(str2);
67580c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		return (1);
67590c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	    }
6760f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            if (str2 != NULL)
6761f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                xmlFree(str2);
67620c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack        } else if (neq)
67630c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	    return (1);
67643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
6765f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    return (0);
67663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
67673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
67683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
676901c13b5be2d249ef66d86585adee87901bb8efa2Daniel Veillard * xmlXPathEqualNodeSetFloat:
67703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @arg:  the nodeset object argument
67713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @f:  the float to compare to
67720c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack * @neq:  flag to show whether to compare '=' (0) or '!=' (1)
67733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
67743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the equal operation on XPath objects content: @arg1 == @arg2
67753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * If one object to be compared is a node-set and the other is a number,
67763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * then the comparison will be true if and only if there is a node in
67773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the node-set such that the result of performing the comparison on the
67783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * number to be compared and on the result of converting the string-value
67793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * of that node to a number using the number function is true.
67803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
67813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns 0 or 1 depending on the results of the test.
67823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
678356a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic int
67840c022ad8234a9228288c651f5e6a9bce7efcd789William M. BrackxmlXPathEqualNodeSetFloat(xmlXPathParserContextPtr ctxt,
67850c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack    xmlXPathObjectPtr arg, double f, int neq) {
67860c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack  int i, ret=0;
67870c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack  xmlNodeSetPtr ns;
67880c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack  xmlChar *str2;
67890c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack  xmlXPathObjectPtr val;
67900c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack  double v;
67913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
67923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if ((arg == NULL) ||
67933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	((arg->type != XPATH_NODESET) && (arg->type != XPATH_XSLT_TREE)))
67943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        return(0);
67953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
67960c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack    ns = arg->nodesetval;
67970c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack    if (ns != NULL) {
67980c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	for (i=0;i<ns->nodeNr;i++) {
67990c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	    str2 = xmlXPathCastNodeToString(ns->nodeTab[i]);
68000c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	    if (str2 != NULL) {
6801a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		valuePush(ctxt, xmlXPathCacheNewString(ctxt->context, str2));
68020c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		xmlFree(str2);
68030c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		xmlXPathNumberFunction(ctxt, 1);
68040c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		val = valuePop(ctxt);
68050c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		v = val->floatval;
6806a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		xmlXPathReleaseObject(ctxt->context, val);
68070c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		if (!xmlXPathIsNaN(v)) {
68080c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		    if ((!neq) && (v==f)) {
68090c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack			ret = 1;
68100c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack			break;
68110c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		    } else if ((neq) && (v!=f)) {
68120c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack			ret = 1;
68130c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack			break;
68140c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		    }
681532f0f717d1e7854d87e03b659e772fa48ec9f91aWilliam M. Brack		} else {	/* NaN is unequal to any value */
681632f0f717d1e7854d87e03b659e772fa48ec9f91aWilliam M. Brack		    if (neq)
681732f0f717d1e7854d87e03b659e772fa48ec9f91aWilliam M. Brack			ret = 1;
68180c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		}
68190c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	    }
68200c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	}
68210c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack    }
68220c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack
68230c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack    return(ret);
68243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
68253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
68263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
68273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
682801c13b5be2d249ef66d86585adee87901bb8efa2Daniel Veillard * xmlXPathEqualNodeSets:
68293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @arg1:  first nodeset object argument
68303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @arg2:  second nodeset object argument
68310c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack * @neq:   flag to show whether to test '=' (0) or '!=' (1)
68323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
68330c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack * Implement the equal / not equal operation on XPath nodesets:
68340c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack * @arg1 == @arg2  or  @arg1 != @arg2
68353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * If both objects to be compared are node-sets, then the comparison
68363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * will be true if and only if there is a node in the first node-set and
68373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * a node in the second node-set such that the result of performing the
68383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * comparison on the string-values of the two nodes is true.
68393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
68403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * (needless to say, this is a costly operation)
68413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
68423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns 0 or 1 depending on the results of the test.
68433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
684456a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic int
68450c022ad8234a9228288c651f5e6a9bce7efcd789William M. BrackxmlXPathEqualNodeSets(xmlXPathObjectPtr arg1, xmlXPathObjectPtr arg2, int neq) {
68463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    int i, j;
6847f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    unsigned int *hashs1;
6848f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    unsigned int *hashs2;
68493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlChar **values1;
68503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlChar **values2;
68513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    int ret = 0;
68523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlNodeSetPtr ns1;
68533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlNodeSetPtr ns2;
68543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
68553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if ((arg1 == NULL) ||
68563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	((arg1->type != XPATH_NODESET) && (arg1->type != XPATH_XSLT_TREE)))
68573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        return(0);
68583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if ((arg2 == NULL) ||
68593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	((arg2->type != XPATH_NODESET) && (arg2->type != XPATH_XSLT_TREE)))
68603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        return(0);
68613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
68623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ns1 = arg1->nodesetval;
68633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ns2 = arg2->nodesetval;
68643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
6865911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard    if ((ns1 == NULL) || (ns1->nodeNr <= 0))
68663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(0);
6867911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard    if ((ns2 == NULL) || (ns2->nodeNr <= 0))
68683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(0);
68693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
68703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    /*
68710c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack     * for equal, check if there is a node pertaining to both sets
68723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor     */
68730c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack    if (neq == 0)
68740c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	for (i = 0;i < ns1->nodeNr;i++)
68750c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	    for (j = 0;j < ns2->nodeNr;j++)
68760c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		if (ns1->nodeTab[i] == ns2->nodeTab[j])
68770c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		    return(1);
68783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
68793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    values1 = (xmlChar **) xmlMalloc(ns1->nodeNr * sizeof(xmlChar *));
6880d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard    if (values1 == NULL) {
6881d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard        xmlXPathErrMemory(NULL, "comparing nodesets\n");
68823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(0);
6883d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard    }
6884f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    hashs1 = (unsigned int *) xmlMalloc(ns1->nodeNr * sizeof(unsigned int));
6885f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    if (hashs1 == NULL) {
6886d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard        xmlXPathErrMemory(NULL, "comparing nodesets\n");
6887f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	xmlFree(values1);
6888f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	return(0);
6889f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    }
68903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    memset(values1, 0, ns1->nodeNr * sizeof(xmlChar *));
68913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    values2 = (xmlChar **) xmlMalloc(ns2->nodeNr * sizeof(xmlChar *));
68923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (values2 == NULL) {
6893d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard        xmlXPathErrMemory(NULL, "comparing nodesets\n");
6894f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	xmlFree(hashs1);
68953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	xmlFree(values1);
68963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(0);
68973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
6898f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    hashs2 = (unsigned int *) xmlMalloc(ns2->nodeNr * sizeof(unsigned int));
6899f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    if (hashs2 == NULL) {
6900d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard        xmlXPathErrMemory(NULL, "comparing nodesets\n");
6901f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	xmlFree(hashs1);
6902f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	xmlFree(values1);
6903f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	xmlFree(values2);
6904f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	return(0);
6905f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    }
69063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    memset(values2, 0, ns2->nodeNr * sizeof(xmlChar *));
69073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    for (i = 0;i < ns1->nodeNr;i++) {
6908f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	hashs1[i] = xmlXPathNodeValHash(ns1->nodeTab[i]);
69093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	for (j = 0;j < ns2->nodeNr;j++) {
69103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    if (i == 0)
6911f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard		hashs2[j] = xmlXPathNodeValHash(ns2->nodeTab[j]);
69120c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	    if (hashs1[i] != hashs2[j]) {
69130c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		if (neq) {
69140c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		    ret = 1;
69150c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		    break;
69160c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		}
69170c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	    }
69180c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	    else {
6919f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard		if (values1[i] == NULL)
6920f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard		    values1[i] = xmlNodeGetContent(ns1->nodeTab[i]);
6921f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard		if (values2[j] == NULL)
6922f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard		    values2[j] = xmlNodeGetContent(ns2->nodeTab[j]);
69230c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		ret = xmlStrEqual(values1[i], values2[j]) ^ neq;
6924f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard		if (ret)
6925f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard		    break;
6926f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	    }
69273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
69283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (ret)
69293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    break;
69303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
69313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    for (i = 0;i < ns1->nodeNr;i++)
69323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (values1[i] != NULL)
69333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    xmlFree(values1[i]);
69343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    for (j = 0;j < ns2->nodeNr;j++)
69353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (values2[j] != NULL)
69363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    xmlFree(values2[j]);
69373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlFree(values1);
69383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlFree(values2);
6939f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    xmlFree(hashs1);
6940f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    xmlFree(hashs2);
69413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(ret);
69423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
69433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
69440c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brackstatic int
69450c022ad8234a9228288c651f5e6a9bce7efcd789William M. BrackxmlXPathEqualValuesCommon(xmlXPathParserContextPtr ctxt,
69460c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack  xmlXPathObjectPtr arg1, xmlXPathObjectPtr arg2) {
69473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    int ret = 0;
69480c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack    /*
69490c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack     *At this point we are assured neither arg1 nor arg2
69500c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack     *is a nodeset, so we can just pick the appropriate routine.
69510c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack     */
69523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    switch (arg1->type) {
69533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        case XPATH_UNDEFINED:
69543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_EXPR
69553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    xmlGenericError(xmlGenericErrorContext,
69563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    "Equal: undefined\n");
69573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif
69583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    break;
69593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        case XPATH_BOOLEAN:
69603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    switch (arg2->type) {
69613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	        case XPATH_UNDEFINED:
69623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_EXPR
69633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    xmlGenericError(xmlGenericErrorContext,
69643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor			    "Equal: undefined\n");
69653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif
69663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    break;
69673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		case XPATH_BOOLEAN:
69683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_EXPR
69693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    xmlGenericError(xmlGenericErrorContext,
69703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor			    "Equal: %d boolean %d \n",
69713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor			    arg1->boolval, arg2->boolval);
69723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif
69733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    ret = (arg1->boolval == arg2->boolval);
69743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    break;
69753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		case XPATH_NUMBER:
6976ef61d208503e41688f4bf86f6e9023c70e65829bWilliam M. Brack		    ret = (arg1->boolval ==
6977ef61d208503e41688f4bf86f6e9023c70e65829bWilliam M. Brack			   xmlXPathCastNumberToBoolean(arg2->floatval));
69783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    break;
69793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		case XPATH_STRING:
69803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    if ((arg2->stringval == NULL) ||
69813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor			(arg2->stringval[0] == 0)) ret = 0;
698245490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard		    else
69833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor			ret = 1;
69843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    ret = (arg1->boolval == ret);
69853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    break;
69863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		case XPATH_USERS:
69873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		case XPATH_POINT:
69883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		case XPATH_RANGE:
69893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		case XPATH_LOCATIONSET:
69903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    TODO
69913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    break;
69920c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		case XPATH_NODESET:
69930c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		case XPATH_XSLT_TREE:
69940c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		    break;
69953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    }
69963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    break;
69973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        case XPATH_NUMBER:
69983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    switch (arg2->type) {
69993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	        case XPATH_UNDEFINED:
70003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_EXPR
70013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    xmlGenericError(xmlGenericErrorContext,
70023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor			    "Equal: undefined\n");
70033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif
70043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    break;
70053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		case XPATH_BOOLEAN:
7006ef61d208503e41688f4bf86f6e9023c70e65829bWilliam M. Brack		    ret = (arg2->boolval==
7007ef61d208503e41688f4bf86f6e9023c70e65829bWilliam M. Brack			   xmlXPathCastNumberToBoolean(arg1->floatval));
70083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    break;
70093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		case XPATH_STRING:
70103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    valuePush(ctxt, arg2);
70113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    xmlXPathNumberFunction(ctxt, 1);
70123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    arg2 = valuePop(ctxt);
70133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    /* no break on purpose */
70143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		case XPATH_NUMBER:
7015d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard		    /* Hand check NaN and Infinity equalities */
7016081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack		    if (xmlXPathIsNaN(arg1->floatval) ||
701745490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard			    xmlXPathIsNaN(arg2->floatval)) {
701821458c85e209cd2621ac3eadfee075ae2dc0121dDaniel Veillard		        ret = 0;
7019d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard		    } else if (xmlXPathIsInf(arg1->floatval) == 1) {
7020d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard		        if (xmlXPathIsInf(arg2->floatval) == 1)
7021d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard			    ret = 1;
7022d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard			else
7023d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard			    ret = 0;
7024d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard		    } else if (xmlXPathIsInf(arg1->floatval) == -1) {
7025d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard			if (xmlXPathIsInf(arg2->floatval) == -1)
7026d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard			    ret = 1;
7027d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard			else
7028d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard			    ret = 0;
7029d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard		    } else if (xmlXPathIsInf(arg2->floatval) == 1) {
7030d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard			if (xmlXPathIsInf(arg1->floatval) == 1)
7031d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard			    ret = 1;
7032d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard			else
7033d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard			    ret = 0;
7034d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard		    } else if (xmlXPathIsInf(arg2->floatval) == -1) {
7035d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard			if (xmlXPathIsInf(arg1->floatval) == -1)
7036d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard			    ret = 1;
7037d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard			else
7038d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard			    ret = 0;
703921458c85e209cd2621ac3eadfee075ae2dc0121dDaniel Veillard		    } else {
704021458c85e209cd2621ac3eadfee075ae2dc0121dDaniel Veillard		        ret = (arg1->floatval == arg2->floatval);
704121458c85e209cd2621ac3eadfee075ae2dc0121dDaniel Veillard		    }
70423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    break;
70433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		case XPATH_USERS:
70443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		case XPATH_POINT:
70453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		case XPATH_RANGE:
70463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		case XPATH_LOCATIONSET:
70473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    TODO
70483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    break;
70490c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		case XPATH_NODESET:
70500c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		case XPATH_XSLT_TREE:
70510c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		    break;
70523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    }
70533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    break;
70543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        case XPATH_STRING:
70553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    switch (arg2->type) {
70563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	        case XPATH_UNDEFINED:
70573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_EXPR
70583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    xmlGenericError(xmlGenericErrorContext,
70593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor			    "Equal: undefined\n");
70603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif
70613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    break;
70623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		case XPATH_BOOLEAN:
70633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    if ((arg1->stringval == NULL) ||
70643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor			(arg1->stringval[0] == 0)) ret = 0;
706545490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard		    else
70663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor			ret = 1;
70673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    ret = (arg2->boolval == ret);
70683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    break;
70693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		case XPATH_STRING:
70703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    ret = xmlStrEqual(arg1->stringval, arg2->stringval);
70713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    break;
70723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		case XPATH_NUMBER:
70733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    valuePush(ctxt, arg1);
70743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    xmlXPathNumberFunction(ctxt, 1);
70753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    arg1 = valuePop(ctxt);
7076d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard		    /* Hand check NaN and Infinity equalities */
7077081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack		    if (xmlXPathIsNaN(arg1->floatval) ||
707845490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard			    xmlXPathIsNaN(arg2->floatval)) {
707921458c85e209cd2621ac3eadfee075ae2dc0121dDaniel Veillard		        ret = 0;
7080d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard		    } else if (xmlXPathIsInf(arg1->floatval) == 1) {
7081d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard			if (xmlXPathIsInf(arg2->floatval) == 1)
7082d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard			    ret = 1;
7083d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard			else
7084d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard			    ret = 0;
7085d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard		    } else if (xmlXPathIsInf(arg1->floatval) == -1) {
7086d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard			if (xmlXPathIsInf(arg2->floatval) == -1)
7087d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard			    ret = 1;
7088d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard			else
7089d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard			    ret = 0;
7090d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard		    } else if (xmlXPathIsInf(arg2->floatval) == 1) {
7091d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard			if (xmlXPathIsInf(arg1->floatval) == 1)
7092d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard			    ret = 1;
7093d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard			else
7094d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard			    ret = 0;
7095d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard		    } else if (xmlXPathIsInf(arg2->floatval) == -1) {
7096d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard			if (xmlXPathIsInf(arg1->floatval) == -1)
7097d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard			    ret = 1;
7098d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard			else
7099d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard			    ret = 0;
710021458c85e209cd2621ac3eadfee075ae2dc0121dDaniel Veillard		    } else {
710121458c85e209cd2621ac3eadfee075ae2dc0121dDaniel Veillard		        ret = (arg1->floatval == arg2->floatval);
710221458c85e209cd2621ac3eadfee075ae2dc0121dDaniel Veillard		    }
71033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    break;
71043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		case XPATH_USERS:
71053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		case XPATH_POINT:
71063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		case XPATH_RANGE:
71073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		case XPATH_LOCATIONSET:
71083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    TODO
71093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    break;
71100c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		case XPATH_NODESET:
71110c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		case XPATH_XSLT_TREE:
71120c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		    break;
71133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    }
71143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    break;
71153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        case XPATH_USERS:
71163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XPATH_POINT:
71173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XPATH_RANGE:
71183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XPATH_LOCATIONSET:
71193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    TODO
71203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    break;
71210c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	case XPATH_NODESET:
71220c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	case XPATH_XSLT_TREE:
71230c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	    break;
71243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
7125a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathReleaseObject(ctxt->context, arg1);
7126a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathReleaseObject(ctxt->context, arg2);
71273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(ret);
71283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
71293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
71300c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack/**
71310c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack * xmlXPathEqualValues:
71320c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack * @ctxt:  the XPath Parser context
71330c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack *
71340c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack * Implement the equal operation on XPath objects content: @arg1 == @arg2
71350c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack *
71360c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack * Returns 0 or 1 depending on the results of the test.
71370c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack */
71380c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brackint
71390c022ad8234a9228288c651f5e6a9bce7efcd789William M. BrackxmlXPathEqualValues(xmlXPathParserContextPtr ctxt) {
71400c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack    xmlXPathObjectPtr arg1, arg2, argtmp;
71410c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack    int ret = 0;
71420c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack
71436128c01ca6a5c1d67970b44cd11aa95a392d8a2dDaniel Veillard    if ((ctxt == NULL) || (ctxt->context == NULL)) return(0);
714445490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard    arg2 = valuePop(ctxt);
71450c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack    arg1 = valuePop(ctxt);
71460c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack    if ((arg1 == NULL) || (arg2 == NULL)) {
71470c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	if (arg1 != NULL)
7148a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathReleaseObject(ctxt->context, arg1);
71490c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	else
7150a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathReleaseObject(ctxt->context, arg2);
71510c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	XP_ERROR0(XPATH_INVALID_OPERAND);
71520c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack    }
71530c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack
71540c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack    if (arg1 == arg2) {
71550c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack#ifdef DEBUG_EXPR
71560c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack        xmlGenericError(xmlGenericErrorContext,
71570c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		"Equal: by pointer\n");
71580c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack#endif
71592c19a7bf2ee0f78485840cac50f2a989f5efe476William M. Brack	xmlXPathFreeObject(arg1);
71600c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack        return(1);
71610c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack    }
71620c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack
71630c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack    /*
71640c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack     *If either argument is a nodeset, it's a 'special case'
71650c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack     */
71660c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack    if ((arg2->type == XPATH_NODESET) || (arg2->type == XPATH_XSLT_TREE) ||
71670c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack      (arg1->type == XPATH_NODESET) || (arg1->type == XPATH_XSLT_TREE)) {
71680c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	/*
71690c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	 *Hack it to assure arg1 is the nodeset
71700c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	 */
71710c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	if ((arg1->type != XPATH_NODESET) && (arg1->type != XPATH_XSLT_TREE)) {
71720c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		argtmp = arg2;
71730c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		arg2 = arg1;
71740c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		arg1 = argtmp;
71750c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	}
71760c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	switch (arg2->type) {
71770c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	    case XPATH_UNDEFINED:
71780c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack#ifdef DEBUG_EXPR
71790c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		xmlGenericError(xmlGenericErrorContext,
71800c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack			"Equal: undefined\n");
71810c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack#endif
71820c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		break;
71830c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	    case XPATH_NODESET:
71840c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	    case XPATH_XSLT_TREE:
71850c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		ret = xmlXPathEqualNodeSets(arg1, arg2, 0);
71860c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		break;
71870c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	    case XPATH_BOOLEAN:
71880c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		if ((arg1->nodesetval == NULL) ||
71890c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		  (arg1->nodesetval->nodeNr == 0)) ret = 0;
719045490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard		else
71910c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		    ret = 1;
71920c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		ret = (ret == arg2->boolval);
71930c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		break;
71940c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	    case XPATH_NUMBER:
71950c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		ret = xmlXPathEqualNodeSetFloat(ctxt, arg1, arg2->floatval, 0);
71960c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		break;
71970c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	    case XPATH_STRING:
71980c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		ret = xmlXPathEqualNodeSetString(arg1, arg2->stringval, 0);
71990c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		break;
72000c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	    case XPATH_USERS:
72010c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	    case XPATH_POINT:
72020c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	    case XPATH_RANGE:
72030c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	    case XPATH_LOCATIONSET:
72040c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		TODO
72050c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		break;
72060c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	}
7207a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	xmlXPathReleaseObject(ctxt->context, arg1);
7208a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	xmlXPathReleaseObject(ctxt->context, arg2);
72090c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	return(ret);
72100c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack    }
72110c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack
72120c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack    return (xmlXPathEqualValuesCommon(ctxt, arg1, arg2));
72130c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack}
72140c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack
72150c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack/**
72160c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack * xmlXPathNotEqualValues:
72170c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack * @ctxt:  the XPath Parser context
72180c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack *
72190c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack * Implement the equal operation on XPath objects content: @arg1 == @arg2
72200c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack *
72210c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack * Returns 0 or 1 depending on the results of the test.
72220c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack */
72230c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brackint
72240c022ad8234a9228288c651f5e6a9bce7efcd789William M. BrackxmlXPathNotEqualValues(xmlXPathParserContextPtr ctxt) {
72250c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack    xmlXPathObjectPtr arg1, arg2, argtmp;
72260c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack    int ret = 0;
72270c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack
72286128c01ca6a5c1d67970b44cd11aa95a392d8a2dDaniel Veillard    if ((ctxt == NULL) || (ctxt->context == NULL)) return(0);
722945490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard    arg2 = valuePop(ctxt);
72300c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack    arg1 = valuePop(ctxt);
72310c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack    if ((arg1 == NULL) || (arg2 == NULL)) {
72320c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	if (arg1 != NULL)
7233a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathReleaseObject(ctxt->context, arg1);
72340c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	else
7235a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathReleaseObject(ctxt->context, arg2);
72360c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	XP_ERROR0(XPATH_INVALID_OPERAND);
72370c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack    }
72380c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack
72390c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack    if (arg1 == arg2) {
72400c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack#ifdef DEBUG_EXPR
72410c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack        xmlGenericError(xmlGenericErrorContext,
72420c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		"NotEqual: by pointer\n");
72430c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack#endif
7244a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	xmlXPathReleaseObject(ctxt->context, arg1);
72450c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack        return(0);
72460c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack    }
72470c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack
72480c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack    /*
72490c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack     *If either argument is a nodeset, it's a 'special case'
72500c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack     */
72510c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack    if ((arg2->type == XPATH_NODESET) || (arg2->type == XPATH_XSLT_TREE) ||
72520c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack      (arg1->type == XPATH_NODESET) || (arg1->type == XPATH_XSLT_TREE)) {
72530c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	/*
72540c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	 *Hack it to assure arg1 is the nodeset
72550c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	 */
72560c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	if ((arg1->type != XPATH_NODESET) && (arg1->type != XPATH_XSLT_TREE)) {
72570c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		argtmp = arg2;
72580c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		arg2 = arg1;
72590c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		arg1 = argtmp;
72600c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	}
72610c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	switch (arg2->type) {
72620c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	    case XPATH_UNDEFINED:
72630c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack#ifdef DEBUG_EXPR
72640c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		xmlGenericError(xmlGenericErrorContext,
72650c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack			"NotEqual: undefined\n");
72660c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack#endif
72670c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		break;
72680c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	    case XPATH_NODESET:
72690c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	    case XPATH_XSLT_TREE:
72700c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		ret = xmlXPathEqualNodeSets(arg1, arg2, 1);
72710c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		break;
72720c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	    case XPATH_BOOLEAN:
72730c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		if ((arg1->nodesetval == NULL) ||
72740c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		  (arg1->nodesetval->nodeNr == 0)) ret = 0;
727545490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard		else
72760c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		    ret = 1;
7277ef61d208503e41688f4bf86f6e9023c70e65829bWilliam M. Brack		ret = (ret != arg2->boolval);
72780c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		break;
72790c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	    case XPATH_NUMBER:
72800c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		ret = xmlXPathEqualNodeSetFloat(ctxt, arg1, arg2->floatval, 1);
72810c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		break;
72820c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	    case XPATH_STRING:
72830c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		ret = xmlXPathEqualNodeSetString(arg1, arg2->stringval,1);
72840c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		break;
72850c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	    case XPATH_USERS:
72860c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	    case XPATH_POINT:
72870c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	    case XPATH_RANGE:
72880c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	    case XPATH_LOCATIONSET:
72890c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		TODO
72900c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		break;
72910c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	}
7292a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	xmlXPathReleaseObject(ctxt->context, arg1);
7293a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	xmlXPathReleaseObject(ctxt->context, arg2);
72940c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	return(ret);
72950c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack    }
72960c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack
72970c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack    return (!xmlXPathEqualValuesCommon(ctxt, arg1, arg2));
72980c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack}
72993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
73003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
73013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathCompareValues:
73023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
73033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @inf:  less than (1) or greater than (0)
73043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @strict:  is the comparison strict
73053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
730645490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard * Implement the compare operation on XPath objects:
73073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *     @arg1 < @arg2    (1, 1, ...
73083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *     @arg1 <= @arg2   (1, 0, ...
73093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *     @arg1 > @arg2    (0, 1, ...
73103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *     @arg1 >= @arg2   (0, 0, ...
73113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
73123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * When neither object to be compared is a node-set and the operator is
73133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * <=, <, >=, >, then the objects are compared by converted both objects
73143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * to numbers and comparing the numbers according to IEEE 754. The <
73153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * comparison will be true if and only if the first number is less than the
73163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * second number. The <= comparison will be true if and only if the first
73173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * number is less than or equal to the second number. The > comparison
73183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * will be true if and only if the first number is greater than the second
73193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * number. The >= comparison will be true if and only if the first number
73203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * is greater than or equal to the second number.
73213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
7322cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * Returns 1 if the comparison succeeded, 0 if it failed
73233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
73243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorint
73253473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathCompareValues(xmlXPathParserContextPtr ctxt, int inf, int strict) {
7326d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard    int ret = 0, arg1i = 0, arg2i = 0;
73273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathObjectPtr arg1, arg2;
73283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
73296128c01ca6a5c1d67970b44cd11aa95a392d8a2dDaniel Veillard    if ((ctxt == NULL) || (ctxt->context == NULL)) return(0);
733045490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard    arg2 = valuePop(ctxt);
73313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    arg1 = valuePop(ctxt);
73320c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack    if ((arg1 == NULL) || (arg2 == NULL)) {
73330c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	if (arg1 != NULL)
7334a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathReleaseObject(ctxt->context, arg1);
73350c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	else
7336a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathReleaseObject(ctxt->context, arg2);
73373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	XP_ERROR0(XPATH_INVALID_OPERAND);
73383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
73393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
73400c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack    if ((arg2->type == XPATH_NODESET) || (arg2->type == XPATH_XSLT_TREE) ||
73410c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack      (arg1->type == XPATH_NODESET) || (arg1->type == XPATH_XSLT_TREE)) {
7342d6e347e865b473f06fd431be926183c77596194aWilliam M. Brack	/*
7343d6e347e865b473f06fd431be926183c77596194aWilliam M. Brack	 * If either argument is a XPATH_NODESET or XPATH_XSLT_TREE the two arguments
7344d6e347e865b473f06fd431be926183c77596194aWilliam M. Brack	 * are not freed from within this routine; they will be freed from the
7345d6e347e865b473f06fd431be926183c77596194aWilliam M. Brack	 * called routine, e.g. xmlXPathCompareNodeSets or xmlXPathCompareNodeSetValue
7346d6e347e865b473f06fd431be926183c77596194aWilliam M. Brack	 */
73470c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	if (((arg2->type == XPATH_NODESET) || (arg2->type == XPATH_XSLT_TREE)) &&
73480c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	  ((arg1->type == XPATH_NODESET) || (arg1->type == XPATH_XSLT_TREE))){
734956a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillard	    ret = xmlXPathCompareNodeSets(inf, strict, arg1, arg2);
73503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	} else {
73510c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	    if ((arg1->type == XPATH_NODESET) || (arg1->type == XPATH_XSLT_TREE)) {
73524af6b6e801346d1c832cf19b7c3833a831871db2Daniel Veillard		ret = xmlXPathCompareNodeSetValue(ctxt, inf, strict,
73534af6b6e801346d1c832cf19b7c3833a831871db2Daniel Veillard			                          arg1, arg2);
73543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    } else {
73554af6b6e801346d1c832cf19b7c3833a831871db2Daniel Veillard		ret = xmlXPathCompareNodeSetValue(ctxt, !inf, strict,
73564af6b6e801346d1c832cf19b7c3833a831871db2Daniel Veillard			                          arg2, arg1);
73573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    }
73583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
73593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(ret);
73603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
73613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
73623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (arg1->type != XPATH_NUMBER) {
73633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	valuePush(ctxt, arg1);
73643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	xmlXPathNumberFunction(ctxt, 1);
73653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	arg1 = valuePop(ctxt);
73663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
73673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (arg1->type != XPATH_NUMBER) {
73683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	xmlXPathFreeObject(arg1);
73693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	xmlXPathFreeObject(arg2);
73703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	XP_ERROR0(XPATH_INVALID_OPERAND);
73713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
73723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (arg2->type != XPATH_NUMBER) {
73733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	valuePush(ctxt, arg2);
73743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	xmlXPathNumberFunction(ctxt, 1);
73753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	arg2 = valuePop(ctxt);
73763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
73773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (arg2->type != XPATH_NUMBER) {
7378a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	xmlXPathReleaseObject(ctxt->context, arg1);
7379a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	xmlXPathReleaseObject(ctxt->context, arg2);
73803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	XP_ERROR0(XPATH_INVALID_OPERAND);
73813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
73823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    /*
73833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor     * Add tests for infinity and nan
73843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor     * => feedback on 3.4 for Inf and NaN
73853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor     */
7386d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard    /* Hand check NaN and Infinity comparisons */
738721458c85e209cd2621ac3eadfee075ae2dc0121dDaniel Veillard    if (xmlXPathIsNaN(arg1->floatval) || xmlXPathIsNaN(arg2->floatval)) {
7388d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard	ret=0;
738921458c85e209cd2621ac3eadfee075ae2dc0121dDaniel Veillard    } else {
7390d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard	arg1i=xmlXPathIsInf(arg1->floatval);
7391d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard	arg2i=xmlXPathIsInf(arg2->floatval);
7392d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard	if (inf && strict) {
7393d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard	    if ((arg1i == -1 && arg2i != -1) ||
7394d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard		(arg2i == 1 && arg1i != 1)) {
7395d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard		ret = 1;
7396d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard	    } else if (arg1i == 0 && arg2i == 0) {
7397d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard		ret = (arg1->floatval < arg2->floatval);
7398d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard	    } else {
7399d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard		ret = 0;
7400d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard	    }
7401d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard	}
7402d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard	else if (inf && !strict) {
7403d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard	    if (arg1i == -1 || arg2i == 1) {
7404d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard		ret = 1;
7405d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard	    } else if (arg1i == 0 && arg2i == 0) {
7406d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard		ret = (arg1->floatval <= arg2->floatval);
7407d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard	    } else {
7408d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard		ret = 0;
7409d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard	    }
7410d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard	}
7411d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard	else if (!inf && strict) {
7412d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard	    if ((arg1i == 1 && arg2i != 1) ||
7413d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard		(arg2i == -1 && arg1i != -1)) {
7414d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard		ret = 1;
7415d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard	    } else if (arg1i == 0 && arg2i == 0) {
7416d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard		ret = (arg1->floatval > arg2->floatval);
7417d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard	    } else {
7418d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard		ret = 0;
7419d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard	    }
7420d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard	}
7421d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard	else if (!inf && !strict) {
7422d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard	    if (arg1i == 1 || arg2i == -1) {
7423d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard		ret = 1;
7424d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard	    } else if (arg1i == 0 && arg2i == 0) {
7425d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard		ret = (arg1->floatval >= arg2->floatval);
7426d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard	    } else {
7427d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard		ret = 0;
7428d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard	    }
7429d30be4add765e2c16840c4f2aab25f447384c7b2Daniel Veillard	}
743021458c85e209cd2621ac3eadfee075ae2dc0121dDaniel Veillard    }
7431a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathReleaseObject(ctxt->context, arg1);
7432a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathReleaseObject(ctxt->context, arg2);
74333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(ret);
74343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
74353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
74363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
74373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathValueFlipSign:
74383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
74393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
74403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the unary - operation on an XPath object
74413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The numeric operators convert their operands to numbers as if
74423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * by calling the number function.
74433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
74443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
74453473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathValueFlipSign(xmlXPathParserContextPtr ctxt) {
7446a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard    if ((ctxt == NULL) || (ctxt->context == NULL)) return;
7447ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    CAST_TO_NUMBER;
7448ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    CHECK_TYPE(XPATH_NUMBER);
7449eca82810f0fb81f3e9936d2018347e1e19de513aDaniel Veillard    if (xmlXPathIsNaN(ctxt->value->floatval))
7450eca82810f0fb81f3e9936d2018347e1e19de513aDaniel Veillard        ctxt->value->floatval=xmlXPathNAN;
7451eca82810f0fb81f3e9936d2018347e1e19de513aDaniel Veillard    else if (xmlXPathIsInf(ctxt->value->floatval) == 1)
7452eca82810f0fb81f3e9936d2018347e1e19de513aDaniel Veillard        ctxt->value->floatval=xmlXPathNINF;
7453eca82810f0fb81f3e9936d2018347e1e19de513aDaniel Veillard    else if (xmlXPathIsInf(ctxt->value->floatval) == -1)
7454eca82810f0fb81f3e9936d2018347e1e19de513aDaniel Veillard        ctxt->value->floatval=xmlXPathPINF;
7455eca82810f0fb81f3e9936d2018347e1e19de513aDaniel Veillard    else if (ctxt->value->floatval == 0) {
74565fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard        if (xmlXPathGetSign(ctxt->value->floatval) == 0)
74575fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard	    ctxt->value->floatval = xmlXPathNZERO;
74585fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard	else
74595fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard	    ctxt->value->floatval = 0;
74605fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard    }
74615fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard    else
74625fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard        ctxt->value->floatval = - ctxt->value->floatval;
74633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
74643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
74653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
74663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathAddValues:
74673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
74683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
74693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the add operation on XPath objects:
74703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The numeric operators convert their operands to numbers as if
74713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * by calling the number function.
74723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
74733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
74743473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathAddValues(xmlXPathParserContextPtr ctxt) {
74753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathObjectPtr arg;
74763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    double val;
74773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
7478ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    arg = valuePop(ctxt);
7479ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    if (arg == NULL)
7480ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	XP_ERROR(XPATH_INVALID_OPERAND);
7481ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    val = xmlXPathCastToNumber(arg);
7482a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathReleaseObject(ctxt->context, arg);
7483ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    CAST_TO_NUMBER;
7484ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    CHECK_TYPE(XPATH_NUMBER);
7485ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    ctxt->value->floatval += val;
74863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
74873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
74883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
74893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathSubValues:
74903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
74913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
7492cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * Implement the subtraction operation on XPath objects:
74933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The numeric operators convert their operands to numbers as if
74943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * by calling the number function.
74953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
74963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
74973473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathSubValues(xmlXPathParserContextPtr ctxt) {
74983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathObjectPtr arg;
74993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    double val;
75003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
7501ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    arg = valuePop(ctxt);
7502ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    if (arg == NULL)
7503ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	XP_ERROR(XPATH_INVALID_OPERAND);
7504ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    val = xmlXPathCastToNumber(arg);
7505a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathReleaseObject(ctxt->context, arg);
7506ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    CAST_TO_NUMBER;
7507ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    CHECK_TYPE(XPATH_NUMBER);
7508ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    ctxt->value->floatval -= val;
75093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
75103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
75113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
75123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathMultValues:
75133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
75143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
75153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the multiply operation on XPath objects:
75163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The numeric operators convert their operands to numbers as if
75173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * by calling the number function.
75183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
75193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
75203473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathMultValues(xmlXPathParserContextPtr ctxt) {
75213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathObjectPtr arg;
75223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    double val;
75233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
7524ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    arg = valuePop(ctxt);
7525ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    if (arg == NULL)
7526ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	XP_ERROR(XPATH_INVALID_OPERAND);
7527ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    val = xmlXPathCastToNumber(arg);
7528a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathReleaseObject(ctxt->context, arg);
7529ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    CAST_TO_NUMBER;
7530ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    CHECK_TYPE(XPATH_NUMBER);
7531ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    ctxt->value->floatval *= val;
75323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
75333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
75343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
75353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathDivValues:
75363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
75373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
75383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the div operation on XPath objects @arg1 / @arg2:
75393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The numeric operators convert their operands to numbers as if
75403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * by calling the number function.
75413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
75423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
75433473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathDivValues(xmlXPathParserContextPtr ctxt) {
75443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathObjectPtr arg;
75453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    double val;
75463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
7547ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    arg = valuePop(ctxt);
7548ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    if (arg == NULL)
7549ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	XP_ERROR(XPATH_INVALID_OPERAND);
7550ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    val = xmlXPathCastToNumber(arg);
7551a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathReleaseObject(ctxt->context, arg);
7552ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    CAST_TO_NUMBER;
7553ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    CHECK_TYPE(XPATH_NUMBER);
7554eca82810f0fb81f3e9936d2018347e1e19de513aDaniel Veillard    if (xmlXPathIsNaN(val) || xmlXPathIsNaN(ctxt->value->floatval))
7555eca82810f0fb81f3e9936d2018347e1e19de513aDaniel Veillard	ctxt->value->floatval = xmlXPathNAN;
7556eca82810f0fb81f3e9936d2018347e1e19de513aDaniel Veillard    else if (val == 0 && xmlXPathGetSign(val) != 0) {
75575fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard	if (ctxt->value->floatval == 0)
75585fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard	    ctxt->value->floatval = xmlXPathNAN;
75595fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard	else if (ctxt->value->floatval > 0)
75605fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard	    ctxt->value->floatval = xmlXPathNINF;
75615fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard	else if (ctxt->value->floatval < 0)
75625fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard	    ctxt->value->floatval = xmlXPathPINF;
75635fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard    }
75645fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard    else if (val == 0) {
75655f4b5999b4eeda2ca68e6d9f54a3c534a8474b38Daniel Veillard	if (ctxt->value->floatval == 0)
75665f4b5999b4eeda2ca68e6d9f54a3c534a8474b38Daniel Veillard	    ctxt->value->floatval = xmlXPathNAN;
75675f4b5999b4eeda2ca68e6d9f54a3c534a8474b38Daniel Veillard	else if (ctxt->value->floatval > 0)
75685f4b5999b4eeda2ca68e6d9f54a3c534a8474b38Daniel Veillard	    ctxt->value->floatval = xmlXPathPINF;
75695f4b5999b4eeda2ca68e6d9f54a3c534a8474b38Daniel Veillard	else if (ctxt->value->floatval < 0)
75705f4b5999b4eeda2ca68e6d9f54a3c534a8474b38Daniel Veillard	    ctxt->value->floatval = xmlXPathNINF;
757145490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard    } else
75725f4b5999b4eeda2ca68e6d9f54a3c534a8474b38Daniel Veillard	ctxt->value->floatval /= val;
75733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
75743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
75753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
75763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathModValues:
75773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
75783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
75793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the mod operation on XPath objects: @arg1 / @arg2
75803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The numeric operators convert their operands to numbers as if
75813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * by calling the number function.
75823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
75833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
75843473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathModValues(xmlXPathParserContextPtr ctxt) {
75853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathObjectPtr arg;
7586fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard    double arg1, arg2;
75873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
7588ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    arg = valuePop(ctxt);
7589ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    if (arg == NULL)
7590ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	XP_ERROR(XPATH_INVALID_OPERAND);
75915fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard    arg2 = xmlXPathCastToNumber(arg);
7592a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathReleaseObject(ctxt->context, arg);
7593ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    CAST_TO_NUMBER;
7594ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    CHECK_TYPE(XPATH_NUMBER);
75955fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard    arg1 = ctxt->value->floatval;
7596268fd1bc97f79b43290041cfda2287fb0b0ef2d6Daniel Veillard    if (arg2 == 0)
7597268fd1bc97f79b43290041cfda2287fb0b0ef2d6Daniel Veillard	ctxt->value->floatval = xmlXPathNAN;
75985fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard    else {
7599fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard	ctxt->value->floatval = fmod(arg1, arg2);
76005fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard    }
76013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
76023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
76033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/************************************************************************
76043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *									*
76053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *		The traversal functions					*
76063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *									*
76073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ************************************************************************/
76083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
76093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/*
76103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * A traversal function enumerates nodes along an axis.
76113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Initially it must be called with NULL, and it indicates
76123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * termination on the axis by returning NULL.
76133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
76143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylortypedef xmlNodePtr (*xmlXPathTraversalFunction)
76153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor                    (xmlXPathParserContextPtr ctxt, xmlNodePtr cur);
76163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
7617df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik/*
7618df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik * xmlXPathTraversalFunctionExt:
7619df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik * A traversal function enumerates nodes along an axis.
7620df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik * Initially it must be called with NULL, and it indicates
7621df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik * termination on the axis by returning NULL.
7622df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik * The context node of the traversal is specified via @contextNode.
7623df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik */
7624df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchciktypedef xmlNodePtr (*xmlXPathTraversalFunctionExt)
7625df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik                    (xmlNodePtr cur, xmlNodePtr contextNode);
7626df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik
76279bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik/*
76289bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik * xmlXPathNodeSetMergeFunction:
76299bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik * Used for merging node sets in xmlXPathCollectAndTest().
76309bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik */
76319bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchciktypedef xmlNodeSetPtr (*xmlXPathNodeSetMergeFunction)
76329bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		    (xmlNodeSetPtr, xmlNodeSetPtr, int);
76339bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik
7634df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik
76353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
76363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNextSelf:
76373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
76383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur:  the current node in the traversal
76393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
76403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Traversal function for the "self" direction
76413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The self axis contains just the context node itself
76423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
76433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the next element following that axis
76443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
76453473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNodePtr
76463473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNextSelf(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
7647a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard    if ((ctxt == NULL) || (ctxt->context == NULL)) return(NULL);
76483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (cur == NULL)
76493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        return(ctxt->context->node);
76503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(NULL);
76513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
76523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
76533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
76543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNextChild:
76553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
76563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur:  the current node in the traversal
76573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
76583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Traversal function for the "child" direction
76593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The child axis contains the children of the context node in document order.
76603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
76613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the next element following that axis
76623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
76633473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNodePtr
76643473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNextChild(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
7665a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard    if ((ctxt == NULL) || (ctxt->context == NULL)) return(NULL);
76663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (cur == NULL) {
76673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (ctxt->context->node == NULL) return(NULL);
76683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	switch (ctxt->context->node->type) {
76693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_ELEMENT_NODE:
76703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_TEXT_NODE:
76713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_CDATA_SECTION_NODE:
76723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_ENTITY_REF_NODE:
76733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_ENTITY_NODE:
76743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_PI_NODE:
76753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_COMMENT_NODE:
76763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_NOTATION_NODE:
76773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_DTD_NODE:
76783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		return(ctxt->context->node->children);
76793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_DOCUMENT_NODE:
76803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_DOCUMENT_TYPE_NODE:
76813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_DOCUMENT_FRAG_NODE:
76823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_HTML_DOCUMENT_NODE:
7683eae522a0d8aa9f830d2e447f29b504030dbb6bbdDaniel Veillard#ifdef LIBXML_DOCB_ENABLED
7684eae522a0d8aa9f830d2e447f29b504030dbb6bbdDaniel Veillard	    case XML_DOCB_DOCUMENT_NODE:
76853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif
76863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		return(((xmlDocPtr) ctxt->context->node)->children);
76873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    case XML_ELEMENT_DECL:
76883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    case XML_ATTRIBUTE_DECL:
76893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    case XML_ENTITY_DECL:
76903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_ATTRIBUTE_NODE:
76913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    case XML_NAMESPACE_DECL:
76923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    case XML_XINCLUDE_START:
76933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    case XML_XINCLUDE_END:
76943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		return(NULL);
76953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
76963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(NULL);
76973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
76983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if ((cur->type == XML_DOCUMENT_NODE) ||
76993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        (cur->type == XML_HTML_DOCUMENT_NODE))
77003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(NULL);
77013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(cur->next);
77023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
77033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
77043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
770575af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik * xmlXPathNextChildElement:
770675af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik * @ctxt:  the XPath Parser context
770775af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik * @cur:  the current node in the traversal
770875af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik *
770975af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik * Traversal function for the "child" direction and nodes of type element.
771075af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik * The child axis contains the children of the context node in document order.
771175af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik *
771275af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik * Returns the next element following that axis
771375af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik */
771475af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcikstatic xmlNodePtr
771575af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. BuchcikxmlXPathNextChildElement(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
771675af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik    if ((ctxt == NULL) || (ctxt->context == NULL)) return(NULL);
771775af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik    if (cur == NULL) {
771875af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik	cur = ctxt->context->node;
771975af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik	if (cur == NULL) return(NULL);
772075af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik	/*
772175af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik	* Get the first element child.
772275af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik	*/
772375af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik	switch (cur->type) {
772475af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik            case XML_ELEMENT_NODE:
772575af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik	    case XML_DOCUMENT_FRAG_NODE:
772675af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik	    case XML_ENTITY_REF_NODE: /* URGENT TODO: entify-refs as well? */
772775af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik            case XML_ENTITY_NODE:
772875af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik		cur = cur->children;
772975af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik		if (cur != NULL) {
773075af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik		    if (cur->type == XML_ELEMENT_NODE)
773175af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik			return(cur);
773275af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik		    do {
773375af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik			cur = cur->next;
773475af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik		    } while ((cur != NULL) &&
773575af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik			(cur->type != XML_ELEMENT_NODE));
773675af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik		    return(cur);
773775af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik		}
773875af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik		return(NULL);
773975af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik            case XML_DOCUMENT_NODE:
774075af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik            case XML_HTML_DOCUMENT_NODE:
774175af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik#ifdef LIBXML_DOCB_ENABLED
774275af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik	    case XML_DOCB_DOCUMENT_NODE:
774375af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik#endif
774475af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik		return(xmlDocGetRootElement((xmlDocPtr) cur));
774575af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik	    default:
774675af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik		return(NULL);
774775af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik	}
774875af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik	return(NULL);
774975af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik    }
775075af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik    /*
775175af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik    * Get the next sibling element node.
775275af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik    */
775375af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik    switch (cur->type) {
775475af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik	case XML_ELEMENT_NODE:
775575af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik	case XML_TEXT_NODE:
775675af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik	case XML_ENTITY_REF_NODE:
775775af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik	case XML_ENTITY_NODE:
775875af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik	case XML_CDATA_SECTION_NODE:
775975af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik	case XML_PI_NODE:
776075af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik	case XML_COMMENT_NODE:
776175af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik	case XML_XINCLUDE_END:
776275af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik	    break;
776375af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik	/* case XML_DTD_NODE: */ /* URGENT TODO: DTD-node as well? */
776475af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik	default:
776575af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik	    return(NULL);
776675af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik    }
776775af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik    if (cur->next != NULL) {
776875af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik	if (cur->next->type == XML_ELEMENT_NODE)
776975af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik	    return(cur->next);
777075af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik	cur = cur->next;
777175af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik	do {
777275af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik	    cur = cur->next;
777375af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik	} while ((cur != NULL) && (cur->type != XML_ELEMENT_NODE));
777475af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik	return(cur);
777575af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik    }
777675af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik    return(NULL);
777775af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik}
777875af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik
77797651606f316c366a6d66358b72b3527a829fb7feDaniel Veillard#if 0
778075af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik/**
7781df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik * xmlXPathNextDescendantOrSelfElemParent:
7782df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik * @ctxt:  the XPath Parser context
7783df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik * @cur:  the current node in the traversal
7784df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik *
7785df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik * Traversal function for the "descendant-or-self" axis.
7786df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik * Additionally it returns only nodes which can be parents of
7787df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik * element nodes.
7788df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik *
7789df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik *
7790df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik * Returns the next element following that axis
7791df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik */
7792df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcikstatic xmlNodePtr
7793df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. BuchcikxmlXPathNextDescendantOrSelfElemParent(xmlNodePtr cur,
7794df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik				       xmlNodePtr contextNode)
7795df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik{
7796df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik    if (cur == NULL) {
7797df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik	if (contextNode == NULL)
7798df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik	    return(NULL);
7799df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik	switch (contextNode->type) {
7800df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik	    case XML_ELEMENT_NODE:
7801df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik	    case XML_XINCLUDE_START:
7802df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik	    case XML_DOCUMENT_FRAG_NODE:
7803df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik	    case XML_DOCUMENT_NODE:
7804df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik#ifdef LIBXML_DOCB_ENABLED
7805df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik	    case XML_DOCB_DOCUMENT_NODE:
7806df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik#endif
7807f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard	    case XML_HTML_DOCUMENT_NODE:
7808df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		return(contextNode);
7809df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik	    default:
781045490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard		return(NULL);
7811df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik	}
7812df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik	return(NULL);
7813df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik    } else {
7814df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik	xmlNodePtr start = cur;
7815df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik
7816df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik	while (cur != NULL) {
7817df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik	    switch (cur->type) {
7818df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		case XML_ELEMENT_NODE:
7819df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		/* TODO: OK to have XInclude here? */
7820df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		case XML_XINCLUDE_START:
782145490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard		case XML_DOCUMENT_FRAG_NODE:
7822df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		    if (cur != start)
7823df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik			return(cur);
7824df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		    if (cur->children != NULL) {
7825df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik			cur = cur->children;
7826df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik			continue;
7827df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		    }
7828df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		    break;
7829df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		/* Not sure if we need those here. */
7830df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		case XML_DOCUMENT_NODE:
783117970a72caf1347025f2cc01eb6a1d7142b50d7cDaniel Veillard#ifdef LIBXML_DOCB_ENABLED
7832df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		case XML_DOCB_DOCUMENT_NODE:
7833df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik#endif
7834df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		case XML_HTML_DOCUMENT_NODE:
7835df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		    if (cur != start)
7836df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik			return(cur);
7837df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		    return(xmlDocGetRootElement((xmlDocPtr) cur));
7838df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		default:
7839df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		    break;
784045490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	    }
784145490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
7842df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchciknext_sibling:
7843df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik	    if ((cur == NULL) || (cur == contextNode))
784445490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard		return(NULL);
7845df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik	    if (cur->next != NULL) {
784645490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard		cur = cur->next;
7847df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik	    } else {
7848df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		cur = cur->parent;
7849df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		goto next_sibling;
7850df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik	    }
7851df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik	}
7852df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik    }
7853df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik    return(NULL);
785445490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard}
78557651606f316c366a6d66358b72b3527a829fb7feDaniel Veillard#endif
7856df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik
7857df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik/**
78583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNextDescendant:
78593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
78603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur:  the current node in the traversal
78613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
78623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Traversal function for the "descendant" direction
78633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the descendant axis contains the descendants of the context node in document
78643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * order; a descendant is a child or a child of a child and so on.
78653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
78663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the next element following that axis
78673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
78683473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNodePtr
78693473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNextDescendant(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
7870a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard    if ((ctxt == NULL) || (ctxt->context == NULL)) return(NULL);
78713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (cur == NULL) {
78723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (ctxt->context->node == NULL)
78733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    return(NULL);
78743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if ((ctxt->context->node->type == XML_ATTRIBUTE_NODE) ||
78753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    (ctxt->context->node->type == XML_NAMESPACE_DECL))
78763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    return(NULL);
78773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
78783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        if (ctxt->context->node == (xmlNodePtr) ctxt->context->doc)
78793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    return(ctxt->context->doc->children);
78803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        return(ctxt->context->node->children);
78813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
78823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
78833e62adbe39f2083c9c2cd3330c320227818fd361Daniel Veillard    if (cur->type == XML_NAMESPACE_DECL)
78843e62adbe39f2083c9c2cd3330c320227818fd361Daniel Veillard        return(NULL);
7885567e1b48e8664163894742d5674c24baa4282f9eDaniel Veillard    if (cur->children != NULL) {
788668e9e74af85ebbc30781787f247c361bc85adfa0Daniel Veillard	/*
788768e9e74af85ebbc30781787f247c361bc85adfa0Daniel Veillard	 * Do not descend on entities declarations
788868e9e74af85ebbc30781787f247c361bc85adfa0Daniel Veillard	 */
788945490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	if (cur->children->type != XML_ENTITY_DECL) {
789068e9e74af85ebbc30781787f247c361bc85adfa0Daniel Veillard	    cur = cur->children;
789168e9e74af85ebbc30781787f247c361bc85adfa0Daniel Veillard	    /*
789268e9e74af85ebbc30781787f247c361bc85adfa0Daniel Veillard	     * Skip DTDs
789368e9e74af85ebbc30781787f247c361bc85adfa0Daniel Veillard	     */
789468e9e74af85ebbc30781787f247c361bc85adfa0Daniel Veillard	    if (cur->type != XML_DTD_NODE)
789568e9e74af85ebbc30781787f247c361bc85adfa0Daniel Veillard		return(cur);
789668e9e74af85ebbc30781787f247c361bc85adfa0Daniel Veillard	}
7897567e1b48e8664163894742d5674c24baa4282f9eDaniel Veillard    }
7898567e1b48e8664163894742d5674c24baa4282f9eDaniel Veillard
7899567e1b48e8664163894742d5674c24baa4282f9eDaniel Veillard    if (cur == ctxt->context->node) return(NULL);
7900567e1b48e8664163894742d5674c24baa4282f9eDaniel Veillard
790168e9e74af85ebbc30781787f247c361bc85adfa0Daniel Veillard    while (cur->next != NULL) {
790268e9e74af85ebbc30781787f247c361bc85adfa0Daniel Veillard	cur = cur->next;
790368e9e74af85ebbc30781787f247c361bc85adfa0Daniel Veillard	if ((cur->type != XML_ENTITY_DECL) &&
790468e9e74af85ebbc30781787f247c361bc85adfa0Daniel Veillard	    (cur->type != XML_DTD_NODE))
790568e9e74af85ebbc30781787f247c361bc85adfa0Daniel Veillard	    return(cur);
790668e9e74af85ebbc30781787f247c361bc85adfa0Daniel Veillard    }
790745490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
79083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    do {
79093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        cur = cur->parent;
791011ce4004d86bb4b317c48b7d5124ba33e40e10f5Daniel Veillard	if (cur == NULL) break;
79113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (cur == ctxt->context->node) return(NULL);
79123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (cur->next != NULL) {
79133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    cur = cur->next;
79143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    return(cur);
79153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
79163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    } while (cur != NULL);
79173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(cur);
79183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
79193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
79203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
79213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNextDescendantOrSelf:
79223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
79233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur:  the current node in the traversal
79243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
79253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Traversal function for the "descendant-or-self" direction
79263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the descendant-or-self axis contains the context node and the descendants
79273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * of the context node in document order; thus the context node is the first
79283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * node on the axis, and the first child of the context node is the second node
79293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * on the axis
79303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
79313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the next element following that axis
79323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
79333473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNodePtr
79343473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNextDescendantOrSelf(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
7935a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard    if ((ctxt == NULL) || (ctxt->context == NULL)) return(NULL);
79363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (cur == NULL) {
79373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (ctxt->context->node == NULL)
79383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    return(NULL);
79393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if ((ctxt->context->node->type == XML_ATTRIBUTE_NODE) ||
79403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    (ctxt->context->node->type == XML_NAMESPACE_DECL))
79413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    return(NULL);
79423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        return(ctxt->context->node);
79433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
79443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
79453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(xmlXPathNextDescendant(ctxt, cur));
79463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
79473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
79483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
79493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNextParent:
79503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
79513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur:  the current node in the traversal
79523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
79533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Traversal function for the "parent" direction
79543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The parent axis contains the parent of the context node, if there is one.
79553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
79563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the next element following that axis
79573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
79583473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNodePtr
79593473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNextParent(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
7960a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard    if ((ctxt == NULL) || (ctxt->context == NULL)) return(NULL);
79613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    /*
79623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor     * the parent of an attribute or namespace node is the element
79633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor     * to which the attribute or namespace node is attached
79643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor     * Namespace handling !!!
79653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor     */
79663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (cur == NULL) {
79673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (ctxt->context->node == NULL) return(NULL);
79683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	switch (ctxt->context->node->type) {
79693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_ELEMENT_NODE:
79703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_TEXT_NODE:
79713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_CDATA_SECTION_NODE:
79723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_ENTITY_REF_NODE:
79733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_ENTITY_NODE:
79743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_PI_NODE:
79753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_COMMENT_NODE:
79763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_NOTATION_NODE:
79773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_DTD_NODE:
79783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    case XML_ELEMENT_DECL:
79793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    case XML_ATTRIBUTE_DECL:
79803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    case XML_XINCLUDE_START:
79813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    case XML_XINCLUDE_END:
79823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    case XML_ENTITY_DECL:
79833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		if (ctxt->context->node->parent == NULL)
79843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    return((xmlNodePtr) ctxt->context->doc);
79858e7e1c00ce5cc3ce959833b888c50ed9fd9d5aaeDaniel Veillard		if ((ctxt->context->node->parent->type == XML_ELEMENT_NODE) &&
7986652d8a949447833405cc0805f4b7ff1179e59ed2Daniel Veillard		    ((ctxt->context->node->parent->name[0] == ' ') ||
7987652d8a949447833405cc0805f4b7ff1179e59ed2Daniel Veillard		     (xmlStrEqual(ctxt->context->node->parent->name,
7988652d8a949447833405cc0805f4b7ff1179e59ed2Daniel Veillard				 BAD_CAST "fake node libxslt"))))
79898e7e1c00ce5cc3ce959833b888c50ed9fd9d5aaeDaniel Veillard		    return(NULL);
79903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		return(ctxt->context->node->parent);
79913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_ATTRIBUTE_NODE: {
79923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		xmlAttrPtr att = (xmlAttrPtr) ctxt->context->node;
79933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
79943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		return(att->parent);
79953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    }
79963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_DOCUMENT_NODE:
79973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_DOCUMENT_TYPE_NODE:
79983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_DOCUMENT_FRAG_NODE:
79993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_HTML_DOCUMENT_NODE:
8000eae522a0d8aa9f830d2e447f29b504030dbb6bbdDaniel Veillard#ifdef LIBXML_DOCB_ENABLED
8001eae522a0d8aa9f830d2e447f29b504030dbb6bbdDaniel Veillard	    case XML_DOCB_DOCUMENT_NODE:
80023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif
80033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor                return(NULL);
8004044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard	    case XML_NAMESPACE_DECL: {
8005044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard		xmlNsPtr ns = (xmlNsPtr) ctxt->context->node;
800645490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
8007044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard		if ((ns->next != NULL) &&
8008044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard		    (ns->next->type != XML_NAMESPACE_DECL))
8009044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard		    return((xmlNodePtr) ns->next);
80103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor                return(NULL);
8011044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard	    }
80123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
80133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
80143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(NULL);
80153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
80163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
80173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
80183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNextAncestor:
80193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
80203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur:  the current node in the traversal
80213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
80223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Traversal function for the "ancestor" direction
80233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the ancestor axis contains the ancestors of the context node; the ancestors
80243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * of the context node consist of the parent of context node and the parent's
80253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * parent and so on; the nodes are ordered in reverse document order; thus the
80263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * parent is the first node on the axis, and the parent's parent is the second
80273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * node on the axis
80283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
80293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the next element following that axis
80303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
80313473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNodePtr
80323473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNextAncestor(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
8033a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard    if ((ctxt == NULL) || (ctxt->context == NULL)) return(NULL);
80343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    /*
80353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor     * the parent of an attribute or namespace node is the element
80363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor     * to which the attribute or namespace node is attached
80373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor     * !!!!!!!!!!!!!
80383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor     */
80393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (cur == NULL) {
80403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (ctxt->context->node == NULL) return(NULL);
80413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	switch (ctxt->context->node->type) {
80423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_ELEMENT_NODE:
80433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_TEXT_NODE:
80443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_CDATA_SECTION_NODE:
80453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_ENTITY_REF_NODE:
80463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_ENTITY_NODE:
80473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_PI_NODE:
80483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_COMMENT_NODE:
80493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    case XML_DTD_NODE:
80503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    case XML_ELEMENT_DECL:
80513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    case XML_ATTRIBUTE_DECL:
80523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    case XML_ENTITY_DECL:
80533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_NOTATION_NODE:
80543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    case XML_XINCLUDE_START:
80553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    case XML_XINCLUDE_END:
80563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		if (ctxt->context->node->parent == NULL)
80573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    return((xmlNodePtr) ctxt->context->doc);
80588e7e1c00ce5cc3ce959833b888c50ed9fd9d5aaeDaniel Veillard		if ((ctxt->context->node->parent->type == XML_ELEMENT_NODE) &&
8059652d8a949447833405cc0805f4b7ff1179e59ed2Daniel Veillard		    ((ctxt->context->node->parent->name[0] == ' ') ||
8060652d8a949447833405cc0805f4b7ff1179e59ed2Daniel Veillard		     (xmlStrEqual(ctxt->context->node->parent->name,
8061652d8a949447833405cc0805f4b7ff1179e59ed2Daniel Veillard				 BAD_CAST "fake node libxslt"))))
80628e7e1c00ce5cc3ce959833b888c50ed9fd9d5aaeDaniel Veillard		    return(NULL);
80633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		return(ctxt->context->node->parent);
80643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_ATTRIBUTE_NODE: {
806556a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillard		xmlAttrPtr tmp = (xmlAttrPtr) ctxt->context->node;
80663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
806756a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillard		return(tmp->parent);
80683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    }
80693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_DOCUMENT_NODE:
80703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_DOCUMENT_TYPE_NODE:
80713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_DOCUMENT_FRAG_NODE:
80723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_HTML_DOCUMENT_NODE:
8073eae522a0d8aa9f830d2e447f29b504030dbb6bbdDaniel Veillard#ifdef LIBXML_DOCB_ENABLED
8074eae522a0d8aa9f830d2e447f29b504030dbb6bbdDaniel Veillard	    case XML_DOCB_DOCUMENT_NODE:
80753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif
80763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor                return(NULL);
8077044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard	    case XML_NAMESPACE_DECL: {
8078044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard		xmlNsPtr ns = (xmlNsPtr) ctxt->context->node;
807945490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
8080044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard		if ((ns->next != NULL) &&
8081044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard		    (ns->next->type != XML_NAMESPACE_DECL))
8082044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard		    return((xmlNodePtr) ns->next);
8083081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack		/* Bad, how did that namespace end up here ? */
80843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor                return(NULL);
8085044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard	    }
80863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
80873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(NULL);
80883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
80893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (cur == ctxt->context->doc->children)
80903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return((xmlNodePtr) ctxt->context->doc);
80913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (cur == (xmlNodePtr) ctxt->context->doc)
80923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(NULL);
80933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    switch (cur->type) {
80943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XML_ELEMENT_NODE:
80953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XML_TEXT_NODE:
80963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XML_CDATA_SECTION_NODE:
80973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XML_ENTITY_REF_NODE:
80983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XML_ENTITY_NODE:
80993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XML_PI_NODE:
81003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XML_COMMENT_NODE:
81013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XML_NOTATION_NODE:
81023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XML_DTD_NODE:
81033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        case XML_ELEMENT_DECL:
81043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        case XML_ATTRIBUTE_DECL:
81053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        case XML_ENTITY_DECL:
81063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XML_XINCLUDE_START:
81073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XML_XINCLUDE_END:
81088e7e1c00ce5cc3ce959833b888c50ed9fd9d5aaeDaniel Veillard	    if (cur->parent == NULL)
81098e7e1c00ce5cc3ce959833b888c50ed9fd9d5aaeDaniel Veillard		return(NULL);
81108e7e1c00ce5cc3ce959833b888c50ed9fd9d5aaeDaniel Veillard	    if ((cur->parent->type == XML_ELEMENT_NODE) &&
8111652d8a949447833405cc0805f4b7ff1179e59ed2Daniel Veillard		((cur->parent->name[0] == ' ') ||
8112652d8a949447833405cc0805f4b7ff1179e59ed2Daniel Veillard		 (xmlStrEqual(cur->parent->name,
8113652d8a949447833405cc0805f4b7ff1179e59ed2Daniel Veillard			      BAD_CAST "fake node libxslt"))))
81148e7e1c00ce5cc3ce959833b888c50ed9fd9d5aaeDaniel Veillard		return(NULL);
81153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    return(cur->parent);
81163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XML_ATTRIBUTE_NODE: {
81173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    xmlAttrPtr att = (xmlAttrPtr) ctxt->context->node;
81183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
81193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    return(att->parent);
81203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
8121dffd5c8dbc7b9052db7ae69dce419a96e22acc68Aleksey Sanin	case XML_NAMESPACE_DECL: {
8122dffd5c8dbc7b9052db7ae69dce419a96e22acc68Aleksey Sanin	    xmlNsPtr ns = (xmlNsPtr) ctxt->context->node;
812345490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
8124dffd5c8dbc7b9052db7ae69dce419a96e22acc68Aleksey Sanin	    if ((ns->next != NULL) &&
8125dffd5c8dbc7b9052db7ae69dce419a96e22acc68Aleksey Sanin	        (ns->next->type != XML_NAMESPACE_DECL))
8126dffd5c8dbc7b9052db7ae69dce419a96e22acc68Aleksey Sanin	        return((xmlNodePtr) ns->next);
8127081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack	    /* Bad, how did that namespace end up here ? */
8128dffd5c8dbc7b9052db7ae69dce419a96e22acc68Aleksey Sanin            return(NULL);
8129dffd5c8dbc7b9052db7ae69dce419a96e22acc68Aleksey Sanin	}
81303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XML_DOCUMENT_NODE:
81313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XML_DOCUMENT_TYPE_NODE:
81323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XML_DOCUMENT_FRAG_NODE:
81333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XML_HTML_DOCUMENT_NODE:
8134eae522a0d8aa9f830d2e447f29b504030dbb6bbdDaniel Veillard#ifdef LIBXML_DOCB_ENABLED
8135eae522a0d8aa9f830d2e447f29b504030dbb6bbdDaniel Veillard	case XML_DOCB_DOCUMENT_NODE:
81363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif
81373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    return(NULL);
81383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
81393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(NULL);
81403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
81413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
81423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
81433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNextAncestorOrSelf:
81443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
81453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur:  the current node in the traversal
81463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
81473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Traversal function for the "ancestor-or-self" direction
81483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * he ancestor-or-self axis contains the context node and ancestors of
81493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the context node in reverse document order; thus the context node is
81503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the first node on the axis, and the context node's parent the second;
81513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * parent here is defined the same as with the parent axis.
81523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
81533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the next element following that axis
81543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
81553473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNodePtr
81563473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNextAncestorOrSelf(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
8157a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard    if ((ctxt == NULL) || (ctxt->context == NULL)) return(NULL);
81583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (cur == NULL)
81593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        return(ctxt->context->node);
81603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(xmlXPathNextAncestor(ctxt, cur));
81613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
81623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
81633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
81643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNextFollowingSibling:
81653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
81663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur:  the current node in the traversal
81673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
81683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Traversal function for the "following-sibling" direction
81693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The following-sibling axis contains the following siblings of the context
81703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * node in document order.
81713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
81723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the next element following that axis
81733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
81743473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNodePtr
81753473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNextFollowingSibling(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
8176a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard    if ((ctxt == NULL) || (ctxt->context == NULL)) return(NULL);
81773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if ((ctxt->context->node->type == XML_ATTRIBUTE_NODE) ||
81783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	(ctxt->context->node->type == XML_NAMESPACE_DECL))
81793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(NULL);
81803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (cur == (xmlNodePtr) ctxt->context->doc)
81813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        return(NULL);
81823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (cur == NULL)
81833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        return(ctxt->context->node->next);
81843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(cur->next);
81853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
81863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
81873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
81883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNextPrecedingSibling:
81893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
81903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur:  the current node in the traversal
81913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
81923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Traversal function for the "preceding-sibling" direction
81933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The preceding-sibling axis contains the preceding siblings of the context
81943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * node in reverse document order; the first preceding sibling is first on the
81953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * axis; the sibling preceding that node is the second on the axis and so on.
81963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
81973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the next element following that axis
81983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
81993473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNodePtr
82003473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNextPrecedingSibling(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
8201a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard    if ((ctxt == NULL) || (ctxt->context == NULL)) return(NULL);
82023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if ((ctxt->context->node->type == XML_ATTRIBUTE_NODE) ||
82033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	(ctxt->context->node->type == XML_NAMESPACE_DECL))
82043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(NULL);
82053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (cur == (xmlNodePtr) ctxt->context->doc)
82063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        return(NULL);
82073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (cur == NULL)
82083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        return(ctxt->context->node->prev);
8209f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    if ((cur->prev != NULL) && (cur->prev->type == XML_DTD_NODE)) {
8210f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	cur = cur->prev;
8211f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	if (cur == NULL)
8212f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	    return(ctxt->context->node->prev);
8213f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    }
82143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(cur->prev);
82153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
82163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
82173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
82183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNextFollowing:
82193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
82203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur:  the current node in the traversal
82213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
82223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Traversal function for the "following" direction
82233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The following axis contains all nodes in the same document as the context
82243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * node that are after the context node in document order, excluding any
82253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * descendants and excluding attribute nodes and namespace nodes; the nodes
82263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * are ordered in document order
82273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
82283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the next element following that axis
82293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
82303473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNodePtr
82313473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNextFollowing(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
8232a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard    if ((ctxt == NULL) || (ctxt->context == NULL)) return(NULL);
8233ea90b894146030c214a7df6d8375310174f134b9Daniel Veillard    if ((cur != NULL) && (cur->type  != XML_ATTRIBUTE_NODE) &&
8234ea90b894146030c214a7df6d8375310174f134b9Daniel Veillard        (cur->type != XML_NAMESPACE_DECL) && (cur->children != NULL))
8235ea90b894146030c214a7df6d8375310174f134b9Daniel Veillard        return(cur->children);
8236ea90b894146030c214a7df6d8375310174f134b9Daniel Veillard
8237ea90b894146030c214a7df6d8375310174f134b9Daniel Veillard    if (cur == NULL) {
8238ea90b894146030c214a7df6d8375310174f134b9Daniel Veillard        cur = ctxt->context->node;
8239ea90b894146030c214a7df6d8375310174f134b9Daniel Veillard        if (cur->type == XML_NAMESPACE_DECL)
824091d19754d46acd4a639a8b9e31f50f31c78f8c9cDaniel Veillard            return(NULL);
8241ea90b894146030c214a7df6d8375310174f134b9Daniel Veillard        if (cur->type == XML_ATTRIBUTE_NODE)
8242ea90b894146030c214a7df6d8375310174f134b9Daniel Veillard            cur = cur->parent;
824391d19754d46acd4a639a8b9e31f50f31c78f8c9cDaniel Veillard    }
82443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (cur == NULL) return(NULL) ; /* ERROR */
82453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (cur->next != NULL) return(cur->next) ;
82463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    do {
82473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        cur = cur->parent;
824811ce4004d86bb4b317c48b7d5124ba33e40e10f5Daniel Veillard        if (cur == NULL) break;
82493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        if (cur == (xmlNodePtr) ctxt->context->doc) return(NULL);
82503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        if (cur->next != NULL) return(cur->next);
82513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    } while (cur != NULL);
82523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(cur);
82533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
82543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
82553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/*
82563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathIsAncestor:
82573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ancestor:  the ancestor node
82583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @node:  the current node
82593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
82603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Check that @ancestor is a @node's ancestor
82613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
82623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * returns 1 if @ancestor is a @node's ancestor, 0 otherwise.
82633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
82643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorstatic int
82653473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathIsAncestor(xmlNodePtr ancestor, xmlNodePtr node) {
82663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if ((ancestor == NULL) || (node == NULL)) return(0);
82673e62adbe39f2083c9c2cd3330c320227818fd361Daniel Veillard    if (node->type == XML_NAMESPACE_DECL)
82683e62adbe39f2083c9c2cd3330c320227818fd361Daniel Veillard        return(0);
82693e62adbe39f2083c9c2cd3330c320227818fd361Daniel Veillard    if (ancestor->type == XML_NAMESPACE_DECL)
82703e62adbe39f2083c9c2cd3330c320227818fd361Daniel Veillard        return(0);
82713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    /* nodes need to be in the same document */
82723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ancestor->doc != node->doc) return(0);
82733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    /* avoid searching if ancestor or node is the root node */
82743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ancestor == (xmlNodePtr) node->doc) return(1);
82753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (node == (xmlNodePtr) ancestor->doc) return(0);
82763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    while (node->parent != NULL) {
82773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        if (node->parent == ancestor)
82783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            return(1);
82793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	node = node->parent;
82803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
82813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(0);
82823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
82833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
82843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
82853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNextPreceding:
82863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
82873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur:  the current node in the traversal
82883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
82893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Traversal function for the "preceding" direction
82903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the preceding axis contains all nodes in the same document as the context
82913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * node that are before the context node in document order, excluding any
82923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * ancestors and excluding attribute nodes and namespace nodes; the nodes are
82933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * ordered in reverse document order
82943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
82953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the next element following that axis
82963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
82973473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNodePtr
8298f06307e2c172284bb41376c396f757bdac9bdd19Daniel VeillardxmlXPathNextPreceding(xmlXPathParserContextPtr ctxt, xmlNodePtr cur)
8299f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard{
8300a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard    if ((ctxt == NULL) || (ctxt->context == NULL)) return(NULL);
8301ea90b894146030c214a7df6d8375310174f134b9Daniel Veillard    if (cur == NULL) {
8302f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        cur = ctxt->context->node;
8303ea90b894146030c214a7df6d8375310174f134b9Daniel Veillard        if (cur->type == XML_NAMESPACE_DECL)
8304ea90b894146030c214a7df6d8375310174f134b9Daniel Veillard            return(NULL);
8305ea90b894146030c214a7df6d8375310174f134b9Daniel Veillard        if (cur->type == XML_ATTRIBUTE_NODE)
8306ea90b894146030c214a7df6d8375310174f134b9Daniel Veillard            return(cur->parent);
8307ea90b894146030c214a7df6d8375310174f134b9Daniel Veillard    }
83083e62adbe39f2083c9c2cd3330c320227818fd361Daniel Veillard    if ((cur == NULL) || (cur->type == XML_NAMESPACE_DECL))
8309f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	return (NULL);
8310f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    if ((cur->prev != NULL) && (cur->prev->type == XML_DTD_NODE))
8311f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	cur = cur->prev;
83123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    do {
83133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        if (cur->prev != NULL) {
8314f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            for (cur = cur->prev; cur->last != NULL; cur = cur->last) ;
8315f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            return (cur);
83163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        }
83173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
83183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        cur = cur->parent;
8319f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        if (cur == NULL)
8320f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            return (NULL);
8321f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        if (cur == ctxt->context->doc->children)
8322f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            return (NULL);
83233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    } while (xmlXPathIsAncestor(cur, ctxt->context->node));
8324f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    return (cur);
8325f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard}
8326f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
8327f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard/**
8328f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * xmlXPathNextPrecedingInternal:
8329f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * @ctxt:  the XPath Parser context
8330f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * @cur:  the current node in the traversal
8331f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard *
8332f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Traversal function for the "preceding" direction
8333f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * the preceding axis contains all nodes in the same document as the context
8334f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * node that are before the context node in document order, excluding any
8335f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * ancestors and excluding attribute nodes and namespace nodes; the nodes are
8336f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * ordered in reverse document order
833745490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard * This is a faster implementation but internal only since it requires a
8338f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * state kept in the parser context: ctxt->ancestor.
8339f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard *
8340f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Returns the next element following that axis
8341f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */
8342f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillardstatic xmlNodePtr
8343f06307e2c172284bb41376c396f757bdac9bdd19Daniel VeillardxmlXPathNextPrecedingInternal(xmlXPathParserContextPtr ctxt,
8344f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                              xmlNodePtr cur)
8345f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard{
8346a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard    if ((ctxt == NULL) || (ctxt->context == NULL)) return(NULL);
8347f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    if (cur == NULL) {
8348f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        cur = ctxt->context->node;
8349f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        if (cur == NULL)
8350f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            return (NULL);
8351ea90b894146030c214a7df6d8375310174f134b9Daniel Veillard        if (cur->type == XML_NAMESPACE_DECL)
8352ea90b894146030c214a7df6d8375310174f134b9Daniel Veillard            return (NULL);
8353f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        ctxt->ancestor = cur->parent;
8354f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    }
83553e62adbe39f2083c9c2cd3330c320227818fd361Daniel Veillard    if (cur->type == XML_NAMESPACE_DECL)
83563e62adbe39f2083c9c2cd3330c320227818fd361Daniel Veillard        return(NULL);
8357f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    if ((cur->prev != NULL) && (cur->prev->type == XML_DTD_NODE))
8358f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	cur = cur->prev;
8359f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    while (cur->prev == NULL) {
8360f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        cur = cur->parent;
8361f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        if (cur == NULL)
8362f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            return (NULL);
8363f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        if (cur == ctxt->context->doc->children)
8364f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            return (NULL);
8365f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        if (cur != ctxt->ancestor)
8366f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            return (cur);
8367f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        ctxt->ancestor = cur->parent;
8368f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    }
8369f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    cur = cur->prev;
8370f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    while (cur->last != NULL)
8371f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        cur = cur->last;
8372f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    return (cur);
83733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
83743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
83753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
83763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNextNamespace:
83773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
83783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur:  the current attribute in the traversal
83793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
83803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Traversal function for the "namespace" direction
83813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the namespace axis contains the namespace nodes of the context node;
83823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the order of nodes on this axis is implementation-defined; the axis will
83833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * be empty unless the context node is an element
83843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
838520ee8c03107e5d5724765da513d595fdaf290dceDaniel Veillard * We keep the XML namespace node at the end of the list.
838620ee8c03107e5d5724765da513d595fdaf290dceDaniel Veillard *
83873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the next element following that axis
83883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
83893473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNodePtr
83903473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNextNamespace(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
8391a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard    if ((ctxt == NULL) || (ctxt->context == NULL)) return(NULL);
83923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ctxt->context->node->type != XML_ELEMENT_NODE) return(NULL);
8393fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard    if (ctxt->context->tmpNsList == NULL && cur != (xmlNodePtr) xmlXPathXMLNamespace) {
83947d7e37919fc6c7f257769c867122d885d2aae26fDaniel Veillard        if (ctxt->context->tmpNsList != NULL)
83957d7e37919fc6c7f257769c867122d885d2aae26fDaniel Veillard	    xmlFree(ctxt->context->tmpNsList);
839645490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	ctxt->context->tmpNsList =
83973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    xmlGetNsList(ctxt->context->doc, ctxt->context->node);
83987d7e37919fc6c7f257769c867122d885d2aae26fDaniel Veillard	ctxt->context->tmpNsNr = 0;
8399fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard	if (ctxt->context->tmpNsList != NULL) {
8400fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard	    while (ctxt->context->tmpNsList[ctxt->context->tmpNsNr] != NULL) {
8401fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard		ctxt->context->tmpNsNr++;
8402fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard	    }
8403fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard	}
8404fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard	return((xmlNodePtr) xmlXPathXMLNamespace);
84057d7e37919fc6c7f257769c867122d885d2aae26fDaniel Veillard    }
8406fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard    if (ctxt->context->tmpNsNr > 0) {
8407fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard	return (xmlNodePtr)ctxt->context->tmpNsList[--ctxt->context->tmpNsNr];
8408fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard    } else {
8409fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard	if (ctxt->context->tmpNsList != NULL)
8410fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard	    xmlFree(ctxt->context->tmpNsList);
84117d7e37919fc6c7f257769c867122d885d2aae26fDaniel Veillard	ctxt->context->tmpNsList = NULL;
8412fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard	return(NULL);
84133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
84143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
84153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
84163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
84173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNextAttribute:
84183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
84193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur:  the current attribute in the traversal
84203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
84213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Traversal function for the "attribute" direction
84223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * TODO: support DTD inherited default attributes
84233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
84243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the next element following that axis
84253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
84263473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNodePtr
84273473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNextAttribute(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
8428a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard    if ((ctxt == NULL) || (ctxt->context == NULL)) return(NULL);
8429e470df7fdd3505c6232d6498f3b8834ebfce522dDaniel Veillard    if (ctxt->context->node == NULL)
8430e470df7fdd3505c6232d6498f3b8834ebfce522dDaniel Veillard	return(NULL);
8431e470df7fdd3505c6232d6498f3b8834ebfce522dDaniel Veillard    if (ctxt->context->node->type != XML_ELEMENT_NODE)
8432e470df7fdd3505c6232d6498f3b8834ebfce522dDaniel Veillard	return(NULL);
84333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (cur == NULL) {
84343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        if (ctxt->context->node == (xmlNodePtr) ctxt->context->doc)
84353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    return(NULL);
84363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        return((xmlNodePtr)ctxt->context->node->properties);
84373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
84383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return((xmlNodePtr)cur->next);
84393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
84403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
84413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/************************************************************************
84423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *									*
84433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *		NodeTest Functions					*
84443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *									*
84453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ************************************************************************/
84463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
84473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define IS_FUNCTION			200
84483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
8449d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard
8450d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard/************************************************************************
8451d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard *									*
8452d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard *		Implicit tree core function library			*
8453d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard *									*
8454d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard ************************************************************************/
8455d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard
84563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
8457d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * xmlXPathRoot:
84583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
84593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
8460d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * Initialize the context to the root of the document
84613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
8462d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillardvoid
8463d8df6c0e8c883e1d618388d266015dda36731440Daniel VeillardxmlXPathRoot(xmlXPathParserContextPtr ctxt) {
8464a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    if ((ctxt == NULL) || (ctxt->context == NULL))
8465a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	return;
8466d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard    ctxt->context->node = (xmlNodePtr) ctxt->context->doc;
8467a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    valuePush(ctxt, xmlXPathCacheNewNodeSet(ctxt->context,
8468a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	ctxt->context->node));
8469d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard}
84703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
8471d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard/************************************************************************
8472d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard *									*
8473d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard *		The explicit core function library			*
8474d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard *http://www.w3.org/Style/XSL/Group/1999/07/xpath-19990705.html#corelib	*
8475d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard *									*
8476d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard ************************************************************************/
84773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
8478d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard
8479d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard/**
8480d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * xmlXPathLastFunction:
8481d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * @ctxt:  the XPath Parser context
8482d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * @nargs:  the number of arguments
8483d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard *
8484d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * Implement the last() XPath function
8485d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard *    number last()
8486d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * The last function returns the number of nodes in the context node list.
8487d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard */
8488d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillardvoid
8489d8df6c0e8c883e1d618388d266015dda36731440Daniel VeillardxmlXPathLastFunction(xmlXPathParserContextPtr ctxt, int nargs) {
8490d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard    CHECK_ARITY(0);
8491d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard    if (ctxt->context->contextSize >= 0) {
8492a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	valuePush(ctxt,
8493a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathCacheNewFloat(ctxt->context,
8494a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		(double) ctxt->context->contextSize));
8495d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_EXPR
8496d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	xmlGenericError(xmlGenericErrorContext,
8497d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard		"last() : %d\n", ctxt->context->contextSize);
84983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif
8499d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard    } else {
8500d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	XP_ERROR(XPATH_INVALID_CTXT_SIZE);
85013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
8502d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard}
85033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
8504d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard/**
8505d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * xmlXPathPositionFunction:
8506d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * @ctxt:  the XPath Parser context
8507d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * @nargs:  the number of arguments
8508d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard *
8509d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * Implement the position() XPath function
8510d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard *    number position()
8511d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * The position function returns the position of the context node in the
8512cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * context node list. The first position is 1, and so the last position
8513d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * will be equal to last().
8514d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard */
8515d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillardvoid
8516d8df6c0e8c883e1d618388d266015dda36731440Daniel VeillardxmlXPathPositionFunction(xmlXPathParserContextPtr ctxt, int nargs) {
8517d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard    CHECK_ARITY(0);
8518d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard    if (ctxt->context->proximityPosition >= 0) {
8519d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	valuePush(ctxt,
8520a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	      xmlXPathCacheNewFloat(ctxt->context,
8521a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		(double) ctxt->context->proximityPosition));
8522d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_EXPR
8523d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	xmlGenericError(xmlGenericErrorContext, "position() : %d\n",
8524d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard		ctxt->context->proximityPosition);
85253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif
8526d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard    } else {
8527d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	XP_ERROR(XPATH_INVALID_CTXT_POSITION);
8528d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard    }
8529d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard}
85303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
85313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
85323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathCountFunction:
85333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
85343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs:  the number of arguments
85353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
85363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the count() XPath function
85373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *    number count(node-set)
85383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
85393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
85403473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathCountFunction(xmlXPathParserContextPtr ctxt, int nargs) {
85413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathObjectPtr cur;
85423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
85433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CHECK_ARITY(1);
854445490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard    if ((ctxt->value == NULL) ||
85453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	((ctxt->value->type != XPATH_NODESET) &&
85463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	 (ctxt->value->type != XPATH_XSLT_TREE)))
85473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	XP_ERROR(XPATH_INVALID_TYPE);
85483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    cur = valuePop(ctxt);
85493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
8550911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard    if ((cur == NULL) || (cur->nodesetval == NULL))
8551a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	valuePush(ctxt, xmlXPathCacheNewFloat(ctxt->context, (double) 0));
85520c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack    else if ((cur->type == XPATH_NODESET) || (cur->type == XPATH_XSLT_TREE)) {
8553a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	valuePush(ctxt, xmlXPathCacheNewFloat(ctxt->context,
8554a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    (double) cur->nodesetval->nodeNr));
8555fe70332f7f29f146a364c73450729a8b3274daeeDaniel Veillard    } else {
8556fe70332f7f29f146a364c73450729a8b3274daeeDaniel Veillard	if ((cur->nodesetval->nodeNr != 1) ||
8557fe70332f7f29f146a364c73450729a8b3274daeeDaniel Veillard	    (cur->nodesetval->nodeTab == NULL)) {
8558a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    valuePush(ctxt, xmlXPathCacheNewFloat(ctxt->context, (double) 0));
8559fe70332f7f29f146a364c73450729a8b3274daeeDaniel Veillard	} else {
8560fe70332f7f29f146a364c73450729a8b3274daeeDaniel Veillard	    xmlNodePtr tmp;
8561fe70332f7f29f146a364c73450729a8b3274daeeDaniel Veillard	    int i = 0;
8562fe70332f7f29f146a364c73450729a8b3274daeeDaniel Veillard
8563fe70332f7f29f146a364c73450729a8b3274daeeDaniel Veillard	    tmp = cur->nodesetval->nodeTab[0];
85643e62adbe39f2083c9c2cd3330c320227818fd361Daniel Veillard	    if ((tmp != NULL) && (tmp->type != XML_NAMESPACE_DECL)) {
8565fe70332f7f29f146a364c73450729a8b3274daeeDaniel Veillard		tmp = tmp->children;
8566fe70332f7f29f146a364c73450729a8b3274daeeDaniel Veillard		while (tmp != NULL) {
8567fe70332f7f29f146a364c73450729a8b3274daeeDaniel Veillard		    tmp = tmp->next;
8568fe70332f7f29f146a364c73450729a8b3274daeeDaniel Veillard		    i++;
8569fe70332f7f29f146a364c73450729a8b3274daeeDaniel Veillard		}
8570fe70332f7f29f146a364c73450729a8b3274daeeDaniel Veillard	    }
8571a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    valuePush(ctxt, xmlXPathCacheNewFloat(ctxt->context, (double) i));
8572fe70332f7f29f146a364c73450729a8b3274daeeDaniel Veillard	}
8573fe70332f7f29f146a364c73450729a8b3274daeeDaniel Veillard    }
8574a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathReleaseObject(ctxt->context, cur);
85753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
85763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
85773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
8578ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathGetElementsByIds:
8579ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @doc:  the document
8580ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @ids:  a whitespace separated list of IDs
8581ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
8582ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Selects elements by their unique ID.
8583ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
8584ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns a node-set of selected elements.
8585ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */
8586ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillardstatic xmlNodeSetPtr
8587ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathGetElementsByIds (xmlDocPtr doc, const xmlChar *ids) {
8588ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    xmlNodeSetPtr ret;
8589ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    const xmlChar *cur = ids;
8590ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    xmlChar *ID;
8591ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    xmlAttrPtr attr;
8592ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    xmlNodePtr elem = NULL;
8593ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
85947a985a18c2fee0aa9b490792dd990b75506e3740Daniel Veillard    if (ids == NULL) return(NULL);
85957a985a18c2fee0aa9b490792dd990b75506e3740Daniel Veillard
8596ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    ret = xmlXPathNodeSetCreate(NULL);
8597f88d849a4e994c94c0d0814a4befb43c990ceebdDaniel Veillard    if (ret == NULL)
8598f88d849a4e994c94c0d0814a4befb43c990ceebdDaniel Veillard        return(ret);
8599ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
860076e95df05556c9610b564b14cf578c8f9e34c9c1William M. Brack    while (IS_BLANK_CH(*cur)) cur++;
8601ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    while (*cur != 0) {
860276e95df05556c9610b564b14cf578c8f9e34c9c1William M. Brack	while ((!IS_BLANK_CH(*cur)) && (*cur != 0))
8603e209b330558d170da195acb3a7618b0048d22c9eDaniel Veillard	    cur++;
8604ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
8605ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard        ID = xmlStrndup(ids, cur - ids);
8606e209b330558d170da195acb3a7618b0048d22c9eDaniel Veillard	if (ID != NULL) {
860768cb4b2498088cf920ed6c9490b134ce7f38909fDaniel Veillard	    /*
860868cb4b2498088cf920ed6c9490b134ce7f38909fDaniel Veillard	     * We used to check the fact that the value passed
860968cb4b2498088cf920ed6c9490b134ce7f38909fDaniel Veillard	     * was an NCName, but this generated much troubles for
861068cb4b2498088cf920ed6c9490b134ce7f38909fDaniel Veillard	     * me and Aleksey Sanin, people blatantly violated that
861168cb4b2498088cf920ed6c9490b134ce7f38909fDaniel Veillard	     * constaint, like Visa3D spec.
861268cb4b2498088cf920ed6c9490b134ce7f38909fDaniel Veillard	     * if (xmlValidateNCName(ID, 1) == 0)
861368cb4b2498088cf920ed6c9490b134ce7f38909fDaniel Veillard	     */
861468cb4b2498088cf920ed6c9490b134ce7f38909fDaniel Veillard	    attr = xmlGetID(doc, ID);
861568cb4b2498088cf920ed6c9490b134ce7f38909fDaniel Veillard	    if (attr != NULL) {
861668cb4b2498088cf920ed6c9490b134ce7f38909fDaniel Veillard		if (attr->type == XML_ATTRIBUTE_NODE)
861768cb4b2498088cf920ed6c9490b134ce7f38909fDaniel Veillard		    elem = attr->parent;
861868cb4b2498088cf920ed6c9490b134ce7f38909fDaniel Veillard		else if (attr->type == XML_ELEMENT_NODE)
861968cb4b2498088cf920ed6c9490b134ce7f38909fDaniel Veillard		    elem = (xmlNodePtr) attr;
862068cb4b2498088cf920ed6c9490b134ce7f38909fDaniel Veillard		else
862168cb4b2498088cf920ed6c9490b134ce7f38909fDaniel Veillard		    elem = NULL;
862268cb4b2498088cf920ed6c9490b134ce7f38909fDaniel Veillard		if (elem != NULL)
862368cb4b2498088cf920ed6c9490b134ce7f38909fDaniel Veillard		    xmlXPathNodeSetAdd(ret, elem);
8624e209b330558d170da195acb3a7618b0048d22c9eDaniel Veillard	    }
8625ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	    xmlFree(ID);
8626e209b330558d170da195acb3a7618b0048d22c9eDaniel Veillard	}
8627ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
862876e95df05556c9610b564b14cf578c8f9e34c9c1William M. Brack	while (IS_BLANK_CH(*cur)) cur++;
8629ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	ids = cur;
8630ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    }
8631ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    return(ret);
8632ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard}
8633ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
8634ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/**
86353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathIdFunction:
86363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
86373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs:  the number of arguments
86383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
86393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the id() XPath function
86403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *    node-set id(object)
86413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The id function selects elements by their unique ID
86423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * (see [5.2.1 Unique IDs]). When the argument to id is of type node-set,
86433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * then the result is the union of the result of applying id to the
86443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * string value of each of the nodes in the argument node-set. When the
86453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * argument to id is of any other type, the argument is converted to a
86463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * string as if by a call to the string function; the string is split
86473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * into a whitespace-separated list of tokens (whitespace is any sequence
86483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * of characters matching the production S); the result is a node-set
86493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * containing the elements in the same document as the context node that
86503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * have a unique ID equal to any of the tokens in the list.
86513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
86523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
86533473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathIdFunction(xmlXPathParserContextPtr ctxt, int nargs) {
8654ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    xmlChar *tokens;
8655ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    xmlNodeSetPtr ret;
8656ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    xmlXPathObjectPtr obj;
86573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
86583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CHECK_ARITY(1);
86593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    obj = valuePop(ctxt);
86603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (obj == NULL) XP_ERROR(XPATH_INVALID_OPERAND);
86610c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack    if ((obj->type == XPATH_NODESET) || (obj->type == XPATH_XSLT_TREE)) {
8662ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	xmlNodeSetPtr ns;
86633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	int i;
86643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
8665ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	ret = xmlXPathNodeSetCreate(NULL);
8666f88d849a4e994c94c0d0814a4befb43c990ceebdDaniel Veillard        /*
8667f88d849a4e994c94c0d0814a4befb43c990ceebdDaniel Veillard         * FIXME -- in an out-of-memory condition this will behave badly.
8668f88d849a4e994c94c0d0814a4befb43c990ceebdDaniel Veillard         * The solution is not clear -- we already popped an item from
8669f88d849a4e994c94c0d0814a4befb43c990ceebdDaniel Veillard         * ctxt, so the object is in a corrupt state.
8670f88d849a4e994c94c0d0814a4befb43c990ceebdDaniel Veillard         */
86713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
8672911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard	if (obj->nodesetval != NULL) {
8673911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard	    for (i = 0; i < obj->nodesetval->nodeNr; i++) {
8674ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard		tokens =
8675ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard		    xmlXPathCastNodeToString(obj->nodesetval->nodeTab[i]);
8676ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard		ns = xmlXPathGetElementsByIds(ctxt->context->doc, tokens);
8677ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard		ret = xmlXPathNodeSetMerge(ret, ns);
8678ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard		xmlXPathFreeNodeSet(ns);
8679ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard		if (tokens != NULL)
8680ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard		    xmlFree(tokens);
8681911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard	    }
86823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
8683a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	xmlXPathReleaseObject(ctxt->context, obj);
8684a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	valuePush(ctxt, xmlXPathCacheWrapNodeSet(ctxt->context, ret));
86853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return;
86863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
8687a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    obj = xmlXPathCacheConvertString(ctxt->context, obj);
8688ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    ret = xmlXPathGetElementsByIds(ctxt->context->doc, obj->stringval);
868945490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard    valuePush(ctxt, xmlXPathCacheWrapNodeSet(ctxt->context, ret));
8690a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathReleaseObject(ctxt->context, obj);
86913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return;
86923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
86933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
86943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
86953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathLocalNameFunction:
86963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
86973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs:  the number of arguments
86983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
86993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the local-name() XPath function
87003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *    string local-name(node-set?)
87013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The local-name function returns a string containing the local part
87023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * of the name of the node in the argument node-set that is first in
87033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * document order. If the node-set is empty or the first node has no
87043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * name, an empty string is returned. If the argument is omitted it
87053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * defaults to the context node.
87063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
87073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
87083473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathLocalNameFunction(xmlXPathParserContextPtr ctxt, int nargs) {
87093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathObjectPtr cur;
87103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
8711a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard    if (ctxt == NULL) return;
8712a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard
87133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (nargs == 0) {
8714a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	valuePush(ctxt, xmlXPathCacheNewNodeSet(ctxt->context,
8715a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    ctxt->context->node));
87163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	nargs = 1;
87173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
87183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
87193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CHECK_ARITY(1);
872045490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard    if ((ctxt->value == NULL) ||
87213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	((ctxt->value->type != XPATH_NODESET) &&
87223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	 (ctxt->value->type != XPATH_XSLT_TREE)))
87233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	XP_ERROR(XPATH_INVALID_TYPE);
87243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    cur = valuePop(ctxt);
87253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
8726911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard    if ((cur->nodesetval == NULL) || (cur->nodesetval->nodeNr == 0)) {
8727a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	valuePush(ctxt, xmlXPathCacheNewCString(ctxt->context, ""));
87283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    } else {
87293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	int i = 0; /* Should be first in document order !!!!! */
87303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	switch (cur->nodesetval->nodeTab[i]->type) {
87313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XML_ELEMENT_NODE:
87323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XML_ATTRIBUTE_NODE:
87333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XML_PI_NODE:
8734652d8a949447833405cc0805f4b7ff1179e59ed2Daniel Veillard	    if (cur->nodesetval->nodeTab[i]->name[0] == ' ')
8735a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		valuePush(ctxt, xmlXPathCacheNewCString(ctxt->context, ""));
8736652d8a949447833405cc0805f4b7ff1179e59ed2Daniel Veillard	    else
8737652d8a949447833405cc0805f4b7ff1179e59ed2Daniel Veillard		valuePush(ctxt,
8738a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		      xmlXPathCacheNewString(ctxt->context,
8739a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik			cur->nodesetval->nodeTab[i]->name));
87403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    break;
87413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XML_NAMESPACE_DECL:
8742a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    valuePush(ctxt, xmlXPathCacheNewString(ctxt->context,
87433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor			((xmlNsPtr)cur->nodesetval->nodeTab[i])->prefix));
87443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    break;
87453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	default:
8746a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    valuePush(ctxt, xmlXPathCacheNewCString(ctxt->context, ""));
87473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
87483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
8749a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathReleaseObject(ctxt->context, cur);
87503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
87513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
87523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
87533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNamespaceURIFunction:
87543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
87553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs:  the number of arguments
87563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
87573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the namespace-uri() XPath function
87583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *    string namespace-uri(node-set?)
87593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The namespace-uri function returns a string containing the
87603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * namespace URI of the expanded name of the node in the argument
87613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * node-set that is first in document order. If the node-set is empty,
87623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the first node has no name, or the expanded name has no namespace
87633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * URI, an empty string is returned. If the argument is omitted it
87643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * defaults to the context node.
87653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
87663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
87673473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNamespaceURIFunction(xmlXPathParserContextPtr ctxt, int nargs) {
87683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathObjectPtr cur;
87693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
8770a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard    if (ctxt == NULL) return;
8771a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard
87723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (nargs == 0) {
8773a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	valuePush(ctxt, xmlXPathCacheNewNodeSet(ctxt->context,
8774a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    ctxt->context->node));
87753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	nargs = 1;
87763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
87773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CHECK_ARITY(1);
877845490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard    if ((ctxt->value == NULL) ||
87793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	((ctxt->value->type != XPATH_NODESET) &&
87803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	 (ctxt->value->type != XPATH_XSLT_TREE)))
87813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	XP_ERROR(XPATH_INVALID_TYPE);
87823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    cur = valuePop(ctxt);
87833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
8784911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard    if ((cur->nodesetval == NULL) || (cur->nodesetval->nodeNr == 0)) {
8785a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	valuePush(ctxt, xmlXPathCacheNewCString(ctxt->context, ""));
87863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    } else {
87873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	int i = 0; /* Should be first in document order !!!!! */
87883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	switch (cur->nodesetval->nodeTab[i]->type) {
87893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XML_ELEMENT_NODE:
87903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XML_ATTRIBUTE_NODE:
87913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    if (cur->nodesetval->nodeTab[i]->ns == NULL)
8792a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		valuePush(ctxt, xmlXPathCacheNewCString(ctxt->context, ""));
87933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    else
8794a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		valuePush(ctxt, xmlXPathCacheNewString(ctxt->context,
87953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor			  cur->nodesetval->nodeTab[i]->ns->href));
87963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    break;
87973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	default:
8798a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    valuePush(ctxt, xmlXPathCacheNewCString(ctxt->context, ""));
87993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
88003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
8801a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathReleaseObject(ctxt->context, cur);
88023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
88033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
88043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
88053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNameFunction:
88063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
88073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs:  the number of arguments
88083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
88093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the name() XPath function
88103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *    string name(node-set?)
88113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The name function returns a string containing a QName representing
8812cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * the name of the node in the argument node-set that is first in document
88133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * order. The QName must represent the name with respect to the namespace
88143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * declarations in effect on the node whose name is being represented.
88153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Typically, this will be the form in which the name occurred in the XML
88163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * source. This need not be the case if there are namespace declarations
88173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * in effect on the node that associate multiple prefixes with the same
88183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * namespace. However, an implementation may include information about
88193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the original prefix in its representation of nodes; in this case, an
88203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * implementation can ensure that the returned string is always the same
88213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * as the QName used in the XML source. If the argument it omitted it
88223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * defaults to the context node.
88233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Libxml keep the original prefix so the "real qualified name" used is
88243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * returned.
88253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
882656a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic void
88270438375d2e6be47d0179826271081ae64df94f8bDaniel VeillardxmlXPathNameFunction(xmlXPathParserContextPtr ctxt, int nargs)
88280438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard{
88293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathObjectPtr cur;
88303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
88313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (nargs == 0) {
8832a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	valuePush(ctxt, xmlXPathCacheNewNodeSet(ctxt->context,
8833a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    ctxt->context->node));
88340438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard        nargs = 1;
88353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
88363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
88373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CHECK_ARITY(1);
88380438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard    if ((ctxt->value == NULL) ||
88390438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard        ((ctxt->value->type != XPATH_NODESET) &&
88400438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard         (ctxt->value->type != XPATH_XSLT_TREE)))
88410438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard        XP_ERROR(XPATH_INVALID_TYPE);
88423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    cur = valuePop(ctxt);
88433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
8844911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard    if ((cur->nodesetval == NULL) || (cur->nodesetval->nodeNr == 0)) {
8845a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik        valuePush(ctxt, xmlXPathCacheNewCString(ctxt->context, ""));
88463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    } else {
88470438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard        int i = 0;              /* Should be first in document order !!!!! */
88483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
88490438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard        switch (cur->nodesetval->nodeTab[i]->type) {
88500438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard            case XML_ELEMENT_NODE:
88510438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard            case XML_ATTRIBUTE_NODE:
8852652d8a949447833405cc0805f4b7ff1179e59ed2Daniel Veillard		if (cur->nodesetval->nodeTab[i]->name[0] == ' ')
8853a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    valuePush(ctxt,
8854a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik			xmlXPathCacheNewCString(ctxt->context, ""));
8855652d8a949447833405cc0805f4b7ff1179e59ed2Daniel Veillard		else if ((cur->nodesetval->nodeTab[i]->ns == NULL) ||
8856652d8a949447833405cc0805f4b7ff1179e59ed2Daniel Veillard                         (cur->nodesetval->nodeTab[i]->ns->prefix == NULL)) {
8857a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    valuePush(ctxt,
8858a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		        xmlXPathCacheNewString(ctxt->context,
8859a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik			    cur->nodesetval->nodeTab[i]->name));
8860652d8a949447833405cc0805f4b7ff1179e59ed2Daniel Veillard		} else {
8861c00cda8c065beba24706c9e8719f08e9de420274Daniel Veillard		    xmlChar *fullname;
886245490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
8863c00cda8c065beba24706c9e8719f08e9de420274Daniel Veillard		    fullname = xmlBuildQName(cur->nodesetval->nodeTab[i]->name,
8864c00cda8c065beba24706c9e8719f08e9de420274Daniel Veillard				     cur->nodesetval->nodeTab[i]->ns->prefix,
8865c00cda8c065beba24706c9e8719f08e9de420274Daniel Veillard				     NULL, 0);
8866c00cda8c065beba24706c9e8719f08e9de420274Daniel Veillard		    if (fullname == cur->nodesetval->nodeTab[i]->name)
8867c00cda8c065beba24706c9e8719f08e9de420274Daniel Veillard			fullname = xmlStrdup(cur->nodesetval->nodeTab[i]->name);
8868c00cda8c065beba24706c9e8719f08e9de420274Daniel Veillard		    if (fullname == NULL) {
8869c00cda8c065beba24706c9e8719f08e9de420274Daniel Veillard			XP_ERROR(XPATH_MEMORY_ERROR);
8870c00cda8c065beba24706c9e8719f08e9de420274Daniel Veillard		    }
8871a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    valuePush(ctxt, xmlXPathCacheWrapString(
8872a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik			ctxt->context, fullname));
88730438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard                }
88740438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard                break;
88750438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard            default:
8876a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		valuePush(ctxt, xmlXPathCacheNewNodeSet(ctxt->context,
8877a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    cur->nodesetval->nodeTab[i]));
88780438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard                xmlXPathLocalNameFunction(ctxt, 1);
88790438375d2e6be47d0179826271081ae64df94f8bDaniel Veillard        }
88803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
8881a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathReleaseObject(ctxt->context, cur);
88823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
88833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
8884fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard
8885fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard/**
88863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathStringFunction:
88873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
88883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs:  the number of arguments
88893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
88903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the string() XPath function
88913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *    string string(object?)
8892081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack * The string function converts an object to a string as follows:
88933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *    - A node-set is converted to a string by returning the value of
88943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *      the node in the node-set that is first in document order.
88953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *      If the node-set is empty, an empty string is returned.
88963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *    - A number is converted to a string as follows
889745490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *      + NaN is converted to the string NaN
889845490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *      + positive zero is converted to the string 0
889945490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *      + negative zero is converted to the string 0
890045490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *      + positive infinity is converted to the string Infinity
890145490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *      + negative infinity is converted to the string -Infinity
89023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *      + if the number is an integer, the number is represented in
89033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *        decimal form as a Number with no decimal point and no leading
89043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *        zeros, preceded by a minus sign (-) if the number is negative
89053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *      + otherwise, the number is represented in decimal form as a
89063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *        Number including a decimal point with at least one digit
89073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *        before the decimal point and at least one digit after the
89083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *        decimal point, preceded by a minus sign (-) if the number
89093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *        is negative; there must be no leading zeros before the decimal
8910cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard *        point apart possibly from the one required digit immediately
89113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *        before the decimal point; beyond the one required digit
89123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *        after the decimal point there must be as many, but only as
89133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *        many, more digits as are needed to uniquely distinguish the
89143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *        number from all other IEEE 754 numeric values.
89153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *    - The boolean false value is converted to the string false.
89163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *      The boolean true value is converted to the string true.
89173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
89183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * If the argument is omitted, it defaults to a node-set with the
89193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * context node as its only member.
89203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
89213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
89223473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathStringFunction(xmlXPathParserContextPtr ctxt, int nargs) {
89233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathObjectPtr cur;
89243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
8925a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard    if (ctxt == NULL) return;
89263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (nargs == 0) {
8927a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    valuePush(ctxt,
8928a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	xmlXPathCacheWrapString(ctxt->context,
8929a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathCastNodeToString(ctxt->context->node)));
8930ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	return;
89313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
89323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
89333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CHECK_ARITY(1);
89343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    cur = valuePop(ctxt);
89353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (cur == NULL) XP_ERROR(XPATH_INVALID_OPERAND);
8936a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    valuePush(ctxt, xmlXPathCacheConvertString(ctxt->context, cur));
89373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
89383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
89393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
89403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathStringLengthFunction:
89413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
89423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs:  the number of arguments
89433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
89443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the string-length() XPath function
89453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *    number string-length(string?)
89463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The string-length returns the number of characters in the string
89473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * (see [3.6 Strings]). If the argument is omitted, it defaults to
89483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the context node converted to a string, in other words the value
89493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * of the context node.
89503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
89513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
89523473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathStringLengthFunction(xmlXPathParserContextPtr ctxt, int nargs) {
89533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathObjectPtr cur;
89543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
89553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (nargs == 0) {
8956a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard        if ((ctxt == NULL) || (ctxt->context == NULL))
8957a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard	    return;
89583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (ctxt->context->node == NULL) {
8959a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    valuePush(ctxt, xmlXPathCacheNewFloat(ctxt->context, 0));
89603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	} else {
89613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    xmlChar *content;
89623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
8963ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	    content = xmlXPathCastNodeToString(ctxt->context->node);
8964a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    valuePush(ctxt, xmlXPathCacheNewFloat(ctxt->context,
8965a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		xmlUTF8Strlen(content)));
89663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    xmlFree(content);
89673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
89683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return;
89693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
89703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CHECK_ARITY(1);
89713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CAST_TO_STRING;
89723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CHECK_TYPE(XPATH_STRING);
89733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    cur = valuePop(ctxt);
8974a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    valuePush(ctxt, xmlXPathCacheNewFloat(ctxt->context,
897545490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	xmlUTF8Strlen(cur->stringval)));
8976a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathReleaseObject(ctxt->context, cur);
89773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
89783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
89793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
89803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathConcatFunction:
89813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
89823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs:  the number of arguments
89833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
89843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the concat() XPath function
89853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *    string concat(string, string, string*)
89863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The concat function returns the concatenation of its arguments.
89873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
89883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
89893473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathConcatFunction(xmlXPathParserContextPtr ctxt, int nargs) {
89903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathObjectPtr cur, newobj;
89913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlChar *tmp;
89923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
8993a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard    if (ctxt == NULL) return;
89943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (nargs < 2) {
89953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	CHECK_ARITY(2);
89963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
89973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
89983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CAST_TO_STRING;
89993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    cur = valuePop(ctxt);
90003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if ((cur == NULL) || (cur->type != XPATH_STRING)) {
9001a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	xmlXPathReleaseObject(ctxt->context, cur);
90023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return;
90033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
90043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    nargs--;
90053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
90063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    while (nargs > 0) {
90073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	CAST_TO_STRING;
90083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	newobj = valuePop(ctxt);
90093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if ((newobj == NULL) || (newobj->type != XPATH_STRING)) {
9010a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathReleaseObject(ctxt->context, newobj);
9011a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathReleaseObject(ctxt->context, cur);
90123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    XP_ERROR(XPATH_INVALID_TYPE);
90133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
90143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	tmp = xmlStrcat(newobj->stringval, cur->stringval);
90153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	newobj->stringval = cur->stringval;
90163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	cur->stringval = tmp;
9017a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	xmlXPathReleaseObject(ctxt->context, newobj);
90183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	nargs--;
90193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
90203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    valuePush(ctxt, cur);
90213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
90223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
90233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
90243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathContainsFunction:
90253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
90263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs:  the number of arguments
90273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
90283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the contains() XPath function
90293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *    boolean contains(string, string)
90303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The contains function returns true if the first argument string
90313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * contains the second argument string, and otherwise returns false.
90323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
90333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
90343473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathContainsFunction(xmlXPathParserContextPtr ctxt, int nargs) {
90353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathObjectPtr hay, needle;
90363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
90373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CHECK_ARITY(2);
90383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CAST_TO_STRING;
90393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CHECK_TYPE(XPATH_STRING);
90403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    needle = valuePop(ctxt);
90413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CAST_TO_STRING;
90423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    hay = valuePop(ctxt);
9043a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
90443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if ((hay == NULL) || (hay->type != XPATH_STRING)) {
9045a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	xmlXPathReleaseObject(ctxt->context, hay);
9046a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	xmlXPathReleaseObject(ctxt->context, needle);
90473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	XP_ERROR(XPATH_INVALID_TYPE);
90483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
90493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (xmlStrstr(hay->stringval, needle->stringval))
9050a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	valuePush(ctxt, xmlXPathCacheNewBoolean(ctxt->context, 1));
90513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    else
9052a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	valuePush(ctxt, xmlXPathCacheNewBoolean(ctxt->context, 0));
9053a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathReleaseObject(ctxt->context, hay);
9054a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathReleaseObject(ctxt->context, needle);
90553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
90563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
90573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
90583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathStartsWithFunction:
90593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
90603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs:  the number of arguments
90613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
90623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the starts-with() XPath function
90633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *    boolean starts-with(string, string)
90643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The starts-with function returns true if the first argument string
90653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * starts with the second argument string, and otherwise returns false.
90663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
90673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
90683473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathStartsWithFunction(xmlXPathParserContextPtr ctxt, int nargs) {
90693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathObjectPtr hay, needle;
90703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    int n;
90713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
90723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CHECK_ARITY(2);
90733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CAST_TO_STRING;
90743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CHECK_TYPE(XPATH_STRING);
90753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    needle = valuePop(ctxt);
90763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CAST_TO_STRING;
90773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    hay = valuePop(ctxt);
9078a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
90793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if ((hay == NULL) || (hay->type != XPATH_STRING)) {
9080a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	xmlXPathReleaseObject(ctxt->context, hay);
9081a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	xmlXPathReleaseObject(ctxt->context, needle);
90823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	XP_ERROR(XPATH_INVALID_TYPE);
90833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
90843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    n = xmlStrlen(needle->stringval);
90853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (xmlStrncmp(hay->stringval, needle->stringval, n))
9086a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik        valuePush(ctxt, xmlXPathCacheNewBoolean(ctxt->context, 0));
90873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    else
9088a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik        valuePush(ctxt, xmlXPathCacheNewBoolean(ctxt->context, 1));
9089a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathReleaseObject(ctxt->context, hay);
9090a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathReleaseObject(ctxt->context, needle);
90913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
90923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
90933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
90943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathSubstringFunction:
90953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
90963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs:  the number of arguments
90973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
90983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the substring() XPath function
90993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *    string substring(string, number, number?)
91003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The substring function returns the substring of the first argument
91013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * starting at the position specified in the second argument with
91023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * length specified in the third argument. For example,
91033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * substring("12345",2,3) returns "234". If the third argument is not
91043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * specified, it returns the substring starting at the position specified
91053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * in the second argument and continuing to the end of the string. For
91063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * example, substring("12345",2) returns "2345".  More precisely, each
91073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * character in the string (see [3.6 Strings]) is considered to have a
91083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * numeric position: the position of the first character is 1, the position
91093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * of the second character is 2 and so on. The returned substring contains
91103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * those characters for which the position of the character is greater than
91113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * or equal to the second argument and, if the third argument is specified,
91123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * less than the sum of the second and third arguments; the comparisons
91133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * and addition used for the above follow the standard IEEE 754 rules. Thus:
911445490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *  - substring("12345", 1.5, 2.6) returns "234"
911545490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *  - substring("12345", 0, 3) returns "12"
911645490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *  - substring("12345", 0 div 0, 3) returns ""
911745490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *  - substring("12345", 1, 0 div 0) returns ""
911845490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *  - substring("12345", -42, 1 div 0) returns "12345"
911945490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *  - substring("12345", -1 div 0, 1 div 0) returns ""
91203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
91213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
91223473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathSubstringFunction(xmlXPathParserContextPtr ctxt, int nargs) {
91233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathObjectPtr str, start, len;
912497ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard    double le=0, in;
912597ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard    int i, l, m;
91263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlChar *ret;
91273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
91283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (nargs < 2) {
91293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	CHECK_ARITY(2);
91303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
91313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (nargs > 3) {
91323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	CHECK_ARITY(3);
91333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
913497ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard    /*
913597ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard     * take care of possible last (position) argument
913697ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard    */
91373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (nargs == 3) {
91383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	CAST_TO_NUMBER;
91393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	CHECK_TYPE(XPATH_NUMBER);
91403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	len = valuePop(ctxt);
91413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	le = len->floatval;
9142a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	xmlXPathReleaseObject(ctxt->context, len);
91433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
914497ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard
91453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CAST_TO_NUMBER;
91463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CHECK_TYPE(XPATH_NUMBER);
91473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    start = valuePop(ctxt);
91483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    in = start->floatval;
9149a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathReleaseObject(ctxt->context, start);
91503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CAST_TO_STRING;
91513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CHECK_TYPE(XPATH_STRING);
91523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    str = valuePop(ctxt);
915397ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard    m = xmlUTF8Strlen((const unsigned char *)str->stringval);
915497ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard
915597ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard    /*
915697ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard     * If last pos not present, calculate last position
915797ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard    */
91589e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard    if (nargs != 3) {
91599e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard	le = (double)m;
916045490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	if (in < 1.0)
91619e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard	    in = 1.0;
91629e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard    }
916397ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard
916445490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard    /* Need to check for the special cases where either
91650eafdef9881c396ce4c014359d8f497cc088cfabDaniel Veillard     * the index is NaN, the length is NaN, or both
91660eafdef9881c396ce4c014359d8f497cc088cfabDaniel Veillard     * arguments are infinity (relying on Inf + -Inf = NaN)
916797ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard     */
916848b3eb22c2b79b5b3bc247f65c376c8154be4edaDaniel Veillard    if (!xmlXPathIsInf(in) && !xmlXPathIsNaN(in + le)) {
91690eafdef9881c396ce4c014359d8f497cc088cfabDaniel Veillard        /*
91709e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard         * To meet the requirements of the spec, the arguments
917145490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	 * must be converted to integer format before
91729e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard	 * initial index calculations are done
91730eafdef9881c396ce4c014359d8f497cc088cfabDaniel Veillard         *
91749e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard         * First we go to integer form, rounding up
91759e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard	 * and checking for special cases
91760eafdef9881c396ce4c014359d8f497cc088cfabDaniel Veillard         */
91770eafdef9881c396ce4c014359d8f497cc088cfabDaniel Veillard        i = (int) in;
91789e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard        if (((double)i)+0.5 <= in) i++;
91799e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard
91809e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard	if (xmlXPathIsInf(le) == 1) {
91819e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard	    l = m;
91829e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard	    if (i < 1)
91839e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard		i = 1;
91849e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard	}
91859e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard	else if (xmlXPathIsInf(le) == -1 || le < 0.0)
91869e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard	    l = 0;
91879e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard	else {
91889e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard	    l = (int) le;
91899e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard	    if (((double)l)+0.5 <= le) l++;
91909e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard	}
91910eafdef9881c396ce4c014359d8f497cc088cfabDaniel Veillard
91929e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard	/* Now we normalize inidices */
91939e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard        i -= 1;
91949e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard        l += i;
91959e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard        if (i < 0)
91969e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard            i = 0;
91979e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard        if (l > m)
91989e4123023a930924e26ca965ef14ea67bff7dfc3Daniel Veillard            l = m;
91993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
92000eafdef9881c396ce4c014359d8f497cc088cfabDaniel Veillard        /* number of chars to copy */
92010eafdef9881c396ce4c014359d8f497cc088cfabDaniel Veillard        l -= i;
92023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
92030eafdef9881c396ce4c014359d8f497cc088cfabDaniel Veillard        ret = xmlUTF8Strsub(str->stringval, i, l);
92040eafdef9881c396ce4c014359d8f497cc088cfabDaniel Veillard    }
92050eafdef9881c396ce4c014359d8f497cc088cfabDaniel Veillard    else {
92060eafdef9881c396ce4c014359d8f497cc088cfabDaniel Veillard        ret = NULL;
92070eafdef9881c396ce4c014359d8f497cc088cfabDaniel Veillard    }
92083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ret == NULL)
9209a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	valuePush(ctxt, xmlXPathCacheNewCString(ctxt->context, ""));
92103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    else {
9211a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	valuePush(ctxt, xmlXPathCacheNewString(ctxt->context, ret));
92123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	xmlFree(ret);
92133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
9214a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathReleaseObject(ctxt->context, str);
92153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
92163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
92173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
92183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathSubstringBeforeFunction:
92193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
92203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs:  the number of arguments
92213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
92223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the substring-before() XPath function
92233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *    string substring-before(string, string)
92243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The substring-before function returns the substring of the first
92253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * argument string that precedes the first occurrence of the second
92263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * argument string in the first argument string, or the empty string
92273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * if the first argument string does not contain the second argument
92283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * string. For example, substring-before("1999/04/01","/") returns 1999.
92293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
92303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
92313473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathSubstringBeforeFunction(xmlXPathParserContextPtr ctxt, int nargs) {
92323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  xmlXPathObjectPtr str;
92333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  xmlXPathObjectPtr find;
9234ade10f2c57b4bd5c3812b96bce1144d8fa1d189eDaniel Veillard  xmlBufPtr target;
92353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  const xmlChar *point;
92363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  int offset;
923745490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
92383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  CHECK_ARITY(2);
92393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  CAST_TO_STRING;
92403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  find = valuePop(ctxt);
92413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  CAST_TO_STRING;
92423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  str = valuePop(ctxt);
924345490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
9244ade10f2c57b4bd5c3812b96bce1144d8fa1d189eDaniel Veillard  target = xmlBufCreate();
92453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  if (target) {
92463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    point = xmlStrstr(str->stringval, find->stringval);
92473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (point) {
92483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor      offset = (int)(point - str->stringval);
9249ade10f2c57b4bd5c3812b96bce1144d8fa1d189eDaniel Veillard      xmlBufAdd(target, str->stringval, offset);
92503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
9251a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    valuePush(ctxt, xmlXPathCacheNewString(ctxt->context,
9252ade10f2c57b4bd5c3812b96bce1144d8fa1d189eDaniel Veillard	xmlBufContent(target)));
9253ade10f2c57b4bd5c3812b96bce1144d8fa1d189eDaniel Veillard    xmlBufFree(target);
92543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  }
9255a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik  xmlXPathReleaseObject(ctxt->context, str);
9256a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik  xmlXPathReleaseObject(ctxt->context, find);
92573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
92583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
92593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
92603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathSubstringAfterFunction:
92613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
92623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs:  the number of arguments
92633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
92643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the substring-after() XPath function
92653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *    string substring-after(string, string)
92663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The substring-after function returns the substring of the first
92673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * argument string that follows the first occurrence of the second
92683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * argument string in the first argument string, or the empty stringi
92693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * if the first argument string does not contain the second argument
92703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * string. For example, substring-after("1999/04/01","/") returns 04/01,
92713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * and substring-after("1999/04/01","19") returns 99/04/01.
92723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
92733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
92743473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathSubstringAfterFunction(xmlXPathParserContextPtr ctxt, int nargs) {
92753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  xmlXPathObjectPtr str;
92763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  xmlXPathObjectPtr find;
9277ade10f2c57b4bd5c3812b96bce1144d8fa1d189eDaniel Veillard  xmlBufPtr target;
92783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  const xmlChar *point;
92793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  int offset;
928045490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
92813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  CHECK_ARITY(2);
92823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  CAST_TO_STRING;
92833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  find = valuePop(ctxt);
92843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  CAST_TO_STRING;
92853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  str = valuePop(ctxt);
928645490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
9287ade10f2c57b4bd5c3812b96bce1144d8fa1d189eDaniel Veillard  target = xmlBufCreate();
92883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  if (target) {
92893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    point = xmlStrstr(str->stringval, find->stringval);
92903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (point) {
92913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor      offset = (int)(point - str->stringval) + xmlStrlen(find->stringval);
9292ade10f2c57b4bd5c3812b96bce1144d8fa1d189eDaniel Veillard      xmlBufAdd(target, &str->stringval[offset],
92933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		   xmlStrlen(str->stringval) - offset);
92943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
9295a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    valuePush(ctxt, xmlXPathCacheNewString(ctxt->context,
9296ade10f2c57b4bd5c3812b96bce1144d8fa1d189eDaniel Veillard	xmlBufContent(target)));
9297ade10f2c57b4bd5c3812b96bce1144d8fa1d189eDaniel Veillard    xmlBufFree(target);
92983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  }
9299a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik  xmlXPathReleaseObject(ctxt->context, str);
9300a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik  xmlXPathReleaseObject(ctxt->context, find);
93013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
93023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
93033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
93043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNormalizeFunction:
93053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
93063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs:  the number of arguments
93073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
93083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the normalize-space() XPath function
93093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *    string normalize-space(string?)
93103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The normalize-space function returns the argument string with white
93113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * space normalized by stripping leading and trailing whitespace
93123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * and replacing sequences of whitespace characters by a single
93133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * space. Whitespace characters are the same allowed by the S production
93143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * in XML. If the argument is omitted, it defaults to the context
93153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * node converted to a string, in other words the value of the context node.
93163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
93173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
93183473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNormalizeFunction(xmlXPathParserContextPtr ctxt, int nargs) {
93193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  xmlXPathObjectPtr obj = NULL;
93203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  xmlChar *source = NULL;
9321ade10f2c57b4bd5c3812b96bce1144d8fa1d189eDaniel Veillard  xmlBufPtr target;
93223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  xmlChar blank;
932345490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
9324a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard  if (ctxt == NULL) return;
93253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  if (nargs == 0) {
93263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    /* Use current context node */
9327a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik      valuePush(ctxt,
9328a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	  xmlXPathCacheWrapString(ctxt->context,
9329a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathCastNodeToString(ctxt->context->node)));
93303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    nargs = 1;
93313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  }
93323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
93333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  CHECK_ARITY(1);
93343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  CAST_TO_STRING;
93353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  CHECK_TYPE(XPATH_STRING);
93363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  obj = valuePop(ctxt);
93373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  source = obj->stringval;
93383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
9339ade10f2c57b4bd5c3812b96bce1144d8fa1d189eDaniel Veillard  target = xmlBufCreate();
93403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  if (target && source) {
934145490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
93423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    /* Skip leading whitespaces */
934376e95df05556c9610b564b14cf578c8f9e34c9c1William M. Brack    while (IS_BLANK_CH(*source))
93443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor      source++;
934545490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
93463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    /* Collapse intermediate whitespaces, and skip trailing whitespaces */
93473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    blank = 0;
93483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    while (*source) {
934976e95df05556c9610b564b14cf578c8f9e34c9c1William M. Brack      if (IS_BLANK_CH(*source)) {
935097ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard	blank = 0x20;
93513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor      } else {
93523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (blank) {
9353ade10f2c57b4bd5c3812b96bce1144d8fa1d189eDaniel Veillard	  xmlBufAdd(target, &blank, 1);
93543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	  blank = 0;
93553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
9356ade10f2c57b4bd5c3812b96bce1144d8fa1d189eDaniel Veillard	xmlBufAdd(target, source, 1);
93573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor      }
93583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor      source++;
93593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
9360a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    valuePush(ctxt, xmlXPathCacheNewString(ctxt->context,
9361ade10f2c57b4bd5c3812b96bce1144d8fa1d189eDaniel Veillard	xmlBufContent(target)));
9362ade10f2c57b4bd5c3812b96bce1144d8fa1d189eDaniel Veillard    xmlBufFree(target);
93633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  }
9364a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik  xmlXPathReleaseObject(ctxt->context, obj);
93653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
93663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
93673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
93683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathTranslateFunction:
93693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
93703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs:  the number of arguments
93713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
93723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the translate() XPath function
93733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *    string translate(string, string, string)
93743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The translate function returns the first argument string with
93753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * occurrences of characters in the second argument string replaced
93763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * by the character at the corresponding position in the third argument
93773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * string. For example, translate("bar","abc","ABC") returns the string
93783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * BAr. If there is a character in the second argument string with no
93793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * character at a corresponding position in the third argument string
93803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * (because the second argument string is longer than the third argument
93813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * string), then occurrences of that character in the first argument
93823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * string are removed. For example, translate("--aaa--","abc-","ABC")
93833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * returns "AAA". If a character occurs more than once in second
93843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * argument string, then the first occurrence determines the replacement
93853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * character. If the third argument string is longer than the second
93863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * argument string, then excess characters are ignored.
93873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
93883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
93893473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathTranslateFunction(xmlXPathParserContextPtr ctxt, int nargs) {
9390e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard    xmlXPathObjectPtr str;
9391e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard    xmlXPathObjectPtr from;
9392e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard    xmlXPathObjectPtr to;
9393ade10f2c57b4bd5c3812b96bce1144d8fa1d189eDaniel Veillard    xmlBufPtr target;
939497ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard    int offset, max;
9395e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard    xmlChar ch;
9396b031cef5b537d8eda30f508627f08bc642bbd31dWilliam M. Brack    const xmlChar *point;
939797ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard    xmlChar *cptr;
93983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
9399e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard    CHECK_ARITY(3);
94003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
9401e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard    CAST_TO_STRING;
9402e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard    to = valuePop(ctxt);
9403e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard    CAST_TO_STRING;
9404e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard    from = valuePop(ctxt);
9405e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard    CAST_TO_STRING;
9406e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard    str = valuePop(ctxt);
94073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
9408ade10f2c57b4bd5c3812b96bce1144d8fa1d189eDaniel Veillard    target = xmlBufCreate();
9409e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard    if (target) {
941097ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard	max = xmlUTF8Strlen(to->stringval);
941197ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard	for (cptr = str->stringval; (ch=*cptr); ) {
941297ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard	    offset = xmlUTF8Strloc(from->stringval, cptr);
941397ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard	    if (offset >= 0) {
941497ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard		if (offset < max) {
941597ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard		    point = xmlUTF8Strpos(to->stringval, offset);
941697ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard		    if (point)
9417ade10f2c57b4bd5c3812b96bce1144d8fa1d189eDaniel Veillard			xmlBufAdd(target, point, xmlUTF8Strsize(point, 1));
941897ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard		}
941997ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard	    } else
9420ade10f2c57b4bd5c3812b96bce1144d8fa1d189eDaniel Veillard		xmlBufAdd(target, cptr, xmlUTF8Strsize(cptr, 1));
942197ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard
942297ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard	    /* Step to next character in input */
942397ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard	    cptr++;
942497ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard	    if ( ch & 0x80 ) {
942597ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard		/* if not simple ascii, verify proper format */
942697ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard		if ( (ch & 0xc0) != 0xc0 ) {
942797ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard		    xmlGenericError(xmlGenericErrorContext,
942897ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard			"xmlXPathTranslateFunction: Invalid UTF8 string\n");
94291d4526f6f4ec8d18c40e2a09b387652a6c1aa2cdDaniel Veillard                    /* not asserting an XPath error is probably better */
943097ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard		    break;
943197ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard		}
943297ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard		/* then skip over remaining bytes for this char */
943397ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard		while ( (ch <<= 1) & 0x80 )
943497ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard		    if ( (*cptr++ & 0xc0) != 0x80 ) {
943597ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard			xmlGenericError(xmlGenericErrorContext,
943697ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard			    "xmlXPathTranslateFunction: Invalid UTF8 string\n");
94371d4526f6f4ec8d18c40e2a09b387652a6c1aa2cdDaniel Veillard                        /* not asserting an XPath error is probably better */
943897ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard			break;
943997ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard		    }
944097ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard		if (ch & 0x80) /* must have had error encountered */
944197ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard		    break;
944297ac13197ce5a6a754a7071a0e95b07f1f54ac6cDaniel Veillard	    }
9443e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard	}
94443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
9445a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    valuePush(ctxt, xmlXPathCacheNewString(ctxt->context,
9446ade10f2c57b4bd5c3812b96bce1144d8fa1d189eDaniel Veillard	xmlBufContent(target)));
9447ade10f2c57b4bd5c3812b96bce1144d8fa1d189eDaniel Veillard    xmlBufFree(target);
9448a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathReleaseObject(ctxt->context, str);
9449a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathReleaseObject(ctxt->context, from);
9450a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathReleaseObject(ctxt->context, to);
94513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
94523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
94533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
9454fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * xmlXPathBooleanFunction:
9455fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * @ctxt:  the XPath Parser context
9456fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * @nargs:  the number of arguments
9457fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard *
9458fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * Implement the boolean() XPath function
9459fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard *    boolean boolean(object)
9460081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack * The boolean function converts its argument to a boolean as follows:
9461fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard *    - a number is true if and only if it is neither positive or
9462fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard *      negative zero nor NaN
9463fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard *    - a node-set is true if and only if it is non-empty
9464fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard *    - a string is true if and only if its length is non-zero
9465fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard */
9466fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillardvoid
9467fbf8a2d0c8145b713099df63d174154a8442e60dDaniel VeillardxmlXPathBooleanFunction(xmlXPathParserContextPtr ctxt, int nargs) {
9468fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard    xmlXPathObjectPtr cur;
9469fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard
9470fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard    CHECK_ARITY(1);
9471fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard    cur = valuePop(ctxt);
9472fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard    if (cur == NULL) XP_ERROR(XPATH_INVALID_OPERAND);
9473a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    cur = xmlXPathCacheConvertBoolean(ctxt->context, cur);
9474fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard    valuePush(ctxt, cur);
94753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
94763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
94773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
94783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNotFunction:
94793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
94803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs:  the number of arguments
94813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
94823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the not() XPath function
94833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *    boolean not(boolean)
94843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The not function returns true if its argument is false,
94853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * and false otherwise.
94863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
94873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
94883473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNotFunction(xmlXPathParserContextPtr ctxt, int nargs) {
94893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CHECK_ARITY(1);
94903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CAST_TO_BOOLEAN;
94913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CHECK_TYPE(XPATH_BOOLEAN);
94923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ctxt->value->boolval = ! ctxt->value->boolval;
94933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
94943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
94953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
94963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathTrueFunction:
94973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
94983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs:  the number of arguments
94993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
95003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the true() XPath function
95013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *    boolean true()
95023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
95033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
95043473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathTrueFunction(xmlXPathParserContextPtr ctxt, int nargs) {
95053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CHECK_ARITY(0);
9506a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    valuePush(ctxt, xmlXPathCacheNewBoolean(ctxt->context, 1));
95073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
95083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
95093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
95103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathFalseFunction:
95113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
95123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs:  the number of arguments
95133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
95143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the false() XPath function
95153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *    boolean false()
95163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
95173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
95183473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathFalseFunction(xmlXPathParserContextPtr ctxt, int nargs) {
95193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CHECK_ARITY(0);
9520a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    valuePush(ctxt, xmlXPathCacheNewBoolean(ctxt->context, 0));
95213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
95223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
95233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
95243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathLangFunction:
95253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
95263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs:  the number of arguments
95273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
95283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the lang() XPath function
95293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *    boolean lang(string)
95303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The lang function returns true or false depending on whether the
95313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * language of the context node as specified by xml:lang attributes
95323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * is the same as or is a sublanguage of the language specified by
95333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the argument string. The language of the context node is determined
95343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * by the value of the xml:lang attribute on the context node, or, if
95353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the context node has no xml:lang attribute, by the value of the
95363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xml:lang attribute on the nearest ancestor of the context node that
95373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * has an xml:lang attribute. If there is no such attribute, then lang
95383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * returns false. If there is such an attribute, then lang returns
95393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * true if the attribute value is equal to the argument ignoring case,
95403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * or if there is some suffix starting with - such that the attribute
95413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * value is equal to the argument ignoring that suffix of the attribute
95423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * value and ignoring case.
95433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
95443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
95453473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathLangFunction(xmlXPathParserContextPtr ctxt, int nargs) {
95464ddaa56d7af6638c20a4446c47b02b299987be65Daniel Veillard    xmlXPathObjectPtr val = NULL;
95474ddaa56d7af6638c20a4446c47b02b299987be65Daniel Veillard    const xmlChar *theLang = NULL;
95483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    const xmlChar *lang;
95493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    int ret = 0;
95503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    int i;
95513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
95523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CHECK_ARITY(1);
95533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CAST_TO_STRING;
95543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CHECK_TYPE(XPATH_STRING);
95553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    val = valuePop(ctxt);
95563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    lang = val->stringval;
95573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    theLang = xmlNodeGetLang(ctxt->context->node);
95583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if ((theLang != NULL) && (lang != NULL)) {
95593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        for (i = 0;lang[i] != 0;i++)
95603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    if (toupper(lang[i]) != toupper(theLang[i]))
95613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	        goto not_equal;
95624ddaa56d7af6638c20a4446c47b02b299987be65Daniel Veillard	if ((theLang[i] == 0) || (theLang[i] == '-'))
95634ddaa56d7af6638c20a4446c47b02b299987be65Daniel Veillard	    ret = 1;
95643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
95653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylornot_equal:
95664ddaa56d7af6638c20a4446c47b02b299987be65Daniel Veillard    if (theLang != NULL)
95674ddaa56d7af6638c20a4446c47b02b299987be65Daniel Veillard	xmlFree((void *)theLang);
9568a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
9569a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathReleaseObject(ctxt->context, val);
9570a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    valuePush(ctxt, xmlXPathCacheNewBoolean(ctxt->context, ret));
95713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
95723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
95733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
95743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNumberFunction:
95753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
95763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs:  the number of arguments
95773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
95783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the number() XPath function
95793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *    number number(object?)
95803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
95813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
95823473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNumberFunction(xmlXPathParserContextPtr ctxt, int nargs) {
95833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathObjectPtr cur;
95843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    double res;
95853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
9586a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard    if (ctxt == NULL) return;
95873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (nargs == 0) {
95883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (ctxt->context->node == NULL) {
9589a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    valuePush(ctxt, xmlXPathCacheNewFloat(ctxt->context, 0.0));
95903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	} else {
95913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    xmlChar* content = xmlNodeGetContent(ctxt->context->node);
95923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
95933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    res = xmlXPathStringEvalNumber(content);
9594a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    valuePush(ctxt, xmlXPathCacheNewFloat(ctxt->context, res));
95953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    xmlFree(content);
95963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
95973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return;
95983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
95993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
96003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CHECK_ARITY(1);
96013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    cur = valuePop(ctxt);
9602a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    valuePush(ctxt, xmlXPathCacheConvertNumber(ctxt->context, cur));
96033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
96043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
96053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
96063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathSumFunction:
96073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
96083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs:  the number of arguments
96093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
96103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the sum() XPath function
96113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *    number sum(node-set)
96123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The sum function returns the sum of the values of the nodes in
96133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the argument node-set.
96143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
96153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
96163473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathSumFunction(xmlXPathParserContextPtr ctxt, int nargs) {
96173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathObjectPtr cur;
96183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    int i;
9619ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    double res = 0.0;
96203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
96213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CHECK_ARITY(1);
962245490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard    if ((ctxt->value == NULL) ||
96233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	((ctxt->value->type != XPATH_NODESET) &&
96243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	 (ctxt->value->type != XPATH_XSLT_TREE)))
96253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	XP_ERROR(XPATH_INVALID_TYPE);
96263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    cur = valuePop(ctxt);
96273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
9628081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack    if ((cur->nodesetval != NULL) && (cur->nodesetval->nodeNr != 0)) {
9629ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	for (i = 0; i < cur->nodesetval->nodeNr; i++) {
9630ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	    res += xmlXPathCastNodeToNumber(cur->nodesetval->nodeTab[i]);
96313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
96323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
9633a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    valuePush(ctxt, xmlXPathCacheNewFloat(ctxt->context, res));
9634a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathReleaseObject(ctxt->context, cur);
96353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
96363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
96373d426663629a53180f3f54282ba27f3d070eef24William M. Brack/*
96383d426663629a53180f3f54282ba27f3d070eef24William M. Brack * To assure working code on multiple platforms, we want to only depend
96393d426663629a53180f3f54282ba27f3d070eef24William M. Brack * upon the characteristic truncation of converting a floating point value
96403d426663629a53180f3f54282ba27f3d070eef24William M. Brack * to an integer.  Unfortunately, because of the different storage sizes
96413d426663629a53180f3f54282ba27f3d070eef24William M. Brack * of our internal floating point value (double) and integer (int), we
96423d426663629a53180f3f54282ba27f3d070eef24William M. Brack * can't directly convert (see bug 301162).  This macro is a messy
96433d426663629a53180f3f54282ba27f3d070eef24William M. Brack * 'workaround'
96443d426663629a53180f3f54282ba27f3d070eef24William M. Brack */
96453d426663629a53180f3f54282ba27f3d070eef24William M. Brack#define XTRUNC(f, v)            \
96463d426663629a53180f3f54282ba27f3d070eef24William M. Brack    f = fmod((v), INT_MAX);     \
96473d426663629a53180f3f54282ba27f3d070eef24William M. Brack    f = (v) - (f) + (double)((int)(f));
96483d426663629a53180f3f54282ba27f3d070eef24William M. Brack
96493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
96503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathFloorFunction:
96513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
96523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs:  the number of arguments
96533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
96543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the floor() XPath function
96553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *    number floor(number)
96563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The floor function returns the largest (closest to positive infinity)
96573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * number that is not greater than the argument and that is an integer.
96583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
96593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
96603473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathFloorFunction(xmlXPathParserContextPtr ctxt, int nargs) {
966156cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard    double f;
966256cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard
96633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CHECK_ARITY(1);
96643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CAST_TO_NUMBER;
96653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CHECK_TYPE(XPATH_NUMBER);
966656cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard
96673d426663629a53180f3f54282ba27f3d070eef24William M. Brack    XTRUNC(f, ctxt->value->floatval);
966856cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard    if (f != ctxt->value->floatval) {
966956cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard	if (ctxt->value->floatval > 0)
967056cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard	    ctxt->value->floatval = f;
967156cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard	else
967256cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard	    ctxt->value->floatval = f - 1;
967356cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard    }
96743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
96753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
96763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
96773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathCeilingFunction:
96783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
96793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs:  the number of arguments
96803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
96813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the ceiling() XPath function
96823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *    number ceiling(number)
96833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The ceiling function returns the smallest (closest to negative infinity)
96843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * number that is not less than the argument and that is an integer.
96853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
96863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
96873473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathCeilingFunction(xmlXPathParserContextPtr ctxt, int nargs) {
96883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    double f;
96893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
96903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CHECK_ARITY(1);
96913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CAST_TO_NUMBER;
96923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CHECK_TYPE(XPATH_NUMBER);
96933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
96943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#if 0
96953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ctxt->value->floatval = ceil(ctxt->value->floatval);
96963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#else
96973d426663629a53180f3f54282ba27f3d070eef24William M. Brack    XTRUNC(f, ctxt->value->floatval);
969856cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard    if (f != ctxt->value->floatval) {
969956cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard	if (ctxt->value->floatval > 0)
970056cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard	    ctxt->value->floatval = f + 1;
97015fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard	else {
97025fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard	    if (ctxt->value->floatval < 0 && f == 0)
97035fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard	        ctxt->value->floatval = xmlXPathNZERO;
97045fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard	    else
97055fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard	        ctxt->value->floatval = f;
97065fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard	}
97075fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard
970856cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard    }
97093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif
97103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
97113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
97123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
97133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathRoundFunction:
97143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
97153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs:  the number of arguments
97163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
97173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the round() XPath function
97183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *    number round(number)
97193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The round function returns the number that is closest to the
97203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * argument and that is an integer. If there are two such numbers,
97213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * then the one that is even is returned.
97223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
97233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
97243473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathRoundFunction(xmlXPathParserContextPtr ctxt, int nargs) {
97253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    double f;
97263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
97273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CHECK_ARITY(1);
97283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CAST_TO_NUMBER;
97293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CHECK_TYPE(XPATH_NUMBER);
97303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
9731cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard    if ((xmlXPathIsNaN(ctxt->value->floatval)) ||
9732cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard	(xmlXPathIsInf(ctxt->value->floatval) == 1) ||
9733cda969218bdda1d3dd8d3c4417f3dc100d076024Daniel Veillard	(xmlXPathIsInf(ctxt->value->floatval) == -1) ||
97343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	(ctxt->value->floatval == 0.0))
97353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return;
97363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
97373d426663629a53180f3f54282ba27f3d070eef24William M. Brack    XTRUNC(f, ctxt->value->floatval);
973856cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard    if (ctxt->value->floatval < 0) {
973956cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard	if (ctxt->value->floatval < f - 0.5)
974056cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard	    ctxt->value->floatval = f - 1;
974145490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	else
974256cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard	    ctxt->value->floatval = f;
97435fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard	if (ctxt->value->floatval == 0)
97445fc1f0893af6ffe76453ac16817204a866bdeab2Daniel Veillard	    ctxt->value->floatval = xmlXPathNZERO;
974556cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard    } else {
974656cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard	if (ctxt->value->floatval < f + 0.5)
974756cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard	    ctxt->value->floatval = f;
974845490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	else
974956cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard	    ctxt->value->floatval = f + 1;
975056cd18b977006c28eaae715ac6590e6ad48186daDaniel Veillard    }
97513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
97523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
97533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/************************************************************************
97543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *									*
97553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *			The Parser					*
97563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *									*
97573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ************************************************************************/
97583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
97593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/*
9760081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack * a few forward declarations since we use a recursive call based
97613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * implementation.
97623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
97635691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcikstatic void xmlXPathCompileExpr(xmlXPathParserContextPtr ctxt, int sort);
9764d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillardstatic void xmlXPathCompPredicate(xmlXPathParserContextPtr ctxt, int filter);
9765afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void xmlXPathCompLocationPath(xmlXPathParserContextPtr ctxt);
9766afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void xmlXPathCompRelativeLocationPath(xmlXPathParserContextPtr ctxt);
97672156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillardstatic xmlChar * xmlXPathParseNameComplex(xmlXPathParserContextPtr ctxt,
97682156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard	                                  int qualified);
97693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
97703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
977161d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard * xmlXPathCurrentChar:
977261d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard * @ctxt:  the XPath parser context
977361d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard * @cur:  pointer to the beginning of the char
977461d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard * @len:  pointer to the length of the char read
977561d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard *
9776cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * The current char value, if using UTF-8 this may actually span multiple
977761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard * bytes in the input buffer.
977861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard *
977960087f30f3b4cf21de48f39181736e7d71e7a661Daniel Veillard * Returns the current char value and its length
978061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard */
978161d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard
978261d80a2822b2678dee885ac2850295cc96277c63Daniel Veillardstatic int
978361d80a2822b2678dee885ac2850295cc96277c63Daniel VeillardxmlXPathCurrentChar(xmlXPathParserContextPtr ctxt, int *len) {
978461d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard    unsigned char c;
978561d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard    unsigned int val;
978661d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard    const xmlChar *cur;
978761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard
978861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard    if (ctxt == NULL)
978961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	return(0);
979061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard    cur = ctxt->cur;
979161d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard
979261d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard    /*
979361d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard     * We are supposed to handle UTF8, check it's valid
979461d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard     * From rfc2044: encoding of the Unicode values on UTF-8:
979561d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard     *
979661d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard     * UCS-4 range (hex.)           UTF-8 octet sequence (binary)
979761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard     * 0000 0000-0000 007F   0xxxxxxx
979861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard     * 0000 0080-0000 07FF   110xxxxx 10xxxxxx
979945490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard     * 0000 0800-0000 FFFF   1110xxxx 10xxxxxx 10xxxxxx
980061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard     *
980161d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard     * Check for the 0x110000 limit too
980261d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard     */
980361d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard    c = *cur;
980461d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard    if (c & 0x80) {
980561d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	if ((cur[1] & 0xc0) != 0x80)
980661d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	    goto encoding_error;
980761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	if ((c & 0xe0) == 0xe0) {
980861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard
980961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	    if ((cur[2] & 0xc0) != 0x80)
981061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard		goto encoding_error;
981161d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	    if ((c & 0xf0) == 0xf0) {
981261d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard		if (((c & 0xf8) != 0xf0) ||
981361d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard		    ((cur[3] & 0xc0) != 0x80))
981461d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard		    goto encoding_error;
981561d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard		/* 4-byte code */
981661d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard		*len = 4;
981761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard		val = (cur[0] & 0x7) << 18;
981861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard		val |= (cur[1] & 0x3f) << 12;
981961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard		val |= (cur[2] & 0x3f) << 6;
982061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard		val |= cur[3] & 0x3f;
982161d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	    } else {
982261d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	      /* 3-byte code */
982361d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard		*len = 3;
982461d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard		val = (cur[0] & 0xf) << 12;
982561d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard		val |= (cur[1] & 0x3f) << 6;
982661d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard		val |= cur[2] & 0x3f;
982761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	    }
982861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	} else {
982961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	  /* 2-byte code */
983061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	    *len = 2;
983161d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	    val = (cur[0] & 0x1f) << 6;
983261d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	    val |= cur[1] & 0x3f;
983361d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	}
983461d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	if (!IS_CHAR(val)) {
983561d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	    XP_ERROR0(XPATH_INVALID_CHAR_ERROR);
983645490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	}
983761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	return(val);
983861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard    } else {
983961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	/* 1-byte code */
984061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	*len = 1;
984161d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	return((int) *cur);
984261d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard    }
984361d80a2822b2678dee885ac2850295cc96277c63Daniel Veillardencoding_error:
984461d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard    /*
9845081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack     * If we detect an UTF8 error that probably means that the
9846081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack     * input encoding didn't get properly advertised in the
984761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard     * declaration header. Report the error and switch the encoding
984861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard     * to ISO-Latin-1 (if you don't like this policy, just declare the
984961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard     * encoding !)
985061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard     */
985142596ad20cdf1925dd79ea801cbe598b6e7b7aecDaniel Veillard    *len = 0;
985261d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard    XP_ERROR0(XPATH_ENCODING_ERROR);
985361d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard}
985461d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard
985561d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard/**
98563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathParseNCName:
98573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
98583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
98593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * parse an XML namespace non qualified name.
98603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
98613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [NS 3] NCName ::= (Letter | '_') (NCNameChar)*
98623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
98633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [NS 4] NCNameChar ::= Letter | Digit | '.' | '-' | '_' |
98643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *                       CombiningChar | Extender
98653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
98663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the namespace name or NULL
98673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
98683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
98693473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlChar *
98703473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathParseNCName(xmlXPathParserContextPtr ctxt) {
98712156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard    const xmlChar *in;
98722156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard    xmlChar *ret;
98732156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard    int count = 0;
98743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
9875a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard    if ((ctxt == NULL) || (ctxt->cur == NULL)) return(NULL);
98762156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard    /*
98772156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard     * Accelerator for simple ASCII names
98782156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard     */
98792156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard    in = ctxt->cur;
98802156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard    if (((*in >= 0x61) && (*in <= 0x7A)) ||
98812156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard	((*in >= 0x41) && (*in <= 0x5A)) ||
98822156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard	(*in == '_')) {
98832156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard	in++;
98842156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard	while (((*in >= 0x61) && (*in <= 0x7A)) ||
98852156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard	       ((*in >= 0x41) && (*in <= 0x5A)) ||
98862156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard	       ((*in >= 0x30) && (*in <= 0x39)) ||
98879a89a8ab80bc021deec9da7d79bda20995c4e78dDaniel Veillard	       (*in == '_') || (*in == '.') ||
98889a89a8ab80bc021deec9da7d79bda20995c4e78dDaniel Veillard	       (*in == '-'))
98892156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard	    in++;
98902156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard	if ((*in == ' ') || (*in == '>') || (*in == '/') ||
98912156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard            (*in == '[') || (*in == ']') || (*in == ':') ||
98922156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard            (*in == '@') || (*in == '*')) {
98932156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard	    count = in - ctxt->cur;
98942156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard	    if (count == 0)
98952156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard		return(NULL);
98962156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard	    ret = xmlStrndup(ctxt->cur, count);
98972156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard	    ctxt->cur = in;
98982156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard	    return(ret);
98992156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard	}
99002156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard    }
99012156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard    return(xmlXPathParseNameComplex(ctxt, 0));
99023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
99033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
99042156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard
99053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
99063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathParseQName:
99073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
990845490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard * @prefix:  a xmlChar **
99093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
99103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * parse an XML qualified name
99113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
99123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [NS 5] QName ::= (Prefix ':')? LocalPart
99133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
99143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [NS 6] Prefix ::= NCName
99153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
99163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [NS 7] LocalPart ::= NCName
99173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
99183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the function returns the local part, and prefix is updated
99193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *   to get the Prefix if any.
99203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
99213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
992256a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic xmlChar *
99233473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathParseQName(xmlXPathParserContextPtr ctxt, xmlChar **prefix) {
99243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlChar *ret = NULL;
99253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
99263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    *prefix = NULL;
99273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret = xmlXPathParseNCName(ctxt);
9928074f37e7ebd5e76ceb584a89745a9e84df5b3be2Daniel Veillard    if (ret && CUR == ':') {
99293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        *prefix = ret;
99303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	NEXT;
99313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	ret = xmlXPathParseNCName(ctxt);
99323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
99333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(ret);
99343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
99353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
99363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
99373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathParseName:
99383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
99393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
99403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * parse an XML name
99413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
99423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [4] NameChar ::= Letter | Digit | '.' | '-' | '_' | ':' |
99433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *                  CombiningChar | Extender
99443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
99453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [5] Name ::= (Letter | '_' | ':') (NameChar)*
99463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
99473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the namespace name or NULL
99483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
99493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
99503473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlChar *
99513473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathParseName(xmlXPathParserContextPtr ctxt) {
995261d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard    const xmlChar *in;
995361d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard    xmlChar *ret;
9954cd852ad154fd919d9a4bd955566b43bac848878aDaniel Veillard    size_t count = 0;
99553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
9956a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard    if ((ctxt == NULL) || (ctxt->cur == NULL)) return(NULL);
995761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard    /*
995861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard     * Accelerator for simple ASCII names
995961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard     */
996061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard    in = ctxt->cur;
996161d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard    if (((*in >= 0x61) && (*in <= 0x7A)) ||
996261d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	((*in >= 0x41) && (*in <= 0x5A)) ||
996361d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	(*in == '_') || (*in == ':')) {
996461d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	in++;
996561d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	while (((*in >= 0x61) && (*in <= 0x7A)) ||
996661d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	       ((*in >= 0x41) && (*in <= 0x5A)) ||
996761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	       ((*in >= 0x30) && (*in <= 0x39)) ||
996876d66f416d2d0d5db4a09d212b4e43087e9cdae7Daniel Veillard	       (*in == '_') || (*in == '-') ||
996976d66f416d2d0d5db4a09d212b4e43087e9cdae7Daniel Veillard	       (*in == ':') || (*in == '.'))
997061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	    in++;
997176d66f416d2d0d5db4a09d212b4e43087e9cdae7Daniel Veillard	if ((*in > 0) && (*in < 0x80)) {
997261d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	    count = in - ctxt->cur;
9973cd852ad154fd919d9a4bd955566b43bac848878aDaniel Veillard            if (count > XML_MAX_NAME_LENGTH) {
9974cd852ad154fd919d9a4bd955566b43bac848878aDaniel Veillard                ctxt->cur = in;
9975cd852ad154fd919d9a4bd955566b43bac848878aDaniel Veillard                XP_ERRORNULL(XPATH_EXPR_ERROR);
9976cd852ad154fd919d9a4bd955566b43bac848878aDaniel Veillard            }
997761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	    ret = xmlStrndup(ctxt->cur, count);
997861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	    ctxt->cur = in;
997961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	    return(ret);
998061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	}
998161d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard    }
99822156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard    return(xmlXPathParseNameComplex(ctxt, 1));
998361d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard}
99843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
998561d80a2822b2678dee885ac2850295cc96277c63Daniel Veillardstatic xmlChar *
99862156a56bcbf5d83fb3d694123be01beebf84d273Daniel VeillardxmlXPathParseNameComplex(xmlXPathParserContextPtr ctxt, int qualified) {
998761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard    xmlChar buf[XML_MAX_NAMELEN + 5];
998861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard    int len = 0, l;
998961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard    int c;
99903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
999161d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard    /*
999261d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard     * Handler for more complex cases
999361d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard     */
999461d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard    c = CUR_CHAR(l);
999561d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard    if ((c == ' ') || (c == '>') || (c == '/') || /* accelerators */
99962156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard        (c == '[') || (c == ']') || (c == '@') || /* accelerators */
99972156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard        (c == '*') || /* accelerators */
999861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	(!IS_LETTER(c) && (c != '_') &&
99992156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard         ((qualified) && (c != ':')))) {
1000061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	return(NULL);
1000161d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard    }
100023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
1000361d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard    while ((c != ' ') && (c != '>') && (c != '/') && /* test bigname.xml */
1000461d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	   ((IS_LETTER(c)) || (IS_DIGIT(c)) ||
1000561d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard            (c == '.') || (c == '-') ||
1000645490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	    (c == '_') || ((qualified) && (c == ':')) ||
1000761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	    (IS_COMBINING(c)) ||
1000861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	    (IS_EXTENDER(c)))) {
1000961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	COPY_BUF(l,buf,len,c);
1001061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	NEXTL(l);
1001161d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	c = CUR_CHAR(l);
1001261d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	if (len >= XML_MAX_NAMELEN) {
1001361d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	    /*
1001461d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	     * Okay someone managed to make a huge name, so he's ready to pay
1001561d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	     * for the processing speed.
1001661d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	     */
1001761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	    xmlChar *buffer;
1001861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	    int max = len * 2;
1001945490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
10020cd852ad154fd919d9a4bd955566b43bac848878aDaniel Veillard            if (len > XML_MAX_NAME_LENGTH) {
10021cd852ad154fd919d9a4bd955566b43bac848878aDaniel Veillard                XP_ERRORNULL(XPATH_EXPR_ERROR);
10022cd852ad154fd919d9a4bd955566b43bac848878aDaniel Veillard            }
100233c908dca479ed50dca24b8593bca90e40dbde6b8Daniel Veillard	    buffer = (xmlChar *) xmlMallocAtomic(max * sizeof(xmlChar));
1002461d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	    if (buffer == NULL) {
1002524505b0f5c872c5afb6da5093565e5a6e09ca541Daniel Veillard		XP_ERRORNULL(XPATH_MEMORY_ERROR);
1002661d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	    }
1002761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	    memcpy(buffer, buf, len);
1002861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	    while ((IS_LETTER(c)) || (IS_DIGIT(c)) || /* test bigname.xml */
1002961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard		   (c == '.') || (c == '-') ||
1003045490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard		   (c == '_') || ((qualified) && (c == ':')) ||
1003161d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard		   (IS_COMBINING(c)) ||
1003261d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard		   (IS_EXTENDER(c))) {
1003361d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard		if (len + 10 > max) {
10034cd852ad154fd919d9a4bd955566b43bac848878aDaniel Veillard                    if (max > XML_MAX_NAME_LENGTH) {
10035cd852ad154fd919d9a4bd955566b43bac848878aDaniel Veillard                        XP_ERRORNULL(XPATH_EXPR_ERROR);
10036cd852ad154fd919d9a4bd955566b43bac848878aDaniel Veillard                    }
1003761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard		    max *= 2;
1003861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard		    buffer = (xmlChar *) xmlRealloc(buffer,
1003961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard			                            max * sizeof(xmlChar));
1004061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard		    if (buffer == NULL) {
1004124505b0f5c872c5afb6da5093565e5a6e09ca541Daniel Veillard			XP_ERRORNULL(XPATH_MEMORY_ERROR);
1004261d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard		    }
1004361d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard		}
1004461d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard		COPY_BUF(l,buffer,len,c);
1004561d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard		NEXTL(l);
1004661d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard		c = CUR_CHAR(l);
1004761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	    }
1004861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	    buffer[len] = 0;
1004961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	    return(buffer);
1005061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	}
1005161d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard    }
100522156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard    if (len == 0)
100532156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard	return(NULL);
1005461d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard    return(xmlStrndup(buf, len));
1005561d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard}
100563cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard
100573cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard#define MAX_FRAC 20
100583cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard
10059372a445479b859bd0fe24df54e9b3db34d113d5aWilliam M. Brack/*
10060372a445479b859bd0fe24df54e9b3db34d113d5aWilliam M. Brack * These are used as divisors for the fractional part of a number.
10061372a445479b859bd0fe24df54e9b3db34d113d5aWilliam M. Brack * Since the table includes 1.0 (representing '0' fractional digits),
10062372a445479b859bd0fe24df54e9b3db34d113d5aWilliam M. Brack * it must be dimensioned at MAX_FRAC+1 (bug 133921)
10063372a445479b859bd0fe24df54e9b3db34d113d5aWilliam M. Brack */
10064372a445479b859bd0fe24df54e9b3db34d113d5aWilliam M. Brackstatic double my_pow10[MAX_FRAC+1] = {
100653cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard    1.0, 10.0, 100.0, 1000.0, 10000.0,
100663cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard    100000.0, 1000000.0, 10000000.0, 100000000.0, 1000000000.0,
100673cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard    10000000000.0, 100000000000.0, 1000000000000.0, 10000000000000.0,
100683cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard    100000000000000.0,
100693cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard    1000000000000000.0, 10000000000000000.0, 100000000000000000.0,
10070372a445479b859bd0fe24df54e9b3db34d113d5aWilliam M. Brack    1000000000000000000.0, 10000000000000000000.0, 100000000000000000000.0
100713cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard};
100723cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard
100733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
100743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathStringEvalNumber:
100753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @str:  A string to scan
100763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
1007770a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese *  [30a]  Float  ::= Number ('e' Digits?)?
1007870a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese *
100793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *  [30]   Number ::=   Digits ('.' Digits?)?
1008045490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *                    | '.' Digits
100813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *  [31]   Digits ::=   [0-9]+
100823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
10083afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile a Number in the string
100843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * In complement of the Number expression, this function also handles
100853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * negative values : '-' Number.
100863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
100873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the double value.
100883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
100893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylordouble
100903473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathStringEvalNumber(const xmlChar *str) {
100913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    const xmlChar *cur = str;
100927b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard    double ret;
10093b06c61455f86758511aa050a06ff1bbd33f8c3c3Daniel Veillard    int ok = 0;
100943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    int isneg = 0;
1009570a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese    int exponent = 0;
1009670a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese    int is_exponent_negative = 0;
10097b06c61455f86758511aa050a06ff1bbd33f8c3c3Daniel Veillard#ifdef __GNUC__
10098b06c61455f86758511aa050a06ff1bbd33f8c3c3Daniel Veillard    unsigned long tmp = 0;
100997b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard    double temp;
10100b06c61455f86758511aa050a06ff1bbd33f8c3c3Daniel Veillard#endif
10101eca82810f0fb81f3e9936d2018347e1e19de513aDaniel Veillard    if (cur == NULL) return(0);
1010276e95df05556c9610b564b14cf578c8f9e34c9c1William M. Brack    while (IS_BLANK_CH(*cur)) cur++;
101033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if ((*cur != '.') && ((*cur < '0') || (*cur > '9')) && (*cur != '-')) {
101043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        return(xmlXPathNAN);
101053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
101063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (*cur == '-') {
101073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	isneg = 1;
101083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	cur++;
101093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
10110b06c61455f86758511aa050a06ff1bbd33f8c3c3Daniel Veillard
10111b06c61455f86758511aa050a06ff1bbd33f8c3c3Daniel Veillard#ifdef __GNUC__
10112d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard    /*
101137b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard     * tmp/temp is a workaround against a gcc compiler bug
101147b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard     * http://veillard.com/gcc.bug
10115d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard     */
101167b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard    ret = 0;
101173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    while ((*cur >= '0') && (*cur <= '9')) {
101187b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard	ret = ret * 10;
101197b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard	tmp = (*cur - '0');
101203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	ok = 1;
101213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	cur++;
101227b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard	temp = (double) tmp;
101237b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard	ret = ret + temp;
101243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
10125b06c61455f86758511aa050a06ff1bbd33f8c3c3Daniel Veillard#else
101267b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard    ret = 0;
10127b06c61455f86758511aa050a06ff1bbd33f8c3c3Daniel Veillard    while ((*cur >= '0') && (*cur <= '9')) {
10128b06c61455f86758511aa050a06ff1bbd33f8c3c3Daniel Veillard	ret = ret * 10 + (*cur - '0');
10129b06c61455f86758511aa050a06ff1bbd33f8c3c3Daniel Veillard	ok = 1;
10130b06c61455f86758511aa050a06ff1bbd33f8c3c3Daniel Veillard	cur++;
10131b06c61455f86758511aa050a06ff1bbd33f8c3c3Daniel Veillard    }
10132b06c61455f86758511aa050a06ff1bbd33f8c3c3Daniel Veillard#endif
10133d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard
101343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (*cur == '.') {
101353cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard	int v, frac = 0;
101363cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard	double fraction = 0;
101373cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard
101383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        cur++;
101393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (((*cur < '0') || (*cur > '9')) && (!ok)) {
101403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    return(xmlXPathNAN);
101413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
101423cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard	while (((*cur >= '0') && (*cur <= '9')) && (frac < MAX_FRAC)) {
101433cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard	    v = (*cur - '0');
101443cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard	    fraction = fraction * 10 + v;
101453cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard	    frac = frac + 1;
101463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    cur++;
101473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
101483cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard	fraction /= my_pow10[frac];
101493cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard	ret = ret + fraction;
101503cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard	while ((*cur >= '0') && (*cur <= '9'))
101513cd7240da45a00a17f003b67881d8e4afb618711Daniel Veillard	    cur++;
101523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
1015370a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese    if ((*cur == 'e') || (*cur == 'E')) {
1015470a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese      cur++;
1015570a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese      if (*cur == '-') {
1015670a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese	is_exponent_negative = 1;
1015770a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese	cur++;
101589912705b82cbf3fbff43e19dd95dd0a6ec494d2dWilliam M. Brack      } else if (*cur == '+') {
101599912705b82cbf3fbff43e19dd95dd0a6ec494d2dWilliam M. Brack        cur++;
1016070a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese      }
1016170a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese      while ((*cur >= '0') && (*cur <= '9')) {
1016270a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese	exponent = exponent * 10 + (*cur - '0');
1016370a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese	cur++;
1016470a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese      }
1016570a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese    }
1016676e95df05556c9610b564b14cf578c8f9e34c9c1William M. Brack    while (IS_BLANK_CH(*cur)) cur++;
101673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (*cur != 0) return(xmlXPathNAN);
101683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (isneg) ret = -ret;
1016970a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese    if (is_exponent_negative) exponent = -exponent;
1017070a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese    ret *= pow(10.0, (double)exponent);
101713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(ret);
101723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
101733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
101743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
10175afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompNumber:
101763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
101773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
101783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *  [30]   Number ::=   Digits ('.' Digits?)?
1017945490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *                    | '.' Digits
101803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *  [31]   Digits ::=   [0-9]+
101813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
10182afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile a Number, then push it on the stack
101833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
101843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
10185afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void
10186d79bcd1b36412a7996ace1900ab613e38a609b60Daniel VeillardxmlXPathCompNumber(xmlXPathParserContextPtr ctxt)
10187d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard{
101883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    double ret = 0.0;
101897b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard    int ok = 0;
1019070a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese    int exponent = 0;
1019170a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese    int is_exponent_negative = 0;
101927b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard#ifdef __GNUC__
101937b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard    unsigned long tmp = 0;
101947b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard    double temp;
101957b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard#endif
101963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
101973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CHECK_ERROR;
101983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if ((CUR != '.') && ((CUR < '0') || (CUR > '9'))) {
101993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        XP_ERROR(XPATH_NUMBER_ERROR);
102003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
102017b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard#ifdef __GNUC__
10202d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard    /*
102037b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard     * tmp/temp is a workaround against a gcc compiler bug
102047b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard     * http://veillard.com/gcc.bug
10205d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard     */
102067b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard    ret = 0;
102073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    while ((CUR >= '0') && (CUR <= '9')) {
102087b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard	ret = ret * 10;
102097b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard	tmp = (CUR - '0');
10210d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard        ok = 1;
10211d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard        NEXT;
102127b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard	temp = (double) tmp;
102137b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard	ret = ret + temp;
102143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
102157b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard#else
102167b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard    ret = 0;
102177b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard    while ((CUR >= '0') && (CUR <= '9')) {
102187b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard	ret = ret * 10 + (CUR - '0');
102197b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard	ok = 1;
102207b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard	NEXT;
102217b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard    }
102227b41613ff3a060180b2e92ad3bb0366061537a29Daniel Veillard#endif
102233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (CUR == '.') {
10224ee32ad3c0f6dfbb1b0e57db63d16f6455d6416dfPhil Shafer	int v, frac = 0;
10225ee32ad3c0f6dfbb1b0e57db63d16f6455d6416dfPhil Shafer	double fraction = 0;
10226ee32ad3c0f6dfbb1b0e57db63d16f6455d6416dfPhil Shafer
102273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        NEXT;
10228d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard        if (((CUR < '0') || (CUR > '9')) && (!ok)) {
10229d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard            XP_ERROR(XPATH_NUMBER_ERROR);
10230d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard        }
10231ee32ad3c0f6dfbb1b0e57db63d16f6455d6416dfPhil Shafer        while ((CUR >= '0') && (CUR <= '9') && (frac < MAX_FRAC)) {
10232ee32ad3c0f6dfbb1b0e57db63d16f6455d6416dfPhil Shafer	    v = (CUR - '0');
10233ee32ad3c0f6dfbb1b0e57db63d16f6455d6416dfPhil Shafer	    fraction = fraction * 10 + v;
10234ee32ad3c0f6dfbb1b0e57db63d16f6455d6416dfPhil Shafer	    frac = frac + 1;
10235d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard            NEXT;
10236d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard        }
10237ee32ad3c0f6dfbb1b0e57db63d16f6455d6416dfPhil Shafer        fraction /= my_pow10[frac];
10238ee32ad3c0f6dfbb1b0e57db63d16f6455d6416dfPhil Shafer        ret = ret + fraction;
10239ee32ad3c0f6dfbb1b0e57db63d16f6455d6416dfPhil Shafer        while ((CUR >= '0') && (CUR <= '9'))
10240ee32ad3c0f6dfbb1b0e57db63d16f6455d6416dfPhil Shafer            NEXT;
102413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
1024270a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese    if ((CUR == 'e') || (CUR == 'E')) {
10243d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard        NEXT;
10244d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard        if (CUR == '-') {
10245d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard            is_exponent_negative = 1;
10246d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard            NEXT;
102479912705b82cbf3fbff43e19dd95dd0a6ec494d2dWilliam M. Brack        } else if (CUR == '+') {
102489912705b82cbf3fbff43e19dd95dd0a6ec494d2dWilliam M. Brack	    NEXT;
102499912705b82cbf3fbff43e19dd95dd0a6ec494d2dWilliam M. Brack	}
10250d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard        while ((CUR >= '0') && (CUR <= '9')) {
10251d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard            exponent = exponent * 10 + (CUR - '0');
10252d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard            NEXT;
10253d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard        }
10254d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard        if (is_exponent_negative)
10255d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard            exponent = -exponent;
10256d79bcd1b36412a7996ace1900ab613e38a609b60Daniel Veillard        ret *= pow(10.0, (double) exponent);
1025770a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese    }
102589e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    PUSH_LONG_EXPR(XPATH_OP_VALUE, XPATH_NUMBER, 0, 0,
10259a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik                   xmlXPathCacheNewFloat(ctxt->context, ret), NULL);
102603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
102613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
102623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
10263fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * xmlXPathParseLiteral:
10264fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * @ctxt:  the XPath Parser context
10265fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard *
10266fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * Parse a Literal
10267fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard *
10268fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard *  [29]   Literal ::=   '"' [^"]* '"'
10269fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard *                    | "'" [^']* "'"
10270fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard *
10271fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * Returns the value found or NULL in case of error
10272fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard */
10273fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillardstatic xmlChar *
10274fbf8a2d0c8145b713099df63d174154a8442e60dDaniel VeillardxmlXPathParseLiteral(xmlXPathParserContextPtr ctxt) {
10275fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard    const xmlChar *q;
10276fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard    xmlChar *ret = NULL;
10277fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard
10278fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard    if (CUR == '"') {
10279fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard        NEXT;
10280fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard	q = CUR_PTR;
1028176e95df05556c9610b564b14cf578c8f9e34c9c1William M. Brack	while ((IS_CHAR_CH(CUR)) && (CUR != '"'))
10282fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard	    NEXT;
1028376e95df05556c9610b564b14cf578c8f9e34c9c1William M. Brack	if (!IS_CHAR_CH(CUR)) {
1028424505b0f5c872c5afb6da5093565e5a6e09ca541Daniel Veillard	    XP_ERRORNULL(XPATH_UNFINISHED_LITERAL_ERROR);
10285fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard	} else {
10286fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard	    ret = xmlStrndup(q, CUR_PTR - q);
10287fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard	    NEXT;
10288fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard        }
10289fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard    } else if (CUR == '\'') {
10290fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard        NEXT;
10291fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard	q = CUR_PTR;
1029276e95df05556c9610b564b14cf578c8f9e34c9c1William M. Brack	while ((IS_CHAR_CH(CUR)) && (CUR != '\''))
10293fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard	    NEXT;
1029476e95df05556c9610b564b14cf578c8f9e34c9c1William M. Brack	if (!IS_CHAR_CH(CUR)) {
1029524505b0f5c872c5afb6da5093565e5a6e09ca541Daniel Veillard	    XP_ERRORNULL(XPATH_UNFINISHED_LITERAL_ERROR);
10296fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard	} else {
10297fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard	    ret = xmlStrndup(q, CUR_PTR - q);
10298fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard	    NEXT;
10299fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard        }
10300fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard    } else {
1030124505b0f5c872c5afb6da5093565e5a6e09ca541Daniel Veillard	XP_ERRORNULL(XPATH_START_LITERAL_ERROR);
10302fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard    }
10303fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard    return(ret);
10304fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard}
10305fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard
10306fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard/**
10307afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompLiteral:
103083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
103093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
103103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Parse a Literal and push it on the stack.
103113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
103123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *  [29]   Literal ::=   '"' [^"]* '"'
103133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *                    | "'" [^']* "'"
103143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
10315afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * TODO: xmlXPathCompLiteral memory allocation could be improved.
103163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
10317afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void
10318afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompLiteral(xmlXPathParserContextPtr ctxt) {
103193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    const xmlChar *q;
103203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlChar *ret = NULL;
103213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
103223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (CUR == '"') {
103233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        NEXT;
103243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	q = CUR_PTR;
1032576e95df05556c9610b564b14cf578c8f9e34c9c1William M. Brack	while ((IS_CHAR_CH(CUR)) && (CUR != '"'))
103263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    NEXT;
1032776e95df05556c9610b564b14cf578c8f9e34c9c1William M. Brack	if (!IS_CHAR_CH(CUR)) {
103283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    XP_ERROR(XPATH_UNFINISHED_LITERAL_ERROR);
103293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	} else {
103303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    ret = xmlStrndup(q, CUR_PTR - q);
103313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    NEXT;
103323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        }
103333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    } else if (CUR == '\'') {
103343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        NEXT;
103353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	q = CUR_PTR;
1033676e95df05556c9610b564b14cf578c8f9e34c9c1William M. Brack	while ((IS_CHAR_CH(CUR)) && (CUR != '\''))
103373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    NEXT;
1033876e95df05556c9610b564b14cf578c8f9e34c9c1William M. Brack	if (!IS_CHAR_CH(CUR)) {
103393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    XP_ERROR(XPATH_UNFINISHED_LITERAL_ERROR);
103403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	} else {
103413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    ret = xmlStrndup(q, CUR_PTR - q);
103423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    NEXT;
103433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        }
103443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    } else {
103453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	XP_ERROR(XPATH_START_LITERAL_ERROR);
103463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
103473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ret == NULL) return;
103489e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    PUSH_LONG_EXPR(XPATH_OP_VALUE, XPATH_STRING, 0, 0,
10349a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	           xmlXPathCacheNewString(ctxt->context, ret), NULL);
103503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlFree(ret);
103513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
103523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
103533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
10354afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompVariableReference:
103553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
103563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
103573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Parse a VariableReference, evaluate it and push it on the stack.
103583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
103593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The variable bindings consist of a mapping from variable names
10360081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack * to variable values. The value of a variable is an object, which can be
103613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * of any of the types that are possible for the value of an expression,
103623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * and may also be of additional types not specified here.
103633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
103643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Early evaluation is possible since:
103653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The variable bindings [...] used to evaluate a subexpression are
1036645490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard * always the same as those used to evaluate the containing expression.
103673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
1036845490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *  [36]   VariableReference ::=   '$' QName
103693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
10370afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void
10371afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompVariableReference(xmlXPathParserContextPtr ctxt) {
103723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlChar *name;
103733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlChar *prefix;
103743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
103753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    SKIP_BLANKS;
103763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (CUR != '$') {
103773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	XP_ERROR(XPATH_VARIABLE_REF_ERROR);
103783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
103793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    NEXT;
103803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    name = xmlXPathParseQName(ctxt, &prefix);
103813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (name == NULL) {
103823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	XP_ERROR(XPATH_VARIABLE_REF_ERROR);
103833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
10384fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard    ctxt->comp->last = -1;
103859e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    PUSH_LONG_EXPR(XPATH_OP_VARIABLE, 0, 0, 0,
103869e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	           name, prefix);
103873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    SKIP_BLANKS;
10388b3d1491b69060f8a67516b9a3ef12617adf88954Daniel Veillard    if ((ctxt->context != NULL) && (ctxt->context->flags & XML_XPATH_NOVAR)) {
1038947881284aeaeeb93b3444419adeffc9e11ed1093Daniel Veillard	XP_ERROR(XPATH_FORBID_VARIABLE_ERROR);
10390b3d1491b69060f8a67516b9a3ef12617adf88954Daniel Veillard    }
103913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
103923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
103933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
103943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathIsNodeType:
103953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @name:  a name string
103963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
103973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Is the name given a NodeType one.
103983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
103993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *  [38]   NodeType ::=   'comment'
104003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *                    | 'text'
104013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *                    | 'processing-instruction'
104023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *                    | 'node'
104033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
104043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns 1 if true 0 otherwise
104053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
104063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorint
104073473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathIsNodeType(const xmlChar *name) {
104083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (name == NULL)
104093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(0);
104103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
104111971ee2698cb84c7699c96d3302f00e20d42c0d3Daniel Veillard    if (xmlStrEqual(name, BAD_CAST "node"))
104123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(1);
104133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (xmlStrEqual(name, BAD_CAST "text"))
104143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(1);
104151971ee2698cb84c7699c96d3302f00e20d42c0d3Daniel Veillard    if (xmlStrEqual(name, BAD_CAST "comment"))
104163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(1);
104171971ee2698cb84c7699c96d3302f00e20d42c0d3Daniel Veillard    if (xmlStrEqual(name, BAD_CAST "processing-instruction"))
104183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(1);
104193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(0);
104203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
104213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
104223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
10423afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompFunctionCall:
104243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
104253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
104263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *  [16]   FunctionCall ::=   FunctionName '(' ( Argument ( ',' Argument)*)? ')'
1042745490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *  [17]   Argument ::=   Expr
104283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
10429afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile a function call, the evaluation of all arguments are
104303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * pushed on the stack
104313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
10432afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void
10433afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompFunctionCall(xmlXPathParserContextPtr ctxt) {
104343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlChar *name;
104353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlChar *prefix;
104363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    int nbargs = 0;
104375691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik    int sort = 1;
104383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
104393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    name = xmlXPathParseQName(ctxt, &prefix);
104403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (name == NULL) {
10441074f37e7ebd5e76ceb584a89745a9e84df5b3be2Daniel Veillard	xmlFree(prefix);
104423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	XP_ERROR(XPATH_EXPR_ERROR);
104433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
104443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    SKIP_BLANKS;
104453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_EXPR
104463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (prefix == NULL)
104473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	xmlGenericError(xmlGenericErrorContext, "Calling function %s\n",
104483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor			name);
104493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    else
104503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	xmlGenericError(xmlGenericErrorContext, "Calling function %s:%s\n",
104513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor			prefix, name);
104523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif
104533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
104543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (CUR != '(') {
104553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	XP_ERROR(XPATH_EXPR_ERROR);
104563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
104573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    NEXT;
104583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    SKIP_BLANKS;
104593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
104605691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik    /*
104615691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik    * Optimization for count(): we don't need the node-set to be sorted.
104625691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik    */
104635691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik    if ((prefix == NULL) && (name[0] == 'c') &&
104645691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	xmlStrEqual(name, BAD_CAST "count"))
104655691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik    {
104665691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	sort = 0;
104675691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik    }
104689e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    ctxt->comp->last = -1;
1046971f9d7310c1f8c587f518ec685b1448160df7336Daniel Veillard    if (CUR != ')') {
1047071f9d7310c1f8c587f518ec685b1448160df7336Daniel Veillard	while (CUR != 0) {
1047171f9d7310c1f8c587f518ec685b1448160df7336Daniel Veillard	    int op1 = ctxt->comp->last;
1047271f9d7310c1f8c587f518ec685b1448160df7336Daniel Veillard	    ctxt->comp->last = -1;
104735691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    xmlXPathCompileExpr(ctxt, sort);
10474074f37e7ebd5e76ceb584a89745a9e84df5b3be2Daniel Veillard	    if (ctxt->error != XPATH_EXPRESSION_OK) {
10475074f37e7ebd5e76ceb584a89745a9e84df5b3be2Daniel Veillard		xmlFree(name);
10476074f37e7ebd5e76ceb584a89745a9e84df5b3be2Daniel Veillard		xmlFree(prefix);
10477074f37e7ebd5e76ceb584a89745a9e84df5b3be2Daniel Veillard		return;
10478074f37e7ebd5e76ceb584a89745a9e84df5b3be2Daniel Veillard	    }
1047971f9d7310c1f8c587f518ec685b1448160df7336Daniel Veillard	    PUSH_BINARY_EXPR(XPATH_OP_ARG, op1, ctxt->comp->last, 0, 0);
1048071f9d7310c1f8c587f518ec685b1448160df7336Daniel Veillard	    nbargs++;
1048171f9d7310c1f8c587f518ec685b1448160df7336Daniel Veillard	    if (CUR == ')') break;
1048271f9d7310c1f8c587f518ec685b1448160df7336Daniel Veillard	    if (CUR != ',') {
1048371f9d7310c1f8c587f518ec685b1448160df7336Daniel Veillard		XP_ERROR(XPATH_EXPR_ERROR);
1048471f9d7310c1f8c587f518ec685b1448160df7336Daniel Veillard	    }
1048571f9d7310c1f8c587f518ec685b1448160df7336Daniel Veillard	    NEXT;
1048671f9d7310c1f8c587f518ec685b1448160df7336Daniel Veillard	    SKIP_BLANKS;
104873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
104883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
104899e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    PUSH_LONG_EXPR(XPATH_OP_FUNCTION, nbargs, 0, 0,
104909e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	           name, prefix);
104913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    NEXT;
104923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    SKIP_BLANKS;
104933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
104943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
104953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
10496afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompPrimaryExpr:
104973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
104983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
1049945490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *  [15]   PrimaryExpr ::=   VariableReference
105003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *                | '(' Expr ')'
1050145490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *                | Literal
1050245490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *                | Number
1050345490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *                | FunctionCall
105043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
10505afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile a primary expression.
105063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
10507afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void
10508afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompPrimaryExpr(xmlXPathParserContextPtr ctxt) {
105093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    SKIP_BLANKS;
10510afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard    if (CUR == '$') xmlXPathCompVariableReference(ctxt);
105113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    else if (CUR == '(') {
105123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	NEXT;
105133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	SKIP_BLANKS;
105145691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	xmlXPathCompileExpr(ctxt, 1);
1051550fe8b1732048003f47b32b009507fe6cdecd39fAleksey Sanin	CHECK_ERROR;
105163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (CUR != ')') {
105173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    XP_ERROR(XPATH_EXPR_ERROR);
105183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
105193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	NEXT;
105203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	SKIP_BLANKS;
10521d1757abcb891e01a9017f4aad041cc306d0d467bWilliam M. Brack    } else if (IS_ASCII_DIGIT(CUR) || (CUR == '.' && IS_ASCII_DIGIT(NXT(1)))) {
10522afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard	xmlXPathCompNumber(ctxt);
105233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    } else if ((CUR == '\'') || (CUR == '"')) {
10524afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard	xmlXPathCompLiteral(ctxt);
105253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    } else {
10526afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard	xmlXPathCompFunctionCall(ctxt);
105273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
105283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    SKIP_BLANKS;
105293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
105303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
105313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
10532afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompFilterExpr:
105333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
105343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
1053545490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *  [20]   FilterExpr ::=   PrimaryExpr
1053645490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *               | FilterExpr Predicate
105373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
10538afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile a filter expression.
105393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Square brackets are used to filter expressions in the same way that
105403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * they are used in location paths. It is an error if the expression to
105413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * be filtered does not evaluate to a node-set. The context node list
105423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * used for evaluating the expression in square brackets is the node-set
105433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * to be filtered listed in document order.
105443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
105453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
10546afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void
10547afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompFilterExpr(xmlXPathParserContextPtr ctxt) {
10548afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard    xmlXPathCompPrimaryExpr(ctxt);
105493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CHECK_ERROR;
105503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    SKIP_BLANKS;
1055145490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
105523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    while (CUR == '[') {
10553d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	xmlXPathCompPredicate(ctxt, 1);
105543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	SKIP_BLANKS;
105553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
105563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
1055745490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
105583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
105593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
105603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
105613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathScanName:
105623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
105633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
105643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Trickery: parse an XML name but without consuming the input flow
105653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Needed to avoid insanity in the parser state.
105663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
105673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [4] NameChar ::= Letter | Digit | '.' | '-' | '_' | ':' |
105683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *                  CombiningChar | Extender
105693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
105703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [5] Name ::= (Letter | '_' | ':') (NameChar)*
105713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
105723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [6] Names ::= Name (S Name)*
105733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
105743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the Name parsed or NULL
105753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
105763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
1057756a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic xmlChar *
105783473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathScanName(xmlXPathParserContextPtr ctxt) {
10579032268145fad72bbf00c944c1f6a067e5da4a1e0Daniel Veillard    int len = 0, l;
10580032268145fad72bbf00c944c1f6a067e5da4a1e0Daniel Veillard    int c;
10581032268145fad72bbf00c944c1f6a067e5da4a1e0Daniel Veillard    const xmlChar *cur;
10582032268145fad72bbf00c944c1f6a067e5da4a1e0Daniel Veillard    xmlChar *ret;
105833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
10584032268145fad72bbf00c944c1f6a067e5da4a1e0Daniel Veillard    cur = ctxt->cur;
10585032268145fad72bbf00c944c1f6a067e5da4a1e0Daniel Veillard
10586032268145fad72bbf00c944c1f6a067e5da4a1e0Daniel Veillard    c = CUR_CHAR(l);
10587032268145fad72bbf00c944c1f6a067e5da4a1e0Daniel Veillard    if ((c == ' ') || (c == '>') || (c == '/') || /* accelerators */
10588032268145fad72bbf00c944c1f6a067e5da4a1e0Daniel Veillard	(!IS_LETTER(c) && (c != '_') &&
10589032268145fad72bbf00c944c1f6a067e5da4a1e0Daniel Veillard         (c != ':'))) {
105903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(NULL);
105913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
105923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
10593032268145fad72bbf00c944c1f6a067e5da4a1e0Daniel Veillard    while ((c != ' ') && (c != '>') && (c != '/') && /* test bigname.xml */
10594032268145fad72bbf00c944c1f6a067e5da4a1e0Daniel Veillard	   ((IS_LETTER(c)) || (IS_DIGIT(c)) ||
10595032268145fad72bbf00c944c1f6a067e5da4a1e0Daniel Veillard            (c == '.') || (c == '-') ||
1059645490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	    (c == '_') || (c == ':') ||
10597032268145fad72bbf00c944c1f6a067e5da4a1e0Daniel Veillard	    (IS_COMBINING(c)) ||
10598032268145fad72bbf00c944c1f6a067e5da4a1e0Daniel Veillard	    (IS_EXTENDER(c)))) {
10599032268145fad72bbf00c944c1f6a067e5da4a1e0Daniel Veillard	len += l;
10600032268145fad72bbf00c944c1f6a067e5da4a1e0Daniel Veillard	NEXTL(l);
10601032268145fad72bbf00c944c1f6a067e5da4a1e0Daniel Veillard	c = CUR_CHAR(l);
106023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
10603032268145fad72bbf00c944c1f6a067e5da4a1e0Daniel Veillard    ret = xmlStrndup(cur, ctxt->cur - cur);
10604032268145fad72bbf00c944c1f6a067e5da4a1e0Daniel Veillard    ctxt->cur = cur;
10605032268145fad72bbf00c944c1f6a067e5da4a1e0Daniel Veillard    return(ret);
106063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
106073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
106083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
10609afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompPathExpr:
106103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
106113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
1061245490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *  [19]   PathExpr ::=   LocationPath
1061345490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *               | FilterExpr
1061445490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *               | FilterExpr '/' RelativeLocationPath
1061545490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *               | FilterExpr '//' RelativeLocationPath
106163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
10617afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile a path expression.
106183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The / operator and // operators combine an arbitrary expression
106193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * and a relative location path. It is an error if the expression
106203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * does not evaluate to a node-set.
106213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The / operator does composition in the same way as when / is
106223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * used in a location path. As in location paths, // is short for
106233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * /descendant-or-self::node()/.
106243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
106253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
10626afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void
10627afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompPathExpr(xmlXPathParserContextPtr ctxt) {
106283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    int lc = 1;           /* Should we branch to LocationPath ?         */
106293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlChar *name = NULL; /* we may have to preparse a name to find out */
106303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
106313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    SKIP_BLANKS;
1063245490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard    if ((CUR == '$') || (CUR == '(') ||
1063345490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	(IS_ASCII_DIGIT(CUR)) ||
10634d1757abcb891e01a9017f4aad041cc306d0d467bWilliam M. Brack        (CUR == '\'') || (CUR == '"') ||
10635d1757abcb891e01a9017f4aad041cc306d0d467bWilliam M. Brack	(CUR == '.' && IS_ASCII_DIGIT(NXT(1)))) {
106363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	lc = 0;
106373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    } else if (CUR == '*') {
106383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	/* relative or absolute location path */
106393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	lc = 1;
106403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    } else if (CUR == '/') {
106413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	/* relative or absolute location path */
106423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	lc = 1;
106433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    } else if (CUR == '@') {
106443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	/* relative abbreviated attribute location path */
106453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	lc = 1;
106463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    } else if (CUR == '.') {
106473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	/* relative abbreviated attribute location path */
106483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	lc = 1;
106493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    } else {
106503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	/*
106513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	 * Problem is finding if we have a name here whether it's:
106523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	 *   - a nodetype
106533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	 *   - a function call in which case it's followed by '('
106543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	 *   - an axis in which case it's followed by ':'
106553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	 *   - a element name
106563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	 * We do an a priori analysis here rather than having to
106573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	 * maintain parsed token content through the recursive function
10658081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack	 * calls. This looks uglier but makes the code easier to
106593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	 * read/write/debug.
106603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	 */
106613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	SKIP_BLANKS;
106623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	name = xmlXPathScanName(ctxt);
106633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if ((name != NULL) && (xmlStrstr(name, (xmlChar *) "::") != NULL)) {
106643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_STEP
106653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    xmlGenericError(xmlGenericErrorContext,
106663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    "PathExpr: Axis\n");
106673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif
106683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    lc = 1;
106693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    xmlFree(name);
106703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	} else if (name != NULL) {
106713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    int len =xmlStrlen(name);
106723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
1067345490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
106743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    while (NXT(len) != 0) {
106753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		if (NXT(len) == '/') {
106763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    /* element name */
106773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_STEP
106783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    xmlGenericError(xmlGenericErrorContext,
106793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor			    "PathExpr: AbbrRelLocation\n");
106803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif
106813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    lc = 1;
106823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    break;
1068376e95df05556c9610b564b14cf578c8f9e34c9c1William M. Brack		} else if (IS_BLANK_CH(NXT(len))) {
1068478637da0ea1c833dfdfad87a9aa5bea14510d08aWilliam M. Brack		    /* ignore blanks */
1068578637da0ea1c833dfdfad87a9aa5bea14510d08aWilliam M. Brack		    ;
106863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		} else if (NXT(len) == ':') {
106873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_STEP
106883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    xmlGenericError(xmlGenericErrorContext,
106893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor			    "PathExpr: AbbrRelLocation\n");
106903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif
106913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    lc = 1;
106923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    break;
106933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		} else if ((NXT(len) == '(')) {
106943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    /* Note Type or Function */
106953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    if (xmlXPathIsNodeType(name)) {
106963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_STEP
106973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		        xmlGenericError(xmlGenericErrorContext,
106983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor				"PathExpr: Type search\n");
106993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif
107003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor			lc = 1;
107013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    } else {
107023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_STEP
107033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		        xmlGenericError(xmlGenericErrorContext,
107043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor				"PathExpr: function call\n");
107053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif
107063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor			lc = 0;
107073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    }
107083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor                    break;
107093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		} else if ((NXT(len) == '[')) {
107103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    /* element name */
107113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_STEP
107123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    xmlGenericError(xmlGenericErrorContext,
107133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor			    "PathExpr: AbbrRelLocation\n");
107143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif
107153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    lc = 1;
107163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    break;
107173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		} else if ((NXT(len) == '<') || (NXT(len) == '>') ||
107183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor			   (NXT(len) == '=')) {
107193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    lc = 1;
107203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    break;
107213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		} else {
107223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    lc = 1;
107233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    break;
107243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		}
107253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		len++;
107263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    }
107273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    if (NXT(len) == 0) {
107283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_STEP
107293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		xmlGenericError(xmlGenericErrorContext,
107303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor			"PathExpr: AbbrRelLocation\n");
107313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif
107323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		/* element name */
107333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		lc = 1;
107343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    }
107353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    xmlFree(name);
107363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	} else {
10737081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack	    /* make sure all cases are covered explicitly */
107383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    XP_ERROR(XPATH_EXPR_ERROR);
107393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
1074045490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard    }
107413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
107423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (lc) {
107439e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	if (CUR == '/') {
107449e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    PUSH_LEAVE_EXPR(XPATH_OP_ROOT, 0, 0);
107459e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	} else {
107469e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    PUSH_LEAVE_EXPR(XPATH_OP_NODE, 0, 0);
107473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
10748afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard	xmlXPathCompLocationPath(ctxt);
107493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    } else {
10750afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard	xmlXPathCompFilterExpr(ctxt);
107513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	CHECK_ERROR;
107523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if ((CUR == '/') && (NXT(1) == '/')) {
107533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    SKIP(2);
107543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    SKIP_BLANKS;
107559e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
107569e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    PUSH_LONG_EXPR(XPATH_OP_COLLECT, AXIS_DESCENDANT_OR_SELF,
107579e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    NODE_TEST_TYPE, NODE_TYPE_NODE, NULL, NULL);
107589e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    PUSH_UNARY_EXPR(XPATH_OP_RESET, ctxt->comp->last, 1, 0);
107599e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
10760afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard	    xmlXPathCompRelativeLocationPath(ctxt);
107613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	} else if (CUR == '/') {
10762afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard	    xmlXPathCompRelativeLocationPath(ctxt);
107633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
107643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
107653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    SKIP_BLANKS;
107663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
107673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
107683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
10769afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompUnionExpr:
107703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
107713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
1077245490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *  [18]   UnionExpr ::=   PathExpr
1077345490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *               | UnionExpr '|' PathExpr
107743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
10775afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile an union expression.
107763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
107773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
10778afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void
10779afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompUnionExpr(xmlXPathParserContextPtr ctxt) {
10780afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard    xmlXPathCompPathExpr(ctxt);
107813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CHECK_ERROR;
107823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    SKIP_BLANKS;
107833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    while (CUR == '|') {
107849e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	int op1 = ctxt->comp->last;
107859e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	PUSH_LEAVE_EXPR(XPATH_OP_NODE, 0, 0);
107863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
107873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	NEXT;
107883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	SKIP_BLANKS;
10789afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard	xmlXPathCompPathExpr(ctxt);
107903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
107919e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	PUSH_BINARY_EXPR(XPATH_OP_UNION, op1, ctxt->comp->last, 0, 0);
107929e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
107933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	SKIP_BLANKS;
107943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
107953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
107963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
107973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
10798afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompUnaryExpr:
107993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
108003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
1080145490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *  [27]   UnaryExpr ::=   UnionExpr
1080245490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *                   | '-' UnaryExpr
108033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
10804afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile an unary expression.
108053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
108063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
10807afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void
10808afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompUnaryExpr(xmlXPathParserContextPtr ctxt) {
108093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    int minus = 0;
108109e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    int found = 0;
108113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
108123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    SKIP_BLANKS;
1081368d7b67ada0941ad7e1d02602f48de4015a67af3Daniel Veillard    while (CUR == '-') {
1081468d7b67ada0941ad7e1d02602f48de4015a67af3Daniel Veillard        minus = 1 - minus;
108159e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	found = 1;
108163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	NEXT;
108173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	SKIP_BLANKS;
108183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
108199e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
10820afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard    xmlXPathCompUnionExpr(ctxt);
108213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CHECK_ERROR;
108229e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    if (found) {
108239e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	if (minus)
108249e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    PUSH_UNARY_EXPR(XPATH_OP_PLUS, ctxt->comp->last, 2, 0);
108259e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	else
108269e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    PUSH_UNARY_EXPR(XPATH_OP_PLUS, ctxt->comp->last, 3, 0);
108273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
108283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
108293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
108303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
10831afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompMultiplicativeExpr:
108323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
108333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
1083445490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *  [26]   MultiplicativeExpr ::=   UnaryExpr
1083545490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *                   | MultiplicativeExpr MultiplyOperator UnaryExpr
1083645490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *                   | MultiplicativeExpr 'div' UnaryExpr
1083745490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *                   | MultiplicativeExpr 'mod' UnaryExpr
108383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *  [34]   MultiplyOperator ::=   '*'
108393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
10840afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile an Additive expression.
108413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
108423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
10843afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void
10844afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompMultiplicativeExpr(xmlXPathParserContextPtr ctxt) {
10845afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard    xmlXPathCompUnaryExpr(ctxt);
108463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CHECK_ERROR;
108473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    SKIP_BLANKS;
1084845490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard    while ((CUR == '*') ||
108493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor           ((CUR == 'd') && (NXT(1) == 'i') && (NXT(2) == 'v')) ||
108503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor           ((CUR == 'm') && (NXT(1) == 'o') && (NXT(2) == 'd'))) {
108513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	int op = -1;
108529e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	int op1 = ctxt->comp->last;
108533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
108543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        if (CUR == '*') {
108553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    op = 0;
108563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    NEXT;
108573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	} else if (CUR == 'd') {
108583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    op = 1;
108593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    SKIP(3);
108603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	} else if (CUR == 'm') {
108613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    op = 2;
108623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    SKIP(3);
108633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
108643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	SKIP_BLANKS;
10865afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard        xmlXPathCompUnaryExpr(ctxt);
108663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	CHECK_ERROR;
108679e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	PUSH_BINARY_EXPR(XPATH_OP_MULT, op1, ctxt->comp->last, op, 0);
108683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	SKIP_BLANKS;
108693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
108703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
108713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
108723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
10873afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompAdditiveExpr:
108743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
108753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
1087645490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *  [25]   AdditiveExpr ::=   MultiplicativeExpr
1087745490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *                   | AdditiveExpr '+' MultiplicativeExpr
1087845490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *                   | AdditiveExpr '-' MultiplicativeExpr
108793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
10880afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile an Additive expression.
108813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
108823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
10883afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void
10884afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompAdditiveExpr(xmlXPathParserContextPtr ctxt) {
108859e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
10886afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard    xmlXPathCompMultiplicativeExpr(ctxt);
108873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CHECK_ERROR;
108883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    SKIP_BLANKS;
108893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    while ((CUR == '+') || (CUR == '-')) {
108903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	int plus;
108919e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	int op1 = ctxt->comp->last;
108923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
108933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        if (CUR == '+') plus = 1;
108943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	else plus = 0;
108953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	NEXT;
108963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	SKIP_BLANKS;
10897afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard        xmlXPathCompMultiplicativeExpr(ctxt);
108983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	CHECK_ERROR;
108999e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	PUSH_BINARY_EXPR(XPATH_OP_PLUS, op1, ctxt->comp->last, plus, 0);
109003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	SKIP_BLANKS;
109013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
109023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
109033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
109043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
10905afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompRelationalExpr:
109063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
109073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
1090845490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *  [24]   RelationalExpr ::=   AdditiveExpr
1090945490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *                 | RelationalExpr '<' AdditiveExpr
1091045490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *                 | RelationalExpr '>' AdditiveExpr
1091145490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *                 | RelationalExpr '<=' AdditiveExpr
1091245490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *                 | RelationalExpr '>=' AdditiveExpr
109133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
109143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *  A <= B > C is allowed ? Answer from James, yes with
109153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *  (AdditiveExpr <= AdditiveExpr) > AdditiveExpr
109163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *  which is basically what got implemented.
109173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
10918afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile a Relational expression, then push the result
109193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * on the stack
109203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
109213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
10922afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void
10923afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompRelationalExpr(xmlXPathParserContextPtr ctxt) {
10924afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard    xmlXPathCompAdditiveExpr(ctxt);
109253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CHECK_ERROR;
109263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    SKIP_BLANKS;
109273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    while ((CUR == '<') ||
109283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor           (CUR == '>') ||
109293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor           ((CUR == '<') && (NXT(1) == '=')) ||
109303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor           ((CUR == '>') && (NXT(1) == '='))) {
109319e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	int inf, strict;
109329e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	int op1 = ctxt->comp->last;
109333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
109343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        if (CUR == '<') inf = 1;
109353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	else inf = 0;
109363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (NXT(1) == '=') strict = 0;
109373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	else strict = 1;
109383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	NEXT;
109393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (!strict) NEXT;
109403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	SKIP_BLANKS;
10941afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard        xmlXPathCompAdditiveExpr(ctxt);
109423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	CHECK_ERROR;
109439e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	PUSH_BINARY_EXPR(XPATH_OP_CMP, op1, ctxt->comp->last, inf, strict);
109443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	SKIP_BLANKS;
109453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
109463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
109473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
109483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
10949afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompEqualityExpr:
109503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
109513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
1095245490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *  [23]   EqualityExpr ::=   RelationalExpr
1095345490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *                 | EqualityExpr '=' RelationalExpr
1095445490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *                 | EqualityExpr '!=' RelationalExpr
109553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
109563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *  A != B != C is allowed ? Answer from James, yes with
109573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *  (RelationalExpr = RelationalExpr) = RelationalExpr
109583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *  (RelationalExpr != RelationalExpr) != RelationalExpr
109593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *  which is basically what got implemented.
109603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
10961afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile an Equality expression.
109623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
109633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
10964afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void
10965afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompEqualityExpr(xmlXPathParserContextPtr ctxt) {
10966afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard    xmlXPathCompRelationalExpr(ctxt);
109673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CHECK_ERROR;
109683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    SKIP_BLANKS;
109693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    while ((CUR == '=') || ((CUR == '!') && (NXT(1) == '='))) {
109709e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	int eq;
109719e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	int op1 = ctxt->comp->last;
109723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
109733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        if (CUR == '=') eq = 1;
109743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	else eq = 0;
109753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	NEXT;
109763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (!eq) NEXT;
109773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	SKIP_BLANKS;
10978afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard        xmlXPathCompRelationalExpr(ctxt);
109793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	CHECK_ERROR;
109809e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	PUSH_BINARY_EXPR(XPATH_OP_EQUAL, op1, ctxt->comp->last, eq, 0);
109813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	SKIP_BLANKS;
109823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
109833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
109843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
109853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
10986afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompAndExpr:
109873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
109883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
1098945490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *  [22]   AndExpr ::=   EqualityExpr
1099045490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *                 | AndExpr 'and' EqualityExpr
109913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
10992afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile an AND expression.
109933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
109943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
10995afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void
10996afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompAndExpr(xmlXPathParserContextPtr ctxt) {
10997afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard    xmlXPathCompEqualityExpr(ctxt);
109983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CHECK_ERROR;
109993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    SKIP_BLANKS;
110003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    while ((CUR == 'a') && (NXT(1) == 'n') && (NXT(2) == 'd')) {
110019e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	int op1 = ctxt->comp->last;
110023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        SKIP(3);
110033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	SKIP_BLANKS;
11004afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard        xmlXPathCompEqualityExpr(ctxt);
110053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	CHECK_ERROR;
110069e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	PUSH_BINARY_EXPR(XPATH_OP_AND, op1, ctxt->comp->last, 0, 0);
110073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	SKIP_BLANKS;
110083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
110093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
110103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
110113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
11012591b4be0fe1986b5e71d54c5c063493987ef4285Daniel Veillard * xmlXPathCompileExpr:
110133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
110143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
1101545490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *  [14]   Expr ::=   OrExpr
1101645490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *  [21]   OrExpr ::=   AndExpr
1101745490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *                 | OrExpr 'or' AndExpr
110183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
11019afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Parse and compile an expression
110203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
11021afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void
110225691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. BuchcikxmlXPathCompileExpr(xmlXPathParserContextPtr ctxt, int sort) {
11023afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard    xmlXPathCompAndExpr(ctxt);
110243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CHECK_ERROR;
110253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    SKIP_BLANKS;
110263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    while ((CUR == 'o') && (NXT(1) == 'r')) {
110279e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	int op1 = ctxt->comp->last;
110283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        SKIP(2);
110293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	SKIP_BLANKS;
11030afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard        xmlXPathCompAndExpr(ctxt);
110313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	CHECK_ERROR;
110329e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	PUSH_BINARY_EXPR(XPATH_OP_OR, op1, ctxt->comp->last, 0, 0);
110333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	SKIP_BLANKS;
110343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
110355691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik    if ((sort) && (ctxt->comp->steps[ctxt->comp->last].op != XPATH_OP_VALUE)) {
110369e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	/* more ops could be optimized too */
110375691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	/*
110385691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	* This is the main place to eliminate sorting for
110395691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	* operations which don't require a sorted node-set.
110405691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	* E.g. count().
110415691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	*/
110429e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	PUSH_UNARY_EXPR(XPATH_OP_SORT, ctxt->comp->last , 0, 0);
110439e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    }
110443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
110453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
110463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
11047afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompPredicate:
110483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
11049d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * @filter:  act as a filter
110503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
110513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *  [8]   Predicate ::=   '[' PredicateExpr ']'
1105245490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *  [9]   PredicateExpr ::=   Expr
110533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
11054afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile a predicate expression
110559e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard */
11056afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void
11057d8df6c0e8c883e1d618388d266015dda36731440Daniel VeillardxmlXPathCompPredicate(xmlXPathParserContextPtr ctxt, int filter) {
110589e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    int op1 = ctxt->comp->last;
110599e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
110609e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    SKIP_BLANKS;
110619e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    if (CUR != '[') {
110629e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	XP_ERROR(XPATH_INVALID_PREDICATE_ERROR);
110639e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    }
110649e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    NEXT;
110659e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    SKIP_BLANKS;
110669e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
110679e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    ctxt->comp->last = -1;
11068631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik    /*
11069631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik    * This call to xmlXPathCompileExpr() will deactivate sorting
11070631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik    * of the predicate result.
11071631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik    * TODO: Sorting is still activated for filters, since I'm not
11072631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik    *  sure if needed. Normally sorting should not be needed, since
11073631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik    *  a filter can only diminish the number of items in a sequence,
11074631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik    *  but won't change its order; so if the initial sequence is sorted,
11075631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik    *  subsequent sorting is not needed.
11076631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik    */
11077631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik    if (! filter)
11078631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	xmlXPathCompileExpr(ctxt, 0);
11079631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik    else
11080631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	xmlXPathCompileExpr(ctxt, 1);
110819e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    CHECK_ERROR;
110829e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
110839e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    if (CUR != ']') {
110849e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	XP_ERROR(XPATH_INVALID_PREDICATE_ERROR);
110859e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    }
110869e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
11087d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard    if (filter)
11088d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	PUSH_BINARY_EXPR(XPATH_OP_FILTER, op1, ctxt->comp->last, 0, 0);
11089d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard    else
11090d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	PUSH_BINARY_EXPR(XPATH_OP_PREDICATE, op1, ctxt->comp->last, 0, 0);
110919e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
110929e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    NEXT;
110939e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    SKIP_BLANKS;
110949e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard}
110959e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
110969e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard/**
11097afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompNodeTest:
110983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
110993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @test:  pointer to a xmlXPathTestVal
111003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @type:  pointer to a xmlXPathTypeVal
111013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @prefix:  placeholder for a possible name prefix
111023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
111033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [7] NodeTest ::=   NameTest
111043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *		    | NodeType '(' ')'
111053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *		    | 'processing-instruction' '(' Literal ')'
111063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
111073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [37] NameTest ::=  '*'
111083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *		    | NCName ':' '*'
111093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *		    | QName
111103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [38] NodeType ::= 'comment'
111113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *		   | 'text'
111123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *		   | 'processing-instruction'
111133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *		   | 'node'
111143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
11115081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack * Returns the name found and updates @test, @type and @prefix appropriately
111163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
1111756a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic xmlChar *
11118afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompNodeTest(xmlXPathParserContextPtr ctxt, xmlXPathTestVal *test,
11119afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard	             xmlXPathTypeVal *type, const xmlChar **prefix,
11120afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard		     xmlChar *name) {
111213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    int blanks;
111223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
111233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if ((test == NULL) || (type == NULL) || (prefix == NULL)) {
111243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	STRANGE;
111253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(NULL);
111263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
1112778637da0ea1c833dfdfad87a9aa5bea14510d08aWilliam M. Brack    *type = (xmlXPathTypeVal) 0;
1112878637da0ea1c833dfdfad87a9aa5bea14510d08aWilliam M. Brack    *test = (xmlXPathTestVal) 0;
111293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    *prefix = NULL;
111303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    SKIP_BLANKS;
111313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
111323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if ((name == NULL) && (CUR == '*')) {
111333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	/*
111343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	 * All elements
111353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	 */
111363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	NEXT;
111373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	*test = NODE_TEST_ALL;
111383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(NULL);
111393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
111403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
111413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (name == NULL)
111423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	name = xmlXPathParseNCName(ctxt);
111433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (name == NULL) {
1114424505b0f5c872c5afb6da5093565e5a6e09ca541Daniel Veillard	XP_ERRORNULL(XPATH_EXPR_ERROR);
111453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
111463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
1114776e95df05556c9610b564b14cf578c8f9e34c9c1William M. Brack    blanks = IS_BLANK_CH(CUR);
111483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    SKIP_BLANKS;
111493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (CUR == '(') {
111503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	NEXT;
111513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	/*
111523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	 * NodeType or PI search
111533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	 */
111543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (xmlStrEqual(name, BAD_CAST "comment"))
111553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    *type = NODE_TYPE_COMMENT;
111563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	else if (xmlStrEqual(name, BAD_CAST "node"))
111573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    *type = NODE_TYPE_NODE;
111583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	else if (xmlStrEqual(name, BAD_CAST "processing-instruction"))
111593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    *type = NODE_TYPE_PI;
111603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	else if (xmlStrEqual(name, BAD_CAST "text"))
111613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    *type = NODE_TYPE_TEXT;
111623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	else {
111633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    if (name != NULL)
111643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		xmlFree(name);
1116524505b0f5c872c5afb6da5093565e5a6e09ca541Daniel Veillard	    XP_ERRORNULL(XPATH_EXPR_ERROR);
111663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
111673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
111683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	*test = NODE_TEST_TYPE;
1116945490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
111703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	SKIP_BLANKS;
111713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (*type == NODE_TYPE_PI) {
111723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    /*
111733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	     * Specific case: search a PI by name.
111743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	     */
111753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    if (name != NULL)
111763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		xmlFree(name);
1117782e4971dc2f470c9b6f19cf8b15ff32781067167Daniel Veillard	    name = NULL;
1117882e4971dc2f470c9b6f19cf8b15ff32781067167Daniel Veillard	    if (CUR != ')') {
1117982e4971dc2f470c9b6f19cf8b15ff32781067167Daniel Veillard		name = xmlXPathParseLiteral(ctxt);
1118024505b0f5c872c5afb6da5093565e5a6e09ca541Daniel Veillard		CHECK_ERROR NULL;
11181ed23b7dc73f6c1146701ece20ed3f03d68366516Daniel Veillard		*test = NODE_TEST_PI;
1118282e4971dc2f470c9b6f19cf8b15ff32781067167Daniel Veillard		SKIP_BLANKS;
1118382e4971dc2f470c9b6f19cf8b15ff32781067167Daniel Veillard	    }
111843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
111853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (CUR != ')') {
111863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    if (name != NULL)
111873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		xmlFree(name);
1118824505b0f5c872c5afb6da5093565e5a6e09ca541Daniel Veillard	    XP_ERRORNULL(XPATH_UNCLOSED_ERROR);
111893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
111903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	NEXT;
111913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(name);
111923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
111933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    *test = NODE_TEST_NAME;
111943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if ((!blanks) && (CUR == ':')) {
111953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	NEXT;
111963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
111973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	/*
11198fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard	 * Since currently the parser context don't have a
11199fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard	 * namespace list associated:
11200fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard	 * The namespace name for this prefix can be computed
11201fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard	 * only at evaluation time. The compilation is done
11202fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard	 * outside of any context.
112033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	 */
11204fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard#if 0
112053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	*prefix = xmlXPathNsLookup(ctxt->context, name);
112063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (name != NULL)
112073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    xmlFree(name);
112083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (*prefix == NULL) {
112093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    XP_ERROR0(XPATH_UNDEF_PREFIX_ERROR);
112103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
11211fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard#else
11212fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard	*prefix = name;
11213fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard#endif
112143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
112153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (CUR == '*') {
112163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    /*
112173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	     * All elements
112183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	     */
112193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    NEXT;
112203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    *test = NODE_TEST_ALL;
112213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    return(NULL);
112223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
112233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
112243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	name = xmlXPathParseNCName(ctxt);
112253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (name == NULL) {
1122624505b0f5c872c5afb6da5093565e5a6e09ca541Daniel Veillard	    XP_ERRORNULL(XPATH_EXPR_ERROR);
112273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
112283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
112293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(name);
112303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
112313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
112323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
112333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathIsAxisName:
112343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @name:  a preparsed name token
112353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
112363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [6] AxisName ::=   'ancestor'
112373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *                  | 'ancestor-or-self'
112383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *                  | 'attribute'
112393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *                  | 'child'
112403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *                  | 'descendant'
112413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *                  | 'descendant-or-self'
112423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *                  | 'following'
112433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *                  | 'following-sibling'
112443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *                  | 'namespace'
112453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *                  | 'parent'
112463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *                  | 'preceding'
112473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *                  | 'preceding-sibling'
112483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *                  | 'self'
112493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
112503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the axis or 0
112513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
1125256a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic xmlXPathAxisVal
112533473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathIsAxisName(const xmlChar *name) {
1125478637da0ea1c833dfdfad87a9aa5bea14510d08aWilliam M. Brack    xmlXPathAxisVal ret = (xmlXPathAxisVal) 0;
112553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    switch (name[0]) {
112563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case 'a':
112573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    if (xmlStrEqual(name, BAD_CAST "ancestor"))
112583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		ret = AXIS_ANCESTOR;
112593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    if (xmlStrEqual(name, BAD_CAST "ancestor-or-self"))
112603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		ret = AXIS_ANCESTOR_OR_SELF;
112613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    if (xmlStrEqual(name, BAD_CAST "attribute"))
112623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		ret = AXIS_ATTRIBUTE;
112633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    break;
112643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case 'c':
112653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    if (xmlStrEqual(name, BAD_CAST "child"))
112663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		ret = AXIS_CHILD;
112673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    break;
112683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case 'd':
112693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    if (xmlStrEqual(name, BAD_CAST "descendant"))
112703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		ret = AXIS_DESCENDANT;
112713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    if (xmlStrEqual(name, BAD_CAST "descendant-or-self"))
112723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		ret = AXIS_DESCENDANT_OR_SELF;
112733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    break;
112743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case 'f':
112753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    if (xmlStrEqual(name, BAD_CAST "following"))
112763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		ret = AXIS_FOLLOWING;
112773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    if (xmlStrEqual(name, BAD_CAST "following-sibling"))
112783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		ret = AXIS_FOLLOWING_SIBLING;
112793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    break;
112803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case 'n':
112813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    if (xmlStrEqual(name, BAD_CAST "namespace"))
112823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		ret = AXIS_NAMESPACE;
112833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    break;
112843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case 'p':
112853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    if (xmlStrEqual(name, BAD_CAST "parent"))
112863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		ret = AXIS_PARENT;
112873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    if (xmlStrEqual(name, BAD_CAST "preceding"))
112883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		ret = AXIS_PRECEDING;
112893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    if (xmlStrEqual(name, BAD_CAST "preceding-sibling"))
112903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		ret = AXIS_PRECEDING_SIBLING;
112913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    break;
112923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case 's':
112933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    if (xmlStrEqual(name, BAD_CAST "self"))
112943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		ret = AXIS_SELF;
112953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    break;
112963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
112973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(ret);
112983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
112993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
113003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
11301afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompStep:
113023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
113033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
113043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [4] Step ::=   AxisSpecifier NodeTest Predicate*
1130545490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *                  | AbbreviatedStep
113063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
113073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [12] AbbreviatedStep ::=   '.' | '..'
113083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
113093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [5] AxisSpecifier ::= AxisName '::'
113103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *                  | AbbreviatedAxisSpecifier
113113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
113123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [13] AbbreviatedAxisSpecifier ::= '@'?
113133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
113143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Modified for XPtr range support as:
113153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
113163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *  [4xptr] Step ::= AxisSpecifier NodeTest Predicate*
113173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *                     | AbbreviatedStep
113183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *                     | 'range-to' '(' Expr ')' Predicate*
113193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
11320afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile one step in a Location Path
113213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * A location step of . is short for self::node(). This is
113223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * particularly useful in conjunction with //. For example, the
113233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * location path .//para is short for
113243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * self::node()/descendant-or-self::node()/child::para
113253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * and so will select all para descendant elements of the context
113263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * node.
113273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Similarly, a location step of .. is short for parent::node().
113283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * For example, ../title is short for parent::node()/child::title
113293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * and so will select the title children of the parent of the context
113303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * node.
113313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
11332afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void
11333afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompStep(xmlXPathParserContextPtr ctxt) {
11334fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard#ifdef LIBXML_XPTR_ENABLED
11335fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard    int rangeto = 0;
11336fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard    int op2 = -1;
11337fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard#endif
11338fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard
113393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    SKIP_BLANKS;
113403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if ((CUR == '.') && (NXT(1) == '.')) {
113413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	SKIP(2);
113423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	SKIP_BLANKS;
113439e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	PUSH_LONG_EXPR(XPATH_OP_COLLECT, AXIS_PARENT,
113449e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    NODE_TEST_TYPE, NODE_TYPE_NODE, NULL, NULL);
113453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    } else if (CUR == '.') {
113463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	NEXT;
113473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	SKIP_BLANKS;
113483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    } else {
113493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	xmlChar *name = NULL;
113503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	const xmlChar *prefix = NULL;
11351aac7c68e87d00732b319698723de1ec43252fb01Daniel Veillard	xmlXPathTestVal test = (xmlXPathTestVal) 0;
1135278637da0ea1c833dfdfad87a9aa5bea14510d08aWilliam M. Brack	xmlXPathAxisVal axis = (xmlXPathAxisVal) 0;
11353aac7c68e87d00732b319698723de1ec43252fb01Daniel Veillard	xmlXPathTypeVal type = (xmlXPathTypeVal) 0;
11354d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	int op1;
113553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
113563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	/*
113573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	 * The modification needed for XPointer change to the production
113583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	 */
113593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef LIBXML_XPTR_ENABLED
11360fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard	if (ctxt->xptr) {
113613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    name = xmlXPathParseNCName(ctxt);
113623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    if ((name != NULL) && (xmlStrEqual(name, BAD_CAST "range-to"))) {
11363fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard                op2 = ctxt->comp->last;
113643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		xmlFree(name);
113653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		SKIP_BLANKS;
113663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		if (CUR != '(') {
113673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    XP_ERROR(XPATH_EXPR_ERROR);
113683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		}
113693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		NEXT;
113703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		SKIP_BLANKS;
113713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
113725691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		xmlXPathCompileExpr(ctxt, 1);
11373fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard		/* PUSH_BINARY_EXPR(XPATH_OP_RANGETO, op2, ctxt->comp->last, 0, 0); */
113743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		CHECK_ERROR;
113753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
113763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		SKIP_BLANKS;
113773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		if (CUR != ')') {
113783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    XP_ERROR(XPATH_EXPR_ERROR);
113793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		}
113803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		NEXT;
11381fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard		rangeto = 1;
113823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		goto eval_predicates;
113833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    }
113843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
113853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif
113862156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard	if (CUR == '*') {
113872156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard	    axis = AXIS_CHILD;
113882156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard	} else {
113892156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard	    if (name == NULL)
113902156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard		name = xmlXPathParseNCName(ctxt);
113912156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard	    if (name != NULL) {
113922156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard		axis = xmlXPathIsAxisName(name);
113932156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard		if (axis != 0) {
113942156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard		    SKIP_BLANKS;
113952156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard		    if ((CUR == ':') && (NXT(1) == ':')) {
113962156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard			SKIP(2);
113972156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard			xmlFree(name);
113982156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard			name = NULL;
113992156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard		    } else {
114002156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard			/* an element name can conflict with an axis one :-\ */
114012156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard			axis = AXIS_CHILD;
114022156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard		    }
114033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		} else {
114043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    axis = AXIS_CHILD;
114053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		}
114062156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard	    } else if (CUR == '@') {
114072156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard		NEXT;
114082156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard		axis = AXIS_ATTRIBUTE;
114093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    } else {
114102156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard		axis = AXIS_CHILD;
114113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    }
114123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
114133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
114142f3523f61f1c7a2a0521c2f6c0db6c80e1cc4111Daniel Veillard        if (ctxt->error != XPATH_EXPRESSION_OK) {
114152f3523f61f1c7a2a0521c2f6c0db6c80e1cc4111Daniel Veillard            xmlFree(name);
114162f3523f61f1c7a2a0521c2f6c0db6c80e1cc4111Daniel Veillard            return;
114172f3523f61f1c7a2a0521c2f6c0db6c80e1cc4111Daniel Veillard        }
114183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
11419afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard	name = xmlXPathCompNodeTest(ctxt, &test, &type, &prefix, name);
114203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (test == 0)
114213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    return;
114223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
11423ed6c54971fdb7fa37c183b1a36c2e581c750984bDaniel Veillard        if ((prefix != NULL) && (ctxt->context != NULL) &&
11424ed6c54971fdb7fa37c183b1a36c2e581c750984bDaniel Veillard	    (ctxt->context->flags & XML_XPATH_CHECKNS)) {
11425ed6c54971fdb7fa37c183b1a36c2e581c750984bDaniel Veillard	    if (xmlXPathNsLookup(ctxt->context, prefix) == NULL) {
11426ed6c54971fdb7fa37c183b1a36c2e581c750984bDaniel Veillard		xmlXPathErr(ctxt, XPATH_UNDEF_PREFIX_ERROR);
11427ed6c54971fdb7fa37c183b1a36c2e581c750984bDaniel Veillard	    }
11428ed6c54971fdb7fa37c183b1a36c2e581c750984bDaniel Veillard	}
114293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_STEP
114303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	xmlGenericError(xmlGenericErrorContext,
114313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		"Basis : computing new set\n");
114323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif
114339e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
114343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_STEP
114353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	xmlGenericError(xmlGenericErrorContext, "Basis : ");
11436fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard	if (ctxt->value == NULL)
11437fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard	    xmlGenericError(xmlGenericErrorContext, "no value\n");
11438fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard	else if (ctxt->value->nodesetval == NULL)
11439fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard	    xmlGenericError(xmlGenericErrorContext, "Empty\n");
11440fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard	else
11441fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard	    xmlGenericErrorContextNodeSet(stdout, ctxt->value->nodesetval);
114423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif
114433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
114445bb9ccd56a812b65e94e71477389be7826203649Daniel Veillard#ifdef LIBXML_XPTR_ENABLED
114453473f88a7abdf4e585e267288fb77e898c580d2bOwen Tayloreval_predicates:
114465bb9ccd56a812b65e94e71477389be7826203649Daniel Veillard#endif
11447d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	op1 = ctxt->comp->last;
11448d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	ctxt->comp->last = -1;
11449d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard
114503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	SKIP_BLANKS;
114513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	while (CUR == '[') {
11452d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	    xmlXPathCompPredicate(ctxt, 0);
114533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
11454d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard
11455fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard#ifdef LIBXML_XPTR_ENABLED
11456fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard	if (rangeto) {
11457fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard	    PUSH_BINARY_EXPR(XPATH_OP_RANGETO, op2, op1, 0, 0);
11458fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard	} else
11459fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard#endif
11460fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard	    PUSH_FULL_EXPR(XPATH_OP_COLLECT, op1, ctxt->comp->last, axis,
11461fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard			   test, type, (void *)prefix, (void *)name);
11462d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard
114633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
114643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_STEP
114653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlGenericError(xmlGenericErrorContext, "Step : ");
11466fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard    if (ctxt->value == NULL)
11467fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard	xmlGenericError(xmlGenericErrorContext, "no value\n");
11468fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard    else if (ctxt->value->nodesetval == NULL)
11469fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard	xmlGenericError(xmlGenericErrorContext, "Empty\n");
11470fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard    else
11471fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard	xmlGenericErrorContextNodeSet(xmlGenericErrorContext,
11472fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard		ctxt->value->nodesetval);
114733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif
114743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
114753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
114763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
11477afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompRelativeLocationPath:
114783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
114793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
1148045490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *  [3]   RelativeLocationPath ::=   Step
1148145490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *                     | RelativeLocationPath '/' Step
1148245490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *                     | AbbreviatedRelativeLocationPath
1148345490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *  [11]  AbbreviatedRelativeLocationPath ::=   RelativeLocationPath '//' Step
114843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
11485afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile a relative location path.
114863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
11487afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void
11488afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompRelativeLocationPath
114893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor(xmlXPathParserContextPtr ctxt) {
114903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    SKIP_BLANKS;
114913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if ((CUR == '/') && (NXT(1) == '/')) {
114923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	SKIP(2);
114933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	SKIP_BLANKS;
114949e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	PUSH_LONG_EXPR(XPATH_OP_COLLECT, AXIS_DESCENDANT_OR_SELF,
114959e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		         NODE_TEST_TYPE, NODE_TYPE_NODE, NULL, NULL);
114963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    } else if (CUR == '/') {
114973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    NEXT;
114983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	SKIP_BLANKS;
114993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
11500afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard    xmlXPathCompStep(ctxt);
11501729601f15772c19778062b98bd0716d8f5c2af3bMartin    CHECK_ERROR;
115023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    SKIP_BLANKS;
115033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    while (CUR == '/') {
115043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if ((CUR == '/') && (NXT(1) == '/')) {
115053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    SKIP(2);
115063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    SKIP_BLANKS;
115079e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    PUSH_LONG_EXPR(XPATH_OP_COLLECT, AXIS_DESCENDANT_OR_SELF,
115083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor			     NODE_TEST_TYPE, NODE_TYPE_NODE, NULL, NULL);
11509afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard	    xmlXPathCompStep(ctxt);
115103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	} else if (CUR == '/') {
115113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    NEXT;
115123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    SKIP_BLANKS;
11513afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard	    xmlXPathCompStep(ctxt);
115143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
115153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	SKIP_BLANKS;
115163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
115173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
115183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
115193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
11520afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompLocationPath:
115213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
115223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
1152345490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *  [1]   LocationPath ::=   RelativeLocationPath
1152445490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *                     | AbsoluteLocationPath
115253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *  [2]   AbsoluteLocationPath ::=   '/' RelativeLocationPath?
1152645490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *                     | AbbreviatedAbsoluteLocationPath
1152745490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *  [10]   AbbreviatedAbsoluteLocationPath ::=
1152845490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *                           '//' RelativeLocationPath
115293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
11530afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile a location path
11531afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard *
115323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * // is short for /descendant-or-self::node()/. For example,
115333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * //para is short for /descendant-or-self::node()/child::para and
115343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * so will select any para element in the document (even a para element
115353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * that is a document element will be selected by //para since the
115363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * document element node is a child of the root node); div//para is
115373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * short for div/descendant-or-self::node()/child::para and so will
115383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * select all para descendants of div children.
115393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
11540afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void
11541afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompLocationPath(xmlXPathParserContextPtr ctxt) {
115423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    SKIP_BLANKS;
115433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (CUR != '/') {
11544afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard        xmlXPathCompRelativeLocationPath(ctxt);
115453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    } else {
115463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	while (CUR == '/') {
115473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    if ((CUR == '/') && (NXT(1) == '/')) {
115483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		SKIP(2);
115493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		SKIP_BLANKS;
115509e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		PUSH_LONG_EXPR(XPATH_OP_COLLECT, AXIS_DESCENDANT_OR_SELF,
115519e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard			     NODE_TEST_TYPE, NODE_TYPE_NODE, NULL, NULL);
11552afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard		xmlXPathCompRelativeLocationPath(ctxt);
115533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    } else if (CUR == '/') {
115543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		NEXT;
11555608ad0791b3b35072c8021ea4f66cf9d700394b9Daniel Veillard		SKIP_BLANKS;
11556608ad0791b3b35072c8021ea4f66cf9d700394b9Daniel Veillard		if ((CUR != 0 ) &&
11557d1757abcb891e01a9017f4aad041cc306d0d467bWilliam M. Brack		    ((IS_ASCII_LETTER(CUR)) || (CUR == '_') || (CUR == '.') ||
11558608ad0791b3b35072c8021ea4f66cf9d700394b9Daniel Veillard		     (CUR == '@') || (CUR == '*')))
11559afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard		    xmlXPathCompRelativeLocationPath(ctxt);
115603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    }
11561729601f15772c19778062b98bd0716d8f5c2af3bMartin	    CHECK_ERROR;
115623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
115633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
115643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
115653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
115669e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard/************************************************************************
115679e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard *									*
1156845490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *		XPath precompiled expression evaluation			*
115699e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard *									*
115709e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard ************************************************************************/
115719e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
11572f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillardstatic int
11573d8df6c0e8c883e1d618388d266015dda36731440Daniel VeillardxmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op);
11574d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard
11575d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP
115769bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcikstatic void
11577074f37e7ebd5e76ceb584a89745a9e84df5b3be2Daniel VeillardxmlXPathDebugDumpStepAxis(xmlXPathStepOpPtr op,
115789bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik			  int nbNodes)
115799bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik{
11580f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    xmlGenericError(xmlGenericErrorContext, "new step : ");
11581074f37e7ebd5e76ceb584a89745a9e84df5b3be2Daniel Veillard    switch (op->value) {
11582d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard        case AXIS_ANCESTOR:
11583f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            xmlGenericError(xmlGenericErrorContext, "axis 'ancestors' ");
11584f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            break;
11585d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard        case AXIS_ANCESTOR_OR_SELF:
11586f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            xmlGenericError(xmlGenericErrorContext,
11587f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                            "axis 'ancestors-or-self' ");
11588f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            break;
11589d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard        case AXIS_ATTRIBUTE:
11590f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            xmlGenericError(xmlGenericErrorContext, "axis 'attributes' ");
11591f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            break;
11592d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard        case AXIS_CHILD:
11593f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            xmlGenericError(xmlGenericErrorContext, "axis 'child' ");
11594f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            break;
11595d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard        case AXIS_DESCENDANT:
11596f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            xmlGenericError(xmlGenericErrorContext, "axis 'descendant' ");
11597f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            break;
11598d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard        case AXIS_DESCENDANT_OR_SELF:
11599f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            xmlGenericError(xmlGenericErrorContext,
11600f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                            "axis 'descendant-or-self' ");
11601f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            break;
11602d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard        case AXIS_FOLLOWING:
11603f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            xmlGenericError(xmlGenericErrorContext, "axis 'following' ");
11604f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            break;
11605d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard        case AXIS_FOLLOWING_SIBLING:
11606f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            xmlGenericError(xmlGenericErrorContext,
11607f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                            "axis 'following-siblings' ");
11608f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            break;
11609d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard        case AXIS_NAMESPACE:
11610f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            xmlGenericError(xmlGenericErrorContext, "axis 'namespace' ");
11611f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            break;
11612d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard        case AXIS_PARENT:
11613f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            xmlGenericError(xmlGenericErrorContext, "axis 'parent' ");
11614f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            break;
11615d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard        case AXIS_PRECEDING:
11616f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            xmlGenericError(xmlGenericErrorContext, "axis 'preceding' ");
11617f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            break;
11618d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard        case AXIS_PRECEDING_SIBLING:
11619f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            xmlGenericError(xmlGenericErrorContext,
11620f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                            "axis 'preceding-sibling' ");
11621f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            break;
11622d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard        case AXIS_SELF:
11623f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            xmlGenericError(xmlGenericErrorContext, "axis 'self' ");
11624f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            break;
11625d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard    }
11626d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard    xmlGenericError(xmlGenericErrorContext,
116279bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	" context contains %d nodes\n", nbNodes);
11628074f37e7ebd5e76ceb584a89745a9e84df5b3be2Daniel Veillard    switch (op->value2) {
11629f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        case NODE_TEST_NONE:
11630f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            xmlGenericError(xmlGenericErrorContext,
11631f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                            "           searching for none !!!\n");
11632f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            break;
11633f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        case NODE_TEST_TYPE:
11634f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            xmlGenericError(xmlGenericErrorContext,
11635074f37e7ebd5e76ceb584a89745a9e84df5b3be2Daniel Veillard                            "           searching for type %d\n", op->value3);
11636f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            break;
11637f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        case NODE_TEST_PI:
11638f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            xmlGenericError(xmlGenericErrorContext,
11639f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                            "           searching for PI !!!\n");
11640f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            break;
11641f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        case NODE_TEST_ALL:
11642f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            xmlGenericError(xmlGenericErrorContext,
11643f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                            "           searching for *\n");
11644f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            break;
11645f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        case NODE_TEST_NS:
11646f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            xmlGenericError(xmlGenericErrorContext,
11647f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                            "           searching for namespace %s\n",
11648074f37e7ebd5e76ceb584a89745a9e84df5b3be2Daniel Veillard                            op->value5);
11649f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            break;
11650f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        case NODE_TEST_NAME:
11651f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            xmlGenericError(xmlGenericErrorContext,
11652074f37e7ebd5e76ceb584a89745a9e84df5b3be2Daniel Veillard                            "           searching for name %s\n", op->value5);
11653074f37e7ebd5e76ceb584a89745a9e84df5b3be2Daniel Veillard            if (op->value4)
11654f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                xmlGenericError(xmlGenericErrorContext,
11655074f37e7ebd5e76ceb584a89745a9e84df5b3be2Daniel Veillard                                "           with namespace %s\n", op->value4);
11656f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            break;
11657d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard    }
11658d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard    xmlGenericError(xmlGenericErrorContext, "Testing : ");
116599bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik}
116609bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik#endif /* DEBUG_STEP */
11661df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik
116629bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcikstatic int
116639bca933a6e39bae6dd8952825528270f006c97dfKasimier T. BuchcikxmlXPathCompOpEvalPredicate(xmlXPathParserContextPtr ctxt,
116649bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik			    xmlXPathStepOpPtr op,
116659bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik			    xmlNodeSetPtr set,
116669bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik			    int contextSize,
116679bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik			    int hasNsNodes)
116689bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik{
116699bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    if (op->ch1 != -1) {
116709bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	xmlXPathCompExprPtr comp = ctxt->comp;
116719bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	/*
116729bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	* Process inner predicates first.
116739bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	*/
116749bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	if (comp->steps[op->ch1].op != XPATH_OP_PREDICATE) {
11675df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik	    /*
116769bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    * TODO: raise an internal error.
11677df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik	    */
116789bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	}
116799bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	contextSize = xmlXPathCompOpEvalPredicate(ctxt,
116809bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    &comp->steps[op->ch1], set, contextSize, hasNsNodes);
116819bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	CHECK_ERROR0;
116829bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	if (contextSize <= 0)
116839bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    return(0);
1168445490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard    }
116859bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    if (op->ch2 != -1) {
116869bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	xmlXPathContextPtr xpctxt = ctxt->context;
116879bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	xmlNodePtr contextNode, oldContextNode;
116889bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	xmlDocPtr oldContextDoc;
11689631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	int i, res, contextPos = 0, newContextSize;
116909bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	xmlXPathStepOpPtr exprOp;
116919bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	xmlXPathObjectPtr contextObj = NULL, exprRes = NULL;
116929bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik
116939bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik#ifdef LIBXML_XPTR_ENABLED
116949bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	/*
116959bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	* URGENT TODO: Check the following:
116969bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	*  We don't expect location sets if evaluating prediates, right?
116979bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	*  Only filters should expect location sets, right?
116989bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	*/
116999bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik#endif
117009bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	/*
117019bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	* SPEC XPath 1.0:
117029bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	*  "For each node in the node-set to be filtered, the
117039bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	*  PredicateExpr is evaluated with that node as the
117049bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	*  context node, with the number of nodes in the
117059bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	*  node-set as the context size, and with the proximity
117069bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	*  position of the node in the node-set with respect to
117079bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	*  the axis as the context position;"
117089bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	* @oldset is the node-set" to be filtered.
117099bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	*
117109bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	* SPEC XPath 1.0:
117119bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	*  "only predicates change the context position and
117129bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	*  context size (see [2.4 Predicates])."
117139bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	* Example:
117149bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	*   node-set  context pos
117159bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	*    nA         1
117169bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	*    nB         2
117179bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	*    nC         3
117189bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	*   After applying predicate [position() > 1] :
117199bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	*   node-set  context pos
117209bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	*    nB         1
117219bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	*    nC         2
117229bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	*/
117239bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	oldContextNode = xpctxt->node;
117249bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	oldContextDoc = xpctxt->doc;
117259bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	/*
117269bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	* Get the expression of this predicate.
117279bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	*/
1172845490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	exprOp = &ctxt->comp->steps[op->ch2];
117299bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	newContextSize = 0;
117309bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	for (i = 0; i < set->nodeNr; i++) {
117319bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    if (set->nodeTab[i] == NULL)
11732df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		continue;
117339bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik
117349bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    contextNode = set->nodeTab[i];
117359bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    xpctxt->node = contextNode;
117369bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    xpctxt->contextSize = contextSize;
117379bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    xpctxt->proximityPosition = ++contextPos;
1173845490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
1173945490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	    /*
117409bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    * Also set the xpath document in case things like
117419bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    * key() are evaluated in the predicate.
117429bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    */
117439bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    if ((contextNode->type != XML_NAMESPACE_DECL) &&
117449bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		(contextNode->doc != NULL))
117459bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		xpctxt->doc = contextNode->doc;
11746df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik	    /*
117479bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    * Evaluate the predicate expression with 1 context node
117489bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    * at a time; this node is packaged into a node set; this
117499bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    * node set is handed over to the evaluation mechanism.
11750df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik	    */
117519bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    if (contextObj == NULL)
117529bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		contextObj = xmlXPathCacheNewNodeSet(xpctxt, contextNode);
117531bd45d13091e5af9e1fe0582b5e335c60d45535fDaniel Veillard	    else {
117541bd45d13091e5af9e1fe0582b5e335c60d45535fDaniel Veillard		if (xmlXPathNodeSetAddUnique(contextObj->nodesetval,
117551bd45d13091e5af9e1fe0582b5e335c60d45535fDaniel Veillard		    contextNode) < 0) {
117561bd45d13091e5af9e1fe0582b5e335c60d45535fDaniel Veillard		    ctxt->error = XPATH_MEMORY_ERROR;
117571bd45d13091e5af9e1fe0582b5e335c60d45535fDaniel Veillard		    goto evaluation_exit;
117581bd45d13091e5af9e1fe0582b5e335c60d45535fDaniel Veillard		}
117591bd45d13091e5af9e1fe0582b5e335c60d45535fDaniel Veillard	    }
11760df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik
117619bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    valuePush(ctxt, contextObj);
117629bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik
11763324c75b3c3edffcd30e7afa2a32f0d83d928b10dKasimier T. Buchcik	    res = xmlXPathCompOpEvalToBoolean(ctxt, exprOp, 1);
11764631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik
117650bcec06d4c261ccff8bdc9111618e6938cb5855fWilliam M. Brack	    if ((ctxt->error != XPATH_EXPRESSION_OK) || (res == -1)) {
117660bcec06d4c261ccff8bdc9111618e6938cb5855fWilliam M. Brack		xmlXPathNodeSetClear(set, hasNsNodes);
117670bcec06d4c261ccff8bdc9111618e6938cb5855fWilliam M. Brack		newContextSize = 0;
117680bcec06d4c261ccff8bdc9111618e6938cb5855fWilliam M. Brack		goto evaluation_exit;
117690bcec06d4c261ccff8bdc9111618e6938cb5855fWilliam M. Brack	    }
11770631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik
11771631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    if (res != 0) {
11772631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik		newContextSize++;
11773631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    } else {
117749bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		/*
117759bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		* Remove the entry from the initial node set.
117769bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		*/
117779bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		set->nodeTab[i] = NULL;
117789bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		if (contextNode->type == XML_NAMESPACE_DECL)
117799bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		    xmlXPathNodeSetFreeNs((xmlNsPtr) contextNode);
1178075af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik	    }
117819bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    if (ctxt->value == contextObj) {
117829bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		/*
117839bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		* Don't free the temporary XPath object holding the
117849bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		* context node, in order to avoid massive recreation
117859bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		* inside this loop.
117869bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		*/
117879bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		valuePop(ctxt);
117889bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		xmlXPathNodeSetClear(contextObj->nodesetval, hasNsNodes);
117899bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    } else {
117909bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		/*
117919bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		* TODO: The object was lost in the evaluation machinery.
117929bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		*  Can this happen? Maybe in internal-error cases.
117939bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		*/
117949bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		contextObj = NULL;
1179575af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik	    }
117969bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	}
11797f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
117989bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	if (contextObj != NULL) {
117999bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    if (ctxt->value == contextObj)
118009bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		valuePop(ctxt);
118019bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    xmlXPathReleaseObject(xpctxt, contextObj);
1180245490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	}
118030bcec06d4c261ccff8bdc9111618e6938cb5855fWilliam M. Brackevaluation_exit:
118049bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	if (exprRes != NULL)
118059bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    xmlXPathReleaseObject(ctxt->context, exprRes);
118069bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	/*
118079bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	* Reset/invalidate the context.
118089bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	*/
118099bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	xpctxt->node = oldContextNode;
118109bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	xpctxt->doc = oldContextDoc;
118119bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	xpctxt->contextSize = -1;
118129bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	xpctxt->proximityPosition = -1;
118139bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	return(newContextSize);
118149bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    }
118159bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    return(contextSize);
118169bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik}
11817f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
118189bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcikstatic int
118199bca933a6e39bae6dd8952825528270f006c97dfKasimier T. BuchcikxmlXPathCompOpEvalPositionalPredicate(xmlXPathParserContextPtr ctxt,
118209bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik				      xmlXPathStepOpPtr op,
118219bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik				      xmlNodeSetPtr set,
118229bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik				      int contextSize,
118239bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik				      int minPos,
118249bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik				      int maxPos,
118259bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik				      int hasNsNodes)
118269bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik{
118279bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    if (op->ch1 != -1) {
118289bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	xmlXPathCompExprPtr comp = ctxt->comp;
118299bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	if (comp->steps[op->ch1].op != XPATH_OP_PREDICATE) {
118309bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    /*
118319bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    * TODO: raise an internal error.
118329bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    */
118339bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	}
118349bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	contextSize = xmlXPathCompOpEvalPredicate(ctxt,
118359bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    &comp->steps[op->ch1], set, contextSize, hasNsNodes);
118369bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	CHECK_ERROR0;
118379bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	if (contextSize <= 0)
118389bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    return(0);
118399bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    }
118409bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    /*
118419bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    * Check if the node set contains a sufficient number of nodes for
118429bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    * the requested range.
118439bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    */
118449bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    if (contextSize < minPos) {
118459bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	xmlXPathNodeSetClear(set, hasNsNodes);
118469bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	return(0);
118479bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    }
118489bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    if (op->ch2 == -1) {
118499bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	/*
118509bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	* TODO: Can this ever happen?
118519bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	*/
118529bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	return (contextSize);
118539bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    } else {
118549bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	xmlDocPtr oldContextDoc;
11855631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	int i, pos = 0, newContextSize = 0, contextPos = 0, res;
118569bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	xmlXPathStepOpPtr exprOp;
118579bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	xmlXPathObjectPtr contextObj = NULL, exprRes = NULL;
118589bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	xmlNodePtr oldContextNode, contextNode = NULL;
118599bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	xmlXPathContextPtr xpctxt = ctxt->context;
11860f5048b3e71fc30ad096970b8df6e7af073bae4cbDaniel Veillard        int frame;
11861f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
118629bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik#ifdef LIBXML_XPTR_ENABLED
118639bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    /*
118649bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    * URGENT TODO: Check the following:
118659bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    *  We don't expect location sets if evaluating prediates, right?
118669bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    *  Only filters should expect location sets, right?
118679bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	*/
118689bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik#endif /* LIBXML_XPTR_ENABLED */
11869f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
118709bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	/*
118719bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	* Save old context.
118729bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	*/
118739bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	oldContextNode = xpctxt->node;
118749bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	oldContextDoc = xpctxt->doc;
118759bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	/*
118769bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	* Get the expression of this predicate.
118779bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	*/
118789bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	exprOp = &ctxt->comp->steps[op->ch2];
118799bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	for (i = 0; i < set->nodeNr; i++) {
11880f5048b3e71fc30ad096970b8df6e7af073bae4cbDaniel Veillard            xmlXPathObjectPtr tmp;
11881f5048b3e71fc30ad096970b8df6e7af073bae4cbDaniel Veillard
118829bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    if (set->nodeTab[i] == NULL)
118839bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		continue;
11884a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
118859bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    contextNode = set->nodeTab[i];
118869bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    xpctxt->node = contextNode;
118879bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    xpctxt->contextSize = contextSize;
118889bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    xpctxt->proximityPosition = ++contextPos;
1188945490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
1189075af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik	    /*
118919bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    * Initialize the new set.
118929bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    * Also set the xpath document in case things like
118939bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    * key() evaluation are attempted on the predicate
1189475af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik	    */
118959bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    if ((contextNode->type != XML_NAMESPACE_DECL) &&
118969bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		(contextNode->doc != NULL))
118979bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		xpctxt->doc = contextNode->doc;
118989bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    /*
118999bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    * Evaluate the predicate expression with 1 context node
119009bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    * at a time; this node is packaged into a node set; this
119019bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    * node set is handed over to the evaluation mechanism.
1190275af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik	    */
119039bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    if (contextObj == NULL)
119049bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		contextObj = xmlXPathCacheNewNodeSet(xpctxt, contextNode);
119051bd45d13091e5af9e1fe0582b5e335c60d45535fDaniel Veillard	    else {
119061bd45d13091e5af9e1fe0582b5e335c60d45535fDaniel Veillard		if (xmlXPathNodeSetAddUnique(contextObj->nodesetval,
119071bd45d13091e5af9e1fe0582b5e335c60d45535fDaniel Veillard		    contextNode) < 0) {
119081bd45d13091e5af9e1fe0582b5e335c60d45535fDaniel Veillard		    ctxt->error = XPATH_MEMORY_ERROR;
119091bd45d13091e5af9e1fe0582b5e335c60d45535fDaniel Veillard		    goto evaluation_exit;
119101bd45d13091e5af9e1fe0582b5e335c60d45535fDaniel Veillard		}
119111bd45d13091e5af9e1fe0582b5e335c60d45535fDaniel Veillard	    }
119129bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik
11913f5048b3e71fc30ad096970b8df6e7af073bae4cbDaniel Veillard            frame = xmlXPathSetFrame(ctxt);
119149bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    valuePush(ctxt, contextObj);
11915324c75b3c3edffcd30e7afa2a32f0d83d928b10dKasimier T. Buchcik	    res = xmlXPathCompOpEvalToBoolean(ctxt, exprOp, 1);
11916f5048b3e71fc30ad096970b8df6e7af073bae4cbDaniel Veillard            tmp = valuePop(ctxt);
11917f5048b3e71fc30ad096970b8df6e7af073bae4cbDaniel Veillard            xmlXPathPopFrame(ctxt, frame);
1191845490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
11919f179456d0f82225ef32196d4947a565bed1b59cbWilliam M. Brack	    if ((ctxt->error != XPATH_EXPRESSION_OK) || (res == -1)) {
11920f5048b3e71fc30ad096970b8df6e7af073bae4cbDaniel Veillard                while (tmp != contextObj) {
11921df83c17e5a2646bd923f75e5e507bc80d73c9722Daniel Veillard                    /*
11922df83c17e5a2646bd923f75e5e507bc80d73c9722Daniel Veillard                     * Free up the result
11923df83c17e5a2646bd923f75e5e507bc80d73c9722Daniel Veillard                     * then pop off contextObj, which will be freed later
11924df83c17e5a2646bd923f75e5e507bc80d73c9722Daniel Veillard                     */
11925df83c17e5a2646bd923f75e5e507bc80d73c9722Daniel Veillard                    xmlXPathReleaseObject(xpctxt, tmp);
11926f5048b3e71fc30ad096970b8df6e7af073bae4cbDaniel Veillard                    tmp = valuePop(ctxt);
11927fec31bcd452e77c10579467ca87a785b41115de6Daniel Veillard                }
119289bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		goto evaluation_error;
11929f179456d0f82225ef32196d4947a565bed1b59cbWilliam M. Brack	    }
11930f5048b3e71fc30ad096970b8df6e7af073bae4cbDaniel Veillard            /* push the result back onto the stack */
11931f5048b3e71fc30ad096970b8df6e7af073bae4cbDaniel Veillard            valuePush(ctxt, tmp);
11932631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik
11933631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    if (res)
119349bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		pos++;
11935631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik
11936631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    if (res && (pos >= minPos) && (pos <= maxPos)) {
119379bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		/*
119389bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		* Fits in the requested range.
119399bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		*/
119409bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		newContextSize++;
119419bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		if (minPos == maxPos) {
119429bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		    /*
119439bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		    * Only 1 node was requested.
119449bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		    */
119459bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		    if (contextNode->type == XML_NAMESPACE_DECL) {
119469bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik			/*
119479bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik			* As always: take care of those nasty
119489bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik			* namespace nodes.
119499bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik			*/
119509bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik			set->nodeTab[i] = NULL;
119519bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		    }
119529bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		    xmlXPathNodeSetClear(set, hasNsNodes);
119539bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		    set->nodeNr = 1;
1195445490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard		    set->nodeTab[0] = contextNode;
119559bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		    goto evaluation_exit;
1195645490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard		}
119579bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		if (pos == maxPos) {
119589bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		    /*
119599bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		    * We are done.
119609bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		    */
119619bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		    xmlXPathNodeSetClearFromPos(set, i +1, hasNsNodes);
119629bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		    goto evaluation_exit;
119639bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		}
119649bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    } else {
119659bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		/*
119669bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		* Remove the entry from the initial node set.
119679bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		*/
119689bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		set->nodeTab[i] = NULL;
119699bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		if (contextNode->type == XML_NAMESPACE_DECL)
119709bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		    xmlXPathNodeSetFreeNs((xmlNsPtr) contextNode);
119719bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    }
119729bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    if (exprRes != NULL) {
119739bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		xmlXPathReleaseObject(ctxt->context, exprRes);
119749bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		exprRes = NULL;
119759bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    }
119769bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    if (ctxt->value == contextObj) {
119779bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		/*
119789bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		* Don't free the temporary XPath object holding the
119799bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		* context node, in order to avoid massive recreation
119809bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		* inside this loop.
119819bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		*/
119829bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		valuePop(ctxt);
119839bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		xmlXPathNodeSetClear(contextObj->nodesetval, hasNsNodes);
119849bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    } else {
119859bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		/*
119869bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		* The object was lost in the evaluation machinery.
119879bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		* Can this happen? Maybe in case of internal-errors.
119889bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		*/
119899bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		contextObj = NULL;
119909bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    }
119919bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	}
119929bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	goto evaluation_exit;
119939bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik
119949bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcikevaluation_error:
119959bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	xmlXPathNodeSetClear(set, hasNsNodes);
119969bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	newContextSize = 0;
119979bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik
119989bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcikevaluation_exit:
119999bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	if (contextObj != NULL) {
120009bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    if (ctxt->value == contextObj)
120019bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		valuePop(ctxt);
120029bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    xmlXPathReleaseObject(xpctxt, contextObj);
120039bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	}
120049bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	if (exprRes != NULL)
120059bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    xmlXPathReleaseObject(ctxt->context, exprRes);
120069bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	/*
120079bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	* Reset/invalidate the context.
120089bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	*/
120099bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	xpctxt->node = oldContextNode;
120109bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	xpctxt->doc = oldContextDoc;
120119bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	xpctxt->contextSize = -1;
120129bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	xpctxt->proximityPosition = -1;
120139bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	return(newContextSize);
12014d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard    }
120159bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    return(contextSize);
120169bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik}
120179bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik
120189bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcikstatic int
120199bca933a6e39bae6dd8952825528270f006c97dfKasimier T. BuchcikxmlXPathIsPositionalPredicate(xmlXPathParserContextPtr ctxt,
1202045490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard			    xmlXPathStepOpPtr op,
120219bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik			    int *maxPos)
120229bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik{
120239bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik
120249bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    xmlXPathStepOpPtr exprOp;
12025df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik
1202675af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik    /*
120279bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    * BIG NOTE: This is not intended for XPATH_OP_FILTER yet!
1202875af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik    */
1202945490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
120309bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    /*
120319bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    * If not -1, then ch1 will point to:
120329bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    * 1) For predicates (XPATH_OP_PREDICATE):
120339bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    *    - an inner predicate operator
120349bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    * 2) For filters (XPATH_OP_FILTER):
120359bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    *    - an inner filter operater OR
120369bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    *    - an expression selecting the node set.
120379bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    *      E.g. "key('a', 'b')" or "(//foo | //bar)".
1203845490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard    */
120399bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    if ((op->op != XPATH_OP_PREDICATE) && (op->op != XPATH_OP_FILTER))
120409bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	return(0);
12041df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik
120429bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    if (op->ch2 != -1) {
120439bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	exprOp = &ctxt->comp->steps[op->ch2];
1204445490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard    } else
120459bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	return(0);
12046a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik
120479bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    if ((exprOp != NULL) &&
120489bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	(exprOp->op == XPATH_OP_VALUE) &&
120499bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	(exprOp->value4 != NULL) &&
120509bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	(((xmlXPathObjectPtr) exprOp->value4)->type == XPATH_NUMBER))
120519bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    {
12052df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik	/*
120539bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	* We have a "[n]" predicate here.
120549bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	* TODO: Unfortunately this simplistic test here is not
120559bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	* able to detect a position() predicate in compound
120569bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	* expressions like "[@attr = 'a" and position() = 1],
120579bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	* and even not the usage of position() in
120589bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	* "[position() = 1]"; thus - obviously - a position-range,
120599bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	* like it "[position() < 5]", is also not detected.
120609bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	* Maybe we could rewrite the AST to ease the optimization.
12061df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik	*/
120629bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	*maxPos = (int) ((xmlXPathObjectPtr) exprOp->value4)->floatval;
1206345490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
120649bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	if (((xmlXPathObjectPtr) exprOp->value4)->floatval ==
120659bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    (float) *maxPos)
1206645490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	{
120679bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    return(1);
120689bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	}
1206975af2a87e52aa16a91bd50f40ad3c0df3b0be54bKasimier T. Buchcik    }
120709bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    return(0);
12071d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard}
12072d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard
12073f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillardstatic int
120749bca933a6e39bae6dd8952825528270f006c97dfKasimier T. BuchcikxmlXPathNodeCollectAndTest(xmlXPathParserContextPtr ctxt,
120759bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik                           xmlXPathStepOpPtr op,
12076631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik			   xmlNodePtr * first, xmlNodePtr * last,
12077631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik			   int toBool)
12078f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard{
120799bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik
120809bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik#define XP_TEST_HIT \
120819bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    if (hasAxisRange != 0) { \
120829bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	if (++pos == maxPos) { \
120831bd45d13091e5af9e1fe0582b5e335c60d45535fDaniel Veillard	    if (addNode(seq, cur) < 0) \
120841bd45d13091e5af9e1fe0582b5e335c60d45535fDaniel Veillard	        ctxt->error = XPATH_MEMORY_ERROR; \
120851bd45d13091e5af9e1fe0582b5e335c60d45535fDaniel Veillard	    goto axis_range_end; } \
12086631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik    } else { \
120871bd45d13091e5af9e1fe0582b5e335c60d45535fDaniel Veillard	if (addNode(seq, cur) < 0) \
120881bd45d13091e5af9e1fe0582b5e335c60d45535fDaniel Veillard	    ctxt->error = XPATH_MEMORY_ERROR; \
12089631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	if (breakOnFirstHit) goto first_hit; }
120909bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik
120919bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik#define XP_TEST_HIT_NS \
120929bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    if (hasAxisRange != 0) { \
120939bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	if (++pos == maxPos) { \
120949bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    hasNsNodes = 1; \
120951bd45d13091e5af9e1fe0582b5e335c60d45535fDaniel Veillard	    if (xmlXPathNodeSetAddNs(seq, xpctxt->node, (xmlNsPtr) cur) < 0) \
120961bd45d13091e5af9e1fe0582b5e335c60d45535fDaniel Veillard	        ctxt->error = XPATH_MEMORY_ERROR; \
120979bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	goto axis_range_end; } \
120989bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    } else { \
120999bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	hasNsNodes = 1; \
121001bd45d13091e5af9e1fe0582b5e335c60d45535fDaniel Veillard	if (xmlXPathNodeSetAddNs(seq, xpctxt->node, (xmlNsPtr) cur) < 0) \
121011bd45d13091e5af9e1fe0582b5e335c60d45535fDaniel Veillard	    ctxt->error = XPATH_MEMORY_ERROR; \
12102631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	if (breakOnFirstHit) goto first_hit; }
121039bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik
1210478637da0ea1c833dfdfad87a9aa5bea14510d08aWilliam M. Brack    xmlXPathAxisVal axis = (xmlXPathAxisVal) op->value;
1210578637da0ea1c833dfdfad87a9aa5bea14510d08aWilliam M. Brack    xmlXPathTestVal test = (xmlXPathTestVal) op->value2;
1210678637da0ea1c833dfdfad87a9aa5bea14510d08aWilliam M. Brack    xmlXPathTypeVal type = (xmlXPathTypeVal) op->value3;
12107f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    const xmlChar *prefix = op->value4;
12108f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    const xmlChar *name = op->value5;
12109f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    const xmlChar *URI = NULL;
12110f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
121119bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik#ifdef DEBUG_STEP
121129bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    int nbMatches = 0, prevMatches = 0;
121139bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik#endif
121149bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    int total = 0, hasNsNodes = 0;
121159bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    /* The popped object holding the context nodes */
121169bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    xmlXPathObjectPtr obj;
121179bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    /* The set of context nodes for the node tests */
121189bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    xmlNodeSetPtr contextSeq;
121199bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    int contextIdx;
121209bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    xmlNodePtr contextNode;
121219bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    /* The final resulting node set wrt to all context nodes */
121229bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    xmlNodeSetPtr outSeq;
121239bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    /*
121249bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    * The temporary resulting node set wrt 1 context node.
121259bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    * Used to feed predicate evaluation.
121269bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    */
121279bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    xmlNodeSetPtr seq;
1212845490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard    xmlNodePtr cur;
121299bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    /* First predicate operator */
121309bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    xmlXPathStepOpPtr predOp;
121319bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    int maxPos; /* The requested position() (when a "[n]" predicate) */
121329bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    int hasPredicateRange, hasAxisRange, pos, size, newSize;
12133631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik    int breakOnFirstHit;
121349bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik
12135f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    xmlXPathTraversalFunction next = NULL;
121361bd45d13091e5af9e1fe0582b5e335c60d45535fDaniel Veillard    int (*addNode) (xmlNodeSetPtr, xmlNodePtr);
121379bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    xmlXPathNodeSetMergeFunction mergeAndClear;
1213845490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard    xmlNodePtr oldContextNode;
121399bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    xmlXPathContextPtr xpctxt = ctxt->context;
12140df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik
12141f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
12142f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    CHECK_TYPE0(XPATH_NODESET);
12143f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    obj = valuePop(ctxt);
121449bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    /*
121459bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    * Setup namespaces.
121469bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    */
12147f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    if (prefix != NULL) {
12148df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik        URI = xmlXPathNsLookup(xpctxt, prefix);
121492c19a7bf2ee0f78485840cac50f2a989f5efe476William M. Brack        if (URI == NULL) {
121509bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    xmlXPathReleaseObject(xpctxt, obj);
12151f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            XP_ERROR0(XPATH_UNDEF_PREFIX_ERROR);
121522c19a7bf2ee0f78485840cac50f2a989f5efe476William M. Brack	}
1215345490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard    }
121549bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    /*
121559bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    * Setup axis.
121569bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    *
121579bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    * MAYBE FUTURE TODO: merging optimizations:
121589bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    * - If the nodes to be traversed wrt to the initial nodes and
121599bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    *   the current axis cannot overlap, then we could avoid searching
121609bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    *   for duplicates during the merge.
121619bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    *   But the question is how/when to evaluate if they cannot overlap.
121629bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    *   Example: if we know that for two initial nodes, the one is
121639bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    *   not in the ancestor-or-self axis of the other, then we could safely
121649bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    *   avoid a duplicate-aware merge, if the axis to be traversed is e.g.
121659bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    *   the descendant-or-self axis.
121669bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    */
121679bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    mergeAndClear = xmlXPathNodeSetMergeAndClear;
12168f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    switch (axis) {
12169f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        case AXIS_ANCESTOR:
12170f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            first = NULL;
12171f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            next = xmlXPathNextAncestor;
12172f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            break;
12173f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        case AXIS_ANCESTOR_OR_SELF:
12174f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            first = NULL;
12175f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            next = xmlXPathNextAncestorOrSelf;
12176f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            break;
12177f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        case AXIS_ATTRIBUTE:
12178f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            first = NULL;
12179f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	    last = NULL;
12180f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            next = xmlXPathNextAttribute;
121819bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    mergeAndClear = xmlXPathNodeSetMergeAndClearNoDupls;
12182f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            break;
12183f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        case AXIS_CHILD:
12184f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	    last = NULL;
121859bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    if (((test == NODE_TEST_NAME) || (test == NODE_TEST_ALL)) &&
121869bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		(type == NODE_TYPE_NODE))
121879bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    {
12188df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		/*
12189df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		* Optimization if an element node type is 'element'.
12190df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		*/
12191df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		next = xmlXPathNextChildElement;
12192df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik	    } else
121939bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		next = xmlXPathNextChild;
121949bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    mergeAndClear = xmlXPathNodeSetMergeAndClearNoDupls;
12195f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            break;
12196f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        case AXIS_DESCENDANT:
12197f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	    last = NULL;
12198f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            next = xmlXPathNextDescendant;
12199f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            break;
12200f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        case AXIS_DESCENDANT_OR_SELF:
12201f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	    last = NULL;
12202f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            next = xmlXPathNextDescendantOrSelf;
12203f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            break;
12204f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        case AXIS_FOLLOWING:
12205f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	    last = NULL;
12206f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            next = xmlXPathNextFollowing;
12207f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            break;
12208f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        case AXIS_FOLLOWING_SIBLING:
12209f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	    last = NULL;
12210f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            next = xmlXPathNextFollowingSibling;
12211f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            break;
12212f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        case AXIS_NAMESPACE:
12213f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            first = NULL;
122149bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    last = NULL;
12215f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            next = (xmlXPathTraversalFunction) xmlXPathNextNamespace;
122169bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    mergeAndClear = xmlXPathNodeSetMergeAndClearNoDupls;
12217f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            break;
12218f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        case AXIS_PARENT:
12219f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            first = NULL;
12220f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            next = xmlXPathNextParent;
12221f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            break;
12222f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        case AXIS_PRECEDING:
12223f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            first = NULL;
12224f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            next = xmlXPathNextPrecedingInternal;
12225f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            break;
12226f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        case AXIS_PRECEDING_SIBLING:
12227f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            first = NULL;
12228f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            next = xmlXPathNextPrecedingSibling;
12229f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            break;
12230f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        case AXIS_SELF:
12231f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            first = NULL;
12232f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	    last = NULL;
12233f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            next = xmlXPathNextSelf;
122349bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    mergeAndClear = xmlXPathNodeSetMergeAndClearNoDupls;
12235f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            break;
12236f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    }
122379bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik
122389bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik#ifdef DEBUG_STEP
12239074f37e7ebd5e76ceb584a89745a9e84df5b3be2Daniel Veillard    xmlXPathDebugDumpStepAxis(op,
12240074f37e7ebd5e76ceb584a89745a9e84df5b3be2Daniel Veillard	(obj->nodesetval != NULL) ? obj->nodesetval->nodeNr : 0);
122419bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik#endif
122429bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik
122432c19a7bf2ee0f78485840cac50f2a989f5efe476William M. Brack    if (next == NULL) {
1224445490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	xmlXPathReleaseObject(xpctxt, obj);
12245f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        return(0);
1224645490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard    }
122479bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    contextSeq = obj->nodesetval;
122489bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    if ((contextSeq == NULL) || (contextSeq->nodeNr <= 0)) {
122499bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	xmlXPathReleaseObject(xpctxt, obj);
122509bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik        valuePush(ctxt, xmlXPathCacheWrapNodeSet(xpctxt, NULL));
12251f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        return(0);
1225245490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard    }
122539bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    /*
122549bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    * Predicate optimization ---------------------------------------------
122559bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    * If this step has a last predicate, which contains a position(),
122569bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    * then we'll optimize (although not exactly "position()", but only
122579bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    * the  short-hand form, i.e., "[n]".
122589bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    *
122599bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    * Example - expression "/foo[parent::bar][1]":
1226045490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard    *
122619bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    * COLLECT 'child' 'name' 'node' foo    -- op (we are here)
122629bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    *   ROOT                               -- op->ch1
122639bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    *   PREDICATE                          -- op->ch2 (predOp)
122649bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    *     PREDICATE                          -- predOp->ch1 = [parent::bar]
122659bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    *       SORT
122669bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    *         COLLECT  'parent' 'name' 'node' bar
122679bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    *           NODE
122689bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    *     ELEM Object is a number : 1        -- predOp->ch2 = [1]
122699bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    *
122709bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    */
122719bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    maxPos = 0;
122729bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    predOp = NULL;
122739bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    hasPredicateRange = 0;
122749bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    hasAxisRange = 0;
122759bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    if (op->ch2 != -1) {
122769bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	/*
122779bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	* There's at least one predicate. 16 == XPATH_OP_PREDICATE
122789bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	*/
122799bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	predOp = &ctxt->comp->steps[op->ch2];
122809bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	if (xmlXPathIsPositionalPredicate(ctxt, predOp, &maxPos)) {
122819bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    if (predOp->ch1 != -1) {
122829bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		/*
122839bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		* Use the next inner predicate operator.
122849bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		*/
122859bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		predOp = &ctxt->comp->steps[predOp->ch1];
122869bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		hasPredicateRange = 1;
122879bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    } else {
122889bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		/*
122899bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		* There's no other predicate than the [n] predicate.
122909bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		*/
122919bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		predOp = NULL;
122929bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		hasAxisRange = 1;
1229345490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	    }
122949bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	}
12295f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    }
12296631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik    breakOnFirstHit = ((toBool) && (predOp == NULL)) ? 1 : 0;
122979bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    /*
122989bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    * Axis traversal -----------------------------------------------------
122999bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    */
12300f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    /*
12301f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard     * 2.3 Node Tests
1230245490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard     *  - For the attribute axis, the principal node type is attribute.
123039bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik     *  - For the namespace axis, the principal node type is namespace.
123049bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik     *  - For other axes, the principal node type is element.
12305f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard     *
12306f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard     * A node test * is true for any node of the
12307cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard     * principal node type. For example, child::* will
12308f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard     * select all element children of the context node
12309f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard     */
12310df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik    oldContextNode = xpctxt->node;
12311df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik    addNode = xmlXPathNodeSetAddUnique;
123129bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    outSeq = NULL;
123139bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    seq = NULL;
12314df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik    contextNode = NULL;
123159bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    contextIdx = 0;
123169bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik
12317df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik
123181bd45d13091e5af9e1fe0582b5e335c60d45535fDaniel Veillard    while (((contextIdx < contextSeq->nodeNr) || (contextNode != NULL)) &&
123191bd45d13091e5af9e1fe0582b5e335c60d45535fDaniel Veillard           (ctxt->error == XPATH_EXPRESSION_OK)) {
12320622705398ab0b9aa3ed5f671432ef894d620f8a4Nick Wellnhofer	xpctxt->node = contextSeq->nodeTab[contextIdx++];
1232145490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
123229bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	if (seq == NULL) {
123239bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    seq = xmlXPathNodeSetCreate(NULL);
123249bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    if (seq == NULL) {
123259bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		total = 0;
123269bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		goto error;
123279bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    }
123289bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	}
123299bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	/*
123309bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	* Traverse the axis and test the nodes.
123319bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	*/
123329bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	pos = 0;
123339bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	cur = NULL;
123349bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	hasNsNodes = 0;
12335f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        do {
12336f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            cur = next(ctxt, cur);
12337f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            if (cur == NULL)
12338f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                break;
12339df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik
123409bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    /*
123419bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    * QUESTION TODO: What does the "first" and "last" stuff do?
123429bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    */
12343631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik            if ((first != NULL) && (*first != NULL)) {
12344df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		if (*first == cur)
12345df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		    break;
12346631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik		if (((total % 256) == 0) &&
12347df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik#ifdef XP_OPTIMIZED_NON_ELEM_COMPARISON
12348df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		    (xmlXPathCmpNodesExt(*first, cur) >= 0))
12349df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik#else
12350631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik		    (xmlXPathCmpNodes(*first, cur) >= 0))
12351df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik#endif
12352df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		{
12353df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		    break;
12354df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		}
12355df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik	    }
12356631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    if ((last != NULL) && (*last != NULL)) {
12357df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		if (*last == cur)
12358df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		    break;
12359631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik		if (((total % 256) == 0) &&
12360df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik#ifdef XP_OPTIMIZED_NON_ELEM_COMPARISON
12361df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		    (xmlXPathCmpNodesExt(cur, *last) >= 0))
12362df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik#else
12363df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		    (xmlXPathCmpNodes(cur, *last) >= 0))
12364df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik#endif
12365df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		{
12366df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		    break;
12367df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		}
12368df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik	    }
12369df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik
12370df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik            total++;
123719bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik
123729bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik#ifdef DEBUG_STEP
123739bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik            xmlGenericError(xmlGenericErrorContext, " %s", cur->name);
123749bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik#endif
1237545490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
123769bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    switch (test) {
12377f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                case NODE_TEST_NONE:
12378df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		    total = 0;
12379df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik                    STRANGE
12380df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		    goto error;
12381f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                case NODE_TEST_TYPE:
123829bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		    /*
123839bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		    * TODO: Don't we need to use
123849bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		    *  xmlXPathNodeSetAddNs() for namespace nodes here?
123859bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		    *  Surprisingly, some c14n tests fail, if we do this.
123869bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		    */
123879bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		    if (type == NODE_TYPE_NODE) {
123889bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik			switch (cur->type) {
123899bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik			    case XML_DOCUMENT_NODE:
123909bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik			    case XML_HTML_DOCUMENT_NODE:
123919bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik#ifdef LIBXML_DOCB_ENABLED
123929bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik			    case XML_DOCB_DOCUMENT_NODE:
123939bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik#endif
1239445490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard			    case XML_ELEMENT_NODE:
123959bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik			    case XML_ATTRIBUTE_NODE:
123969bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik			    case XML_PI_NODE:
123979bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik			    case XML_COMMENT_NODE:
123989bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik			    case XML_CDATA_SECTION_NODE:
123999bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik			    case XML_TEXT_NODE:
124009bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik			    case XML_NAMESPACE_DECL:
124019bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik				XP_TEST_HIT
124029bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik				break;
124039bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik			    default:
124049bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik				break;
124059bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik			}
124069bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		    } else if (cur->type == type) {
12407713434d2309da469d64b35e163ea6556dadccadaDaniel Veillard			if (cur->type == XML_NAMESPACE_DECL)
12408889b76229b544ec2fe1a4996c8a3b0733f4fc828Kasimier T. Buchcik			    XP_TEST_HIT_NS
12409889b76229b544ec2fe1a4996c8a3b0733f4fc828Kasimier T. Buchcik			else
12410889b76229b544ec2fe1a4996c8a3b0733f4fc828Kasimier T. Buchcik			    XP_TEST_HIT
124119bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		    } else if ((type == NODE_TYPE_TEXT) &&
124129bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik			 (cur->type == XML_CDATA_SECTION_NODE))
124139bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		    {
124149bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik			XP_TEST_HIT
124159bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		    }
124169bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		    break;
12417f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                case NODE_TEST_PI:
124189bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik                    if ((cur->type == XML_PI_NODE) &&
124199bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik                        ((name == NULL) || xmlStrEqual(name, cur->name)))
124209bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		    {
124219bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik			XP_TEST_HIT
12422f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    }
12423f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    break;
12424f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                case NODE_TEST_ALL:
12425f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    if (axis == AXIS_ATTRIBUTE) {
124269bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik                        if (cur->type == XML_ATTRIBUTE_NODE)
124279bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik			{
12428e8de99f90cde4832065d7a87d74393a46c191d0bNick Wellnhofer                            if (prefix == NULL)
12429e8de99f90cde4832065d7a87d74393a46c191d0bNick Wellnhofer			    {
12430e8de99f90cde4832065d7a87d74393a46c191d0bNick Wellnhofer				XP_TEST_HIT
12431e8de99f90cde4832065d7a87d74393a46c191d0bNick Wellnhofer                            } else if ((cur->ns != NULL) &&
12432e8de99f90cde4832065d7a87d74393a46c191d0bNick Wellnhofer				(xmlStrEqual(URI, cur->ns->href)))
12433e8de99f90cde4832065d7a87d74393a46c191d0bNick Wellnhofer			    {
12434e8de99f90cde4832065d7a87d74393a46c191d0bNick Wellnhofer				XP_TEST_HIT
12435e8de99f90cde4832065d7a87d74393a46c191d0bNick Wellnhofer                            }
12436f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        }
12437f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    } else if (axis == AXIS_NAMESPACE) {
124389bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik                        if (cur->type == XML_NAMESPACE_DECL)
124399bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik			{
124409bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik			    XP_TEST_HIT_NS
12441f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        }
12442f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    } else {
12443f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        if (cur->type == XML_ELEMENT_NODE) {
124449bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik                            if (prefix == NULL)
124459bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik			    {
124469bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik				XP_TEST_HIT
124479bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik
12448f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                            } else if ((cur->ns != NULL) &&
124499bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik				(xmlStrEqual(URI, cur->ns->href)))
124509bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik			    {
124519bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik				XP_TEST_HIT
12452f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                            }
12453f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        }
12454f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    }
12455f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    break;
12456f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                case NODE_TEST_NS:{
12457f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        TODO;
12458f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        break;
12459f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    }
12460f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                case NODE_TEST_NAME:
12461fe3970e09fc95a78eea09225e21ec24b69c1dc75Daniel Veillard                    if (axis == AXIS_ATTRIBUTE) {
12462fe3970e09fc95a78eea09225e21ec24b69c1dc75Daniel Veillard                        if (cur->type != XML_ATTRIBUTE_NODE)
12463fe3970e09fc95a78eea09225e21ec24b69c1dc75Daniel Veillard			    break;
12464fe3970e09fc95a78eea09225e21ec24b69c1dc75Daniel Veillard		    } else if (axis == AXIS_NAMESPACE) {
12465fe3970e09fc95a78eea09225e21ec24b69c1dc75Daniel Veillard                        if (cur->type != XML_NAMESPACE_DECL)
12466fe3970e09fc95a78eea09225e21ec24b69c1dc75Daniel Veillard			    break;
12467fe3970e09fc95a78eea09225e21ec24b69c1dc75Daniel Veillard		    } else {
12468fe3970e09fc95a78eea09225e21ec24b69c1dc75Daniel Veillard		        if (cur->type != XML_ELEMENT_NODE)
12469fe3970e09fc95a78eea09225e21ec24b69c1dc75Daniel Veillard			    break;
12470fe3970e09fc95a78eea09225e21ec24b69c1dc75Daniel Veillard		    }
12471f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    switch (cur->type) {
12472f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        case XML_ELEMENT_NODE:
12473f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                            if (xmlStrEqual(name, cur->name)) {
12474f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                                if (prefix == NULL) {
124759bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik                                    if (cur->ns == NULL)
124769bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik				    {
124779bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik					XP_TEST_HIT
12478f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                                    }
12479f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                                } else {
12480f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                                    if ((cur->ns != NULL) &&
124819bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik                                        (xmlStrEqual(URI, cur->ns->href)))
12482df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik				    {
124839bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik					XP_TEST_HIT
12484f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                                    }
12485f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                                }
12486f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                            }
12487f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                            break;
12488f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        case XML_ATTRIBUTE_NODE:{
12489f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                                xmlAttrPtr attr = (xmlAttrPtr) cur;
12490f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
12491f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                                if (xmlStrEqual(name, attr->name)) {
12492f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                                    if (prefix == NULL) {
12493f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                                        if ((attr->ns == NULL) ||
12494df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik                                            (attr->ns->prefix == NULL))
12495df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik					{
124969bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik					    XP_TEST_HIT
12497f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                                        }
12498f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                                    } else {
12499f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                                        if ((attr->ns != NULL) &&
12500f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                                            (xmlStrEqual(URI,
12501df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik					      attr->ns->href)))
12502df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik					{
125039bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik					    XP_TEST_HIT
12504f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                                        }
12505f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                                    }
12506f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                                }
12507f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                                break;
12508f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                            }
12509f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        case XML_NAMESPACE_DECL:
12510f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                            if (cur->type == XML_NAMESPACE_DECL) {
12511f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                                xmlNsPtr ns = (xmlNsPtr) cur;
12512f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
12513f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                                if ((ns->prefix != NULL) && (name != NULL)
125149bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik                                    && (xmlStrEqual(ns->prefix, name)))
125159bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik				{
125169bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik				    XP_TEST_HIT_NS
12517f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                                }
12518f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                            }
12519f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                            break;
12520f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        default:
12521f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                            break;
12522f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    }
12523f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    break;
125249bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    } /* switch(test) */
125251bd45d13091e5af9e1fe0582b5e335c60d45535fDaniel Veillard        } while ((cur != NULL) && (ctxt->error == XPATH_EXPRESSION_OK));
12526df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik
125279bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	goto apply_predicates;
125289bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik
1252945490aebe7a60704e8ed850c498969858ab900eeDaniel Veillardaxis_range_end: /* ----------------------------------------------------- */
125309bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	/*
125319bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	* We have a "/foo[n]", and position() = n was reached.
125329bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	* Note that we can have as well "/foo/::parent::foo[1]", so
125339bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	* a duplicate-aware merge is still needed.
125349bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	* Merge with the result.
125359bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	*/
125369bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	if (outSeq == NULL) {
125379bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    outSeq = seq;
125389bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    seq = NULL;
125399bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	} else
12540631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    outSeq = mergeAndClear(outSeq, seq, 0);
12541631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	/*
12542631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	* Break if only a true/false result was requested.
12543631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	*/
12544631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	if (toBool)
12545631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    break;
125469bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	continue;
125479bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik
12548631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcikfirst_hit: /* ---------------------------------------------------------- */
12549631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	/*
12550631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	* Break if only a true/false result was requested and
12551631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	* no predicates existed and a node test succeeded.
12552631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	*/
12553631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	if (outSeq == NULL) {
12554631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    outSeq = seq;
12555631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    seq = NULL;
12556631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	} else
12557631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    outSeq = mergeAndClear(outSeq, seq, 0);
12558631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	break;
12559631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik
125609bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik#ifdef DEBUG_STEP
125619bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	if (seq != NULL)
125629bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    nbMatches += seq->nodeNr;
12563f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#endif
12564df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik
125659bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcikapply_predicates: /* --------------------------------------------------- */
125661bd45d13091e5af9e1fe0582b5e335c60d45535fDaniel Veillard        if (ctxt->error != XPATH_EXPRESSION_OK)
125671bd45d13091e5af9e1fe0582b5e335c60d45535fDaniel Veillard	    goto error;
125681bd45d13091e5af9e1fe0582b5e335c60d45535fDaniel Veillard
125699bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik        /*
125709bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	* Apply predicates.
1257145490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	*/
125729bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik        if ((predOp != NULL) && (seq->nodeNr > 0)) {
125739bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    /*
125749bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    * E.g. when we have a "/foo[some expression][n]".
12575f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard	    */
125769bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    /*
125779bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    * QUESTION TODO: The old predicate evaluation took into
125789bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    *  account location-sets.
125799bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    *  (E.g. ctxt->value->type == XPATH_LOCATIONSET)
125809bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    *  Do we expect such a set here?
125819bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    *  All what I learned now from the evaluation semantics
125829bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    *  does not indicate that a location-set will be processed
125839bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    *  here, so this looks OK.
12584f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard	    */
125859bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    /*
125869bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    * Iterate over all predicates, starting with the outermost
125879bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    * predicate.
125889bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    * TODO: Problem: we cannot execute the inner predicates first
125899bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    *  since we cannot go back *up* the operator tree!
125909bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    *  Options we have:
125919bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    *  1) Use of recursive functions (like is it currently done
125929bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    *     via xmlXPathCompOpEval())
125939bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    *  2) Add a predicate evaluation information stack to the
125949bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    *     context struct
125959bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    *  3) Change the way the operators are linked; we need a
125969bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    *     "parent" field on xmlXPathStepOp
125979bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    *
125989bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    * For the moment, I'll try to solve this with a recursive
125999bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    * function: xmlXPathCompOpEvalPredicate().
1260045490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	    */
126019bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    size = seq->nodeNr;
126029bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    if (hasPredicateRange != 0)
126039bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		newSize = xmlXPathCompOpEvalPositionalPredicate(ctxt,
126049bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		    predOp, seq, size, maxPos, maxPos, hasNsNodes);
126059bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    else
126069bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		newSize = xmlXPathCompOpEvalPredicate(ctxt,
126079bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		    predOp, seq, size, hasNsNodes);
126089bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik
126099bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    if (ctxt->error != XPATH_EXPRESSION_OK) {
126109bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		total = 0;
126119bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		goto error;
126129bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    }
126139bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    /*
126149bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    * Add the filtered set of nodes to the result node set.
126159bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    */
126169bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    if (newSize == 0) {
126179bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		/*
126189bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		* The predicates filtered all nodes out.
126199bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		*/
126209bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		xmlXPathNodeSetClear(seq, hasNsNodes);
126219bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    } else if (seq->nodeNr > 0) {
126229bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		/*
126239bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		* Add to result set.
126249bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		*/
126259bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		if (outSeq == NULL) {
126269bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		    if (size != newSize) {
126279bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik			/*
126289bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik			* We need to merge and clear here, since
126299bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik			* the sequence will contained NULLed entries.
126309bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik			*/
126319bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik			outSeq = mergeAndClear(NULL, seq, 1);
126329bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		    } else {
126339bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik			outSeq = seq;
126349bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik			seq = NULL;
126359bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		    }
126369bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		} else
126379bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		    outSeq = mergeAndClear(outSeq, seq,
126389bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik			(size != newSize) ? 1: 0);
12639631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik		/*
12640631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik		* Break if only a true/false result was requested.
12641631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik		*/
12642631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik		if (toBool)
12643631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik		    break;
126449bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    }
126459bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik        } else if (seq->nodeNr > 0) {
126469bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    /*
126479bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    * Add to result set.
126489bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    */
126499bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    if (outSeq == NULL) {
126509bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		outSeq = seq;
126519bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		seq = NULL;
126529bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    } else {
126539bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		outSeq = mergeAndClear(outSeq, seq, 0);
126549bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    }
1265545490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	}
126569bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    }
12657df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik
126589bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcikerror:
126590ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard    if ((obj->boolval) && (obj->user != NULL)) {
126609bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	/*
126619bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	* QUESTION TODO: What does this do and why?
126629bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	* TODO: Do we have to do this also for the "error"
126639bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	* cleanup further down?
126649bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	*/
126650ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard	ctxt->value->boolval = 1;
126660ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard	ctxt->value->user = obj->user;
126670ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard	obj->user = NULL;
126680ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard	obj->boolval = 0;
126690ab5caba5b47a2cdafa83059ec3e02fde78d6262Daniel Veillard    }
12670df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik    xmlXPathReleaseObject(xpctxt, obj);
12671df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik
126729bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    /*
126739bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    * Ensure we return at least an emtpy set.
126749bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    */
126759bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    if (outSeq == NULL) {
126769bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	if ((seq != NULL) && (seq->nodeNr == 0))
126779bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    outSeq = seq;
126789bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	else
126799bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	    outSeq = xmlXPathNodeSetCreate(NULL);
12680f88d849a4e994c94c0d0814a4befb43c990ceebdDaniel Veillard        /* XXX what if xmlXPathNodeSetCreate returned NULL here? */
126819bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    }
126829bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    if ((seq != NULL) && (seq != outSeq)) {
126839bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	 xmlXPathFreeNodeSet(seq);
1268445490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard    }
126859bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    /*
126869bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    * Hand over the result. Better to push the set also in
126879bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    * case of errors.
126889bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    */
126899bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    valuePush(ctxt, xmlXPathCacheWrapNodeSet(xpctxt, outSeq));
126909bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    /*
126919bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    * Reset the context node.
126929bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    */
12693df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik    xpctxt->node = oldContextNode;
126949bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik
126959bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik#ifdef DEBUG_STEP
126969bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik    xmlGenericError(xmlGenericErrorContext,
126979bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	"\nExamined %d nodes, found %d nodes at that step\n",
126989bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	total, nbMatches);
126999bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik#endif
127009bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik
12701df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik    return(total);
12702f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard}
12703f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
127045691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcikstatic int
127055691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. BuchcikxmlXPathCompOpEvalFilterFirst(xmlXPathParserContextPtr ctxt,
127065691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik			      xmlXPathStepOpPtr op, xmlNodePtr * first);
127075691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik
12708f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard/**
12709f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * xmlXPathCompOpEvalFirst:
12710d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * @ctxt:  the XPath parser context with the compiled expression
12711d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * @op:  an XPath compiled operation
12712f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * @first:  the first elem found so far
12713d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard *
12714f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Evaluate the Precompiled XPath operation searching only the first
12715f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * element in document order
12716f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard *
12717f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Returns the number of examined objects.
12718d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard */
12719f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillardstatic int
12720f06307e2c172284bb41376c396f757bdac9bdd19Daniel VeillardxmlXPathCompOpEvalFirst(xmlXPathParserContextPtr ctxt,
12721f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        xmlXPathStepOpPtr op, xmlNodePtr * first)
12722f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard{
12723f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    int total = 0, cur;
12724d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard    xmlXPathCompExprPtr comp;
12725d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard    xmlXPathObjectPtr arg1, arg2;
12726d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard
12727556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard    CHECK_ERROR0;
12728d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard    comp = ctxt->comp;
12729d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard    switch (op->op) {
12730f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        case XPATH_OP_END:
12731f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            return (0);
12732f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        case XPATH_OP_UNION:
12733f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            total =
12734f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                xmlXPathCompOpEvalFirst(ctxt, &comp->steps[op->ch1],
12735f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                                        first);
12736556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard	    CHECK_ERROR0;
12737f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            if ((ctxt->value != NULL)
12738f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                && (ctxt->value->type == XPATH_NODESET)
12739f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                && (ctxt->value->nodesetval != NULL)
12740f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                && (ctxt->value->nodesetval->nodeNr >= 1)) {
12741f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                /*
12742f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                 * limit tree traversing to first node in the result
12743f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                 */
127445691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		/*
127455691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		* OPTIMIZE TODO: This implicitely sorts
127465691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		*  the result, even if not needed. E.g. if the argument
127475691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		*  of the count() function, no sorting is needed.
127485691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		* OPTIMIZE TODO: How do we know if the node-list wasn't
127495691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		*  aready sorted?
127505691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		*/
1275164f7e1a85fe9c973cf9b21cc0bd53efa6cc3dafcKasimier T. Buchcik		if (ctxt->value->nodesetval->nodeNr > 1)
1275264f7e1a85fe9c973cf9b21cc0bd53efa6cc3dafcKasimier T. Buchcik		    xmlXPathNodeSetSort(ctxt->value->nodesetval);
12753f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                *first = ctxt->value->nodesetval->nodeTab[0];
12754f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            }
12755f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            cur =
12756f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                xmlXPathCompOpEvalFirst(ctxt, &comp->steps[op->ch2],
12757f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                                        first);
12758556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard	    CHECK_ERROR0;
12759f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            CHECK_TYPE0(XPATH_NODESET);
12760f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            arg2 = valuePop(ctxt);
12761f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
12762f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            CHECK_TYPE0(XPATH_NODESET);
12763f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            arg1 = valuePop(ctxt);
12764f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
12765f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            arg1->nodesetval = xmlXPathNodeSetMerge(arg1->nodesetval,
12766f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                                                    arg2->nodesetval);
12767f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            valuePush(ctxt, arg1);
12768a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathReleaseObject(ctxt->context, arg2);
12769f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            /* optimizer */
12770f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	    if (total > cur)
12771f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard		xmlXPathCompSwap(op);
12772f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            return (total + cur);
12773f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        case XPATH_OP_ROOT:
12774f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            xmlXPathRoot(ctxt);
12775f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            return (0);
12776f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        case XPATH_OP_NODE:
12777f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            if (op->ch1 != -1)
12778f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
12779556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard	    CHECK_ERROR0;
12780f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            if (op->ch2 != -1)
12781f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
12782556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard	    CHECK_ERROR0;
12783a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    valuePush(ctxt, xmlXPathCacheNewNodeSet(ctxt->context,
12784a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		ctxt->context->node));
12785f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            return (total);
12786f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        case XPATH_OP_RESET:
12787f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            if (op->ch1 != -1)
12788f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
12789556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard	    CHECK_ERROR0;
12790f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            if (op->ch2 != -1)
12791f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
12792556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard	    CHECK_ERROR0;
12793f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            ctxt->context->node = NULL;
12794f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            return (total);
12795f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        case XPATH_OP_COLLECT:{
12796f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                if (op->ch1 == -1)
12797f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    return (total);
12798f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
12799f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                total = xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
12800556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard		CHECK_ERROR0;
12801f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
12802631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik                total += xmlXPathNodeCollectAndTest(ctxt, op, first, NULL, 0);
12803f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                return (total);
12804f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            }
12805f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        case XPATH_OP_VALUE:
12806f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            valuePush(ctxt,
12807a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik                      xmlXPathCacheObjectCopy(ctxt->context,
12808a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik			(xmlXPathObjectPtr) op->value4));
12809f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            return (0);
12810f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        case XPATH_OP_SORT:
12811f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            if (op->ch1 != -1)
12812f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                total +=
12813f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    xmlXPathCompOpEvalFirst(ctxt, &comp->steps[op->ch1],
12814f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                                            first);
12815556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard	    CHECK_ERROR0;
12816f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            if ((ctxt->value != NULL)
12817f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                && (ctxt->value->type == XPATH_NODESET)
128185691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik                && (ctxt->value->nodesetval != NULL)
128195691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		&& (ctxt->value->nodesetval->nodeNr > 1))
12820f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                xmlXPathNodeSetSort(ctxt->value->nodesetval);
12821f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            return (total);
128225691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik#ifdef XP_OPTIMIZED_FILTER_FIRST
128235691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	case XPATH_OP_FILTER:
128242ddecc23862bab1a9a9e51e097aefc92ec305e28Marius Wachtler                total += xmlXPathCompOpEvalFilterFirst(ctxt, op, first);
128255691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik            return (total);
128265691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik#endif
12827f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        default:
12828f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            return (xmlXPathCompOpEval(ctxt, op));
12829f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    }
12830f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard}
1283142596ad20cdf1925dd79ea801cbe598b6e7b7aecDaniel Veillard
12832f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard/**
12833f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * xmlXPathCompOpEvalLast:
12834f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * @ctxt:  the XPath parser context with the compiled expression
12835f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * @op:  an XPath compiled operation
12836f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * @last:  the last elem found so far
12837f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard *
12838f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Evaluate the Precompiled XPath operation searching only the last
12839f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * element in document order
12840f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard *
12841081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack * Returns the number of nodes traversed
12842f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */
12843f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillardstatic int
12844f06307e2c172284bb41376c396f757bdac9bdd19Daniel VeillardxmlXPathCompOpEvalLast(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op,
12845f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                       xmlNodePtr * last)
12846f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard{
12847f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    int total = 0, cur;
12848f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    xmlXPathCompExprPtr comp;
12849f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    xmlXPathObjectPtr arg1, arg2;
12850ce4fc56e1b56253ae794b47515948f3bc3142024William M. Brack    xmlNodePtr bak;
12851ce4fc56e1b56253ae794b47515948f3bc3142024William M. Brack    xmlDocPtr bakd;
12852ce4fc56e1b56253ae794b47515948f3bc3142024William M. Brack    int pp;
12853ce4fc56e1b56253ae794b47515948f3bc3142024William M. Brack    int cs;
128549e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
12855556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard    CHECK_ERROR0;
12856f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    comp = ctxt->comp;
12857f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    switch (op->op) {
12858f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        case XPATH_OP_END:
12859f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            return (0);
12860f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        case XPATH_OP_UNION:
12861ce4fc56e1b56253ae794b47515948f3bc3142024William M. Brack	    bakd = ctxt->context->doc;
12862ce4fc56e1b56253ae794b47515948f3bc3142024William M. Brack	    bak = ctxt->context->node;
12863ce4fc56e1b56253ae794b47515948f3bc3142024William M. Brack	    pp = ctxt->context->proximityPosition;
12864ce4fc56e1b56253ae794b47515948f3bc3142024William M. Brack	    cs = ctxt->context->contextSize;
12865f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            total =
12866f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                xmlXPathCompOpEvalLast(ctxt, &comp->steps[op->ch1], last);
12867556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard	    CHECK_ERROR0;
12868f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            if ((ctxt->value != NULL)
12869f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                && (ctxt->value->type == XPATH_NODESET)
12870f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                && (ctxt->value->nodesetval != NULL)
12871f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                && (ctxt->value->nodesetval->nodeNr >= 1)) {
12872f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                /*
12873f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                 * limit tree traversing to first node in the result
12874f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                 */
1287564f7e1a85fe9c973cf9b21cc0bd53efa6cc3dafcKasimier T. Buchcik		if (ctxt->value->nodesetval->nodeNr > 1)
1287664f7e1a85fe9c973cf9b21cc0bd53efa6cc3dafcKasimier T. Buchcik		    xmlXPathNodeSetSort(ctxt->value->nodesetval);
12877f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                *last =
12878f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    ctxt->value->nodesetval->nodeTab[ctxt->value->
12879f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                                                     nodesetval->nodeNr -
12880f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                                                     1];
12881f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            }
12882ce4fc56e1b56253ae794b47515948f3bc3142024William M. Brack	    ctxt->context->doc = bakd;
12883ce4fc56e1b56253ae794b47515948f3bc3142024William M. Brack	    ctxt->context->node = bak;
12884ce4fc56e1b56253ae794b47515948f3bc3142024William M. Brack	    ctxt->context->proximityPosition = pp;
12885ce4fc56e1b56253ae794b47515948f3bc3142024William M. Brack	    ctxt->context->contextSize = cs;
12886f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            cur =
12887f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                xmlXPathCompOpEvalLast(ctxt, &comp->steps[op->ch2], last);
12888556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard	    CHECK_ERROR0;
12889f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            if ((ctxt->value != NULL)
12890f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                && (ctxt->value->type == XPATH_NODESET)
12891f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                && (ctxt->value->nodesetval != NULL)
1289264f7e1a85fe9c973cf9b21cc0bd53efa6cc3dafcKasimier T. Buchcik                && (ctxt->value->nodesetval->nodeNr >= 1)) { /* TODO: NOP ? */
12893f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            }
12894f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            CHECK_TYPE0(XPATH_NODESET);
12895f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            arg2 = valuePop(ctxt);
12896f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
12897f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            CHECK_TYPE0(XPATH_NODESET);
12898f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            arg1 = valuePop(ctxt);
12899f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
12900f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            arg1->nodesetval = xmlXPathNodeSetMerge(arg1->nodesetval,
12901f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                                                    arg2->nodesetval);
12902f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            valuePush(ctxt, arg1);
12903a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathReleaseObject(ctxt->context, arg2);
12904f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            /* optimizer */
12905f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	    if (total > cur)
12906f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard		xmlXPathCompSwap(op);
12907f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            return (total + cur);
12908f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        case XPATH_OP_ROOT:
12909f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            xmlXPathRoot(ctxt);
12910f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            return (0);
12911f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        case XPATH_OP_NODE:
12912f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            if (op->ch1 != -1)
12913f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
12914556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard	    CHECK_ERROR0;
12915f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            if (op->ch2 != -1)
12916f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
12917556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard	    CHECK_ERROR0;
12918a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    valuePush(ctxt, xmlXPathCacheNewNodeSet(ctxt->context,
12919a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		ctxt->context->node));
12920f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            return (total);
12921f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        case XPATH_OP_RESET:
12922f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            if (op->ch1 != -1)
12923f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
12924556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard	    CHECK_ERROR0;
12925f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            if (op->ch2 != -1)
12926f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
12927556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard	    CHECK_ERROR0;
12928f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            ctxt->context->node = NULL;
12929f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            return (total);
12930f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        case XPATH_OP_COLLECT:{
12931f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                if (op->ch1 == -1)
12932f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    return (0);
12933f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
12934f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
12935556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard		CHECK_ERROR0;
12936f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
12937631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik                total += xmlXPathNodeCollectAndTest(ctxt, op, NULL, last, 0);
12938f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                return (total);
12939f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            }
12940f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        case XPATH_OP_VALUE:
12941f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            valuePush(ctxt,
12942a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik                      xmlXPathCacheObjectCopy(ctxt->context,
12943a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik			(xmlXPathObjectPtr) op->value4));
12944f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            return (0);
12945f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        case XPATH_OP_SORT:
12946f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            if (op->ch1 != -1)
12947f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                total +=
12948f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    xmlXPathCompOpEvalLast(ctxt, &comp->steps[op->ch1],
12949f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                                           last);
12950556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard	    CHECK_ERROR0;
12951f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            if ((ctxt->value != NULL)
12952f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                && (ctxt->value->type == XPATH_NODESET)
1295364f7e1a85fe9c973cf9b21cc0bd53efa6cc3dafcKasimier T. Buchcik                && (ctxt->value->nodesetval != NULL)
1295464f7e1a85fe9c973cf9b21cc0bd53efa6cc3dafcKasimier T. Buchcik		&& (ctxt->value->nodesetval->nodeNr > 1))
12955f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                xmlXPathNodeSetSort(ctxt->value->nodesetval);
12956f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            return (total);
12957f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        default:
12958f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            return (xmlXPathCompOpEval(ctxt, op));
12959f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    }
12960f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard}
129619e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
129625691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik#ifdef XP_OPTIMIZED_FILTER_FIRST
129635691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcikstatic int
129645691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. BuchcikxmlXPathCompOpEvalFilterFirst(xmlXPathParserContextPtr ctxt,
129655691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik			      xmlXPathStepOpPtr op, xmlNodePtr * first)
129665691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik{
129675691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik    int total = 0;
1296845490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard    xmlXPathCompExprPtr comp;
129695691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik    xmlXPathObjectPtr res;
1297045490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard    xmlXPathObjectPtr obj;
129715691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik    xmlNodeSetPtr oldset;
129725691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik    xmlNodePtr oldnode;
129735691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik    xmlDocPtr oldDoc;
129745691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik    int i;
129755691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik
129765691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik    CHECK_ERROR0;
129775691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik    comp = ctxt->comp;
129785691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik    /*
129795691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik    * Optimization for ()[last()] selection i.e. the last elem
129805691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik    */
129815691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik    if ((op->ch1 != -1) && (op->ch2 != -1) &&
129825691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	(comp->steps[op->ch1].op == XPATH_OP_SORT) &&
129835691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	(comp->steps[op->ch2].op == XPATH_OP_SORT)) {
129845691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	int f = comp->steps[op->ch2].ch1;
1298545490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
129865691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	if ((f != -1) &&
129875691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    (comp->steps[f].op == XPATH_OP_FUNCTION) &&
129885691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    (comp->steps[f].value5 == NULL) &&
129895691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    (comp->steps[f].value == 0) &&
129905691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    (comp->steps[f].value4 != NULL) &&
129915691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    (xmlStrEqual
129925691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    (comp->steps[f].value4, BAD_CAST "last"))) {
129935691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    xmlNodePtr last = NULL;
1299445490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
129955691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    total +=
129965691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		xmlXPathCompOpEvalLast(ctxt,
129975691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		    &comp->steps[op->ch1],
129985691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		    &last);
129995691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    CHECK_ERROR0;
130005691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    /*
130015691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    * The nodeset should be in document order,
130025691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    * Keep only the last value
130035691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    */
130045691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    if ((ctxt->value != NULL) &&
130055691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		(ctxt->value->type == XPATH_NODESET) &&
130065691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		(ctxt->value->nodesetval != NULL) &&
130075691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		(ctxt->value->nodesetval->nodeTab != NULL) &&
130085691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		(ctxt->value->nodesetval->nodeNr > 1)) {
130095691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		ctxt->value->nodesetval->nodeTab[0] =
130105691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		    ctxt->value->nodesetval->nodeTab[ctxt->
130115691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		    value->
130125691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		    nodesetval->
130135691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		    nodeNr -
130145691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		    1];
130155691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		ctxt->value->nodesetval->nodeNr = 1;
130165691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		*first = *(ctxt->value->nodesetval->nodeTab);
130175691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    }
130185691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    return (total);
130195691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	}
130205691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik    }
1302145490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
130225691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik    if (op->ch1 != -1)
130235691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
130245691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik    CHECK_ERROR0;
130255691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik    if (op->ch2 == -1)
130265691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	return (total);
130275691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik    if (ctxt->value == NULL)
130285691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	return (total);
1302945490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
130305691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik#ifdef LIBXML_XPTR_ENABLED
130315691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik    oldnode = ctxt->context->node;
130325691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik    /*
130335691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik    * Hum are we filtering the result of an XPointer expression
130345691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik    */
130355691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik    if (ctxt->value->type == XPATH_LOCATIONSET) {
130365691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	xmlXPathObjectPtr tmp = NULL;
130375691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	xmlLocationSetPtr newlocset = NULL;
130385691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	xmlLocationSetPtr oldlocset;
1303945490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
130405691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	/*
130415691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	* Extract the old locset, and then evaluate the result of the
130425691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	* expression for all the element in the locset. use it to grow
130435691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	* up a new locset.
130445691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	*/
130455691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	CHECK_TYPE0(XPATH_LOCATIONSET);
130465691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	obj = valuePop(ctxt);
130475691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	oldlocset = obj->user;
130485691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	ctxt->context->node = NULL;
1304945490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
130505691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	if ((oldlocset == NULL) || (oldlocset->locNr == 0)) {
130515691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    ctxt->context->contextSize = 0;
130525691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    ctxt->context->proximityPosition = 0;
130535691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    if (op->ch2 != -1)
130545691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
130555691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    res = valuePop(ctxt);
13056a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    if (res != NULL) {
13057a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		xmlXPathReleaseObject(ctxt->context, res);
13058a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    }
130595691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    valuePush(ctxt, obj);
130605691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    CHECK_ERROR0;
130615691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    return (total);
130625691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	}
130635691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	newlocset = xmlXPtrLocationSetCreate(NULL);
1306445490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
130655691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	for (i = 0; i < oldlocset->locNr; i++) {
130665691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    /*
130675691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    * Run the evaluation with a node list made of a
130685691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    * single item in the nodelocset.
130695691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    */
130705691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    ctxt->context->node = oldlocset->locTab[i]->user;
130715691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    ctxt->context->contextSize = oldlocset->locNr;
130725691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    ctxt->context->proximityPosition = i + 1;
13073a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    if (tmp == NULL) {
13074a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		tmp = xmlXPathCacheNewNodeSet(ctxt->context,
13075a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    ctxt->context->node);
13076a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    } else {
130771bd45d13091e5af9e1fe0582b5e335c60d45535fDaniel Veillard		if (xmlXPathNodeSetAddUnique(tmp->nodesetval,
130781bd45d13091e5af9e1fe0582b5e335c60d45535fDaniel Veillard		                             ctxt->context->node) < 0) {
130791bd45d13091e5af9e1fe0582b5e335c60d45535fDaniel Veillard		    ctxt->error = XPATH_MEMORY_ERROR;
130801bd45d13091e5af9e1fe0582b5e335c60d45535fDaniel Veillard		}
1308145490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	    }
130825691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    valuePush(ctxt, tmp);
130835691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    if (op->ch2 != -1)
130845691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
130855691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    if (ctxt->error != XPATH_EXPRESSION_OK) {
130865691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		xmlXPathFreeObject(obj);
130875691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		return(0);
130885691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    }
130895691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    /*
130905691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    * The result of the evaluation need to be tested to
130915691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    * decided whether the filter succeeded or not
130925691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    */
130935691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    res = valuePop(ctxt);
130945691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    if (xmlXPathEvaluatePredicateResult(ctxt, res)) {
130955691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		xmlXPtrLocationSetAdd(newlocset,
13096a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    xmlXPathCacheObjectCopy(ctxt->context,
13097a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik			oldlocset->locTab[i]));
130985691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    }
130995691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    /*
131005691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    * Cleanup
131015691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    */
13102a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    if (res != NULL) {
13103a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		xmlXPathReleaseObject(ctxt->context, res);
13104a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    }
131055691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    if (ctxt->value == tmp) {
131065691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		valuePop(ctxt);
1310745490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard		xmlXPathNodeSetClear(tmp->nodesetval, 1);
131085691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		/*
13109a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		* REVISIT TODO: Don't create a temporary nodeset
13110a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		* for everly iteration.
131115691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		*/
13112a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		/* OLD: xmlXPathFreeObject(res); */
13113a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    } else
1311445490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard		tmp = NULL;
131155691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    ctxt->context->node = NULL;
131165691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    /*
131175691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    * Only put the first node in the result, then leave.
131185691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    */
131195691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    if (newlocset->locNr > 0) {
131205691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		*first = (xmlNodePtr) oldlocset->locTab[i]->user;
131215691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		break;
131225691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    }
131235691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	}
13124a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	if (tmp != NULL) {
13125a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathReleaseObject(ctxt->context, tmp);
13126a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	}
131275691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	/*
131285691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	* The result is used as the new evaluation locset.
131295691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	*/
13130a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	xmlXPathReleaseObject(ctxt->context, obj);
131315691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	ctxt->context->node = NULL;
131325691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	ctxt->context->contextSize = -1;
131335691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	ctxt->context->proximityPosition = -1;
131345691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	valuePush(ctxt, xmlXPtrWrapLocationSet(newlocset));
131355691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	ctxt->context->node = oldnode;
131365691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	return (total);
131375691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik    }
131385691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik#endif /* LIBXML_XPTR_ENABLED */
1313945490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
131405691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik    /*
131415691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik    * Extract the old set, and then evaluate the result of the
131425691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik    * expression for all the element in the set. use it to grow
131435691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik    * up a new set.
131445691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik    */
131455691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik    CHECK_TYPE0(XPATH_NODESET);
131465691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik    obj = valuePop(ctxt);
131475691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik    oldset = obj->nodesetval;
1314845490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
131495691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik    oldnode = ctxt->context->node;
131505691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik    oldDoc = ctxt->context->doc;
131515691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik    ctxt->context->node = NULL;
1315245490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
131535691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik    if ((oldset == NULL) || (oldset->nodeNr == 0)) {
131545691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	ctxt->context->contextSize = 0;
131555691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	ctxt->context->proximityPosition = 0;
131565691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	/* QUESTION TODO: Why was this code commented out?
131575691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    if (op->ch2 != -1)
131585691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		total +=
131595691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		    xmlXPathCompOpEval(ctxt,
131605691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik			&comp->steps[op->ch2]);
131615691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    CHECK_ERROR0;
131625691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    res = valuePop(ctxt);
131635691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    if (res != NULL)
131645691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		xmlXPathFreeObject(res);
131655691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	*/
131665691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	valuePush(ctxt, obj);
131675691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	ctxt->context->node = oldnode;
131685691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	CHECK_ERROR0;
131695691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik    } else {
131705691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	xmlNodeSetPtr newset;
131715691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	xmlXPathObjectPtr tmp = NULL;
131725691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	/*
131735691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	* Initialize the new set.
131745691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	* Also set the xpath document in case things like
131755691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	* key() evaluation are attempted on the predicate
1317645490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	*/
131775691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	newset = xmlXPathNodeSetCreate(NULL);
13178f88d849a4e994c94c0d0814a4befb43c990ceebdDaniel Veillard        /* XXX what if xmlXPathNodeSetCreate returned NULL? */
1317945490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
131805691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	for (i = 0; i < oldset->nodeNr; i++) {
131815691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    /*
131825691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    * Run the evaluation with a node list made of
131835691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    * a single item in the nodeset.
131845691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    */
131855691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    ctxt->context->node = oldset->nodeTab[i];
131865691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    if ((oldset->nodeTab[i]->type != XML_NAMESPACE_DECL) &&
131875691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		(oldset->nodeTab[i]->doc != NULL))
131885691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		ctxt->context->doc = oldset->nodeTab[i]->doc;
13189a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    if (tmp == NULL) {
13190a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		tmp = xmlXPathCacheNewNodeSet(ctxt->context,
13191a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    ctxt->context->node);
13192a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    } else {
131931bd45d13091e5af9e1fe0582b5e335c60d45535fDaniel Veillard		if (xmlXPathNodeSetAddUnique(tmp->nodesetval,
131941bd45d13091e5af9e1fe0582b5e335c60d45535fDaniel Veillard		                             ctxt->context->node) < 0) {
131951bd45d13091e5af9e1fe0582b5e335c60d45535fDaniel Veillard		    ctxt->error = XPATH_MEMORY_ERROR;
131961bd45d13091e5af9e1fe0582b5e335c60d45535fDaniel Veillard		}
131975691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    }
131985691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    valuePush(ctxt, tmp);
131995691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    ctxt->context->contextSize = oldset->nodeNr;
132005691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    ctxt->context->proximityPosition = i + 1;
132015691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    if (op->ch2 != -1)
132025691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
132035691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    if (ctxt->error != XPATH_EXPRESSION_OK) {
132045691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		xmlXPathFreeNodeSet(newset);
132055691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		xmlXPathFreeObject(obj);
132065691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		return(0);
1320745490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	    }
132085691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    /*
132095691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    * The result of the evaluation needs to be tested to
132105691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    * decide whether the filter succeeded or not
132115691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    */
132125691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    res = valuePop(ctxt);
132135691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    if (xmlXPathEvaluatePredicateResult(ctxt, res)) {
132141bd45d13091e5af9e1fe0582b5e335c60d45535fDaniel Veillard		if (xmlXPathNodeSetAdd(newset, oldset->nodeTab[i]) < 0)
132151bd45d13091e5af9e1fe0582b5e335c60d45535fDaniel Veillard		    ctxt->error = XPATH_MEMORY_ERROR;
1321645490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	    }
132175691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    /*
132185691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    * Cleanup
132195691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    */
13220a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    if (res != NULL) {
13221a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		xmlXPathReleaseObject(ctxt->context, res);
13222a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    }
132235691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    if (ctxt->value == tmp) {
132245691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		valuePop(ctxt);
132255691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		/*
13226a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		* Don't free the temporary nodeset
132275691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		* in order to avoid massive recreation inside this
132285691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		* loop.
13229a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		*/
132309bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik		xmlXPathNodeSetClear(tmp->nodesetval, 1);
13231a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    } else
13232a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		tmp = NULL;
132335691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    ctxt->context->node = NULL;
132345691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    /*
132355691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    * Only put the first node in the result, then leave.
132365691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    */
132375691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    if (newset->nodeNr > 0) {
132385691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		*first = *(newset->nodeTab);
132395691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		break;
132405691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	    }
132415691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	}
13242a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	if (tmp != NULL) {
13243a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathReleaseObject(ctxt->context, tmp);
13244a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	}
132455691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	/*
132465691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	* The result is used as the new evaluation set.
132475691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	*/
13248a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	xmlXPathReleaseObject(ctxt->context, obj);
132495691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	ctxt->context->node = NULL;
132505691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	ctxt->context->contextSize = -1;
132515691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	ctxt->context->proximityPosition = -1;
132525691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	/* may want to move this past the '}' later */
132535691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	ctxt->context->doc = oldDoc;
13254a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	valuePush(ctxt, xmlXPathCacheWrapNodeSet(ctxt->context, newset));
132555691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik    }
132565691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik    ctxt->context->node = oldnode;
132575691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik    return(total);
132585691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik}
132595691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik#endif /* XP_OPTIMIZED_FILTER_FIRST */
132605691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik
13261f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard/**
13262f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * xmlXPathCompOpEval:
13263f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * @ctxt:  the XPath parser context with the compiled expression
13264f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * @op:  an XPath compiled operation
13265f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard *
13266f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard * Evaluate the Precompiled XPath operation
13267081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack * Returns the number of nodes traversed
13268f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard */
13269f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillardstatic int
13270f06307e2c172284bb41376c396f757bdac9bdd19Daniel VeillardxmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op)
13271f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard{
13272f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    int total = 0;
13273f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    int equal, ret;
13274f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    xmlXPathCompExprPtr comp;
13275f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    xmlXPathObjectPtr arg1, arg2;
132767089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard    xmlNodePtr bak;
132777089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard    xmlDocPtr bakd;
132786000af549b49464a3b1947fc582998a1c9ff7c79William M. Brack    int pp;
13279692092b5886073a8cd1c97bb7d57579e4a9cfc3fWilliam M. Brack    int cs;
132809e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
13281556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard    CHECK_ERROR0;
13282f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    comp = ctxt->comp;
13283f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    switch (op->op) {
13284f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        case XPATH_OP_END:
13285f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            return (0);
13286f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        case XPATH_OP_AND:
132877089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard	    bakd = ctxt->context->doc;
132887089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard	    bak = ctxt->context->node;
132896000af549b49464a3b1947fc582998a1c9ff7c79William M. Brack	    pp = ctxt->context->proximityPosition;
13290692092b5886073a8cd1c97bb7d57579e4a9cfc3fWilliam M. Brack	    cs = ctxt->context->contextSize;
13291f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
13292556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard	    CHECK_ERROR0;
13293f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            xmlXPathBooleanFunction(ctxt, 1);
13294f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            if ((ctxt->value == NULL) || (ctxt->value->boolval == 0))
13295f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                return (total);
13296f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            arg2 = valuePop(ctxt);
132977089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard	    ctxt->context->doc = bakd;
132987089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard	    ctxt->context->node = bak;
132996000af549b49464a3b1947fc582998a1c9ff7c79William M. Brack	    ctxt->context->proximityPosition = pp;
13300692092b5886073a8cd1c97bb7d57579e4a9cfc3fWilliam M. Brack	    ctxt->context->contextSize = cs;
13301f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
13302556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard	    if (ctxt->error) {
13303556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard		xmlXPathFreeObject(arg2);
13304556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard		return(0);
13305556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard	    }
13306f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            xmlXPathBooleanFunction(ctxt, 1);
13307f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            arg1 = valuePop(ctxt);
13308f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            arg1->boolval &= arg2->boolval;
13309f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            valuePush(ctxt, arg1);
13310a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathReleaseObject(ctxt->context, arg2);
13311f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            return (total);
13312f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        case XPATH_OP_OR:
133137089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard	    bakd = ctxt->context->doc;
133147089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard	    bak = ctxt->context->node;
133156000af549b49464a3b1947fc582998a1c9ff7c79William M. Brack	    pp = ctxt->context->proximityPosition;
13316692092b5886073a8cd1c97bb7d57579e4a9cfc3fWilliam M. Brack	    cs = ctxt->context->contextSize;
13317f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
13318556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard	    CHECK_ERROR0;
13319f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            xmlXPathBooleanFunction(ctxt, 1);
13320f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            if ((ctxt->value == NULL) || (ctxt->value->boolval == 1))
13321f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                return (total);
13322f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            arg2 = valuePop(ctxt);
133237089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard	    ctxt->context->doc = bakd;
133247089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard	    ctxt->context->node = bak;
133256000af549b49464a3b1947fc582998a1c9ff7c79William M. Brack	    ctxt->context->proximityPosition = pp;
13326692092b5886073a8cd1c97bb7d57579e4a9cfc3fWilliam M. Brack	    ctxt->context->contextSize = cs;
13327f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
13328556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard	    if (ctxt->error) {
13329556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard		xmlXPathFreeObject(arg2);
13330556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard		return(0);
13331556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard	    }
13332f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            xmlXPathBooleanFunction(ctxt, 1);
13333f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            arg1 = valuePop(ctxt);
13334f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            arg1->boolval |= arg2->boolval;
13335f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            valuePush(ctxt, arg1);
13336a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathReleaseObject(ctxt->context, arg2);
13337f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            return (total);
13338f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        case XPATH_OP_EQUAL:
133397089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard	    bakd = ctxt->context->doc;
133407089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard	    bak = ctxt->context->node;
133416000af549b49464a3b1947fc582998a1c9ff7c79William M. Brack	    pp = ctxt->context->proximityPosition;
13342692092b5886073a8cd1c97bb7d57579e4a9cfc3fWilliam M. Brack	    cs = ctxt->context->contextSize;
13343f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
13344556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard	    CHECK_ERROR0;
133457089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard	    ctxt->context->doc = bakd;
133467089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard	    ctxt->context->node = bak;
133476000af549b49464a3b1947fc582998a1c9ff7c79William M. Brack	    ctxt->context->proximityPosition = pp;
13348692092b5886073a8cd1c97bb7d57579e4a9cfc3fWilliam M. Brack	    ctxt->context->contextSize = cs;
13349f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
13350556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard	    CHECK_ERROR0;
133510c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	    if (op->value)
1335245490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard		equal = xmlXPathEqualValues(ctxt);
133530c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack	    else
133540c022ad8234a9228288c651f5e6a9bce7efcd789William M. Brack		equal = xmlXPathNotEqualValues(ctxt);
13355a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    valuePush(ctxt, xmlXPathCacheNewBoolean(ctxt->context, equal));
13356f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            return (total);
13357f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        case XPATH_OP_CMP:
133587089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard	    bakd = ctxt->context->doc;
133597089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard	    bak = ctxt->context->node;
133606000af549b49464a3b1947fc582998a1c9ff7c79William M. Brack	    pp = ctxt->context->proximityPosition;
13361692092b5886073a8cd1c97bb7d57579e4a9cfc3fWilliam M. Brack	    cs = ctxt->context->contextSize;
13362f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
13363556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard	    CHECK_ERROR0;
133647089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard	    ctxt->context->doc = bakd;
133657089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard	    ctxt->context->node = bak;
133666000af549b49464a3b1947fc582998a1c9ff7c79William M. Brack	    ctxt->context->proximityPosition = pp;
13367692092b5886073a8cd1c97bb7d57579e4a9cfc3fWilliam M. Brack	    ctxt->context->contextSize = cs;
13368f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
13369556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard	    CHECK_ERROR0;
13370f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            ret = xmlXPathCompareValues(ctxt, op->value, op->value2);
13371a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    valuePush(ctxt, xmlXPathCacheNewBoolean(ctxt->context, ret));
13372f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            return (total);
13373f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        case XPATH_OP_PLUS:
133747089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard	    bakd = ctxt->context->doc;
133757089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard	    bak = ctxt->context->node;
133766000af549b49464a3b1947fc582998a1c9ff7c79William M. Brack	    pp = ctxt->context->proximityPosition;
13377692092b5886073a8cd1c97bb7d57579e4a9cfc3fWilliam M. Brack	    cs = ctxt->context->contextSize;
13378f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
13379556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard	    CHECK_ERROR0;
133807089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard            if (op->ch2 != -1) {
133817089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard		ctxt->context->doc = bakd;
133827089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard		ctxt->context->node = bak;
133836000af549b49464a3b1947fc582998a1c9ff7c79William M. Brack		ctxt->context->proximityPosition = pp;
13384692092b5886073a8cd1c97bb7d57579e4a9cfc3fWilliam M. Brack		ctxt->context->contextSize = cs;
13385f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
133867089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard	    }
13387556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard	    CHECK_ERROR0;
13388f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            if (op->value == 0)
13389f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                xmlXPathSubValues(ctxt);
13390f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            else if (op->value == 1)
13391f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                xmlXPathAddValues(ctxt);
13392f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            else if (op->value == 2)
13393f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                xmlXPathValueFlipSign(ctxt);
13394f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            else if (op->value == 3) {
13395f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                CAST_TO_NUMBER;
13396f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                CHECK_TYPE0(XPATH_NUMBER);
13397f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            }
13398f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            return (total);
13399f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        case XPATH_OP_MULT:
134007089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard	    bakd = ctxt->context->doc;
134017089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard	    bak = ctxt->context->node;
134026000af549b49464a3b1947fc582998a1c9ff7c79William M. Brack	    pp = ctxt->context->proximityPosition;
13403692092b5886073a8cd1c97bb7d57579e4a9cfc3fWilliam M. Brack	    cs = ctxt->context->contextSize;
13404f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
13405556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard	    CHECK_ERROR0;
134067089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard	    ctxt->context->doc = bakd;
134077089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard	    ctxt->context->node = bak;
134086000af549b49464a3b1947fc582998a1c9ff7c79William M. Brack	    ctxt->context->proximityPosition = pp;
13409692092b5886073a8cd1c97bb7d57579e4a9cfc3fWilliam M. Brack	    ctxt->context->contextSize = cs;
13410f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
13411556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard	    CHECK_ERROR0;
13412f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            if (op->value == 0)
13413f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                xmlXPathMultValues(ctxt);
13414f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            else if (op->value == 1)
13415f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                xmlXPathDivValues(ctxt);
13416f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            else if (op->value == 2)
13417f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                xmlXPathModValues(ctxt);
13418f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            return (total);
13419f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        case XPATH_OP_UNION:
134207089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard	    bakd = ctxt->context->doc;
134217089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard	    bak = ctxt->context->node;
134226000af549b49464a3b1947fc582998a1c9ff7c79William M. Brack	    pp = ctxt->context->proximityPosition;
13423692092b5886073a8cd1c97bb7d57579e4a9cfc3fWilliam M. Brack	    cs = ctxt->context->contextSize;
13424f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
13425556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard	    CHECK_ERROR0;
134267089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard	    ctxt->context->doc = bakd;
134277089d6bfac04415e3373dd7d5e92f9989d052e4aDaniel Veillard	    ctxt->context->node = bak;
134286000af549b49464a3b1947fc582998a1c9ff7c79William M. Brack	    ctxt->context->proximityPosition = pp;
13429692092b5886073a8cd1c97bb7d57579e4a9cfc3fWilliam M. Brack	    ctxt->context->contextSize = cs;
13430f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
13431556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard	    CHECK_ERROR0;
13432f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            CHECK_TYPE0(XPATH_NODESET);
13433f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            arg2 = valuePop(ctxt);
13434f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
13435f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            CHECK_TYPE0(XPATH_NODESET);
13436f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            arg1 = valuePop(ctxt);
13437f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
1343864f7e1a85fe9c973cf9b21cc0bd53efa6cc3dafcKasimier T. Buchcik	    if ((arg1->nodesetval == NULL) ||
1343964f7e1a85fe9c973cf9b21cc0bd53efa6cc3dafcKasimier T. Buchcik		((arg2->nodesetval != NULL) &&
1344064f7e1a85fe9c973cf9b21cc0bd53efa6cc3dafcKasimier T. Buchcik		 (arg2->nodesetval->nodeNr != 0)))
1344164f7e1a85fe9c973cf9b21cc0bd53efa6cc3dafcKasimier T. Buchcik	    {
1344264f7e1a85fe9c973cf9b21cc0bd53efa6cc3dafcKasimier T. Buchcik		arg1->nodesetval = xmlXPathNodeSetMerge(arg1->nodesetval,
1344364f7e1a85fe9c973cf9b21cc0bd53efa6cc3dafcKasimier T. Buchcik							arg2->nodesetval);
1344464f7e1a85fe9c973cf9b21cc0bd53efa6cc3dafcKasimier T. Buchcik	    }
1344564f7e1a85fe9c973cf9b21cc0bd53efa6cc3dafcKasimier T. Buchcik
13446f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            valuePush(ctxt, arg1);
13447a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathReleaseObject(ctxt->context, arg2);
13448f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            return (total);
13449f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        case XPATH_OP_ROOT:
13450f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            xmlXPathRoot(ctxt);
13451f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            return (total);
13452f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        case XPATH_OP_NODE:
13453f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            if (op->ch1 != -1)
13454f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
13455556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard	    CHECK_ERROR0;
13456f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            if (op->ch2 != -1)
13457f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
13458556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard	    CHECK_ERROR0;
13459a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    valuePush(ctxt, xmlXPathCacheNewNodeSet(ctxt->context,
13460a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		ctxt->context->node));
13461f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            return (total);
13462f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        case XPATH_OP_RESET:
13463f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            if (op->ch1 != -1)
13464f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
13465556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard	    CHECK_ERROR0;
13466f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            if (op->ch2 != -1)
13467f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
13468556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard	    CHECK_ERROR0;
13469f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            ctxt->context->node = NULL;
13470f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            return (total);
13471f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        case XPATH_OP_COLLECT:{
13472f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                if (op->ch1 == -1)
13473f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    return (total);
13474f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
13475f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
13476556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard		CHECK_ERROR0;
13477f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
13478631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik                total += xmlXPathNodeCollectAndTest(ctxt, op, NULL, NULL, 0);
13479f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                return (total);
13480f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            }
13481f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        case XPATH_OP_VALUE:
13482f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            valuePush(ctxt,
13483a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik                      xmlXPathCacheObjectCopy(ctxt->context,
13484a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik			(xmlXPathObjectPtr) op->value4));
13485f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            return (total);
13486f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        case XPATH_OP_VARIABLE:{
13487556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard		xmlXPathObjectPtr val;
13488556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard
13489f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                if (op->ch1 != -1)
13490f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    total +=
13491f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
13492556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard                if (op->value5 == NULL) {
13493556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard		    val = xmlXPathVariableLookup(ctxt->context, op->value4);
13494556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard		    if (val == NULL) {
13495556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard			ctxt->error = XPATH_UNDEF_VARIABLE_ERROR;
13496556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard			return(0);
13497556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard		    }
13498556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard                    valuePush(ctxt, val);
13499556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard		} else {
13500f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    const xmlChar *URI;
13501f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
13502f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    URI = xmlXPathNsLookup(ctxt->context, op->value5);
13503f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    if (URI == NULL) {
13504f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        xmlGenericError(xmlGenericErrorContext,
13505f63085de5e33a95e326d1d810fb18d979359012bDaniel Veillard            "xmlXPathCompOpEval: variable %s bound to undefined prefix %s\n",
13506f63085de5e33a95e326d1d810fb18d979359012bDaniel Veillard                                    (char *) op->value4, (char *)op->value5);
135071d4526f6f4ec8d18c40e2a09b387652a6c1aa2cdDaniel Veillard                        ctxt->error = XPATH_UNDEF_PREFIX_ERROR;
13508f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        return (total);
13509f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    }
13510556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard		    val = xmlXPathVariableLookupNS(ctxt->context,
13511556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard                                                       op->value4, URI);
13512556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard		    if (val == NULL) {
13513556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard			ctxt->error = XPATH_UNDEF_VARIABLE_ERROR;
13514556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard			return(0);
13515556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard		    }
13516556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard                    valuePush(ctxt, val);
13517f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                }
13518f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                return (total);
13519f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            }
13520f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        case XPATH_OP_FUNCTION:{
13521f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                xmlXPathFunction func;
13522f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                const xmlChar *oldFunc, *oldFuncURI;
13523556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard		int i;
13524f5048b3e71fc30ad096970b8df6e7af073bae4cbDaniel Veillard                int frame;
13525f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
13526f5048b3e71fc30ad096970b8df6e7af073bae4cbDaniel Veillard                frame = xmlXPathSetFrame(ctxt);
1352703c6723043775122313f107695066e5744189a08Nick Wellnhofer                if (op->ch1 != -1) {
13528f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    total +=
13529f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
1353003c6723043775122313f107695066e5744189a08Nick Wellnhofer                    if (ctxt->error != XPATH_EXPRESSION_OK) {
1353103c6723043775122313f107695066e5744189a08Nick Wellnhofer                        xmlXPathPopFrame(ctxt, frame);
1353203c6723043775122313f107695066e5744189a08Nick Wellnhofer                        return (total);
1353303c6723043775122313f107695066e5744189a08Nick Wellnhofer                    }
1353403c6723043775122313f107695066e5744189a08Nick Wellnhofer                }
1353503c6723043775122313f107695066e5744189a08Nick Wellnhofer		if (ctxt->valueNr < ctxt->valueFrame + op->value) {
13536556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard		    xmlGenericError(xmlGenericErrorContext,
13537cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard			    "xmlXPathCompOpEval: parameter error\n");
13538556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard		    ctxt->error = XPATH_INVALID_OPERAND;
13539f5048b3e71fc30ad096970b8df6e7af073bae4cbDaniel Veillard                    xmlXPathPopFrame(ctxt, frame);
13540556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard		    return (total);
13541556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard		}
13542f5048b3e71fc30ad096970b8df6e7af073bae4cbDaniel Veillard		for (i = 0; i < op->value; i++) {
13543556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard		    if (ctxt->valueTab[(ctxt->valueNr - 1) - i] == NULL) {
13544556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard			xmlGenericError(xmlGenericErrorContext,
13545cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard				"xmlXPathCompOpEval: parameter error\n");
13546556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard			ctxt->error = XPATH_INVALID_OPERAND;
13547f5048b3e71fc30ad096970b8df6e7af073bae4cbDaniel Veillard                        xmlXPathPopFrame(ctxt, frame);
13548556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard			return (total);
13549556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard		    }
13550f5048b3e71fc30ad096970b8df6e7af073bae4cbDaniel Veillard                }
13551f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                if (op->cache != NULL)
13552ad0e67c57f26f691fc120d5c5336cee9885cf324William M. Brack                    XML_CAST_FPTR(func) = op->cache;
13553f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                else {
13554f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    const xmlChar *URI = NULL;
13555f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
13556f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    if (op->value5 == NULL)
13557f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        func =
13558f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                            xmlXPathFunctionLookup(ctxt->context,
13559f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                                                   op->value4);
13560f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    else {
13561f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        URI = xmlXPathNsLookup(ctxt->context, op->value5);
13562f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        if (URI == NULL) {
13563f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                            xmlGenericError(xmlGenericErrorContext,
13564f63085de5e33a95e326d1d810fb18d979359012bDaniel Veillard            "xmlXPathCompOpEval: function %s bound to undefined prefix %s\n",
13565f63085de5e33a95e326d1d810fb18d979359012bDaniel Veillard                                    (char *)op->value4, (char *)op->value5);
13566f5048b3e71fc30ad096970b8df6e7af073bae4cbDaniel Veillard                            xmlXPathPopFrame(ctxt, frame);
135671d4526f6f4ec8d18c40e2a09b387652a6c1aa2cdDaniel Veillard                            ctxt->error = XPATH_UNDEF_PREFIX_ERROR;
13568f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                            return (total);
13569f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        }
13570f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        func = xmlXPathFunctionLookupNS(ctxt->context,
13571f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                                                        op->value4, URI);
13572f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    }
13573f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    if (func == NULL) {
13574f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        xmlGenericError(xmlGenericErrorContext,
13575f63085de5e33a95e326d1d810fb18d979359012bDaniel Veillard                                "xmlXPathCompOpEval: function %s not found\n",
13576f63085de5e33a95e326d1d810fb18d979359012bDaniel Veillard                                        (char *)op->value4);
13577f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        XP_ERROR0(XPATH_UNKNOWN_FUNC_ERROR);
13578f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    }
13579ad0e67c57f26f691fc120d5c5336cee9885cf324William M. Brack                    op->cache = XML_CAST_FPTR(func);
13580f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    op->cacheURI = (void *) URI;
13581f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                }
13582f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                oldFunc = ctxt->context->function;
13583f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                oldFuncURI = ctxt->context->functionURI;
13584f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                ctxt->context->function = op->value4;
13585f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                ctxt->context->functionURI = op->cacheURI;
13586f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                func(ctxt, op->value);
13587f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                ctxt->context->function = oldFunc;
13588f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                ctxt->context->functionURI = oldFuncURI;
13589f5048b3e71fc30ad096970b8df6e7af073bae4cbDaniel Veillard                xmlXPathPopFrame(ctxt, frame);
13590f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                return (total);
13591f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            }
13592f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        case XPATH_OP_ARG:
13593088bf1163080cbbb72ba9d4a52ab08cc7c8ff6c7Daniel Veillard	    bakd = ctxt->context->doc;
13594088bf1163080cbbb72ba9d4a52ab08cc7c8ff6c7Daniel Veillard	    bak = ctxt->context->node;
13595645a924a9d50d8e0eced5dd7277214a65756c2e1William M. Brack	    pp = ctxt->context->proximityPosition;
13596645a924a9d50d8e0eced5dd7277214a65756c2e1William M. Brack	    cs = ctxt->context->contextSize;
13597f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            if (op->ch1 != -1)
13598f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
13599645a924a9d50d8e0eced5dd7277214a65756c2e1William M. Brack	    ctxt->context->contextSize = cs;
13600645a924a9d50d8e0eced5dd7277214a65756c2e1William M. Brack	    ctxt->context->proximityPosition = pp;
13601088bf1163080cbbb72ba9d4a52ab08cc7c8ff6c7Daniel Veillard	    ctxt->context->node = bak;
13602645a924a9d50d8e0eced5dd7277214a65756c2e1William M. Brack	    ctxt->context->doc = bakd;
13603556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard	    CHECK_ERROR0;
1360472ee48d55f9002544d011826e2897b5054b7e32cWilliam M. Brack            if (op->ch2 != -1) {
13605f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
1360672ee48d55f9002544d011826e2897b5054b7e32cWilliam M. Brack	        ctxt->context->doc = bakd;
1360772ee48d55f9002544d011826e2897b5054b7e32cWilliam M. Brack	        ctxt->context->node = bak;
1360872ee48d55f9002544d011826e2897b5054b7e32cWilliam M. Brack	        CHECK_ERROR0;
1360972ee48d55f9002544d011826e2897b5054b7e32cWilliam M. Brack	    }
13610f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            return (total);
13611f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        case XPATH_OP_PREDICATE:
13612f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        case XPATH_OP_FILTER:{
13613f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                xmlXPathObjectPtr res;
13614f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                xmlXPathObjectPtr obj, tmp;
13615f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                xmlNodeSetPtr newset = NULL;
13616f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                xmlNodeSetPtr oldset;
13617f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                xmlNodePtr oldnode;
136183794b9e84ac51072830a0b34d1ddd0378c0f7cb6William M. Brack		xmlDocPtr oldDoc;
13619f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                int i;
13620f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
13621f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                /*
13622f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                 * Optimization for ()[1] selection i.e. the first elem
13623f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                 */
13624f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                if ((op->ch1 != -1) && (op->ch2 != -1) &&
136255691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik#ifdef XP_OPTIMIZED_FILTER_FIRST
136265691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		    /*
136275691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		    * FILTER TODO: Can we assume that the inner processing
136285691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		    *  will result in an ordered list if we have an
136295691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		    *  XPATH_OP_FILTER?
136305691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		    *  What about an additional field or flag on
136315691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		    *  xmlXPathObject like @sorted ? This way we wouln'd need
136325691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		    *  to assume anything, so it would be more robust and
136335691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		    *  easier to optimize.
136345691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		    */
136355691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik                    ((comp->steps[op->ch1].op == XPATH_OP_SORT) || /* 18 */
136365691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		     (comp->steps[op->ch1].op == XPATH_OP_FILTER)) && /* 17 */
136375691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik#else
136385691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		    (comp->steps[op->ch1].op == XPATH_OP_SORT) &&
136395691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik#endif
136405691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik                    (comp->steps[op->ch2].op == XPATH_OP_VALUE)) { /* 12 */
13641f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    xmlXPathObjectPtr val;
13642f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
13643f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    val = comp->steps[op->ch2].value4;
13644f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    if ((val != NULL) && (val->type == XPATH_NUMBER) &&
13645f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        (val->floatval == 1.0)) {
13646f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        xmlNodePtr first = NULL;
13647f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
13648f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        total +=
13649f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                            xmlXPathCompOpEvalFirst(ctxt,
13650f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                                                    &comp->steps[op->ch1],
13651f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                                                    &first);
13652556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard			CHECK_ERROR0;
13653f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        /*
13654f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                         * The nodeset should be in document order,
13655f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                         * Keep only the first value
13656f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                         */
13657f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        if ((ctxt->value != NULL) &&
13658f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                            (ctxt->value->type == XPATH_NODESET) &&
13659f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                            (ctxt->value->nodesetval != NULL) &&
13660f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                            (ctxt->value->nodesetval->nodeNr > 1))
13661f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                            ctxt->value->nodesetval->nodeNr = 1;
13662f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        return (total);
13663f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    }
13664f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                }
13665f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                /*
13666f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                 * Optimization for ()[last()] selection i.e. the last elem
13667f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                 */
13668f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                if ((op->ch1 != -1) && (op->ch2 != -1) &&
13669f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    (comp->steps[op->ch1].op == XPATH_OP_SORT) &&
13670f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    (comp->steps[op->ch2].op == XPATH_OP_SORT)) {
13671f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    int f = comp->steps[op->ch2].ch1;
13672f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
13673f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    if ((f != -1) &&
13674f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        (comp->steps[f].op == XPATH_OP_FUNCTION) &&
13675f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        (comp->steps[f].value5 == NULL) &&
13676f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        (comp->steps[f].value == 0) &&
13677f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        (comp->steps[f].value4 != NULL) &&
13678f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        (xmlStrEqual
13679f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                         (comp->steps[f].value4, BAD_CAST "last"))) {
13680f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        xmlNodePtr last = NULL;
13681f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
13682f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        total +=
13683f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                            xmlXPathCompOpEvalLast(ctxt,
13684f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                                                   &comp->steps[op->ch1],
13685f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                                                   &last);
13686556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard			CHECK_ERROR0;
13687f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        /*
13688f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                         * The nodeset should be in document order,
13689f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                         * Keep only the last value
13690f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                         */
13691f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        if ((ctxt->value != NULL) &&
13692f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                            (ctxt->value->type == XPATH_NODESET) &&
13693f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                            (ctxt->value->nodesetval != NULL) &&
13694f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                            (ctxt->value->nodesetval->nodeTab != NULL) &&
13695f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                            (ctxt->value->nodesetval->nodeNr > 1)) {
13696f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                            ctxt->value->nodesetval->nodeTab[0] =
13697f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                                ctxt->value->nodesetval->nodeTab[ctxt->
13698f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                                                                 value->
13699f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                                                                 nodesetval->
13700f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                                                                 nodeNr -
13701f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                                                                 1];
13702f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                            ctxt->value->nodesetval->nodeNr = 1;
13703f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        }
13704f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        return (total);
13705f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    }
13706f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                }
13707df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		/*
13708df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		* Process inner predicates first.
13709df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		* Example "index[parent::book][1]":
13710df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		* ...
13711df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		*   PREDICATE   <-- we are here "[1]"
13712df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		*     PREDICATE <-- process "[parent::book]" first
13713df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		*       SORT
13714df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		*         COLLECT  'parent' 'name' 'node' book
13715df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		*           NODE
13716df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		*     ELEM Object is a number : 1
13717df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		*/
13718f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                if (op->ch1 != -1)
13719f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    total +=
13720f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
13721556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard		CHECK_ERROR0;
13722f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                if (op->ch2 == -1)
13723f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    return (total);
13724f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                if (ctxt->value == NULL)
13725f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    return (total);
13726f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
13727f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                oldnode = ctxt->context->node;
137289e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
13729f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#ifdef LIBXML_XPTR_ENABLED
13730f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                /*
13731f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                 * Hum are we filtering the result of an XPointer expression
13732f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                 */
13733f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                if (ctxt->value->type == XPATH_LOCATIONSET) {
13734f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    xmlLocationSetPtr newlocset = NULL;
13735f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    xmlLocationSetPtr oldlocset;
13736f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
13737f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    /*
13738f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                     * Extract the old locset, and then evaluate the result of the
13739f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                     * expression for all the element in the locset. use it to grow
13740f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                     * up a new locset.
13741f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                     */
13742f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    CHECK_TYPE0(XPATH_LOCATIONSET);
13743f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    obj = valuePop(ctxt);
13744f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    oldlocset = obj->user;
13745f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    ctxt->context->node = NULL;
13746f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
13747f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    if ((oldlocset == NULL) || (oldlocset->locNr == 0)) {
13748f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        ctxt->context->contextSize = 0;
13749f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        ctxt->context->proximityPosition = 0;
13750f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        if (op->ch2 != -1)
13751f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                            total +=
13752f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                                xmlXPathCompOpEval(ctxt,
13753f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                                                   &comp->steps[op->ch2]);
13754f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        res = valuePop(ctxt);
13755a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik                        if (res != NULL) {
13756a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik			    xmlXPathReleaseObject(ctxt->context, res);
13757a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik			}
13758f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        valuePush(ctxt, obj);
13759f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        CHECK_ERROR0;
13760f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        return (total);
13761f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    }
13762f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    newlocset = xmlXPtrLocationSetCreate(NULL);
13763f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
13764f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    for (i = 0; i < oldlocset->locNr; i++) {
13765f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        /*
13766f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                         * Run the evaluation with a node list made of a
13767f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                         * single item in the nodelocset.
13768f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                         */
13769f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        ctxt->context->node = oldlocset->locTab[i]->user;
13770f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        ctxt->context->contextSize = oldlocset->locNr;
13771f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        ctxt->context->proximityPosition = i + 1;
13772a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik			tmp = xmlXPathCacheNewNodeSet(ctxt->context,
13773a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik			    ctxt->context->node);
13774f7eb794c142e31ca895f2d7743f872a809e514abWilliam M. Brack                        valuePush(ctxt, tmp);
1377545490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
13776f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        if (op->ch2 != -1)
13777f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                            total +=
13778f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                                xmlXPathCompOpEval(ctxt,
13779f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                                                   &comp->steps[op->ch2]);
137802c19a7bf2ee0f78485840cac50f2a989f5efe476William M. Brack			if (ctxt->error != XPATH_EXPRESSION_OK) {
137812c19a7bf2ee0f78485840cac50f2a989f5efe476William M. Brack			    xmlXPathFreeObject(obj);
137822c19a7bf2ee0f78485840cac50f2a989f5efe476William M. Brack			    return(0);
137832c19a7bf2ee0f78485840cac50f2a989f5efe476William M. Brack			}
13784f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
13785f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        /*
13786f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                         * The result of the evaluation need to be tested to
13787f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                         * decided whether the filter succeeded or not
13788f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                         */
13789f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        res = valuePop(ctxt);
13790f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        if (xmlXPathEvaluatePredicateResult(ctxt, res)) {
13791f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                            xmlXPtrLocationSetAdd(newlocset,
13792f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                                                  xmlXPathObjectCopy
13793f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                                                  (oldlocset->locTab[i]));
13794f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        }
13795f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
13796f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        /*
13797f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                         * Cleanup
13798f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                         */
13799a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik                        if (res != NULL) {
13800a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik			    xmlXPathReleaseObject(ctxt->context, res);
13801a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik			}
13802f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        if (ctxt->value == tmp) {
13803f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                            res = valuePop(ctxt);
13804a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik			    xmlXPathReleaseObject(ctxt->context, res);
13805f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        }
13806f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
13807f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        ctxt->context->node = NULL;
13808f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    }
13809f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
13810f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    /*
13811f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                     * The result is used as the new evaluation locset.
13812f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                     */
13813a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    xmlXPathReleaseObject(ctxt->context, obj);
13814f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    ctxt->context->node = NULL;
13815f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    ctxt->context->contextSize = -1;
13816f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    ctxt->context->proximityPosition = -1;
13817f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    valuePush(ctxt, xmlXPtrWrapLocationSet(newlocset));
13818f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    ctxt->context->node = oldnode;
13819f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    return (total);
13820f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                }
138219e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard#endif /* LIBXML_XPTR_ENABLED */
138229e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
13823f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                /*
13824f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                 * Extract the old set, and then evaluate the result of the
13825f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                 * expression for all the element in the set. use it to grow
13826f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                 * up a new set.
13827f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                 */
13828f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                CHECK_TYPE0(XPATH_NODESET);
13829f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                obj = valuePop(ctxt);
13830f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                oldset = obj->nodesetval;
13831f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
13832f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                oldnode = ctxt->context->node;
138333794b9e84ac51072830a0b34d1ddd0378c0f7cb6William M. Brack		oldDoc = ctxt->context->doc;
13834f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                ctxt->context->node = NULL;
13835f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
13836f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                if ((oldset == NULL) || (oldset->nodeNr == 0)) {
13837f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    ctxt->context->contextSize = 0;
13838f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    ctxt->context->proximityPosition = 0;
138398fad8bff2c2e0b064a6d48d4eeb663804de5545fWilliam M. Brack/*
13840f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    if (op->ch2 != -1)
13841f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        total +=
13842f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                            xmlXPathCompOpEval(ctxt,
13843f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                                               &comp->steps[op->ch2]);
13844556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard		    CHECK_ERROR0;
13845f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    res = valuePop(ctxt);
13846f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    if (res != NULL)
13847f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        xmlXPathFreeObject(res);
138488fad8bff2c2e0b064a6d48d4eeb663804de5545fWilliam M. Brack*/
13849f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    valuePush(ctxt, obj);
13850f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    ctxt->context->node = oldnode;
13851f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    CHECK_ERROR0;
13852f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                } else {
138535691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		    tmp = NULL;
13854f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    /*
13855f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                     * Initialize the new set.
138563794b9e84ac51072830a0b34d1ddd0378c0f7cb6William M. Brack		     * Also set the xpath document in case things like
138573794b9e84ac51072830a0b34d1ddd0378c0f7cb6William M. Brack		     * key() evaluation are attempted on the predicate
13858f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                     */
13859f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    newset = xmlXPathNodeSetCreate(NULL);
13860df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		    /*
13861df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		    * SPEC XPath 1.0:
13862df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		    *  "For each node in the node-set to be filtered, the
13863df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		    *  PredicateExpr is evaluated with that node as the
13864df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		    *  context node, with the number of nodes in the
13865df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		    *  node-set as the context size, and with the proximity
13866df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		    *  position of the node in the node-set with respect to
13867df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		    *  the axis as the context position;"
13868df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		    * @oldset is the node-set" to be filtered.
13869df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		    *
13870df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		    * SPEC XPath 1.0:
13871df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		    *  "only predicates change the context position and
13872df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		    *  context size (see [2.4 Predicates])."
13873df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		    * Example:
13874df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		    *   node-set  context pos
13875df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		    *    nA         1
13876df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		    *    nB         2
13877df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		    *    nC         3
13878df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		    *   After applying predicate [position() > 1] :
13879df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		    *   node-set  context pos
13880df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		    *    nB         1
13881df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		    *    nC         2
13882df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		    *
13883df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		    * removed the first node in the node-set, then
1388445490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard		    * the context position of the
13885df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik		    */
13886f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    for (i = 0; i < oldset->nodeNr; i++) {
13887f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        /*
13888f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                         * Run the evaluation with a node list made of
13889f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                         * a single item in the nodeset.
13890f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                         */
13891f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        ctxt->context->node = oldset->nodeTab[i];
138923794b9e84ac51072830a0b34d1ddd0378c0f7cb6William M. Brack			if ((oldset->nodeTab[i]->type != XML_NAMESPACE_DECL) &&
138933794b9e84ac51072830a0b34d1ddd0378c0f7cb6William M. Brack			    (oldset->nodeTab[i]->doc != NULL))
138943794b9e84ac51072830a0b34d1ddd0378c0f7cb6William M. Brack		            ctxt->context->doc = oldset->nodeTab[i]->doc;
13895a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik			if (tmp == NULL) {
13896a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik			    tmp = xmlXPathCacheNewNodeSet(ctxt->context,
13897a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik				ctxt->context->node);
13898a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik			} else {
138991bd45d13091e5af9e1fe0582b5e335c60d45535fDaniel Veillard			    if (xmlXPathNodeSetAddUnique(tmp->nodesetval,
139001bd45d13091e5af9e1fe0582b5e335c60d45535fDaniel Veillard				               ctxt->context->node) < 0) {
139011bd45d13091e5af9e1fe0582b5e335c60d45535fDaniel Veillard				ctxt->error = XPATH_MEMORY_ERROR;
139021bd45d13091e5af9e1fe0582b5e335c60d45535fDaniel Veillard			    }
139035691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik			}
13904f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        valuePush(ctxt, tmp);
13905f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        ctxt->context->contextSize = oldset->nodeNr;
13906f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        ctxt->context->proximityPosition = i + 1;
13907df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik			/*
13908df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik			* Evaluate the predicate against the context node.
13909df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik			* Can/should we optimize position() predicates
13910df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik			* here (e.g. "[1]")?
13911df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik			*/
13912f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        if (op->ch2 != -1)
13913f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                            total +=
13914f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                                xmlXPathCompOpEval(ctxt,
13915f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                                                   &comp->steps[op->ch2]);
139162c19a7bf2ee0f78485840cac50f2a989f5efe476William M. Brack			if (ctxt->error != XPATH_EXPRESSION_OK) {
139172c19a7bf2ee0f78485840cac50f2a989f5efe476William M. Brack			    xmlXPathFreeNodeSet(newset);
139182c19a7bf2ee0f78485840cac50f2a989f5efe476William M. Brack			    xmlXPathFreeObject(obj);
139192c19a7bf2ee0f78485840cac50f2a989f5efe476William M. Brack			    return(0);
139202c19a7bf2ee0f78485840cac50f2a989f5efe476William M. Brack			}
13921f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
13922f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        /*
13923081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                         * The result of the evaluation needs to be tested to
13924081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                         * decide whether the filter succeeded or not
13925df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik                         */
13926df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik			/*
13927df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik			* OPTIMIZE TODO: Can we use
13928df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik			* xmlXPathNodeSetAdd*Unique()* instead?
13929df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik			*/
13930f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        res = valuePop(ctxt);
13931f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        if (xmlXPathEvaluatePredicateResult(ctxt, res)) {
139321bd45d13091e5af9e1fe0582b5e335c60d45535fDaniel Veillard                            if (xmlXPathNodeSetAdd(newset, oldset->nodeTab[i])
139331bd45d13091e5af9e1fe0582b5e335c60d45535fDaniel Veillard			        < 0)
139341bd45d13091e5af9e1fe0582b5e335c60d45535fDaniel Veillard				ctxt->error = XPATH_MEMORY_ERROR;
13935f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        }
13936f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
13937f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        /*
13938f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                         * Cleanup
13939f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                         */
13940a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik                        if (res != NULL) {
13941a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik			    xmlXPathReleaseObject(ctxt->context, res);
13942a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik			}
13943f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        if (ctxt->value == tmp) {
139445691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik                            valuePop(ctxt);
1394545490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard			    xmlXPathNodeSetClear(tmp->nodesetval, 1);
139465691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik			    /*
13947df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik			    * Don't free the temporary nodeset
139485691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik			    * in order to avoid massive recreation inside this
139495691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik			    * loop.
13950df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik			    */
139515691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik                        } else
13952a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik			    tmp = NULL;
13953f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        ctxt->context->node = NULL;
13954f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    }
139555691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik		    if (tmp != NULL)
13956a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik			xmlXPathReleaseObject(ctxt->context, tmp);
13957f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    /*
13958f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                     * The result is used as the new evaluation set.
13959f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                     */
13960a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    xmlXPathReleaseObject(ctxt->context, obj);
13961f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    ctxt->context->node = NULL;
13962f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    ctxt->context->contextSize = -1;
13963f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    ctxt->context->proximityPosition = -1;
139643794b9e84ac51072830a0b34d1ddd0378c0f7cb6William M. Brack		    /* may want to move this past the '}' later */
139653794b9e84ac51072830a0b34d1ddd0378c0f7cb6William M. Brack		    ctxt->context->doc = oldDoc;
13966a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		    valuePush(ctxt,
13967a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik			xmlXPathCacheWrapNodeSet(ctxt->context, newset));
13968f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                }
13969f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                ctxt->context->node = oldnode;
13970f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                return (total);
13971f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            }
13972f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        case XPATH_OP_SORT:
13973f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            if (op->ch1 != -1)
13974f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
13975556c668f04a45a3aafc52b8445c821569807dd19Daniel Veillard	    CHECK_ERROR0;
13976f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            if ((ctxt->value != NULL) &&
13977f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                (ctxt->value->type == XPATH_NODESET) &&
1397864f7e1a85fe9c973cf9b21cc0bd53efa6cc3dafcKasimier T. Buchcik                (ctxt->value->nodesetval != NULL) &&
1397964f7e1a85fe9c973cf9b21cc0bd53efa6cc3dafcKasimier T. Buchcik		(ctxt->value->nodesetval->nodeNr > 1))
13980a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    {
13981f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                xmlXPathNodeSetSort(ctxt->value->nodesetval);
13982a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    }
13983f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            return (total);
139849e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard#ifdef LIBXML_XPTR_ENABLED
13985f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard        case XPATH_OP_RANGETO:{
13986f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                xmlXPathObjectPtr range;
13987f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                xmlXPathObjectPtr res, obj;
13988f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                xmlXPathObjectPtr tmp;
13989081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                xmlLocationSetPtr newlocset = NULL;
13990081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack		    xmlLocationSetPtr oldlocset;
13991f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                xmlNodeSetPtr oldset;
1399272ee48d55f9002544d011826e2897b5054b7e32cWilliam M. Brack                int i, j;
13993f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
13994f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                if (op->ch1 != -1)
13995f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    total +=
13996f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
13997f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                if (op->ch2 == -1)
13998f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    return (total);
13999f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
14000081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                if (ctxt->value->type == XPATH_LOCATIONSET) {
14001081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                    /*
14002081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                     * Extract the old locset, and then evaluate the result of the
14003081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                     * expression for all the element in the locset. use it to grow
14004081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                     * up a new locset.
14005081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                     */
14006081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                    CHECK_TYPE0(XPATH_LOCATIONSET);
14007081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                    obj = valuePop(ctxt);
14008081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                    oldlocset = obj->user;
14009f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
14010081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                    if ((oldlocset == NULL) || (oldlocset->locNr == 0)) {
1401172ee48d55f9002544d011826e2897b5054b7e32cWilliam M. Brack		        ctxt->context->node = NULL;
14012081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                        ctxt->context->contextSize = 0;
14013081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                        ctxt->context->proximityPosition = 0;
14014081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                        total += xmlXPathCompOpEval(ctxt,&comp->steps[op->ch2]);
14015081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                        res = valuePop(ctxt);
14016a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik                        if (res != NULL) {
14017a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik			    xmlXPathReleaseObject(ctxt->context, res);
14018a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik			}
14019081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                        valuePush(ctxt, obj);
14020081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                        CHECK_ERROR0;
14021081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                        return (total);
14022081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                    }
14023081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                    newlocset = xmlXPtrLocationSetCreate(NULL);
14024f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
14025081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                    for (i = 0; i < oldlocset->locNr; i++) {
14026f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        /*
14027081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                         * Run the evaluation with a node list made of a
14028081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                         * single item in the nodelocset.
14029f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                         */
14030f7eb794c142e31ca895f2d7743f872a809e514abWilliam M. Brack                        ctxt->context->node = oldlocset->locTab[i]->user;
14031f7eb794c142e31ca895f2d7743f872a809e514abWilliam M. Brack                        ctxt->context->contextSize = oldlocset->locNr;
14032f7eb794c142e31ca895f2d7743f872a809e514abWilliam M. Brack                        ctxt->context->proximityPosition = i + 1;
14033a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik			tmp = xmlXPathCacheNewNodeSet(ctxt->context,
14034a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik			    ctxt->context->node);
14035f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        valuePush(ctxt, tmp);
14036f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
14037f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        if (op->ch2 != -1)
14038f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                            total +=
14039f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                                xmlXPathCompOpEval(ctxt,
14040f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                                                   &comp->steps[op->ch2]);
140412c19a7bf2ee0f78485840cac50f2a989f5efe476William M. Brack			if (ctxt->error != XPATH_EXPRESSION_OK) {
140422c19a7bf2ee0f78485840cac50f2a989f5efe476William M. Brack			    xmlXPathFreeObject(obj);
140432c19a7bf2ee0f78485840cac50f2a989f5efe476William M. Brack			    return(0);
140442c19a7bf2ee0f78485840cac50f2a989f5efe476William M. Brack			}
14045f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
14046f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        res = valuePop(ctxt);
1404772ee48d55f9002544d011826e2897b5054b7e32cWilliam M. Brack			if (res->type == XPATH_LOCATIONSET) {
1404845490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard			    xmlLocationSetPtr rloc =
1404972ee48d55f9002544d011826e2897b5054b7e32cWilliam M. Brack			        (xmlLocationSetPtr)res->user;
1405072ee48d55f9002544d011826e2897b5054b7e32cWilliam M. Brack			    for (j=0; j<rloc->locNr; j++) {
1405172ee48d55f9002544d011826e2897b5054b7e32cWilliam M. Brack			        range = xmlXPtrNewRange(
1405272ee48d55f9002544d011826e2897b5054b7e32cWilliam M. Brack				  oldlocset->locTab[i]->user,
1405372ee48d55f9002544d011826e2897b5054b7e32cWilliam M. Brack				  oldlocset->locTab[i]->index,
1405472ee48d55f9002544d011826e2897b5054b7e32cWilliam M. Brack				  rloc->locTab[j]->user2,
1405572ee48d55f9002544d011826e2897b5054b7e32cWilliam M. Brack				  rloc->locTab[j]->index2);
1405672ee48d55f9002544d011826e2897b5054b7e32cWilliam M. Brack				if (range != NULL) {
1405772ee48d55f9002544d011826e2897b5054b7e32cWilliam M. Brack				    xmlXPtrLocationSetAdd(newlocset, range);
1405872ee48d55f9002544d011826e2897b5054b7e32cWilliam M. Brack				}
1405972ee48d55f9002544d011826e2897b5054b7e32cWilliam M. Brack			    }
1406072ee48d55f9002544d011826e2897b5054b7e32cWilliam M. Brack			} else {
1406172ee48d55f9002544d011826e2897b5054b7e32cWilliam M. Brack			    range = xmlXPtrNewRangeNodeObject(
1406272ee48d55f9002544d011826e2897b5054b7e32cWilliam M. Brack				(xmlNodePtr)oldlocset->locTab[i]->user, res);
1406372ee48d55f9002544d011826e2897b5054b7e32cWilliam M. Brack                            if (range != NULL) {
1406472ee48d55f9002544d011826e2897b5054b7e32cWilliam M. Brack                                xmlXPtrLocationSetAdd(newlocset,range);
1406572ee48d55f9002544d011826e2897b5054b7e32cWilliam M. Brack			    }
14066f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        }
14067f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
14068f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        /*
14069f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                         * Cleanup
14070f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                         */
14071a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik                        if (res != NULL) {
14072a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik			    xmlXPathReleaseObject(ctxt->context, res);
14073a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik			}
14074f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        if (ctxt->value == tmp) {
14075f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                            res = valuePop(ctxt);
14076a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik			    xmlXPathReleaseObject(ctxt->context, res);
14077f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        }
14078f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
14079f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                        ctxt->context->node = NULL;
14080f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    }
1408172ee48d55f9002544d011826e2897b5054b7e32cWilliam M. Brack		} else {	/* Not a location set */
14082081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                    CHECK_TYPE0(XPATH_NODESET);
14083081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                    obj = valuePop(ctxt);
14084081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                    oldset = obj->nodesetval;
14085081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                    ctxt->context->node = NULL;
14086081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack
14087081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                    newlocset = xmlXPtrLocationSetCreate(NULL);
14088081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack
14089081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                    if (oldset != NULL) {
14090081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                        for (i = 0; i < oldset->nodeNr; i++) {
14091081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                            /*
14092081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                             * Run the evaluation with a node list made of a single item
14093081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                             * in the nodeset.
14094081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                             */
14095081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                            ctxt->context->node = oldset->nodeTab[i];
14096a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik			    /*
14097a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik			    * OPTIMIZE TODO: Avoid recreation for every iteration.
14098a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik			    */
14099a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik			    tmp = xmlXPathCacheNewNodeSet(ctxt->context,
14100a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik				ctxt->context->node);
14101081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                            valuePush(ctxt, tmp);
14102081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack
14103081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                            if (op->ch2 != -1)
14104081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                                total +=
14105081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                                    xmlXPathCompOpEval(ctxt,
14106081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                                                   &comp->steps[op->ch2]);
141072c19a7bf2ee0f78485840cac50f2a989f5efe476William M. Brack			    if (ctxt->error != XPATH_EXPRESSION_OK) {
141082c19a7bf2ee0f78485840cac50f2a989f5efe476William M. Brack				xmlXPathFreeObject(obj);
141092c19a7bf2ee0f78485840cac50f2a989f5efe476William M. Brack				return(0);
141102c19a7bf2ee0f78485840cac50f2a989f5efe476William M. Brack			    }
14111081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack
14112081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                            res = valuePop(ctxt);
14113081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                            range =
14114081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                                xmlXPtrNewRangeNodeObject(oldset->nodeTab[i],
14115081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                                                      res);
14116081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                            if (range != NULL) {
14117081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                                xmlXPtrLocationSetAdd(newlocset, range);
14118081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                            }
14119081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack
14120081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                            /*
14121081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                             * Cleanup
14122081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                             */
14123a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik                            if (res != NULL) {
14124a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik				xmlXPathReleaseObject(ctxt->context, res);
14125a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik			    }
14126081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                            if (ctxt->value == tmp) {
14127081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                                res = valuePop(ctxt);
14128a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik				xmlXPathReleaseObject(ctxt->context, res);
14129081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                            }
14130081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack
14131081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                            ctxt->context->node = NULL;
14132081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                        }
14133081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                    }
14134f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                }
14135f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard
14136f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                /*
14137f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                 * The result is used as the new evaluation set.
14138f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                 */
14139a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		xmlXPathReleaseObject(ctxt->context, obj);
14140f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                ctxt->context->node = NULL;
14141f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                ctxt->context->contextSize = -1;
14142f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                ctxt->context->proximityPosition = -1;
14143081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack                valuePush(ctxt, xmlXPtrWrapLocationSet(newlocset));
14144f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                return (total);
14145f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard            }
141469e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard#endif /* LIBXML_XPTR_ENABLED */
141479e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    }
141489e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    xmlGenericError(xmlGenericErrorContext,
14149f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard                    "XPath: unknown precompiled operation %d\n", op->op);
141501d4526f6f4ec8d18c40e2a09b387652a6c1aa2cdDaniel Veillard    ctxt->error = XPATH_INVALID_OPERAND;
14151f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    return (total);
141529e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard}
141539e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
14154631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik/**
14155631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik * xmlXPathCompOpEvalToBoolean:
14156631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik * @ctxt:  the XPath parser context
14157631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik *
14158631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik * Evaluates if the expression evaluates to true.
14159631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik *
14160631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik * Returns 1 if true, 0 if false and -1 on API or internal errors.
14161631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik */
14162631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcikstatic int
14163631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. BuchcikxmlXPathCompOpEvalToBoolean(xmlXPathParserContextPtr ctxt,
14164324c75b3c3edffcd30e7afa2a32f0d83d928b10dKasimier T. Buchcik			    xmlXPathStepOpPtr op,
14165324c75b3c3edffcd30e7afa2a32f0d83d928b10dKasimier T. Buchcik			    int isPredicate)
14166631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik{
14167324c75b3c3edffcd30e7afa2a32f0d83d928b10dKasimier T. Buchcik    xmlXPathObjectPtr resObj = NULL;
14168631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik
14169631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcikstart:
14170631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik    /* comp = ctxt->comp; */
14171631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik    switch (op->op) {
14172631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik        case XPATH_OP_END:
14173631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik            return (0);
14174631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	case XPATH_OP_VALUE:
14175324c75b3c3edffcd30e7afa2a32f0d83d928b10dKasimier T. Buchcik	    resObj = (xmlXPathObjectPtr) op->value4;
141762bdb12ff9fdb69169604fdf544e1026b2459aca1Kasimier T. Buchcik	    if (isPredicate)
141772bdb12ff9fdb69169604fdf544e1026b2459aca1Kasimier T. Buchcik		return(xmlXPathEvaluatePredicateResult(ctxt, resObj));
141782bdb12ff9fdb69169604fdf544e1026b2459aca1Kasimier T. Buchcik	    return(xmlXPathCastToBoolean(resObj));
14179631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	case XPATH_OP_SORT:
14180631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    /*
14181631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    * We don't need sorting for boolean results. Skip this one.
14182631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    */
14183631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik            if (op->ch1 != -1) {
14184631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik		op = &ctxt->comp->steps[op->ch1];
14185631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik		goto start;
14186631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    }
14187631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    return(0);
14188324c75b3c3edffcd30e7afa2a32f0d83d928b10dKasimier T. Buchcik	case XPATH_OP_COLLECT:
14189631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    if (op->ch1 == -1)
14190631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik		return(0);
14191631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik
14192631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik            xmlXPathCompOpEval(ctxt, &ctxt->comp->steps[op->ch1]);
14193631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    if (ctxt->error != XPATH_EXPRESSION_OK)
14194631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik		return(-1);
14195631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik
14196631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik            xmlXPathNodeCollectAndTest(ctxt, op, NULL, NULL, 1);
14197631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    if (ctxt->error != XPATH_EXPRESSION_OK)
14198631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik		return(-1);
14199631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik
14200631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    resObj = valuePop(ctxt);
14201631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    if (resObj == NULL)
14202631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik		return(-1);
14203324c75b3c3edffcd30e7afa2a32f0d83d928b10dKasimier T. Buchcik	    break;
14204324c75b3c3edffcd30e7afa2a32f0d83d928b10dKasimier T. Buchcik	default:
14205631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    /*
14206631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    * Fallback to call xmlXPathCompOpEval().
14207631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    */
14208631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    xmlXPathCompOpEval(ctxt, op);
14209631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    if (ctxt->error != XPATH_EXPRESSION_OK)
14210631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik		return(-1);
1421145490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
14212631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    resObj = valuePop(ctxt);
14213631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    if (resObj == NULL)
142142bdb12ff9fdb69169604fdf544e1026b2459aca1Kasimier T. Buchcik		return(-1);
14215324c75b3c3edffcd30e7afa2a32f0d83d928b10dKasimier T. Buchcik	    break;
14216324c75b3c3edffcd30e7afa2a32f0d83d928b10dKasimier T. Buchcik    }
14217324c75b3c3edffcd30e7afa2a32f0d83d928b10dKasimier T. Buchcik
14218324c75b3c3edffcd30e7afa2a32f0d83d928b10dKasimier T. Buchcik    if (resObj) {
14219324c75b3c3edffcd30e7afa2a32f0d83d928b10dKasimier T. Buchcik	int res;
14220324c75b3c3edffcd30e7afa2a32f0d83d928b10dKasimier T. Buchcik
14221324c75b3c3edffcd30e7afa2a32f0d83d928b10dKasimier T. Buchcik	if (resObj->type == XPATH_BOOLEAN) {
14222324c75b3c3edffcd30e7afa2a32f0d83d928b10dKasimier T. Buchcik	    res = resObj->boolval;
14223324c75b3c3edffcd30e7afa2a32f0d83d928b10dKasimier T. Buchcik	} else if (isPredicate) {
14224631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    /*
14225324c75b3c3edffcd30e7afa2a32f0d83d928b10dKasimier T. Buchcik	    * For predicates a result of type "number" is handled
14226324c75b3c3edffcd30e7afa2a32f0d83d928b10dKasimier T. Buchcik	    * differently:
14227324c75b3c3edffcd30e7afa2a32f0d83d928b10dKasimier T. Buchcik	    * SPEC XPath 1.0:
14228324c75b3c3edffcd30e7afa2a32f0d83d928b10dKasimier T. Buchcik	    * "If the result is a number, the result will be converted
14229324c75b3c3edffcd30e7afa2a32f0d83d928b10dKasimier T. Buchcik	    *  to true if the number is equal to the context position
14230324c75b3c3edffcd30e7afa2a32f0d83d928b10dKasimier T. Buchcik	    *  and will be converted to false otherwise;"
14231631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    */
1423245490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	    res = xmlXPathEvaluatePredicateResult(ctxt, resObj);
14233324c75b3c3edffcd30e7afa2a32f0d83d928b10dKasimier T. Buchcik	} else {
14234324c75b3c3edffcd30e7afa2a32f0d83d928b10dKasimier T. Buchcik	    res = xmlXPathCastToBoolean(resObj);
14235631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	}
14236324c75b3c3edffcd30e7afa2a32f0d83d928b10dKasimier T. Buchcik	xmlXPathReleaseObject(ctxt->context, resObj);
14237324c75b3c3edffcd30e7afa2a32f0d83d928b10dKasimier T. Buchcik	return(res);
14238631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik    }
14239324c75b3c3edffcd30e7afa2a32f0d83d928b10dKasimier T. Buchcik
14240631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik    return(0);
14241631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik}
14242631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik
1424356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard#ifdef XPATH_STREAMING
1424456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard/**
1424556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard * xmlXPathRunStreamEval:
1424656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard * @ctxt:  the XPath parser context with the compiled expression
1424756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard *
1424856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard * Evaluate the Precompiled Streamable XPath expression in the given context.
1424956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard */
14250631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcikstatic int
14251631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. BuchcikxmlXPathRunStreamEval(xmlXPathContextPtr ctxt, xmlPatternPtr comp,
14252631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik		      xmlXPathObjectPtr *resultSeq, int toBool)
14253631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik{
14254f03a8cdacdce917d09972c65371953e8a57a2ac3Daniel Veillard    int max_depth, min_depth;
1425545490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard    int from_root;
1425656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard    int ret, depth;
1425797258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik    int eval_all_nodes;
1425812d37ab63441baf9e03db70168cc1d0d6f1c2373William M. Brack    xmlNodePtr cur = NULL, limit = NULL;
142598af1f0bb83cfc3f57fd5637dcfce28c95eb99638Kasimier T. Buchcik    xmlStreamCtxtPtr patstream = NULL;
1426045490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
1426145490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard    int nb_nodes = 0;
1426256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard
1426356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard    if ((ctxt == NULL) || (comp == NULL))
14264631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik        return(-1);
1426556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard    max_depth = xmlPatternMaxDepth(comp);
1426656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard    if (max_depth == -1)
14267631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik        return(-1);
1426856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard    if (max_depth == -2)
1426956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard        max_depth = 10000;
14270f03a8cdacdce917d09972c65371953e8a57a2ac3Daniel Veillard    min_depth = xmlPatternMinDepth(comp);
14271f03a8cdacdce917d09972c65371953e8a57a2ac3Daniel Veillard    if (min_depth == -1)
14272631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik        return(-1);
1427356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard    from_root = xmlPatternFromRoot(comp);
1427456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard    if (from_root < 0)
14275631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik        return(-1);
14276fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard#if 0
14277fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard    printf("stream eval: depth %d from root %d\n", max_depth, from_root);
14278fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard#endif
1427956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard
14280631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik    if (! toBool) {
14281631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	if (resultSeq == NULL)
14282631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    return(-1);
14283631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	*resultSeq = xmlXPathCacheNewNodeSet(ctxt, NULL);
14284631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	if (*resultSeq == NULL)
14285631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    return(-1);
14286631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik    }
1428745490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
14288f03a8cdacdce917d09972c65371953e8a57a2ac3Daniel Veillard    /*
142898af1f0bb83cfc3f57fd5637dcfce28c95eb99638Kasimier T. Buchcik     * handle the special cases of "/" amd "." being matched
14290f03a8cdacdce917d09972c65371953e8a57a2ac3Daniel Veillard     */
14291f03a8cdacdce917d09972c65371953e8a57a2ac3Daniel Veillard    if (min_depth == 0) {
14292f03a8cdacdce917d09972c65371953e8a57a2ac3Daniel Veillard	if (from_root) {
142938af1f0bb83cfc3f57fd5637dcfce28c95eb99638Kasimier T. Buchcik	    /* Select "/" */
14294631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    if (toBool)
14295631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik		return(1);
14296631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    xmlXPathNodeSetAddUnique((*resultSeq)->nodesetval,
142971bd45d13091e5af9e1fe0582b5e335c60d45535fDaniel Veillard		                     (xmlNodePtr) ctxt->doc);
14298f03a8cdacdce917d09972c65371953e8a57a2ac3Daniel Veillard	} else {
142998af1f0bb83cfc3f57fd5637dcfce28c95eb99638Kasimier T. Buchcik	    /* Select "self::node()" */
14300631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    if (toBool)
14301631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik		return(1);
14302631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    xmlXPathNodeSetAddUnique((*resultSeq)->nodesetval, ctxt->node);
14303f03a8cdacdce917d09972c65371953e8a57a2ac3Daniel Veillard	}
14304f03a8cdacdce917d09972c65371953e8a57a2ac3Daniel Veillard    }
14305f03a8cdacdce917d09972c65371953e8a57a2ac3Daniel Veillard    if (max_depth == 0) {
14306631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	return(0);
1430756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard    }
14308f03a8cdacdce917d09972c65371953e8a57a2ac3Daniel Veillard
1430956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard    if (from_root) {
1431012d37ab63441baf9e03db70168cc1d0d6f1c2373William M. Brack        cur = (xmlNodePtr)ctxt->doc;
1431156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard    } else if (ctxt->node != NULL) {
1431256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard        switch (ctxt->node->type) {
1431356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard            case XML_ELEMENT_NODE:
1431456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard            case XML_DOCUMENT_NODE:
1431556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard            case XML_DOCUMENT_FRAG_NODE:
1431656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard            case XML_HTML_DOCUMENT_NODE:
1431756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard#ifdef LIBXML_DOCB_ENABLED
1431856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard            case XML_DOCB_DOCUMENT_NODE:
1431956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard#endif
1432056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	        cur = ctxt->node;
1432156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard		break;
1432256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard            case XML_ATTRIBUTE_NODE:
1432356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard            case XML_TEXT_NODE:
1432456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard            case XML_CDATA_SECTION_NODE:
1432556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard            case XML_ENTITY_REF_NODE:
1432656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard            case XML_ENTITY_NODE:
1432756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard            case XML_PI_NODE:
1432856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard            case XML_COMMENT_NODE:
1432956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard            case XML_NOTATION_NODE:
1433056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard            case XML_DTD_NODE:
1433156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard            case XML_DOCUMENT_TYPE_NODE:
1433256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard            case XML_ELEMENT_DECL:
1433356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard            case XML_ATTRIBUTE_DECL:
1433456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard            case XML_ENTITY_DECL:
1433556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard            case XML_NAMESPACE_DECL:
1433656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard            case XML_XINCLUDE_START:
1433756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard            case XML_XINCLUDE_END:
1433856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard		break;
1433956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	}
1434056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	limit = cur;
1434156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard    }
14342631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik    if (cur == NULL) {
14343631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik        return(0);
14344631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik    }
1434556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard
1434656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard    patstream = xmlPatternGetStreamCtxt(comp);
1434756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard    if (patstream == NULL) {
14348631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	/*
14349631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	* QUESTION TODO: Is this an error?
14350631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	*/
14351631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	return(0);
1435256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard    }
1435356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard
1435497258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik    eval_all_nodes = xmlStreamWantsAnyNode(patstream);
1435597258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik
1435656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard    if (from_root) {
1435756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	ret = xmlStreamPush(patstream, NULL, NULL);
1435856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	if (ret < 0) {
1435956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	} else if (ret == 1) {
14360631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    if (toBool)
143618af1f0bb83cfc3f57fd5637dcfce28c95eb99638Kasimier T. Buchcik		goto return_1;
14362631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    xmlXPathNodeSetAddUnique((*resultSeq)->nodesetval, cur);
1436356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	}
1436456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard    }
1436556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard    depth = 0;
1436656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard    goto scan_children;
1436756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillardnext_node:
14368d3ff7ef6d3247872b1231718bdf1773c16d88806Daniel Veillard    do {
1436956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard        nb_nodes++;
1437097258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik
1437197258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik	switch (cur->type) {
1437297258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik	    case XML_ELEMENT_NODE:
1437397258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik	    case XML_TEXT_NODE:
1437497258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik	    case XML_CDATA_SECTION_NODE:
1437597258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik	    case XML_COMMENT_NODE:
14376631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    case XML_PI_NODE:
1437797258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik		if (cur->type == XML_ELEMENT_NODE) {
1437897258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik		    ret = xmlStreamPush(patstream, cur->name,
1437956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard				(cur->ns ? cur->ns->href : NULL));
14380631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik		} else if (eval_all_nodes)
1438197258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik		    ret = xmlStreamPushNode(patstream, NULL, NULL, cur->type);
1438297258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik		else
1438397258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik		    break;
1438445490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
1438597258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik		if (ret < 0) {
1438697258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik		    /* NOP. */
1438797258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik		} else if (ret == 1) {
14388631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik		    if (toBool)
143898af1f0bb83cfc3f57fd5637dcfce28c95eb99638Kasimier T. Buchcik			goto return_1;
143901bd45d13091e5af9e1fe0582b5e335c60d45535fDaniel Veillard		    if (xmlXPathNodeSetAddUnique((*resultSeq)->nodesetval, cur)
143911bd45d13091e5af9e1fe0582b5e335c60d45535fDaniel Veillard		        < 0) {
143921bd45d13091e5af9e1fe0582b5e335c60d45535fDaniel Veillard			ctxt->lastError.domain = XML_FROM_XPATH;
143931bd45d13091e5af9e1fe0582b5e335c60d45535fDaniel Veillard			ctxt->lastError.code = XML_ERR_NO_MEMORY;
143941bd45d13091e5af9e1fe0582b5e335c60d45535fDaniel Veillard		    }
1439597258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik		}
1439697258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik		if ((cur->children == NULL) || (depth >= max_depth)) {
1439797258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik		    ret = xmlStreamPop(patstream);
1439897258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik		    while (cur->next != NULL) {
1439997258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik			cur = cur->next;
1440097258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik			if ((cur->type != XML_ENTITY_DECL) &&
1440197258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik			    (cur->type != XML_DTD_NODE))
1440297258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik			    goto next_node;
1440397258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik		    }
1440497258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik		}
1440597258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik	    default:
1440697258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik		break;
14407631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	}
14408631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik
1440956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillardscan_children:
144103e62adbe39f2083c9c2cd3330c320227818fd361Daniel Veillard	if (cur->type == XML_NAMESPACE_DECL) break;
1441156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	if ((cur->children != NULL) && (depth < max_depth)) {
1441256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	    /*
1441345490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	     * Do not descend on entities declarations
1441456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	     */
1441556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	    if (cur->children->type != XML_ENTITY_DECL) {
1441656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard		cur = cur->children;
1441756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard		depth++;
1441856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard		/*
1441956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard		 * Skip DTDs
1442056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard		 */
1442156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard		if (cur->type != XML_DTD_NODE)
1442256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard		    continue;
1442356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	    }
1442456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	}
1442556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard
1442656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	if (cur == limit)
1442756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	    break;
1442856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard
1442956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	while (cur->next != NULL) {
1443056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	    cur = cur->next;
1443156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	    if ((cur->type != XML_ENTITY_DECL) &&
1443256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard		(cur->type != XML_DTD_NODE))
1443356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard		goto next_node;
1443456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	}
1443545490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
1443656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	do {
1443756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	    cur = cur->parent;
1443856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	    depth--;
1443956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	    if ((cur == NULL) || (cur == limit))
1444056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	        goto done;
1444197258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik	    if (cur->type == XML_ELEMENT_NODE) {
1444297258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik		ret = xmlStreamPop(patstream);
14443631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    } else if ((eval_all_nodes) &&
1444497258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik		((cur->type == XML_TEXT_NODE) ||
1444597258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik		 (cur->type == XML_CDATA_SECTION_NODE) ||
1444697258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik		 (cur->type == XML_COMMENT_NODE) ||
1444797258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik		 (cur->type == XML_PI_NODE)))
1444897258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik	    {
1444997258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik		ret = xmlStreamPop(patstream);
1445097258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik	    }
1445156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	    if (cur->next != NULL) {
1445256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard		cur = cur->next;
1445356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard		break;
1445456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	    }
1445556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	} while (cur != NULL);
1445656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard
1445756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard    } while ((cur != NULL) && (depth >= 0));
14458631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik
1445956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillarddone:
14460631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik
14461fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard#if 0
14462fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard    printf("stream eval: checked %d nodes selected %d\n",
14463631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik           nb_nodes, retObj->nodesetval->nodeNr);
14464fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard#endif
14465631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik
144668af1f0bb83cfc3f57fd5637dcfce28c95eb99638Kasimier T. Buchcik    if (patstream)
144678af1f0bb83cfc3f57fd5637dcfce28c95eb99638Kasimier T. Buchcik	xmlFreeStreamCtxt(patstream);
14468631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik    return(0);
144698af1f0bb83cfc3f57fd5637dcfce28c95eb99638Kasimier T. Buchcik
144708af1f0bb83cfc3f57fd5637dcfce28c95eb99638Kasimier T. Buchcikreturn_1:
144718af1f0bb83cfc3f57fd5637dcfce28c95eb99638Kasimier T. Buchcik    if (patstream)
144728af1f0bb83cfc3f57fd5637dcfce28c95eb99638Kasimier T. Buchcik	xmlFreeStreamCtxt(patstream);
144738af1f0bb83cfc3f57fd5637dcfce28c95eb99638Kasimier T. Buchcik    return(1);
1447456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard}
1447556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard#endif /* XPATH_STREAMING */
1447656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard
144779e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard/**
144789e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * xmlXPathRunEval:
144799e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * @ctxt:  the XPath parser context with the compiled expression
14480631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik * @toBool:  evaluate to a boolean result
144819e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard *
144829e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * Evaluate the Precompiled XPath expression in the given context.
144839e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard */
14484631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcikstatic int
14485631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. BuchcikxmlXPathRunEval(xmlXPathParserContextPtr ctxt, int toBool)
14486631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik{
144879e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    xmlXPathCompExprPtr comp;
144889e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
144899e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    if ((ctxt == NULL) || (ctxt->comp == NULL))
14490631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	return(-1);
144919e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
144929e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    if (ctxt->valueTab == NULL) {
144939e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	/* Allocate the value stack */
1449445490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	ctxt->valueTab = (xmlXPathObjectPtr *)
144959e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard			 xmlMalloc(10 * sizeof(xmlXPathObjectPtr));
144969e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	if (ctxt->valueTab == NULL) {
14497d96f6d34295c8ce73c15c60115e970132e6fd18eDaniel Veillard	    xmlXPathPErrMemory(ctxt, "creating evaluation context\n");
144989e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    xmlFree(ctxt);
144999e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	}
145009e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	ctxt->valueNr = 0;
145019e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	ctxt->valueMax = 10;
145029e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	ctxt->value = NULL;
14503f5048b3e71fc30ad096970b8df6e7af073bae4cbDaniel Veillard        ctxt->valueFrame = 0;
145049e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    }
1450556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard#ifdef XPATH_STREAMING
1450656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard    if (ctxt->comp->stream) {
14507631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	int res;
14508631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik
14509631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	if (toBool) {
14510631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    /*
14511631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    * Evaluation to boolean result.
14512631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    */
14513631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    res = xmlXPathRunStreamEval(ctxt->context,
14514631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik		ctxt->comp->stream, NULL, 1);
14515631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    if (res != -1)
14516631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik		return(res);
14517631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	} else {
1451845490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	    xmlXPathObjectPtr resObj = NULL;
14519631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik
14520631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    /*
14521631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    * Evaluation to a sequence.
14522631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    */
14523631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    res = xmlXPathRunStreamEval(ctxt->context,
14524631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik		ctxt->comp->stream, &resObj, 0);
14525631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik
14526631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    if ((res != -1) && (resObj != NULL)) {
14527631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik		valuePush(ctxt, resObj);
14528631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik		return(0);
14529631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    }
14530631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    if (resObj != NULL)
1453145490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard		xmlXPathReleaseObject(ctxt->context, resObj);
1453256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	}
14533631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	/*
14534631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	* QUESTION TODO: This falls back to normal XPath evaluation
14535631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	* if res == -1. Is this intended?
14536631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	*/
1453756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard    }
1453856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard#endif
145399e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    comp = ctxt->comp;
14540631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik    if (comp->last < 0) {
1454129b6f76c5326616aed5dcff9cb55145137863e97Aleksey Sanin	xmlGenericError(xmlGenericErrorContext,
1454229b6f76c5326616aed5dcff9cb55145137863e97Aleksey Sanin	    "xmlXPathRunEval: last is less than zero\n");
14543631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	return(-1);
1454429b6f76c5326616aed5dcff9cb55145137863e97Aleksey Sanin    }
14545631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik    if (toBool)
14546324c75b3c3edffcd30e7afa2a32f0d83d928b10dKasimier T. Buchcik	return(xmlXPathCompOpEvalToBoolean(ctxt,
14547324c75b3c3edffcd30e7afa2a32f0d83d928b10dKasimier T. Buchcik	    &comp->steps[comp->last], 0));
14548631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik    else
14549631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	xmlXPathCompOpEval(ctxt, &comp->steps[comp->last]);
14550631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik
14551631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik    return(0);
145529e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard}
145539e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
14554afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard/************************************************************************
14555afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard *									*
1455645490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *			Public interfaces				*
14557afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard *									*
14558afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard ************************************************************************/
14559afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard
14560afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard/**
14561fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * xmlXPathEvalPredicate:
14562fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * @ctxt:  the XPath context
14563fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * @res:  the Predicate Expression evaluation result
14564fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard *
14565fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * Evaluate a predicate result for the current node.
14566fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * A PredicateExpr is evaluated by evaluating the Expr and converting
14567fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * the result to a boolean. If the result is a number, the result will
14568fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * be converted to true if the number is equal to the position of the
14569fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * context node in the context node list (as returned by the position
14570fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * function) and will be converted to false otherwise; if the result
14571fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * is not a number, then the result will be converted as if by a call
1457245490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard * to the boolean function.
14573fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard *
14574cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * Returns 1 if predicate is true, 0 otherwise
14575fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard */
14576fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillardint
14577fbf8a2d0c8145b713099df63d174154a8442e60dDaniel VeillardxmlXPathEvalPredicate(xmlXPathContextPtr ctxt, xmlXPathObjectPtr res) {
14578ce682bc24b79f1dd29b781d4c17f9bf169ce7e32Daniel Veillard    if ((ctxt == NULL) || (res == NULL)) return(0);
14579fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard    switch (res->type) {
14580fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard        case XPATH_BOOLEAN:
14581fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard	    return(res->boolval);
14582fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard        case XPATH_NUMBER:
14583fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard	    return(res->floatval == ctxt->proximityPosition);
14584fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard        case XPATH_NODESET:
14585fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard        case XPATH_XSLT_TREE:
14586d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	    if (res->nodesetval == NULL)
14587d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard		return(0);
14588fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard	    return(res->nodesetval->nodeNr != 0);
14589fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard        case XPATH_STRING:
14590fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard	    return((res->stringval != NULL) &&
14591fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard	           (xmlStrlen(res->stringval) != 0));
14592fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard        default:
14593fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard	    STRANGE
14594fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard    }
14595fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard    return(0);
14596fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard}
14597fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard
14598fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard/**
14599afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathEvaluatePredicateResult:
14600afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * @ctxt:  the XPath Parser context
14601afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * @res:  the Predicate Expression evaluation result
14602afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard *
14603afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Evaluate a predicate result for the current node.
14604afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * A PredicateExpr is evaluated by evaluating the Expr and converting
14605afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * the result to a boolean. If the result is a number, the result will
14606afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * be converted to true if the number is equal to the position of the
14607afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * context node in the context node list (as returned by the position
14608afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * function) and will be converted to false otherwise; if the result
14609afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * is not a number, then the result will be converted as if by a call
1461045490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard * to the boolean function.
14611afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard *
14612cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * Returns 1 if predicate is true, 0 otherwise
14613afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard */
14614afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardint
1461545490aebe7a60704e8ed850c498969858ab900eeDaniel VeillardxmlXPathEvaluatePredicateResult(xmlXPathParserContextPtr ctxt,
14616afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard                                xmlXPathObjectPtr res) {
14617ce682bc24b79f1dd29b781d4c17f9bf169ce7e32Daniel Veillard    if ((ctxt == NULL) || (res == NULL)) return(0);
14618afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard    switch (res->type) {
14619afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard        case XPATH_BOOLEAN:
14620afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard	    return(res->boolval);
14621afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard        case XPATH_NUMBER:
146229ea6231ecef04c848b688355b8f7532dd5e4c6f8Daniel Veillard#if defined(__BORLANDC__) || (defined(_MSC_VER) && (_MSC_VER == 1200))
146237c4eb63bb01d754b17860cd7dc2ab2fef81f6a08Daniel Veillard	    return((res->floatval == ctxt->context->proximityPosition) &&
146247c4eb63bb01d754b17860cd7dc2ab2fef81f6a08Daniel Veillard	           (!xmlXPathIsNaN(res->floatval))); /* MSC pbm Mark Vakoc !*/
146252582a338bff77569b5aadbba8f40e1f3862d090dDaniel Veillard#else
14626afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard	    return(res->floatval == ctxt->context->proximityPosition);
146272582a338bff77569b5aadbba8f40e1f3862d090dDaniel Veillard#endif
14628afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard        case XPATH_NODESET:
14629afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard        case XPATH_XSLT_TREE:
1463073639a73c5a51c3739595f54c338bb531c1319c2Daniel Veillard	    if (res->nodesetval == NULL)
14631911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard		return(0);
14632afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard	    return(res->nodesetval->nodeNr != 0);
14633afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard        case XPATH_STRING:
14634631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    return((res->stringval != NULL) && (res->stringval[0] != 0));
14635081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack#ifdef LIBXML_XPTR_ENABLED
14636081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack	case XPATH_LOCATIONSET:{
14637081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack	    xmlLocationSetPtr ptr = res->user;
14638081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack	    if (ptr == NULL)
14639081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack	        return(0);
14640081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack	    return (ptr->locNr != 0);
14641081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack	    }
14642081719182de3d15e6a438f32fdc3d1ca240a08e8William M. Brack#endif
14643afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard        default:
14644afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard	    STRANGE
14645afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard    }
14646afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard    return(0);
14647afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard}
14648afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard
1464956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard#ifdef XPATH_STREAMING
1465056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard/**
1465156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard * xmlXPathTryStreamCompile:
1465256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard * @ctxt: an XPath context
1465356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard * @str:  the XPath expression
1465456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard *
1465556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard * Try to compile the XPath expression as a streamable subset.
1465656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard *
1465756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard * Returns the compiled expression or NULL if failed to compile.
1465856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard */
1465956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillardstatic xmlXPathCompExprPtr
1466056de87ee0d147d04a041eb1ec95048566375bc3fDaniel VeillardxmlXPathTryStreamCompile(xmlXPathContextPtr ctxt, const xmlChar *str) {
1466156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard    /*
1466256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard     * Optimization: use streaming patterns when the XPath expression can
1466356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard     * be compiled to a stream lookup
1466456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard     */
1466556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard    xmlPatternPtr stream;
1466656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard    xmlXPathCompExprPtr comp;
1466756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard    xmlDictPtr dict = NULL;
1466856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard    const xmlChar **namespaces = NULL;
1466956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard    xmlNsPtr ns;
1467056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard    int i, j;
1467156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard
1467256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard    if ((!xmlStrchr(str, '[')) && (!xmlStrchr(str, '(')) &&
1467356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard        (!xmlStrchr(str, '@'))) {
146741f33c4d61f3cc9820643ef726b373ec3044bcac3Daniel Veillard	const xmlChar *tmp;
146751f33c4d61f3cc9820643ef726b373ec3044bcac3Daniel Veillard
146761f33c4d61f3cc9820643ef726b373ec3044bcac3Daniel Veillard	/*
146776ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik	 * We don't try to handle expressions using the verbose axis
146786ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik	 * specifiers ("::"), just the simplied form at this point.
146796ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik	 * Additionally, if there is no list of namespaces available and
146806ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik	 *  there's a ":" in the expression, indicating a prefixed QName,
146816ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik	 *  then we won't try to compile either. xmlPatterncompile() needs
146826ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik	 *  to have a list of namespaces at compilation time in order to
146836ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik	 *  compile prefixed name tests.
146841f33c4d61f3cc9820643ef726b373ec3044bcac3Daniel Veillard	 */
146851f33c4d61f3cc9820643ef726b373ec3044bcac3Daniel Veillard	tmp = xmlStrchr(str, ':');
146866ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik	if ((tmp != NULL) &&
146876ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik	    ((ctxt == NULL) || (ctxt->nsNr == 0) || (tmp[1] == ':')))
1468845490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	    return(NULL);
146891f33c4d61f3cc9820643ef726b373ec3044bcac3Daniel Veillard
1469056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	if (ctxt != NULL) {
1469156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	    dict = ctxt->dict;
1469256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	    if (ctxt->nsNr > 0) {
14693dbfe05aff4d242e31fcd7621a4901a6fa10b988eDaniel Veillard		namespaces = xmlMalloc(2 * (ctxt->nsNr + 1) * sizeof(xmlChar*));
1469456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard		if (namespaces == NULL) {
1469556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard		    xmlXPathErrMemory(ctxt, "allocating namespaces array\n");
1469656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard		    return(NULL);
1469756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard		}
1469856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard		for (i = 0, j = 0; (j < ctxt->nsNr); j++) {
1469956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard		    ns = ctxt->namespaces[j];
1470056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard		    namespaces[i++] = ns->href;
1470156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard		    namespaces[i++] = ns->prefix;
1470256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard		}
1470356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard		namespaces[i++] = NULL;
1470413cee4e37ba9f2a401f976e069539514ebfce7bcDaniel Veillard		namespaces[i] = NULL;
1470556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	    }
1470656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	}
1470756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard
14708ea152c05b3f3d9e47b282b88ffdb16fcb8c779c1William M. Brack	stream = xmlPatterncompile(str, dict, XML_PATTERN_XPATH,
14709ea152c05b3f3d9e47b282b88ffdb16fcb8c779c1William M. Brack			&namespaces[0]);
147106ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik	if (namespaces != NULL) {
147116ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik	    xmlFree((xmlChar **)namespaces);
1471245490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	}
1471356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	if ((stream != NULL) && (xmlPatternStreamable(stream) == 1)) {
1471456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	    comp = xmlXPathNewCompExpr();
1471556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	    if (comp == NULL) {
1471656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard		xmlXPathErrMemory(ctxt, "allocating streamable expression\n");
1471756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard		return(NULL);
1471856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	    }
1471956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	    comp->stream = stream;
1472056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	    comp->dict = dict;
1472156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	    if (comp->dict)
1472256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard		xmlDictReference(comp->dict);
1472356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	    return(comp);
1472456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	}
1472556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	xmlFreePattern(stream);
1472656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard    }
1472756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard    return(NULL);
1472856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard}
1472956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard#endif /* XPATH_STREAMING */
1473056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard
14731df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcikstatic void
14732622705398ab0b9aa3ed5f671432ef894d620f8a4Nick WellnhoferxmlXPathOptimizeExpression(xmlXPathCompExprPtr comp, xmlXPathStepOpPtr op)
14733df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik{
14734df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik    /*
14735df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik    * Try to rewrite "descendant-or-self::node()/foo" to an optimized
14736df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik    * internal representation.
14737df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik    */
14738622705398ab0b9aa3ed5f671432ef894d620f8a4Nick Wellnhofer
14739b4bcba23f64b71105514875f165a63d4cc720609Nick Wellnhofer    if ((op->op == XPATH_OP_COLLECT /* 11 */) &&
14740b4bcba23f64b71105514875f165a63d4cc720609Nick Wellnhofer        (op->ch1 != -1) &&
14741b4bcba23f64b71105514875f165a63d4cc720609Nick Wellnhofer        (op->ch2 == -1 /* no predicate */))
14742622705398ab0b9aa3ed5f671432ef894d620f8a4Nick Wellnhofer    {
14743622705398ab0b9aa3ed5f671432ef894d620f8a4Nick Wellnhofer        xmlXPathStepOpPtr prevop = &comp->steps[op->ch1];
14744622705398ab0b9aa3ed5f671432ef894d620f8a4Nick Wellnhofer
14745622705398ab0b9aa3ed5f671432ef894d620f8a4Nick Wellnhofer        if ((prevop->op == XPATH_OP_COLLECT /* 11 */) &&
14746622705398ab0b9aa3ed5f671432ef894d620f8a4Nick Wellnhofer            ((xmlXPathAxisVal) prevop->value ==
14747622705398ab0b9aa3ed5f671432ef894d620f8a4Nick Wellnhofer                AXIS_DESCENDANT_OR_SELF) &&
14748622705398ab0b9aa3ed5f671432ef894d620f8a4Nick Wellnhofer            (prevop->ch2 == -1) &&
14749622705398ab0b9aa3ed5f671432ef894d620f8a4Nick Wellnhofer            ((xmlXPathTestVal) prevop->value2 == NODE_TEST_TYPE) &&
14750622705398ab0b9aa3ed5f671432ef894d620f8a4Nick Wellnhofer            ((xmlXPathTypeVal) prevop->value3 == NODE_TYPE_NODE))
14751622705398ab0b9aa3ed5f671432ef894d620f8a4Nick Wellnhofer        {
14752622705398ab0b9aa3ed5f671432ef894d620f8a4Nick Wellnhofer            /*
14753622705398ab0b9aa3ed5f671432ef894d620f8a4Nick Wellnhofer            * This is a "descendant-or-self::node()" without predicates.
14754622705398ab0b9aa3ed5f671432ef894d620f8a4Nick Wellnhofer            * Try to eliminate it.
14755622705398ab0b9aa3ed5f671432ef894d620f8a4Nick Wellnhofer            */
14756622705398ab0b9aa3ed5f671432ef894d620f8a4Nick Wellnhofer
14757622705398ab0b9aa3ed5f671432ef894d620f8a4Nick Wellnhofer            switch ((xmlXPathAxisVal) op->value) {
14758622705398ab0b9aa3ed5f671432ef894d620f8a4Nick Wellnhofer                case AXIS_CHILD:
14759622705398ab0b9aa3ed5f671432ef894d620f8a4Nick Wellnhofer                case AXIS_DESCENDANT:
14760622705398ab0b9aa3ed5f671432ef894d620f8a4Nick Wellnhofer                    /*
14761622705398ab0b9aa3ed5f671432ef894d620f8a4Nick Wellnhofer                    * Convert "descendant-or-self::node()/child::" or
14762622705398ab0b9aa3ed5f671432ef894d620f8a4Nick Wellnhofer                    * "descendant-or-self::node()/descendant::" to
14763622705398ab0b9aa3ed5f671432ef894d620f8a4Nick Wellnhofer                    * "descendant::"
14764622705398ab0b9aa3ed5f671432ef894d620f8a4Nick Wellnhofer                    */
14765622705398ab0b9aa3ed5f671432ef894d620f8a4Nick Wellnhofer                    op->ch1   = prevop->ch1;
14766622705398ab0b9aa3ed5f671432ef894d620f8a4Nick Wellnhofer                    op->value = AXIS_DESCENDANT;
14767622705398ab0b9aa3ed5f671432ef894d620f8a4Nick Wellnhofer                    break;
14768622705398ab0b9aa3ed5f671432ef894d620f8a4Nick Wellnhofer                case AXIS_SELF:
14769622705398ab0b9aa3ed5f671432ef894d620f8a4Nick Wellnhofer                case AXIS_DESCENDANT_OR_SELF:
14770622705398ab0b9aa3ed5f671432ef894d620f8a4Nick Wellnhofer                    /*
14771622705398ab0b9aa3ed5f671432ef894d620f8a4Nick Wellnhofer                    * Convert "descendant-or-self::node()/self::" or
14772622705398ab0b9aa3ed5f671432ef894d620f8a4Nick Wellnhofer                    * "descendant-or-self::node()/descendant-or-self::" to
14773622705398ab0b9aa3ed5f671432ef894d620f8a4Nick Wellnhofer                    * to "descendant-or-self::"
14774622705398ab0b9aa3ed5f671432ef894d620f8a4Nick Wellnhofer                    */
14775622705398ab0b9aa3ed5f671432ef894d620f8a4Nick Wellnhofer                    op->ch1   = prevop->ch1;
14776622705398ab0b9aa3ed5f671432ef894d620f8a4Nick Wellnhofer                    op->value = AXIS_DESCENDANT_OR_SELF;
14777622705398ab0b9aa3ed5f671432ef894d620f8a4Nick Wellnhofer                    break;
14778622705398ab0b9aa3ed5f671432ef894d620f8a4Nick Wellnhofer                default:
14779622705398ab0b9aa3ed5f671432ef894d620f8a4Nick Wellnhofer                    break;
14780622705398ab0b9aa3ed5f671432ef894d620f8a4Nick Wellnhofer            }
14781df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik	}
14782df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik    }
14783622705398ab0b9aa3ed5f671432ef894d620f8a4Nick Wellnhofer
14784622705398ab0b9aa3ed5f671432ef894d620f8a4Nick Wellnhofer    /* Recurse */
14785622705398ab0b9aa3ed5f671432ef894d620f8a4Nick Wellnhofer    if (op->ch1 != -1)
14786622705398ab0b9aa3ed5f671432ef894d620f8a4Nick Wellnhofer        xmlXPathOptimizeExpression(comp, &comp->steps[op->ch1]);
14787df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik    if (op->ch2 != -1)
14788622705398ab0b9aa3ed5f671432ef894d620f8a4Nick Wellnhofer	xmlXPathOptimizeExpression(comp, &comp->steps[op->ch2]);
14789df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik}
14790df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik
14791afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard/**
147924773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard * xmlXPathCtxtCompile:
147934773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard * @ctxt: an XPath context
14794afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * @str:  the XPath expression
14795afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard *
14796afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile an XPath expression
14797afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard *
14798591b4be0fe1986b5e71d54c5c063493987ef4285Daniel Veillard * Returns the xmlXPathCompExprPtr resulting from the compilation or NULL.
14799afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard *         the caller has to free the object.
14800afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard */
14801afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompExprPtr
148024773df2a58be83e1b9b1b55840371acf37386820Daniel VeillardxmlXPathCtxtCompile(xmlXPathContextPtr ctxt, const xmlChar *str) {
148034773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard    xmlXPathParserContextPtr pctxt;
14804afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard    xmlXPathCompExprPtr comp;
14805afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard
1480656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard#ifdef XPATH_STREAMING
1480756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard    comp = xmlXPathTryStreamCompile(ctxt, str);
1480856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard    if (comp != NULL)
1480956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard        return(comp);
1481056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard#endif
1481156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard
14812afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard    xmlXPathInit();
14813afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard
148144773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard    pctxt = xmlXPathNewParserContext(str, ctxt);
1481511be2d02b0261c9b5fd5d2f511b7a5ca8a81342dWilliam M. Brack    if (pctxt == NULL)
1481611be2d02b0261c9b5fd5d2f511b7a5ca8a81342dWilliam M. Brack        return NULL;
148175691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik    xmlXPathCompileExpr(pctxt, 1);
14818ae9733aeaf99e5d967b6b2cd961c98bf58cfbb4cDaniel Veillard
148194773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard    if( pctxt->error != XPATH_EXPRESSION_OK )
14820ae9733aeaf99e5d967b6b2cd961c98bf58cfbb4cDaniel Veillard    {
148214773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard        xmlXPathFreeParserContext(pctxt);
1482224505b0f5c872c5afb6da5093565e5a6e09ca541Daniel Veillard        return(NULL);
14823ae9733aeaf99e5d967b6b2cd961c98bf58cfbb4cDaniel Veillard    }
14824ae9733aeaf99e5d967b6b2cd961c98bf58cfbb4cDaniel Veillard
148254773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard    if (*pctxt->cur != 0) {
1482645490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	/*
1482750fe8b1732048003f47b32b009507fe6cdecd39fAleksey Sanin	 * aleksey: in some cases this line prints *second* error message
1482850fe8b1732048003f47b32b009507fe6cdecd39fAleksey Sanin	 * (see bug #78858) and probably this should be fixed.
1482950fe8b1732048003f47b32b009507fe6cdecd39fAleksey Sanin	 * However, we are not sure that all error messages are printed
1483050fe8b1732048003f47b32b009507fe6cdecd39fAleksey Sanin	 * out in other places. It's not critical so we leave it as-is for now
1483150fe8b1732048003f47b32b009507fe6cdecd39fAleksey Sanin	 */
148324773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard	xmlXPatherror(pctxt, __FILE__, __LINE__, XPATH_EXPR_ERROR);
1483340af649f9b5b32f97879f10432c56bb5ef60c958Daniel Veillard	comp = NULL;
1483440af649f9b5b32f97879f10432c56bb5ef60c958Daniel Veillard    } else {
148354773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard	comp = pctxt->comp;
148364773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard	pctxt->comp = NULL;
1483740af649f9b5b32f97879f10432c56bb5ef60c958Daniel Veillard    }
148384773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard    xmlXPathFreeParserContext(pctxt);
14839631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik
14840f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    if (comp != NULL) {
14841ceb09b956efa2cf1ec41c1887394396e5a6030f2Daniel Veillard	comp->expr = xmlStrdup(str);
14842ceb09b956efa2cf1ec41c1887394396e5a6030f2Daniel Veillard#ifdef DEBUG_EVAL_COUNTS
14843f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	comp->string = xmlStrdup(str);
14844f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	comp->nb = 0;
1484545490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard#endif
14846622705398ab0b9aa3ed5f671432ef894d620f8a4Nick Wellnhofer	if ((comp->nbStep > 1) && (comp->last >= 0)) {
14847622705398ab0b9aa3ed5f671432ef894d620f8a4Nick Wellnhofer	    xmlXPathOptimizeExpression(comp, &comp->steps[comp->last]);
148489bca933a6e39bae6dd8952825528270f006c97dfKasimier T. Buchcik	}
14849df0ba2640931d8da5052977154fb03bc1ede08f8Kasimier T. Buchcik    }
14850afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard    return(comp);
14851afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard}
14852afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard
148539e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard/**
148544773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard * xmlXPathCompile:
148554773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard * @str:  the XPath expression
148564773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard *
148574773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard * Compile an XPath expression
148584773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard *
148594773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard * Returns the xmlXPathCompExprPtr resulting from the compilation or NULL.
148604773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard *         the caller has to free the object.
148614773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard */
148624773df2a58be83e1b9b1b55840371acf37386820Daniel VeillardxmlXPathCompExprPtr
148634773df2a58be83e1b9b1b55840371acf37386820Daniel VeillardxmlXPathCompile(const xmlChar *str) {
148644773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard    return(xmlXPathCtxtCompile(NULL, str));
148654773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard}
148664773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard
148674773df2a58be83e1b9b1b55840371acf37386820Daniel Veillard/**
14868631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik * xmlXPathCompiledEvalInternal:
148699e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * @comp:  the compiled XPath expression
14870631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik * @ctxt:  the XPath context
14871631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik * @resObj: the resulting XPath object or NULL
14872631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik * @toBool: 1 if only a boolean result is requested
148739e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard *
148749e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * Evaluate the Precompiled XPath expression in the given context.
14875631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik * The caller has to free @resObj.
148769e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard *
14877cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * Returns the xmlXPathObjectPtr resulting from the evaluation or NULL.
148789e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard *         the caller has to free the object.
148799e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard */
14880631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcikstatic int
14881631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. BuchcikxmlXPathCompiledEvalInternal(xmlXPathCompExprPtr comp,
14882631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik			     xmlXPathContextPtr ctxt,
14883631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik			     xmlXPathObjectPtr *resObj,
14884631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik			     int toBool)
14885631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik{
1488645490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard    xmlXPathParserContextPtr pctxt;
148878146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard#ifndef LIBXML_THREAD_ENABLED
148888146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard    static int reentance = 0;
148898146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard#endif
14890631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik    int res;
148919e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
14892631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik    CHECK_CTXT_NEG(ctxt)
14893f13f77f0e6a7876063d5fba15c096befb0827cedWilliam M. Brack
14894f13f77f0e6a7876063d5fba15c096befb0827cedWilliam M. Brack    if (comp == NULL)
14895631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	return(-1);
148969e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    xmlXPathInit();
148979e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
148988146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard#ifndef LIBXML_THREAD_ENABLED
148998146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard    reentance++;
149008146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard    if (reentance > 1)
149018146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard	xmlXPathDisableOptimizer = 1;
149028146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard#endif
149038146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard
14904f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#ifdef DEBUG_EVAL_COUNTS
14905f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    comp->nb++;
14906f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    if ((comp->string != NULL) && (comp->nb > 100)) {
14907f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	fprintf(stderr, "100 x %s\n", comp->string);
14908f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard	comp->nb = 0;
14909f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard    }
14910f06307e2c172284bb41376c396f757bdac9bdd19Daniel Veillard#endif
14911631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik    pctxt = xmlXPathCompParserContext(comp, ctxt);
14912631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik    res = xmlXPathRunEval(pctxt, toBool);
149139e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
14914631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik    if (resObj) {
1491545490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	if (pctxt->value == NULL) {
14916631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    xmlGenericError(xmlGenericErrorContext,
14917cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard		"xmlXPathCompiledEval: evaluation failed\n");
1491845490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard	    *resObj = NULL;
14919631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	} else {
14920631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    *resObj = valuePop(pctxt);
14921631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	}
149229e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    }
1492345490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
14924631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik    /*
14925631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik    * Pop all remaining objects from the stack.
14926631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik    */
14927631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik    if (pctxt->valueNr > 0) {
14928631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	xmlXPathObjectPtr tmp;
14929631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	int stack = 0;
14930631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik
14931631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	do {
14932631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    tmp = valuePop(pctxt);
14933631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    if (tmp != NULL) {
1493445490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard		stack++;
14935631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik		xmlXPathReleaseObject(ctxt, tmp);
14936631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    }
14937631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	} while (tmp != NULL);
14938631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	if ((stack != 0) &&
14939631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    ((toBool) || ((resObj) && (*resObj))))
14940631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	{
14941631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	    xmlGenericError(xmlGenericErrorContext,
14942631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik		"xmlXPathCompiledEval: %d objects left on the stack.\n",
14943631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik		stack);
14944631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	}
149459e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    }
1494645490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
14947631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik    if ((pctxt->error != XPATH_EXPRESSION_OK) && (resObj) && (*resObj)) {
14948631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	xmlXPathFreeObject(*resObj);
14949631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik	*resObj = NULL;
1495045490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard    }
14951631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik    pctxt->comp = NULL;
14952631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik    xmlXPathFreeParserContext(pctxt);
149538146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard#ifndef LIBXML_THREAD_ENABLED
149548146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard    reentance--;
149558146394d05edb4f9c3eba3d97884d4e50fd6a92aDaniel Veillard#endif
14956631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik
149579e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    return(res);
149589e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard}
149599e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
14960afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard/**
14961631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik * xmlXPathCompiledEval:
14962631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik * @comp:  the compiled XPath expression
14963631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik * @ctx:  the XPath context
14964631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik *
14965631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik * Evaluate the Precompiled XPath expression in the given context.
14966631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik *
14967631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik * Returns the xmlXPathObjectPtr resulting from the evaluation or NULL.
14968631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik *         the caller has to free the object.
14969631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik */
14970631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. BuchcikxmlXPathObjectPtr
14971631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. BuchcikxmlXPathCompiledEval(xmlXPathCompExprPtr comp, xmlXPathContextPtr ctx)
14972631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik{
14973631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik    xmlXPathObjectPtr res = NULL;
14974631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik
14975631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik    xmlXPathCompiledEvalInternal(comp, ctx, &res, 0);
14976631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik    return(res);
14977631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik}
14978631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik
14979631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik/**
14980631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik * xmlXPathCompiledEvalToBoolean:
14981631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik * @comp:  the compiled XPath expression
14982631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik * @ctxt:  the XPath context
14983631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik *
14984631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik * Applies the XPath boolean() function on the result of the given
14985631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik * compiled expression.
14986631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik *
14987631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik * Returns 1 if the expression evaluated to true, 0 if to false and
14988631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik *         -1 in API and internal errors.
14989631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik */
14990631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcikint
14991631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. BuchcikxmlXPathCompiledEvalToBoolean(xmlXPathCompExprPtr comp,
14992631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik			      xmlXPathContextPtr ctxt)
14993631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik{
14994631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik    return(xmlXPathCompiledEvalInternal(comp, ctxt, NULL, 1));
14995631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik}
14996631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik
14997631ea8176ad5ae7662145e2ab18b3a62e8838decKasimier T. Buchcik/**
14998afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathEvalExpr:
14999afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * @ctxt:  the XPath Parser context
15000afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard *
15001afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Parse and evaluate an XPath expression in the given context,
15002afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * then push the result on the context stack
15003afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard */
15004afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardvoid
15005afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathEvalExpr(xmlXPathParserContextPtr ctxt) {
1500656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard#ifdef XPATH_STREAMING
1500756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard    xmlXPathCompExprPtr comp;
1500856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard#endif
1500956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard
15010a82b182655ccee95e3b7210066206ddb3918823fDaniel Veillard    if (ctxt == NULL) return;
1501145490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
1501256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard#ifdef XPATH_STREAMING
1501356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard    comp = xmlXPathTryStreamCompile(ctxt->context, ctxt->base);
1501456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard    if (comp != NULL) {
1501556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard        if (ctxt->comp != NULL)
1501656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	    xmlXPathFreeCompExpr(ctxt->comp);
1501756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard        ctxt->comp = comp;
1501856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	if (ctxt->cur != NULL)
1501956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	    while (*ctxt->cur != 0) ctxt->cur++;
1502056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard    } else
1502156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard#endif
1502256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard    {
150235691f436d92cda5db1ef06174d9edef4d12ff118Kasimier T. Buchcik	xmlXPathCompileExpr(ctxt, 1);
15024766ed7e1e5a4361f3b107ba8dc7af3a8960801c9Kasimier T. Buchcik	if ((ctxt->error == XPATH_EXPRESSION_OK) &&
15025766ed7e1e5a4361f3b107ba8dc7af3a8960801c9Kasimier T. Buchcik	    (ctxt->comp != NULL) &&
15026622705398ab0b9aa3ed5f671432ef894d620f8a4Nick Wellnhofer	    (ctxt->comp->nbStep > 1) &&
15027622705398ab0b9aa3ed5f671432ef894d620f8a4Nick Wellnhofer	    (ctxt->comp->last >= 0))
15028080152c9017a0ee4b97149d54f85fea3ab348b6dKasimier T. Buchcik	{
15029622705398ab0b9aa3ed5f671432ef894d620f8a4Nick Wellnhofer	    xmlXPathOptimizeExpression(ctxt->comp,
15030766ed7e1e5a4361f3b107ba8dc7af3a8960801c9Kasimier T. Buchcik		&ctxt->comp->steps[ctxt->comp->last]);
15031080152c9017a0ee4b97149d54f85fea3ab348b6dKasimier T. Buchcik	}
1503256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard    }
1503350fe8b1732048003f47b32b009507fe6cdecd39fAleksey Sanin    CHECK_ERROR;
1503445490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard    xmlXPathRunEval(ctxt, 0);
15035afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard}
150369e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
150373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
150383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathEval:
150393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @str:  the XPath expression
150403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctx:  the XPath context
150413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
150423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Evaluate the XPath Location Path in the given context.
150433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
15044cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * Returns the xmlXPathObjectPtr resulting from the evaluation or NULL.
150453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *         the caller has to free the object.
150463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
150473473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathObjectPtr
150483473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathEval(const xmlChar *str, xmlXPathContextPtr ctx) {
150493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathParserContextPtr ctxt;
150503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathObjectPtr res, tmp, init = NULL;
150513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    int stack = 0;
150523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
15053f13f77f0e6a7876063d5fba15c096befb0827cedWilliam M. Brack    CHECK_CTXT(ctx)
150543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
15055f13f77f0e6a7876063d5fba15c096befb0827cedWilliam M. Brack    xmlXPathInit();
150563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
150573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ctxt = xmlXPathNewParserContext(str, ctx);
1505811be2d02b0261c9b5fd5d2f511b7a5ca8a81342dWilliam M. Brack    if (ctxt == NULL)
1505911be2d02b0261c9b5fd5d2f511b7a5ca8a81342dWilliam M. Brack        return NULL;
150603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathEvalExpr(ctxt);
150613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
150623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ctxt->value == NULL) {
150633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	xmlGenericError(xmlGenericErrorContext,
150643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		"xmlXPathEval: evaluation failed\n");
150653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	res = NULL;
1506645490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard    } else if ((*ctxt->cur != 0) && (ctxt->comp != NULL)
1506756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard#ifdef XPATH_STREAMING
1506856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard            && (ctxt->comp->stream == NULL)
1506956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard#endif
1507056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	      ) {
150713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	xmlXPatherror(ctxt, __FILE__, __LINE__, XPATH_EXPR_ERROR);
150723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	res = NULL;
150733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    } else {
150743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	res = valuePop(ctxt);
150753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
150763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
150773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    do {
150783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        tmp = valuePop(ctxt);
150793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (tmp != NULL) {
150803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    if (tmp != init)
15081a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik		stack++;
15082a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathReleaseObject(ctx, tmp);
150833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        }
150843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    } while (tmp != NULL);
150853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if ((stack != 0) && (res != NULL)) {
150863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	xmlGenericError(xmlGenericErrorContext,
150873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		"xmlXPathEval: %d object left on the stack\n",
150883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	        stack);
150893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
150903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ctxt->error != XPATH_EXPRESSION_OK) {
150913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	xmlXPathFreeObject(res);
150923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	res = NULL;
150933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
150949e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
150953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathFreeParserContext(ctxt);
150963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(res);
150973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
150983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
150993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
1510028876afb4e67f9f4292fc2a7134f6b97f0618b7dAlex Bligh * xmlXPathSetContextNode:
1510128876afb4e67f9f4292fc2a7134f6b97f0618b7dAlex Bligh * @node: the node to to use as the context node
1510228876afb4e67f9f4292fc2a7134f6b97f0618b7dAlex Bligh * @ctx:  the XPath context
1510328876afb4e67f9f4292fc2a7134f6b97f0618b7dAlex Bligh *
1510428876afb4e67f9f4292fc2a7134f6b97f0618b7dAlex Bligh * Sets 'node' as the context node. The node must be in the same
1510528876afb4e67f9f4292fc2a7134f6b97f0618b7dAlex Bligh * document as that associated with the context.
1510628876afb4e67f9f4292fc2a7134f6b97f0618b7dAlex Bligh *
1510728876afb4e67f9f4292fc2a7134f6b97f0618b7dAlex Bligh * Returns -1 in case of error or 0 if successful
1510828876afb4e67f9f4292fc2a7134f6b97f0618b7dAlex Bligh */
1510928876afb4e67f9f4292fc2a7134f6b97f0618b7dAlex Blighint
1511028876afb4e67f9f4292fc2a7134f6b97f0618b7dAlex BlighxmlXPathSetContextNode(xmlNodePtr node, xmlXPathContextPtr ctx) {
1511128876afb4e67f9f4292fc2a7134f6b97f0618b7dAlex Bligh    if ((node == NULL) || (ctx == NULL))
1511228876afb4e67f9f4292fc2a7134f6b97f0618b7dAlex Bligh        return(-1);
1511328876afb4e67f9f4292fc2a7134f6b97f0618b7dAlex Bligh
1511428876afb4e67f9f4292fc2a7134f6b97f0618b7dAlex Bligh    if (node->doc == ctx->doc) {
1511528876afb4e67f9f4292fc2a7134f6b97f0618b7dAlex Bligh        ctx->node = node;
1511628876afb4e67f9f4292fc2a7134f6b97f0618b7dAlex Bligh	return(0);
1511728876afb4e67f9f4292fc2a7134f6b97f0618b7dAlex Bligh    }
1511828876afb4e67f9f4292fc2a7134f6b97f0618b7dAlex Bligh    return(-1);
1511928876afb4e67f9f4292fc2a7134f6b97f0618b7dAlex Bligh}
1512028876afb4e67f9f4292fc2a7134f6b97f0618b7dAlex Bligh
1512128876afb4e67f9f4292fc2a7134f6b97f0618b7dAlex Bligh/**
1512228876afb4e67f9f4292fc2a7134f6b97f0618b7dAlex Bligh * xmlXPathNodeEval:
1512328876afb4e67f9f4292fc2a7134f6b97f0618b7dAlex Bligh * @node: the node to to use as the context node
1512428876afb4e67f9f4292fc2a7134f6b97f0618b7dAlex Bligh * @str:  the XPath expression
1512528876afb4e67f9f4292fc2a7134f6b97f0618b7dAlex Bligh * @ctx:  the XPath context
1512628876afb4e67f9f4292fc2a7134f6b97f0618b7dAlex Bligh *
1512728876afb4e67f9f4292fc2a7134f6b97f0618b7dAlex Bligh * Evaluate the XPath Location Path in the given context. The node 'node'
1512828876afb4e67f9f4292fc2a7134f6b97f0618b7dAlex Bligh * is set as the context node. The context node is not restored.
1512928876afb4e67f9f4292fc2a7134f6b97f0618b7dAlex Bligh *
1513028876afb4e67f9f4292fc2a7134f6b97f0618b7dAlex Bligh * Returns the xmlXPathObjectPtr resulting from the evaluation or NULL.
1513128876afb4e67f9f4292fc2a7134f6b97f0618b7dAlex Bligh *         the caller has to free the object.
1513228876afb4e67f9f4292fc2a7134f6b97f0618b7dAlex Bligh */
1513328876afb4e67f9f4292fc2a7134f6b97f0618b7dAlex BlighxmlXPathObjectPtr
1513428876afb4e67f9f4292fc2a7134f6b97f0618b7dAlex BlighxmlXPathNodeEval(xmlNodePtr node, const xmlChar *str, xmlXPathContextPtr ctx) {
1513528876afb4e67f9f4292fc2a7134f6b97f0618b7dAlex Bligh    if (str == NULL)
1513628876afb4e67f9f4292fc2a7134f6b97f0618b7dAlex Bligh        return(NULL);
1513728876afb4e67f9f4292fc2a7134f6b97f0618b7dAlex Bligh    if (xmlXPathSetContextNode(node, ctx) < 0)
1513828876afb4e67f9f4292fc2a7134f6b97f0618b7dAlex Bligh        return(NULL);
1513928876afb4e67f9f4292fc2a7134f6b97f0618b7dAlex Bligh    return(xmlXPathEval(str, ctx));
1514028876afb4e67f9f4292fc2a7134f6b97f0618b7dAlex Bligh}
1514128876afb4e67f9f4292fc2a7134f6b97f0618b7dAlex Bligh
1514228876afb4e67f9f4292fc2a7134f6b97f0618b7dAlex Bligh/**
151433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathEvalExpression:
151443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @str:  the XPath expression
151453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath context
151463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
151473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Evaluate the XPath expression in the given context.
151483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
151493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the xmlXPathObjectPtr resulting from the evaluation or NULL.
151503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *         the caller has to free the object.
151513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
151523473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathObjectPtr
151533473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathEvalExpression(const xmlChar *str, xmlXPathContextPtr ctxt) {
151543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathParserContextPtr pctxt;
151553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathObjectPtr res, tmp;
151563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    int stack = 0;
151573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
15158f13f77f0e6a7876063d5fba15c096befb0827cedWilliam M. Brack    CHECK_CTXT(ctxt)
151593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
15160f13f77f0e6a7876063d5fba15c096befb0827cedWilliam M. Brack    xmlXPathInit();
151613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
151623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    pctxt = xmlXPathNewParserContext(str, ctxt);
1516311be2d02b0261c9b5fd5d2f511b7a5ca8a81342dWilliam M. Brack    if (pctxt == NULL)
1516411be2d02b0261c9b5fd5d2f511b7a5ca8a81342dWilliam M. Brack        return NULL;
151653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathEvalExpr(pctxt);
151663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
15167c465ffc20c75f6ee4656aec9649d5bc6a3bbbf26Daniel Veillard    if ((*pctxt->cur != 0) || (pctxt->error != XPATH_EXPRESSION_OK)) {
151683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	xmlXPatherror(pctxt, __FILE__, __LINE__, XPATH_EXPR_ERROR);
151693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	res = NULL;
151703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    } else {
151713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	res = valuePop(pctxt);
151723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
151733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    do {
151743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        tmp = valuePop(pctxt);
151753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (tmp != NULL) {
15176a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik	    xmlXPathReleaseObject(ctxt, tmp);
151773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    stack++;
151783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
151793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    } while (tmp != NULL);
151803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if ((stack != 0) && (res != NULL)) {
151813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	xmlGenericError(xmlGenericErrorContext,
151823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		"xmlXPathEvalExpression: %d object left on the stack\n",
151833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	        stack);
151843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
151853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathFreeParserContext(pctxt);
151863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(res);
151873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
151883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
1518942766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard/************************************************************************
1519042766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard *									*
1519142766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard *	Extra functions not pertaining to the XPath spec		*
1519242766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard *									*
1519342766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard ************************************************************************/
1519442766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard/**
1519542766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * xmlXPathEscapeUriFunction:
1519642766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * @ctxt:  the XPath Parser context
1519742766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * @nargs:  the number of arguments
1519842766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard *
1519942766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * Implement the escape-uri() XPath function
1520042766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard *    string escape-uri(string $str, bool $escape-reserved)
1520142766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard *
1520242766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * This function applies the URI escaping rules defined in section 2 of [RFC
1520342766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * 2396] to the string supplied as $uri-part, which typically represents all
1520442766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * or part of a URI. The effect of the function is to replace any special
1520542766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * character in the string by an escape sequence of the form %xx%yy...,
1520642766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * where xxyy... is the hexadecimal representation of the octets used to
1520742766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * represent the character in UTF-8.
1520842766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard *
1520942766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * The set of characters that are escaped depends on the setting of the
1521042766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * boolean argument $escape-reserved.
1521142766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard *
1521242766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * If $escape-reserved is true, all characters are escaped other than lower
1521342766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * case letters a-z, upper case letters A-Z, digits 0-9, and the characters
1521442766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * referred to in [RFC 2396] as "marks": specifically, "-" | "_" | "." | "!"
1521542766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * | "~" | "*" | "'" | "(" | ")". The "%" character itself is escaped only
1521642766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * if it is not followed by two hexadecimal digits (that is, 0-9, a-f, and
1521742766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * A-F).
1521842766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard *
1521942766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * If $escape-reserved is false, the behavior differs in that characters
1522042766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * referred to in [RFC 2396] as reserved characters are not escaped. These
1522142766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * characters are ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" | "$" | ",".
1522245490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *
1522342766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * [RFC 2396] does not define whether escaped URIs should use lower case or
1522442766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * upper case for hexadecimal digits. To ensure that escaped URIs can be
1522542766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * compared using string comparison functions, this function must always use
1522642766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * the upper-case letters A-F.
1522745490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *
1522842766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * Generally, $escape-reserved should be set to true when escaping a string
1522942766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * that is to form a single part of a URI, and to false when escaping an
1523042766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * entire URI or URI reference.
1523145490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *
1523245490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard * In the case of non-ascii characters, the string is encoded according to
1523342766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * utf-8 and then converted according to RFC 2396.
1523442766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard *
1523542766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard * Examples
1523645490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard *  xf:escape-uri ("gopher://spinaltap.micro.umn.edu/00/Weather/California/Los%20Angeles#ocean"), true())
1523742766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard *  returns "gopher%3A%2F%2Fspinaltap.micro.umn.edu%2F00%2FWeather%2FCalifornia%2FLos%20Angeles%23ocean"
1523842766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard *  xf:escape-uri ("gopher://spinaltap.micro.umn.edu/00/Weather/California/Los%20Angeles#ocean"), false())
1523942766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard *  returns "gopher://spinaltap.micro.umn.edu/00/Weather/California/Los%20Angeles%23ocean"
1524042766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard *
1524142766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard */
15242118aed78f360f51d182770e62b251ef324707aa2Daniel Veillardstatic void
1524342766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel VeillardxmlXPathEscapeUriFunction(xmlXPathParserContextPtr ctxt, int nargs) {
1524442766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard    xmlXPathObjectPtr str;
1524542766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard    int escape_reserved;
15246ade10f2c57b4bd5c3812b96bce1144d8fa1d189eDaniel Veillard    xmlBufPtr target;
1524742766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard    xmlChar *cptr;
1524842766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard    xmlChar escape[4];
1524945490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
1525042766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard    CHECK_ARITY(2);
1525145490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
1525242766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard    escape_reserved = xmlXPathPopBoolean(ctxt);
1525345490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
1525442766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard    CAST_TO_STRING;
1525542766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard    str = valuePop(ctxt);
1525645490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
15257ade10f2c57b4bd5c3812b96bce1144d8fa1d189eDaniel Veillard    target = xmlBufCreate();
1525845490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
1525942766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard    escape[0] = '%';
1526042766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard    escape[3] = 0;
1526145490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
1526242766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard    if (target) {
1526342766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard	for (cptr = str->stringval; *cptr; cptr++) {
1526442766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard	    if ((*cptr >= 'A' && *cptr <= 'Z') ||
1526542766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard		(*cptr >= 'a' && *cptr <= 'z') ||
1526642766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard		(*cptr >= '0' && *cptr <= '9') ||
1526745490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard		*cptr == '-' || *cptr == '_' || *cptr == '.' ||
1526842766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard		*cptr == '!' || *cptr == '~' || *cptr == '*' ||
1526942766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard		*cptr == '\''|| *cptr == '(' || *cptr == ')' ||
1527045490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard		(*cptr == '%' &&
1527142766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard		 ((cptr[1] >= 'A' && cptr[1] <= 'F') ||
1527242766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard		  (cptr[1] >= 'a' && cptr[1] <= 'f') ||
1527342766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard		  (cptr[1] >= '0' && cptr[1] <= '9')) &&
1527442766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard		 ((cptr[2] >= 'A' && cptr[2] <= 'F') ||
1527542766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard		  (cptr[2] >= 'a' && cptr[2] <= 'f') ||
1527642766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard		  (cptr[2] >= '0' && cptr[2] <= '9'))) ||
1527742766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard		(!escape_reserved &&
1527842766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard		 (*cptr == ';' || *cptr == '/' || *cptr == '?' ||
1527942766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard		  *cptr == ':' || *cptr == '@' || *cptr == '&' ||
1528042766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard		  *cptr == '=' || *cptr == '+' || *cptr == '$' ||
1528142766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard		  *cptr == ','))) {
15282ade10f2c57b4bd5c3812b96bce1144d8fa1d189eDaniel Veillard		xmlBufAdd(target, cptr, 1);
1528342766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard	    } else {
1528442766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard		if ((*cptr >> 4) < 10)
1528542766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard		    escape[1] = '0' + (*cptr >> 4);
1528642766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard		else
1528742766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard		    escape[1] = 'A' - 10 + (*cptr >> 4);
1528842766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard		if ((*cptr & 0xF) < 10)
1528942766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard		    escape[2] = '0' + (*cptr & 0xF);
1529042766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard		else
1529142766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard		    escape[2] = 'A' - 10 + (*cptr & 0xF);
1529245490aebe7a60704e8ed850c498969858ab900eeDaniel Veillard
15293ade10f2c57b4bd5c3812b96bce1144d8fa1d189eDaniel Veillard		xmlBufAdd(target, &escape[0], 3);
1529442766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard	    }
1529542766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard	}
1529642766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard    }
15297a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    valuePush(ctxt, xmlXPathCacheNewString(ctxt->context,
15298ade10f2c57b4bd5c3812b96bce1144d8fa1d189eDaniel Veillard	xmlBufContent(target)));
15299ade10f2c57b4bd5c3812b96bce1144d8fa1d189eDaniel Veillard    xmlBufFree(target);
15300a72484438f798d821fcd65ef26ddd25f2380c5c7Kasimier T. Buchcik    xmlXPathReleaseObject(ctxt->context, str);
1530142766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard}
1530242766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard
153033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
153043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathRegisterAllFunctions:
153053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath context
153063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
153073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Registers all default XPath functions in this context
153083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
153093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
153103473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathRegisterAllFunctions(xmlXPathContextPtr ctxt)
153113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor{
153123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathRegisterFunc(ctxt, (const xmlChar *)"boolean",
153133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor                         xmlXPathBooleanFunction);
153143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathRegisterFunc(ctxt, (const xmlChar *)"ceiling",
153153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor                         xmlXPathCeilingFunction);
153163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathRegisterFunc(ctxt, (const xmlChar *)"count",
153173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor                         xmlXPathCountFunction);
153183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathRegisterFunc(ctxt, (const xmlChar *)"concat",
153193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor                         xmlXPathConcatFunction);
153203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathRegisterFunc(ctxt, (const xmlChar *)"contains",
153213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor                         xmlXPathContainsFunction);
153223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathRegisterFunc(ctxt, (const xmlChar *)"id",
153233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor                         xmlXPathIdFunction);
153243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathRegisterFunc(ctxt, (const xmlChar *)"false",
153253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor                         xmlXPathFalseFunction);
153263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathRegisterFunc(ctxt, (const xmlChar *)"floor",
153273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor                         xmlXPathFloorFunction);
153283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathRegisterFunc(ctxt, (const xmlChar *)"last",
153293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor                         xmlXPathLastFunction);
153303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathRegisterFunc(ctxt, (const xmlChar *)"lang",
153313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor                         xmlXPathLangFunction);
153323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathRegisterFunc(ctxt, (const xmlChar *)"local-name",
153333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor                         xmlXPathLocalNameFunction);
153343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathRegisterFunc(ctxt, (const xmlChar *)"not",
153353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor                         xmlXPathNotFunction);
153363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathRegisterFunc(ctxt, (const xmlChar *)"name",
153373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor                         xmlXPathNameFunction);
153383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathRegisterFunc(ctxt, (const xmlChar *)"namespace-uri",
153393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor                         xmlXPathNamespaceURIFunction);
153403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathRegisterFunc(ctxt, (const xmlChar *)"normalize-space",
153413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor                         xmlXPathNormalizeFunction);
153423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathRegisterFunc(ctxt, (const xmlChar *)"number",
153433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor                         xmlXPathNumberFunction);
153443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathRegisterFunc(ctxt, (const xmlChar *)"position",
153453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor                         xmlXPathPositionFunction);
153463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathRegisterFunc(ctxt, (const xmlChar *)"round",
153473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor                         xmlXPathRoundFunction);
153483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathRegisterFunc(ctxt, (const xmlChar *)"string",
153493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor                         xmlXPathStringFunction);
153503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathRegisterFunc(ctxt, (const xmlChar *)"string-length",
153513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor                         xmlXPathStringLengthFunction);
153523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathRegisterFunc(ctxt, (const xmlChar *)"starts-with",
153533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor                         xmlXPathStartsWithFunction);
153543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathRegisterFunc(ctxt, (const xmlChar *)"substring",
153553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor                         xmlXPathSubstringFunction);
153563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathRegisterFunc(ctxt, (const xmlChar *)"substring-before",
153573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor                         xmlXPathSubstringBeforeFunction);
153583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathRegisterFunc(ctxt, (const xmlChar *)"substring-after",
153593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor                         xmlXPathSubstringAfterFunction);
153603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathRegisterFunc(ctxt, (const xmlChar *)"sum",
153613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor                         xmlXPathSumFunction);
153623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathRegisterFunc(ctxt, (const xmlChar *)"true",
153633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor                         xmlXPathTrueFunction);
153643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathRegisterFunc(ctxt, (const xmlChar *)"translate",
153653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor                         xmlXPathTranslateFunction);
1536642766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard
1536742766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard    xmlXPathRegisterFuncNS(ctxt, (const xmlChar *)"escape-uri",
1536842766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard	 (const xmlChar *)"http://www.w3.org/2002/08/xquery-functions",
1536942766c0eea0fa40c7b721fa4c9cf56b4c484b4c7Daniel Veillard                         xmlXPathEscapeUriFunction);
153703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
153713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
153723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif /* LIBXML_XPATH_ENABLED */
153735d4644ef6e38479a648615eca758c5e962a141d5Daniel Veillard#define bottom_xpath
153745d4644ef6e38479a648615eca758c5e962a141d5Daniel Veillard#include "elfgcchack.h"
15375